jwyu 2 éve
szülő
commit
8c94662f3d

+ 1 - 1
README.md

@@ -8,5 +8,5 @@ https://ybpc.hzinsights.com
 
 开发说明
 1./components/SelfList.vue 为公共列表加载组件。如列表加载逻辑同样 请使用此组件
-2.
+2.mac PC小程序尺寸 1024*720
 

+ 7 - 0
src/api/report.js

@@ -100,4 +100,11 @@ export const apiSpecialColumnReportList=params=>{
  */
 export const apiChapterTickerValue=params=>{
     return get('/report/chapter/ticker',params)
+}
+
+/**
+ * 研报首页上新公告背景图
+ */
+export const apiReportIndexNewbanner=()=>{
+    return get('/pc/banner',{})
 }

BIN
src/assets/audio-pause-big.png


BIN
src/assets/icon-back-top.png


BIN
src/assets/icon-wechat.png


BIN
src/assets/icon-wechat2.png


+ 20 - 14
src/components/Search.vue

@@ -4,46 +4,51 @@ const props=defineProps({
   placeholder:{
     type:String,
     default:'请输入关键词'
+  },
+  disabled:{//是否禁用
+    type:Boolean,
+    default:false
+  },
+  autoFocus:{
+    type:Boolean,
+    default:false
   }
 })
 
 const emit = defineEmits(["search",'clean','blur'])
 let searchData = ref("");
-let isFocus = ref(false);
-let input = ref(null);
+let isFocus=ref(false)
 let showClean = computed(() => {
   return searchData.value.length > 0 ? true : false;
 });
-const handleClick = () => {
+const handleFocus = () => {
   //聚焦到input框上,样式改变
-  isFocus.value = true;
-  input.value.focus();
+  isFocus.value=true
 };
 const handleBlur = () => {
-  if (!showClean.value) {
-    isFocus.value = false;
-  }
-  
+  isFocus.value=false
 };
 const handleClean = () => {
   searchData.value = "";
   emit('clean')
 };
 const handleSearch = ()=>{
-    if(!searchData.value.length) return
-    emit('search',searchData)
+  if(!searchData.value.length) return
+  emit('search',searchData.value)
 }
 </script>
 <template>
-  <div class="search-wrap" @click="handleClick" :class="{ focus: isFocus }">
-    <span v-show="!isFocus"></span>
+  <div :class="['search-wrap',(isFocus||searchData)&&'focus']">
+    <span v-show="!isFocus&&!searchData"></span>
     <input
       type="text"
       :placeholder="props.placeholder"
+      :autofocus="props.autoFocus"
       v-model="searchData"
       @blur="handleBlur"
+      @focus="handleFocus"
       @keyup.enter="handleSearch"
-      ref="input"
+      :disabled="props.disabled"
     />
     <span class="clean" v-show="showClean" @click="handleClean"></span>
   </div>
@@ -80,6 +85,7 @@ const handleSearch = ()=>{
       width: 20px;
       height: 20px;
       margin-right: 0;
+      cursor: pointer;
       background: no-repeat center/cover url("../assets/icon-close.png");
     }
   }

+ 1 - 1
src/layout/Index.vue

@@ -107,7 +107,7 @@ store.state.audioData.INS=globalAudioIns
 }
 .el-main {
   .page-container{
-    min-width: 880px;
+    // min-width: 820px;
     max-width: 1240px;
     margin: 0 auto;
   }

+ 1 - 1
src/layout/component/Aside.vue

@@ -18,7 +18,7 @@ const menuList = reactive([
   {
     MenuId: 1,
     name: "研报",
-    path: "/report/list",
+    path: "/report/index",
     icon_path: new URL('../../assets/leftNav/activity-s.png', import.meta.url).href,
     children: null,
   },

+ 6 - 0
src/layout/component/Header.vue

@@ -202,6 +202,8 @@ const goBack=()=>{
       </div>
       <!-- 图库模块搜索与筛选 -->
       <div id="chart-in-head"></div>
+      <!-- 研报首页搜索 -->
+      <div id="reportIndex-in-head"></div>
     </div>
   </div>
 </template>
@@ -268,6 +270,10 @@ const goBack=()=>{
       float: right;
       height: 100%;
     }
+    #reportIndex-in-head{
+      float: right;
+      height: 100%;
+    }
     
   }
 }

+ 39 - 5
src/router/index.js

@@ -15,7 +15,7 @@ const routes=[
     redirect:'/activity/list',
     component: ()=>import("@/layout/Index.vue"),
   },
-
+  //活动模块
   {
     path: "/activity",
     name: "Activity",
@@ -64,6 +64,7 @@ const routes=[
       }
     ]
   },
+  // 报告模块
   {
     path:'/report',
     name:'Report',
@@ -74,9 +75,9 @@ const routes=[
     },
     children:[
       {
-        path: "list",
+        path: "index",
         name: "ReportList",
-        component: () => import("@/views/report/List.vue"),
+        component: () => import("@/views/report/Index.vue"),
         meta: {
           title: "研报首页",
           keepAlive:true,
@@ -88,8 +89,41 @@ const routes=[
         name: "ReportClassify",
         component: () => import("@/views/report/Classify.vue"),
         meta: {
-          title: "研报分类",
-          keepAlive:true,
+          title: "FICC研报分类",
+          keepAlive:false,
+          isRoot:false,
+          hasBack:true
+        },
+      },
+      {
+        path: "search",
+        name: "ReportSearch",
+        component: () => import("@/views/report/Search.vue"),
+        meta: {
+          title: "研报搜索",
+          keepAlive:false,
+          isRoot:false,
+          hasBack:true
+        },
+      },
+      {
+        path: "detail",
+        name: "ReportDetail",
+        component: () => import("@/views/report/Detail.vue"),
+        meta: {
+          title: "报告详情",
+          keepAlive:false,
+          isRoot:false,
+          hasBack:true
+        },
+      },
+      {
+        path: "chapterdetail",
+        name: "ReportChapterDetail",
+        component: () => import("@/views/report/ChapterDetail.vue"),
+        meta: {
+          title: "报告详情",
+          keepAlive:false,
           isRoot:false,
           hasBack:true
         },

+ 1 - 0
src/store/index.js

@@ -13,6 +13,7 @@ export default createStore({
       loginTop:'https://hzstatic.hzinsights.com/static/icon/hzyb/login_top_img.png',
       idCardExp:'https://hzstatic.hzinsights.com/static/icon/hzyb/idcard_exp.jpg',
       defaultAvatar:'https://hzstatic.hzinsights.com/static/icon/hzyb/default_avatar.png',
+      ficcServiceImg:'https://hzstatic.hzinsights.com/static/icon/hzyb/ficc_service_pc.png'
     },
     token:token,
     userInfo:null,

+ 116 - 28
src/style/global.scss

@@ -4,13 +4,13 @@ body,
 #app {
   width: 100%;
   height: 100%;
-  font-size: 14px;
+  font-size: 16px;
   color: #333;
-  min-width: 1024px;
+  // min-width: 1024px;
 }
 
-div{
-    box-sizing: border-box;
+div {
+  box-sizing: border-box;
 }
 
 ul,
@@ -21,48 +21,54 @@ li {
   box-sizing: border-box;
 }
 
-a{
+a {
   text-decoration: none;
 }
 
 .flex {
   display: flex;
 }
+
 .flex-row-center {
   display: flex;
   justify-content: center;
 }
+
 .flex-col-center {
   display: flex;
   align-items: center;
 }
+
 .flex-row-col-center {
   display: flex;
   justify-content: center;
   align-items: center;
 }
+
 .bg-white {
   background-color: #fff;
 }
+
 .box-shadow {
   border: 1px solid #ececec;
   box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
   border-radius: 4px;
 }
 
-.empty-list{
+.empty-list {
   text-align: center;
   color: #7a7a7a;
-  img{
+
+  img {
     width: 315px;
   }
 }
 
-img{
-  image-rendering: -moz-crisp-edges; 
-  image-rendering: -o-crisp-edges; 
-  image-rendering: -webkit-optimize-contrast; 
-  image-rendering: crisp-edges; 
+img {
+  image-rendering: -moz-crisp-edges;
+  image-rendering: -o-crisp-edges;
+  image-rendering: -webkit-optimize-contrast;
+  image-rendering: crisp-edges;
   -ms-interpolation-mode: nearest-neighbor;
 }
 
@@ -77,46 +83,51 @@ img{
 }
 
 // 全局滚动条样式
-::-webkit-scrollbar{
+::-webkit-scrollbar {
   width: 10px;
   background-color: rgba(0, 0, 0, 0.05);
 }
-::-webkit-scrollbar-thumb{
+
+::-webkit-scrollbar-thumb {
   background: #7a7a7a;
   border-radius: 5px;
 }
 
-.el-message-box__btns{
+.el-message-box__btns {
   justify-content: center;
 }
-.self-elmessage-confirm-btn{
+
+.self-elmessage-confirm-btn {
   background-color: #DAB37C;
   color: #fff;
   border: none;
   width: 90px;
-  &:hover{
-      background-color: #DAB37C;
+
+  &:hover {
+    background-color: #DAB37C;
   }
 }
-.self-elmessage-cancel-btn{
+
+.self-elmessage-cancel-btn {
   background-color: #fff;
   border-color: #DAB37C;
   color: #DAB37C;
   width: 90px;
-  &:hover{
-      background-color: #fff;
+
+  &:hover {
+    background-color: #fff;
   }
 }
 
-.el-popover.el-popper{
+.el-popover.el-popper {
   min-width: 50px;
 }
 
-.el-image-viewer__canvas img{
+.el-image-viewer__canvas img {
   background-color: #fff;
 }
 
-.global-main-btn{
+.global-main-btn {
   text-align: center;
   color: #fff;
   padding: 9px 20px;
@@ -125,25 +136,102 @@ img{
   cursor: pointer;
 }
 
-.global-plain-btn{
+.global-plain-btn {
   text-align: center;
   color: #fff;
   padding: 9px 20px;
   border-radius: 33px;
-  border:1px solid #F3A52F;
+  border: 1px solid #F3A52F;
   cursor: pointer;
   color: #F3A52F;
-  &:hover{
+
+  &:hover {
     background-color: #F3A52F;
     color: #fff;
   }
 }
 
 // 两行省略
-.multi-ellipsis-l2{
+.multi-ellipsis-l2 {
   display: -webkit-box;
   overflow: hidden;
   text-overflow: ellipsis;
   -webkit-line-clamp: 2;
   -webkit-box-orient: vertical;
+}
+
+// 有右边盒子的模块样式
+.hasrightaside-box {
+  display: flex;
+  .content-box{
+    flex:1;
+  }
+
+  .right-aside-box {
+    flex-shrink: 0;
+    width: 240px;
+    border-left: 2px solid #F2F2F2;
+    padding: 30px;
+    background-color: #fff;
+
+    .fix-top {
+      position: fixed;
+      top: 100px;
+    }
+
+    .label {
+      font-size: 18px;
+      font-weight: bold;
+      margin-bottom: 22px;
+
+      &::before {
+        content: '';
+        display: inline-block;
+        width: 3px;
+        height: 17px;
+        background: #F3A52F;
+        border-radius: 2px 2px 2px 2px;
+        margin-right: 10px;
+        position: relative;
+        top: 2px;
+      }
+    }
+
+    .share-box {
+      .icon {
+        cursor: pointer;
+        width: 24px;
+        height: 24px;
+        background-image: url('@/assets/icon-wechat.png');
+        background-size: cover;
+
+        &:hover {
+          background-image: url('@/assets/icon-wechat2.png');
+        }
+      }
+    }
+
+    .hot-box {
+      .img-con {
+        width: 180px;
+        height: 108px;
+        background: linear-gradient(180deg, #282F4B 0%, #586184 100%);
+        box-shadow: 0px 4px 12px 1px rgba(0, 0, 0, 0.06);
+        border-radius: 4px;
+      }
+    }
+
+    .recmd-box {
+      .recmd-item {
+        padding-top: 16px;
+        padding-bottom: 12px;
+        border-bottom: 1px solid #F2F2F2;
+
+        .title {
+          font-weight: bold;
+          margin-bottom: 10px;
+        }
+      }
+    }
+  }
 }

+ 316 - 0
src/views/report/ChapterDetail.vue

@@ -0,0 +1,316 @@
+<script setup>
+import {ref} from 'vue'
+import {apiChapterDetail,apiChapterTickerValue} from '@/api/report'
+import moment from 'moment';
+import AudioBox from './components/AudioBox.vue'
+import { useRoute } from 'vue-router';
+
+const route=useRoute()
+
+let chapterId=ref(route.query.chapterId||'') //章节id
+let frompage=ref(route.query.frompage||'')//如果来自报告详情页 则展示底部章节列表
+
+//获取晨报中指标数据
+let tickerInfo=ref(null)
+let tickerHead=ref([])
+const getTickerValue=async ()=>{
+    const res=await apiChapterTickerValue({report_chapter_id:Number(this.chapterId)})
+    if(res.code===200){
+        if(!res.data||!res.data.list) return
+        tickerInfo.value=res.data
+        if(res.data.ticker_title.report_chapter_type_id===17){
+            tickerHead.value=[
+                {
+                    label:res.data.ticker_title.ticker_title,
+                    key:'base_column_name'
+                },
+                {
+                    label:'公布日期',
+                    key:'date'
+                },
+                {
+                    label:'最新值',
+                    key:'ticker_value'
+                },
+                {
+                    label:'上期值',
+                    key:'last_value'
+                }
+            ]
+        }else{
+            tickerHead.value=[
+                {
+                    label:res.data.ticker_title.ticker_title,
+                    key:'base_column_name'
+                },
+                {
+                    label:res.data.list[0].date,
+                    key:'ticker_value'
+                },
+                {
+                    label:'当日涨跌',
+                    key:'dd_value'
+                },
+                {
+                    label:'一周涨跌',
+                    key:'ww_value'
+                },
+                {
+                    label:'一月涨跌',
+                    key:'mm_value'
+                }
+            ]
+        }
+    }
+}
+
+// 获取章节报告详情
+let info=ref(null)
+let audioData=ref(null)
+const getChapterReportDetail=async ()=>{
+    const res=await apiChapterDetail({
+        report_chapter_id:Number(chapterId.value)
+    })
+    if(res.code===200){
+        info.value=res.data
+        audioData.value={
+            auth_ok:res.data.auth_ok,
+            video_name:res.data.report_chapter_item.video_name,
+            video_size:res.data.report_chapter_item.video_size,
+            video_play_seconds:res.data.report_chapter_item.video_play_seconds,
+            video_url:res.data.report_chapter_item.video_url
+        }
+        document.title=res.data.report_chapter_item.classify_name_first
+        if(res.data.auth_ok&&res.data.report_chapter_item.classify_name_first==='晨报'){
+          getTickerValue()
+        }
+    }
+}
+getChapterReportDetail()
+
+
+
+</script>
+
+<template>
+    <div class="report-chapter-detail-page" v-if="info">
+        <div class="hasrightaside-box">
+            <div class="content-box">
+                <div class="report-box">
+                    <div class="title">【第{{info.report_chapter_item.stage}}期 | {{info.report_chapter_item.classify_name_first}}  | {{info.report_chapter_item.type_name}}】{{info.report_chapter_item.title}}</div>
+                    <div class="time">
+                        <span>FICC团队</span>
+                        <span>{{moment(info.report_chapter_item.publish_time).format('YYYY.MM.DD HH:mm')}}</span>
+                    </div>
+                    <div class="tips">
+                        <span>注:请务必阅读</span>
+                        <span style="color:#F3A52F;margin-left:20px;cursor: pointer;">免责声明</span>
+                    </div>
+                    <AudioBox :data="audioData" v-if="info.report_chapter_item.video_url&&info.report_chapter_item.video_play_seconds>0"></AudioBox>
+                    <div class="abstract" v-if="info.report_chapter_item.abstract">摘要:{{info.report_chapter_item.abstract}}</div>
+                    <div class="rich-content">
+                        <div v-html="info.report_chapter_item.content" v-if="info.auth_ok"></div>
+                        <div v-html="info.report_chapter_item.content_sub" v-else ></div>
+                    </div>
+                    <!-- 指标数据模块 -->
+                    <div class="ticker-wrap" v-if="tickerInfo">
+                        <div class="top-title">{{tickerInfo.ticker_title.report_chapter_type_name}}数据表</div>
+                        <div class="table-box">
+                            <div class="table-row table-head">
+                                <div class="table-item" v-for="item in tickerHead" :key="item.key">{{item.label}}</div>
+                            </div>
+                            <div class="table-row table-body" v-for="(tr,index) in tickerInfo.list" :key="tr.base_column_name">
+                                <div :class="['table-item',index%2==0?'grey':'',tr[td.key]<0?'minus':'']" v-for="td in tickerHead" :key="td.key">{{tr[td.key]}}</div>
+                            </div>
+                        </div>
+                        <div v-if="tickerInfo.ticker_title.report_chapter_type_id ===26" style="text-align:center;font-weight:bold">注:与新加坡TSR20相关数据均取展示日期前一交易日数据</div>
+                    </div>
+                    <!-- 无权限 -->
+                    <div class="no-auth-wrap" v-if="!info.auth_ok">
+                        <div class="apply-box" v-if="info.permission_check.type=='apply'">
+                            <div>您暂无权限查看报告,若想查看请申请开通</div>
+                            <div class="global-main-btn btn" @click="handleGoApply">立即申请</div>
+                        </div>
+                        <div class="apply-box" v-else>
+                            <div>您暂无权限查看报告 </div>
+                            <div>若想查看请联系对口销售:{{info.permission_check.name}}--{{info.permission_check.mobile}}</div>
+                        </div>
+                    </div>
+                </div>
+                <!-- 章节列表 -->
+                <div class="chapter-list-wrap" v-if="frompage=='reportdetail'">
+                    <div class="top-name">更多</div>
+                    <div class="flex list">
+                        <div :class="['item',item.report_chapter_id==chapterId&&'active']" v-for="item in info.report_chapter_menu_list" :key="item.report_chapter_id">
+                            <img :src="item.report_chapter_type_thumb" alt="">
+                            <span>{{item.report_chapter_type_name}}</span>
+                        </div>
+                    </div>
+                </div>
+
+            </div>
+            <div class="right-aside-box">
+                <div class="fix-top">
+                <div class="share-box">
+                    <div class="label">分享</div>
+                    <el-popover 
+                        :width="120" 
+                        popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;"
+                    >
+                        <template #reference><div class="icon"></div></template>
+                        <template #default>
+                            <img src="" class="share-xcx-img" alt="" style="width: 80px;height: 80px;">
+                        </template>
+                    </el-popover>
+                </div>
+                <div class="hot-box" style="margin-top: 60px;">
+                    <div class="label">热门栏目</div>
+                    <div class="img-con"></div>
+                </div>
+                <div class="recmd-box" style="margin-top: 60px;">
+                    <div class="label">更多推荐</div>
+                    <div class="recmd-item">
+                        <div class="title">股债日评</div>
+                        <div>178 | 关注中美领导交流</div>
+                    </div>
+                    <div class="recmd-item">
+                        <div class="title">股债日评</div>
+                        <div>178 | 关注中美领导交流</div>
+                    </div>
+                    <div class="recmd-item">
+                        <div class="title">股债日评</div>
+                        <div>178 | 关注中美领导交流</div>
+                    </div>
+                </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.report-chapter-detail-page{
+
+    .content-box{
+        flex: 1;
+        padding-right: 30px;
+    }
+        
+    .report-box{
+        .title{
+            display: inline;
+            font-size: 24px;
+            font-weight: bold;
+            margin-left: -14px;
+        }
+        .time{
+            color: #666;
+            margin-top: 20px;
+            margin-bottom: 30px;
+            font-size: 16px;
+            span:last-child{
+                float: right;
+            }
+        }
+        .tips{
+            font-size: 18px;
+            margin-bottom: 30px;
+            &::before{
+                content: '';
+                width: 6px;
+                height: 30px;
+                display: inline-block;
+                background-color: #F3A52F;
+                margin-right: 10px;
+                position: relative;
+                top: 10px;
+            }
+        }
+        .abstract{
+            font-size: 18px;
+            font-weight: bold;
+            margin-top: 20px;
+            &::before{
+                content: '';
+                width: 6px;
+                height: 30px;
+                display: inline-block;
+                background-color: #F3A52F;
+                margin-right: 10px;
+                position: relative;
+                top: 10px;
+            }
+        }
+        .rich-content{
+            margin-top: 30px;
+            line-height: 1.8;
+            font-size: 18px;
+            :deep(img){
+                width: 100% !important;
+            }
+            :deep(span){
+                font-size: 18px !important;
+                line-height: 1.8 !important;
+            }
+            :deep(p){
+                font-size: 18px !important;
+                line-height: 1.8 !important;
+            }
+        }
+    }
+    .no-auth-wrap{
+        text-align: center;
+        color: #F3A52F;
+        margin-top: -140px;
+        padding-top: 140px;
+        min-height: 200px;
+        background: linear-gradient(360deg, #FFFFFF 60%, rgba(255, 255, 255, 0) 88%);
+        .btn{
+            width: 218px;
+            margin-left: auto;
+            margin-right: auto;
+            margin-top: 20px;
+        }
+    }
+
+    .chapter-list-wrap{
+        .top-name{
+            text-align: center;
+            color: #F3A52F;
+            font-size: 18px;
+            margin-bottom: 50px;
+            &::before,&::after{
+                content: '';
+                display: inline-block;
+                width: 83px;
+                height: 1px;
+                background-color: #F3A52F;
+                vertical-align: middle;
+                margin: 0 22px;
+            }
+        }
+        .list{
+            flex-wrap: wrap;
+            .item{
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                width: 148px;
+                height: 36px;
+                background-color: #F7F7F7;
+                border-radius: 4px;
+                cursor: pointer;
+                img{
+                    width: 20px;
+                    height: 20px;
+                }
+            }
+            .active{
+                background-color: #F3A52F;
+                color: #fff;
+            }
+        }
+    }
+
+}
+</style>

+ 9 - 3
src/views/report/Classify.vue

@@ -2,13 +2,19 @@
 
 </script>
 <template>
-    <div>
-        研报分类页
+    <div class="report-classify-page">
+        <img :src="$store.state.globalImgUrls.ficcServiceImg" alt=""  class="top-banner">
+        
     </div>
 </template>
 
 
 
 <style lang="scss" scoped>
-
+.report-classify-page{
+    .top-banner{
+        width: 100%;
+        display: block;
+    }
+}
 </style>

+ 85 - 0
src/views/report/Detail.vue

@@ -0,0 +1,85 @@
+<script setup>
+import {ref} from 'vue'
+import {apiReportDetail} from '@/api/report'
+import { useRoute, useRouter } from 'vue-router';
+
+const route=useRoute()
+const router=useRouter()
+
+let reportId=ref(route.query.reportId||'')
+// 获取报告详情
+let info=ref(null)
+let audioData=ref(null)
+const getReportDetail=async ()=>{
+    const res=await apiReportDetail({
+        report_id:Number(reportId.value)
+    })
+    if(res.code===200){
+        info.value=res.data 
+        audioData.value={
+            auth_ok:res.data.auth_ok,
+            video_name:res.data.report_info.video_name,
+            video_size:res.data.report_info.video_size,
+            video_play_seconds:res.data.report_info.video_play_seconds,
+            video_url:res.data.report_info.video_url
+        }
+        document.title = res.data.report_info.classify_name_first
+
+    }
+}
+getReportDetail()
+
+</script>
+
+<template>
+    <div class="report-detail-page">
+        <div class="hasrightaside-box">
+            <div class="content-box">
+
+            </div>
+            <div class="right-aside-box">
+                <div class="fix-top">
+                <div class="share-box">
+                    <div class="label">分享</div>
+                    <el-popover 
+                        :width="120" 
+                        popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;"
+                    >
+                        <template #reference><div class="icon"></div></template>
+                        <template #default>
+                            <img src="" class="share-xcx-img" alt="" style="width: 80px;height: 80px;">
+                        </template>
+                    </el-popover>
+                </div>
+                <div class="hot-box" style="margin-top: 60px;">
+                    <div class="label">热门栏目</div>
+                    <div class="img-con"></div>
+                </div>
+                <div class="recmd-box" style="margin-top: 60px;">
+                    <div class="label">更多推荐</div>
+                    <div class="recmd-item">
+                        <div class="title">股债日评</div>
+                        <div>178 | 关注中美领导交流</div>
+                    </div>
+                    <div class="recmd-item">
+                        <div class="title">股债日评</div>
+                        <div>178 | 关注中美领导交流</div>
+                    </div>
+                    <div class="recmd-item">
+                        <div class="title">股债日评</div>
+                        <div>178 | 关注中美领导交流</div>
+                    </div>
+                </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.report-detail-page{
+    .content-box{
+        
+    }
+}
+</style>

+ 438 - 0
src/views/report/Index.vue

@@ -0,0 +1,438 @@
+<script setup>
+import { apiReportIndexPageAuthList, apiReportIndexPageList,apiReportIndexNewbanner } from '@/api/report'
+import { onMounted, reactive, ref } from "vue"
+import { useRouter } from "vue-router"
+import moment from 'moment'
+import 'moment/dist/locale/zh-cn'
+moment.locale('zh-cn')
+
+import Search from "@/components/Search.vue"
+import SelfList from '@/components/SelfList.vue'
+
+const router = useRouter()
+
+
+// 获取顶部权限分类数据
+let firstTypeList = ref([])//一级分类数据
+let subTypeList = ref([])//二级分类数据
+let selectFirstType = ref('')//选择的一级分类
+let selectSubType = ref('')//选择的二级分类ID
+const getTopPermissionList = async () => {
+  const res = await apiReportIndexPageAuthList()
+  if (res.code === 200) {
+    firstTypeList.value = res.data.permission_list.filter(item => item.sort != 100000)
+    clickFirstType(firstTypeList.value[0])
+  }
+}
+getTopPermissionList()
+
+// 获取报告列表数据
+let reportState = reactive({
+  list: [],
+  page: 1,
+  pageSize: 20,
+  finished: false,
+  loading: false,
+  dateArr: [],//日期数据
+})
+const getReportList = async () => {
+  reportState.loading = true
+  const res = await apiReportIndexPageList({
+    chart_permission_id: Number(selectSubType.value),
+    current_index: reportState.page,
+    page_size: reportState.pageSize
+  })
+  reportState.loading = false
+  if (res.code === 200) {
+    if (res.data.paging.is_end) {
+      reportState.finished = true
+    }
+    //处理数据
+    if (res.data.list) {
+      if(reportState.list.length==0){
+        // 第一页数据
+        reportState.list = res.data.list
+        res.data.list.forEach(item => {
+          reportState.dateArr.push(item.date)
+        })
+      }else {
+        //判断是否前面已经有相同日期数据 有的话添加合并
+        let arr = []
+        let temTimearr = []
+        res.data.list.forEach(item => {
+          if (reportState.dateArr.includes(item.date)) {
+            reportState.list.forEach(_item => {
+              if (item.date === _item.date) {
+                _item.sub_list = [..._item.sub_list, ...item.sub_list]
+              }
+            })
+          } else {
+            arr.push(item)
+            temTimearr.push(item.date)
+          }
+        });
+        reportState.list = [...reportState.list, ...arr]
+        reportState.dateArr = [...reportState.dateArr, ...temTimearr]
+      }
+    }
+  }
+}
+
+//点击顶部一级分类
+const clickFirstType = (item) => {
+  selectFirstType.value = item.classify_name
+  subTypeList.value = item.list
+  clickSubType(item.list[0])
+}
+//点击二级分类
+const clickSubType = (item) => {
+  selectSubType.value = item.chart_permission_id
+  reportState.list = []
+  reportState.page = 1
+  reportState.finished = false
+  getReportList()
+}
+
+// 列表加载更多
+const onLoad=()=>{
+  reportState.page++
+  getReportList()
+}
+
+
+// 获取上新公告
+const getNewAnnounce=async ()=>{
+  // const res1=await apiReportIndexNewbanner()
+}
+getNewAnnounce()
+
+//跳转至研报分类页
+const handleGoMoreClassify = () => {
+  router.push({ path:'/report/classify' });
+};
+
+//跳转报告详情
+const handleGoReportDetail=(item)=>{
+  if(['晨报','周报'].includes(item.classify_name_first)){
+    router.push({
+      path:'/report/chapterdetail',
+      query:{
+        chapterId:item.report_chapter_id
+      }
+    })
+  }else{
+    router.push({
+      path:'/report/detail',
+      query:{
+        reportId:item.report_id
+      }
+    })
+  }
+  
+} 
+
+let isMounted = ref(false);
+onMounted(() => {
+  isMounted.value = true;
+});
+
+// 格式化列表日期
+const formatDate=(e)=>{
+  const isSameYear=moment(e).isSame(new Date(), 'year');
+  if(isSameYear){//今年
+    return moment(e).format('MM.DD')+' '+ moment(e).format('ddd')
+  }else{
+    return moment(e).format('YY.MM.DD')+' '+moment(e).format('ddd')
+  }
+}
+
+</script>
+<template>
+  <!-- 搜索 -->
+  <template v-if="isMounted&&$route.path=='/report/index'">
+    <teleport to="#reportIndex-in-head">
+      <Search
+        style="margin-top: 10px;"
+        placeholder="请输入标题/关键词"
+        :disabled="true"
+        @click="$router.push('/report/search')"
+      ></Search>
+    </teleport>
+  </template>
+  <div class="hasrightaside-box report-list-page">
+    <div class="report-main">
+      <div class="top-nav-wrap">
+        <div class="flex first-nav">
+          <div 
+            :class="['item', item.classify_name == selectFirstType && 'item-active']" 
+            v-for="item in firstTypeList" 
+            :key="item.classify_name" 
+            @click="clickFirstType(item)"
+          >{{ item.classify_name }}</div>
+          <!-- 查看更多 -->
+          <div class="see-more" @click="handleGoMoreClassify">查看更多</div>
+        </div>
+        <div class="flex sub-nav">
+          <span 
+            :class="['sub-item', item.chart_permission_id == selectSubType && 'sub-active']" 
+            v-for="item in subTypeList" 
+            :key="item.chart_permission_id" 
+            @click="clickSubType(item)"
+          >{{ item.chart_permission_name }}</span>
+        </div>
+      </div>
+      <!-- 报告列表 -->
+      <SelfList 
+        :finished="reportState.finished" 
+        :isEmpty="reportState.list.length === 0 && reportState.finished" 
+        :loading="reportState.loading" 
+        @listOnload="onLoad"
+      >
+        <div class="report-list-wrap">
+          <div class="item" v-for="item in reportState.list" :key="item.date">
+            <div class="item-time">{{ formatDate(item.date) }}</div>
+            <div class="content-list">
+              <div class="content-item" v-for="citem in item.sub_list" :key="citem.report_id">
+                <div class="content-box">
+                  <div class="all-btn" @click="handleGoReportDetail(citem)">查看全部</div>
+                  <div class="c-time">{{ moment(citem.publish_time).format('HH:mm:ss')  }}</div>
+                  <div class="c-title">{{ citem.title }}</div>
+                  <div class="desc" v-html="citem.content_sub"></div>
+                  <div class="tags">
+                    <span style="margin-right:30px" v-if="citem.classify_name_first">#{{ citem.classify_name_first }}</span>
+                    <span v-if="citem.classify_name_second">#{{ citem.classify_name_second }}</span>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </SelfList>
+
+    </div>
+    <div class="right-aside-box" style="position: relative;z-index: 100;">
+      <div class="fix-top" style="z-index: 100;">
+        <div class="recmd-box">
+          <div class="label">最新资讯</div>
+          <div class="recmd-item">
+            <div class="title">股债日评</div>
+            <div>178 | 关注中美领导交流</div>
+          </div>
+          <div class="recmd-item">
+            <div class="title">股债日评</div>
+            <div>178 | 关注中美领导交流</div>
+          </div>
+          <div class="recmd-item">
+            <div class="title">股债日评</div>
+            <div>178 | 关注中美领导交流</div>
+          </div>  
+        </div>
+        <div class="hot-box" style="margin-top: 60px;">
+          <div class="label">上新公告</div>
+          <div class="img-con"></div>
+        </div>
+      </div>
+    </div>
+  </div>
+  <!-- 回到顶部 -->
+  <el-backtop :bottom="100" visibility-height="500">
+    <img src="@/assets/icon-back-top.png" alt="" style="width: 60px;">
+  </el-backtop>
+</template>
+
+<style lang="scss" scoped>
+.el-backtop{
+  z-index: 1000;
+}
+$bg-color: #f6f6f6;
+$active-color: #f3a52f;
+
+.report-list-page {
+  position: relative;
+  .report-main {
+    padding-right: 250px;
+    .top-nav-wrap {
+      position: fixed;
+      top: 60px;
+      z-index: 99;
+      background-color: #fff;
+      padding-top: 30px;
+      padding-bottom: 12px;
+      min-width: 880px;
+      max-width: 1240px;
+      width: 100%;
+      border-bottom: 1px solid #f2f2f2;
+      .first-nav {
+        .item {
+          width: 140px;
+          height: 40px;
+          flex-shrink: 0;
+          background: #F6F6F6;
+          border-radius: 20px;
+          text-align: center;
+          line-height: 40px;
+          font-size: 16px;
+          margin-right: 30px;
+          cursor: pointer;
+
+          &:hover {
+            background: #FFFBF5;
+            color: #F3A52F;
+            border: 1px solid #F3A52F;
+            box-shadow: 0px 6px 7px 1px #FFF7EB;
+          }
+        }
+        .item-active {
+          background: #FFFBF5;
+          color: #F3A52F;
+          border: 1px solid #F3A52F;
+          box-shadow: 0px 6px 7px 1px #FFF7EB;
+        }
+        .see-more{
+          color: #f3a52f;
+          font-size: 16px;
+          position: relative;
+          top: 10px;
+          margin-left: 30px;
+          cursor: pointer;
+          &::after{
+            content: '';
+            display: inline-block;
+            width: 16px;
+            height: 16px;
+            background-image: url('../../assets/icon-more.png');
+            background-size: cover;
+            position: relative;
+            top: 2px;
+            left: 5px;
+          }
+        }
+      }
+
+      .sub-nav {
+        margin-top: 30px;
+        overflow-x: scroll;
+
+        &::-webkit-scrollbar {
+          display: none;
+        }
+
+        .sub-item {
+          flex-shrink: 0;
+          margin-right: 30px;
+          font-size: 16px;
+          color: #666666;
+          cursor: pointer;
+        }
+
+        .sub-active {
+          color: #F3A52F;
+        }
+      }
+    }
+
+    .report-list-wrap {
+      margin-top: 120px;
+      .item{
+        margin-bottom: 30px;
+      }
+      .item-time {
+        font-size: 16px;
+        margin-bottom: 40px;
+      }
+
+      .content-list {
+        padding-left: 20px;
+        .content-box {
+          padding: 0 0px 20px 14px;
+          position: relative;
+          .all-btn {
+            position: absolute;
+            right: 20px;
+            bottom: 20px;
+            width: 88px;
+            height: 30px;
+            line-height: 30px;
+            background: #FFFBF5;
+            border-radius: 15px;
+            border: 1px solid #F3A52F;
+            color: #F3A52F;
+            font-size: 14px;
+            text-align: center;
+            cursor: pointer;
+          }
+        }
+
+        .content-item {
+          padding: 0 0 50px 20px;
+          border-left: 1px solid #F3A52F;
+          position: relative;
+
+          &:last-child {
+            border-bottom: none;
+            padding-bottom: 0px;
+          }
+
+          &::before {
+            content: '';
+            display: block;
+            box-sizing: border-box;
+            width: 14px;
+            height: 14px;
+            border-radius: 50%;
+            border: 3px solid #FADBAC;
+            position: absolute;
+            left: 0;
+            top: 0;
+            background: #F3A52F;
+            transform: translate(-50%, -50%);
+            z-index: 2;
+          }
+
+          &::after {
+            content: '';
+            display: block;
+            width: 20px;
+            height: 1px;
+            background-color: #F3A52F;
+            position: absolute;
+            top: 0;
+            left: 0;
+            z-index: 1;
+          }
+
+          .c-time {
+            position: relative;
+            top: -8px;
+            font-size: 14px;
+            color: #666;
+          }
+
+          .c-title {
+            font-size: 16px;
+            font-weight: bold;
+            word-wrap: break-word;
+            white-space: normal;
+            word-break: break-all;
+            margin-top: 5px;
+          }
+
+          .desc {
+            line-height: 1.5;
+            margin-top: 10px;
+            color: #666666;
+            font-size: 14px;
+          }
+
+          .tags {
+            margin-top: 14px;
+            color: #F3A52F;
+            min-height: 30px;
+          }
+        }
+      }
+    }
+
+  }
+}
+</style>

+ 0 - 376
src/views/report/List.vue

@@ -1,376 +0,0 @@
-<script setup>
-import {apiReportIndexPageAuthList,apiReportIndexPageList} from '@/api/report'
-import { computed, onMounted, reactive, ref } from "vue";
-import { useRouter } from "vue-router";
-import throttle from "lodash/throttle";
-import Search from "@/components/Search.vue";
-
-const router = useRouter();
-
-
-// 获取顶部权限分类数据
-let firstTypeList=ref([])//一级分类数据
-let subTypeList=ref([])//二级分类数据
-let selectFirstType=ref('')//选择的一级分类
-let selectSubType=ref('')//选择的二级分类ID
-const getTopPermissionList=async ()=>{
-  const res=await apiReportIndexPageAuthList()
-  if(res.code===200){
-    firstTypeList.value=res.data.permission_list.filter(item=>item.sort!=100000)
-    clickFirstType(firstTypeList.value[0])
-  }
-}
-getTopPermissionList()
-
-// 获取报告列表数据
-let reportState=reactive({
-  list:[],
-  page:1,
-  pageSize:20,
-  finished:false,
-  loading:false,
-  dateArr:[],//日期数据
-})
-const getReportList=async ()=>{
-  reportState.loading=true
-  const res=await apiReportIndexPageList({
-    chart_permission_id:Number(selectSubType.value),
-    current_index:reportState.page,
-    page_size:reportState.pageSize
-  })
-  reportState.loading=false 
-  if(res.code===200){
-    if(res.data.paging.is_end){
-      reportState.finished=true
-    }
-    //处理数据
-    if(res.data.list){
-      // 第一页数据
-      reportState.list=res.data.list
-      res.data.list.forEach(item=>{
-        reportState.dateArr.push(item.date)
-      })
-    }else{
-      //判断是否前面已经有相同日期数据 有的话添加合并
-      let arr=[]
-      let temTimearr=[]
-      res.data.list.forEach(item => {
-        if(reportState.dateArr.includes(item.date)){
-          this.list.forEach(_item=>{
-            if(item.date===_item.date){
-              _item.sub_list=[..._item.sub_list,...item.sub_list]
-            }
-          })
-        }else{
-          arr.push(item)
-          temTimearr.push(item.date)
-        }
-      });
-      reportState.list=[...this.list,...arr]
-      reportState.dateArr=[...this.dateArr,...temTimearr]
-    }
-  }
-}
-
-//点击顶部一级分类
-const clickFirstType=(item)=>{
-  selectFirstType.value=item.classify_name
-  subTypeList.value=item.list
-  clickSubType(item.list[0])
-}
-//点击二级分类
-const clickSubType=(item)=>{
-  selectSubType.value=item.chart_permission_id
-  reportState.list=[]
-  reportState.page=1
-  reportState.finished=false
-  getReportList()
-}
-
-
-let icon_more_path = new URL("../../assets/icon-more.png", import.meta.url).href; //查看更多的icon
-let mounted = ref(false);
-
-
-
-let showBackTop = ref(false); //是否显示回到顶部按钮
-
-const backToTop = () => {
-  window.scrollTo({ top: 0, behavior: "smooth" });
-};
-
-
-const toClassPage = () => {
-  //跳转至研报分类页
-  router.push({ name: "ReportClassify" });
-};
-
-onMounted(() => {
-  mounted.value = true;
-});
-</script>
-<template>
-  <div class="report-list-page">
-    <div class="report-main">
-      <div class="top-nav-wrap">
-        <div class="flex first-nav">
-          <div 
-            :class="['item',item.classify_name==selectFirstType&&'item-active']" 
-            v-for="item in firstTypeList" 
-            :key="item.classify_name"
-            @click="clickFirstType(item)"
-          >{{item.classify_name}}</div>
-        </div>
-        <div class="flex sub-nav">
-          <span 
-            :class="['sub-item',item.chart_permission_id==selectSubType&&'sub-active']"
-            v-for="item in subTypeList"
-            :key="item.chart_permission_id"
-            @click="clickSubType(item)"
-          >{{item.chart_permission_name}}</span>
-        </div>
-      </div>
-    </div>
-    <div class="report-aside">
-      <div class="aside-item">
-        <div class="aside-title">最新资讯</div>
-        <div class="infomation-wrap">
-          <div class="infomation-item" v-for="item in informationData" :key="item.title">
-            <div class="item-title">{{ item.title }}</div>
-            <div class="item-content">{{ item.no }}|{{ item.main }}</div>
-          </div>
-        </div>
-      </div>
-      <div class="aside-item">
-        <div class="aside-title" style="margin-top: 60px">上新公告</div>
-        <div class="annoucement">
-          <div class="title">行业调研</div>
-          <p class="content">带您感知最微观的行业变化</p>
-        </div>
-      </div>
-    </div>
-
-    <transition name="fade">
-      <div class="back-top" v-show="showBackTop" @click="backToTop"></div>
-    </transition>
-  </div>
-  <!-- <template v-if="mounted">
-    <teleport to=".head-main">
-      <Search
-        @search="handleSearch"
-        @clean="changePageStyle('normal')"
-      ></Search>
-    </teleport>
-  </template> -->
-</template>
-
-<style lang="scss" scoped>
-$bg-color: #f6f6f6;
-$active-color: #f3a52f;
-
-.report-list-page {
-  position: relative;
-  .report-main {
-    .top-nav-wrap{
-      .first-nav{
-        .item{
-          width: 140px;
-          height: 40px;
-          background: #F6F6F6;
-          border-radius: 20px;
-          text-align: center;
-          line-height: 40px;
-          font-size: 16px;
-          margin-right: 30px;
-          cursor: pointer;
-          &:hover{
-            background: #FFFBF5;
-            color: #F3A52F;
-            border: 1px solid #F3A52F;
-            box-shadow: 0px 6px 7px 1px #FFF7EB;
-          }
-        }
-        .item-active{
-          background: #FFFBF5;
-          color: #F3A52F;
-          border: 1px solid #F3A52F;
-          box-shadow: 0px 6px 7px 1px #FFF7EB;
-        }
-      }
-      .sub-nav{
-        margin-top: 30px;
-        overflow-x: scroll;
-        &::-webkit-scrollbar{display:none;}
-        .sub-item{
-          flex-shrink: 0;
-          margin-right: 30px;
-          font-size: 16px;
-          color: #666666;
-          cursor: pointer;
-        }
-        .sub-active{
-          color: #F3A52F;
-        }
-      }
-    }
-    
-  }
-
-  .report-aside {
-    position: absolute;
-    top: -20px;
-    bottom: -20px;
-    right: -20px;
-    width: 240px;
-    box-sizing: border-box;
-    padding: 30px;
-    border-left: 2px solid #f2f2f2;
-
-    .aside-title {
-      font-size: 18px;
-      color: #333333;
-
-      &::before {
-        content: "";
-        display: inline-block;
-        width: 3px;
-        height: 17px;
-        background-color: $active-color;
-        margin-right: 10px;
-      }
-    }
-
-    .infomation-wrap {
-      margin-top: 20px;
-      font-size: 14px;
-
-      .infomation-item {
-        margin-top: 20px;
-        padding-bottom: 12px;
-        border-bottom: 1px solid #f2f2f2;
-        cursor: pointer;
-
-        .item-title {
-          color: #333333;
-          margin-bottom: 10px;
-        }
-
-        .item-content {
-          color: #666666;
-        }
-
-        &:hover {
-
-          .item-title,
-          .item-content {
-            color: $active-color;
-            transition: 0.3s;
-          }
-        }
-      }
-    }
-
-    .annoucement {
-      margin-top: 20px;
-      padding: 18px;
-      height: 110px;
-      border: 1px solid black;
-      border-radius: 5px;
-      background: no-repeat center/cover url("../../assets/announce-pic.png");
-
-      /*  background-image: url("../../assets/announce-pic.png");
-        background-repeat: no-repeat;
-        background-position: center;
-        background-size: cover; */
-      .title {
-        color: #cfc09f;
-        font-size: 18px;
-      }
-
-      .content {
-        color: #cfc09f;
-        line-height: 18px;
-      }
-    }
-  }
-
-  .back-top {
-    position: fixed;
-    z-index: 2000;
-    cursor: pointer;
-    width: 60px;
-    height: 60px;
-    bottom: 110px;
-    right: 30px;
-    border-radius: 50%;
-    background-color: #ffffff;
-    border: 2px solid #e6e6e6;
-    box-shadow: 0px 0px 6px #e3e3e3;
-
-    &::before {
-      content: "";
-      width: 0;
-      display: block;
-      margin: auto;
-      border: 17px solid $active-color;
-      border-color: transparent transparent $active-color transparent;
-    }
-  }
-
-  .search-main {
-    .search-item {
-      cursor: pointer;
-      padding: 30px;
-      width: 820px;
-      margin: 20px auto;
-      background-color: #ffffff;
-      border: 1px solid #e5e5e5;
-      box-shadow: 3px 3px 12px rgba(184, 184, 184, 0.16);
-      border-radius: 4px;
-
-      &:first-child {
-        margin-top: 0px;
-      }
-
-      .search-title {
-        color: #333333;
-        font-size: 18px;
-      }
-
-      .search-content {
-        font-size: 14px;
-        color: #666666;
-        margin: 15px 0;
-        max-height: 50px;
-      }
-
-      .search-label {
-        display: inline-block;
-        font-size: 14px;
-        color: $active-color;
-        margin-right: 30px;
-
-        &:last-child {
-          margin-right: 0;
-        }
-      }
-
-      .search-time {
-        float: right;
-        color: #999999;
-      }
-    }
-
-  }
-
-  .fade-enter-active,
-  .fade-leave-active {
-    transition: opacity 0.3s ease;
-  }
-
-  .fade-enter-from,
-  .fade-leave-to {
-    opacity: 0;
-  }
-}
-</style>

+ 123 - 0
src/views/report/Search.vue

@@ -0,0 +1,123 @@
+<script setup>
+import {onMounted,reactive,ref} from 'vue'
+import {apiReportSearch} from '@/api/report'
+import moment from 'moment'
+import Search from "@/components/Search.vue"
+import SelfList from '@/components/SelfList.vue'
+
+let listState=reactive({
+    list:[],
+    page:1,
+    pageSize:20,
+    finished:false,
+    loading:false,
+    keyword:''
+})
+const getSearchList=async ()=>{
+    listState.loading=true
+    const res=await apiReportSearch({
+        key_word:listState.keyword,
+        current_index:listState.page,
+        page_size:listState.pageSize
+    })
+    listState.loading=false
+    if(res.code===200){
+        if(res.data.paging.is_end){
+            listState.finished=true
+        }
+        let arr=res.data.list||[]
+        listState.list=[...listState.list,...arr]
+    }
+}
+
+
+const handleSearch=(e)=>{
+    listState.page=1
+    listState.list=[]
+    listState.finished=false
+    listState.keyword=e
+    getSearchList()
+}
+
+let isMounted = ref(false);
+onMounted(() => {
+  isMounted.value = true;
+});
+</script>
+
+<template>
+    <!-- 搜索 -->
+    <template v-if="isMounted&&$route.path=='/report/search'">
+        <teleport to="#reportIndex-in-head">
+            <Search
+                style="margin-top: 10px;"
+                placeholder="请输入标题/关键词"
+                :autoFocus="true"
+                @search="handleSearch"
+            ></Search>
+        </teleport>
+    </template>
+    <div class="report-search-page" v-if="listState.keyword">
+        <SelfList 
+            :finished="listState.finished" 
+            :isEmpty="listState.list.length === 0 && listState.finished" 
+            :loading="listState.loading" 
+            @listOnload="onLoad"
+        >
+        <div class="search-list-wrap">
+            <div class="item" v-for="item in listState.list" :key="item.report_id+item.report_chapter_id">
+                <div class="title" v-html="item.title"></div>
+                <div class="des" v-html="item.content_sub"></div>
+                <div class="tags">
+                    <span v-if="item.classify_name_first">#{{item.classify_name_first}}</span>
+                    <span v-if="item.classify_name_second">#{{item.classify_name_second}}</span>
+                    <span class="time">{{moment(item.publish_time).format('YYYY年MM月DD日 HH:mm')}}</span>
+                </div>
+            </div>
+        </div>
+        </SelfList>
+
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.report-search-page{
+    .search-list-wrap{
+        .item{
+            background: #FFFFFF;
+            box-shadow: 3px 3px 12px 1px rgba(184, 184, 184, 0.16);
+            border-radius: 4px;
+            border: 1px solid #E5E5E5;
+            padding: 30px;
+            margin-bottom: 20px;
+            cursor: pointer;
+            .title{
+                font-size: 18px;
+                :deep(span){
+                    color: #F3A52F !important;
+                }
+            }
+            .des{
+                font-size: 14px;
+                margin: 10px 0;
+                line-height: 18px;
+                :deep(span){
+                    color: #F3A52F !important;
+                }
+            }
+            .tags{
+                span{
+                    font-size: 14px;
+                    color: #F3A52F;
+                    margin-right: 30px;
+                }
+                .time{
+                    float: right;
+                    color: #999999;
+                }
+            }
+        }
+    }
+}
+
+</style>

+ 60 - 0
src/views/report/components/AudioBox.vue

@@ -0,0 +1,60 @@
+<script setup>
+const props=defineProps({
+    data:{
+        type:Object
+    }
+})
+
+const formatVoiceTime = (e) => {
+  let minus = parseInt(e / 60);
+  let sec = parseInt(e % 60);
+  return `${minus > 9 ? minus : "0" + minus}:${sec > 9 ? sec : "0" + sec}`;
+};
+
+</script>
+
+<template>
+    <div class="flex audio-box">
+        <img class="img" src="@/assets/audio-pause-big.png" alt="">
+        <div class="content">
+            <div class="name">{{props.data.video_name}}</div>
+            <div class="des">
+                <span>主讲人:FICC团队</span>
+                <span>大小:{{props.data.video_size}}M</span>
+                <span>时长:{{formatVoiceTime(props.data.video_play_seconds)}}</span>
+            </div>
+        </div>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.audio-box{
+    background: #FFFBF5;
+    border-radius: 8px 8px 8px 8px;
+    border: 1px solid rgba(243, 165, 47, 0.6);
+    padding: 15px 20px;
+    align-items: center;
+    .img{
+        width: 70px;
+        height: 70px;
+        flex-shrink: 0;
+        margin-right: 20px;
+        background-color: #fff;
+        cursor: pointer;
+    }
+    .content{
+        flex: 1;
+        .name{
+            font-weight: bold;
+            margin-bottom: 18px;
+        }
+        .des{
+            span{
+                color: #666;
+                font-size: 14px;
+                margin-right: 20px;
+            }
+        }
+    }
+}
+</style>

+ 0 - 188
src/views/report/staticData.js

@@ -1,188 +0,0 @@
-//品种数据
-const varietyData = [{
-        key: '',
-        label: '宏观经济',
-        child: [{
-                label: '宏观',
-            },
-            {
-                label: '利率债'
-            }
-        ]
-    },
-    {
-        label: '化工',
-        child: [{
-                label: '原油'
-            },
-            {
-                label: '沥青',
-                alias: ['BU']
-            },
-            {
-                label: 'PTA'
-            },
-            {
-                label: 'MEG',
-                alias: ['EG', '乙二醇']
-            },
-            {
-                label: '聚酯',
-                alias: ['长丝', '短纤', '瓶片']
-            },
-            {
-                label: '织造终端'
-            },
-            {
-                label: '纯苯+苯乙烯',
-                alias: ['EB']
-            },
-            {
-                label: '甲醇',
-                alias: ['MA']
-            },
-            {
-                label: '聚烯烃',
-                alias: ['PP', 'PE']
-            },
-            {
-                label: '橡胶',
-                alias: ['RU']
-            },
-            {
-                label: 'PVC'
-            }
-        ]
-    },
-    {
-        label: '黑色',
-        child: [{
-                label: '钢材'
-            },
-            {
-                label: '铁矿'
-            },
-            {
-                label: '双焦(焦煤、焦炭)'
-            },
-            {
-                label: '玻璃纯碱',
-                alias: ['玻璃', '纯碱', 'FG', 'SA']
-            }
-        ]
-    },
-    {
-        label: '有色',
-        child: [{
-                label: '有色(铜、铝)'
-            },
-            {
-                label: '有色(锌、铅)'
-            },
-            {
-                label: '镍+不锈钢'
-            },
-            {
-                label: '钴锂'
-            }
-        ]
-    }
-]
-//mock 最新资讯数据
-const informationData = [{
-        title: '股债日评',
-        no: 178,
-        main: '关注中美领导交流'
-    },
-    {
-        title: '知白守黑日度点评',
-        no: 190,
-        main: '关注中美领导交流'
-    },
-    {
-        title: '甲醇库存数据点评',
-        no: 230,
-        main: '甲醇库存甲醇库存甲醇库存甲醇库存'
-    }
-]
-//mock 研报首页数据
-const reportData = [{
-    timeLabel: '3.28周一',
-    child: [{
-        timeLabel: '15:40:40',
-        title: '关注中美领导交流',
-        abstract: '中美领导视频会在本周进行,从会前吹风来看,中美在碳中和和关税上存在政策诉求。如果中美关税下调,则人民币会有明确的升值反应。中美领导视频会在本周进行,从会前吹风来看,中美在碳中和和关税上存在政策诉求。如果中美关税下调,则人民币会有明确的升值反应。',
-        label:['双周报','宏观双周报']
-    },{
-        timeLabel: '15:42:40',
-        title: '啦啦啦啦',
-        abstract: '随便写点什么',
-        label:['宏观双周报']
-    },{
-        timeLabel: '15:40:49',
-        title: '关注中美领导交流',
-        abstract: 'aaaa',
-        label:['双周报','宏观双周报']
-    },{
-        timeLabel: '15:42:48',
-        title: '啦啦啦啦',
-        abstract: '随便写点什么',
-        label:['宏观双周报']
-    }
-]
-},{
-    timeLabel: '3.29周二',
-    child: [{
-        timeLabel: '15:40:40',
-        title: '关注中美领导交流',
-        abstract: 'aaaa',
-        label:['双周报','宏观双周报']
-    },{
-        timeLabel: '15:42:40',
-        title: '啦啦啦啦',
-        abstract: '随便写点什么',
-        label:['宏观双周报']
-    }
-]
-}
-]
-//mock 首页的搜索数据
-const searchData = [
-    {
-        title:'地产政策的变化和影响',
-        abstract:'中美领导视频会在本周进行,从会前吹风来看,中美在碳中和和关税上存在政策诉求。如果中美关税下调,则人民币会有明确的升值反应。中美领导视频会在本周进行,从会前吹风来看,中美在碳中和和关税上存在政策诉求。如果中美关税下调,则人民币会有明确的升值反应。中美在碳中和和关税上存在政策诉求。如果中美关税下调,则人民币会有明确的升值反应。中美领导视频会在本周进行,从会前吹中美在碳中和和关税上存在政策诉求。如果中美关税下调,则人民币会有明确的升值反应。中美领导视频会在本周进行,从会前吹',
-        label:['双周报','煤炭双周报'],
-        time:'2021年8月31日 15:30'
-    },
-    {
-        title:'地产政策的变化和影响2',
-        abstract:'abjahajh',
-        label:['双周报','煤炭双周报'],
-        time:'2021年8月31日 15:30'
-    },
-    {
-        title:'地产政策的变化和影响3',
-        abstract:'abjahajh',
-        label:['双周报','煤炭双周报'],
-        time:'2021年8月31日 15:30'
-    },
-    {
-        title:'地产政策的变化和影响4',
-        abstract:'abjahajh',
-        label:['双周报','煤炭双周报'],
-        time:'2021年8月31日 15:30'
-    },
-    {
-        title:'地产政策的变化和影响5',
-        abstract:'abjahajh',
-        label:['双周报','煤炭双周报'],
-        time:'2021年8月31日 15:30'
-    }
-]
-
-export {
-    varietyData,
-    informationData,
-    reportData,
-    searchData
-}