Selaa lähdekoodia

Merge branch 'master' into xqc_640

bding 1 vuosi sitten
vanhempi
commit
8f34c854f4

+ 1 - 1
.env.product

@@ -9,4 +9,4 @@ VITE_APP_HZSL_BASEAPIURL="https://openapi.hzinsights.com/api"
 
 VITE_APP_HTGJ_BASEAPIURL="https://cygx.hzinsights.com/api"
 
-VITE_APP_SSBG_BASEAPIURL="https://ficc.hzinsights.com/h5adminapi"
+VITE_APP_SSBG_BASEAPIURL="https://ssbg.hzinsights.com/h5adminapi"

+ 1 - 0
package.json

@@ -20,6 +20,7 @@
     "normalize.css": "^8.0.1",
     "vant": "^3.3.4",
     "vue": "^3.2.16",
+    "vue-pdf-embed": "^1.1.6",
     "vue-router": "^4.0.12",
     "vuex": "^4.0.2"
   },

+ 14 - 0
src/api/ssbg/api.js

@@ -10,6 +10,13 @@ export const researcherList = params=>{
 	return get('/roadshow/researcher/list',params)
 }
 
+/**
+ * 路演销售员列表
+ */
+export const sellerList = params=>{
+	return get('/custom/seller/roadshow_ficc/list',params)
+}
+
 /**
  * 研究员日历日程 StartDate  EndDate ResearcherId
  */
@@ -17,6 +24,13 @@ export const researchEvents = params => {
 	return get('/roadshow/researcher/calendar/detail', params)
 }
 
+/**
+ * 销售员日历日程 StartDate  EndDate SellerId
+ */
+ export const sellerEvents = params => {
+	return get('/roadshow/seller/calendar/detail', params)
+}
+
 /**
  * 我的日历日程 StartDate  EndDate
  */

+ 6 - 1
src/api/ssbg/http.js

@@ -35,7 +35,12 @@ _axios.interceptors.request.use(
 _axios.interceptors.response.use(
   function (response) {
     // Do something with response data
-    
+    if(response.data.code===403){
+      wx.miniProgram.reLaunch({
+        url:"/pages/login/login"
+      })
+      return
+    }
     return response.data;
   },
   function (error) {

BIN
src/assets/hzyb/chart/calendar-new-1.png


BIN
src/assets/hzyb/chart/more.png


BIN
src/assets/hzyb/chart/search-new-1.png


+ 5 - 0
src/router/hzyb/index.js

@@ -61,6 +61,11 @@ export const hzybRoutes=[
                 name:"hzybChapterDetail",
                 component: () => import("@/views/hzyb/report/ChapterDetail.vue"),
             },
+            {
+                path:"previewpdf",
+                name:"hzybPreviewPDF",
+                component:() => import("@/views/hzyb/report/PreviewPDF.vue")
+            }
         ]
     }
 ]

+ 5 - 0
src/router/ssbg/index.js

@@ -15,6 +15,11 @@ export const ssbgRoutes = [
 				path: 'researcher',
 				name: 'researcherCalendar',
 				component: () => import("@/views/ssbg/roadshow/rsCalendar.vue")
+			},
+			{
+				path: 'seller',
+				name: 'sellerCalendar',
+				component: () => import("@/views/ssbg/roadshow/sellerCalendar.vue")
 			}
 		]
 	},

+ 35 - 0
src/views/cygx/loadog.vue

@@ -0,0 +1,35 @@
+<script setup>
+import { onMounted, ref } from "vue";
+const props = defineProps({
+  loadingShow: {
+    type: Boolean,
+    required: true,
+    default: false,
+  },
+});
+</script>
+
+<template>
+  <div class="container-loading" v-if="loadingShow">
+    <img src="https://hzchart.oss-cn-shanghai.aliyuncs.com/cygx/loading_all.gif" alt="" />
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.container-loading {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 10000;
+  // background-color: rgba(0, 0, 0, 0.6);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  img {
+    width: 110px;
+    height: 110px;
+  }
+}
+</style>

+ 18 - 1
src/views/cygx/strategyReport.vue

@@ -1,19 +1,36 @@
 <script setup>
 import { onMounted, ref } from "vue";
 import { useRoute } from "vue-router";
+import LoadingPage from "./loadog.vue";
 const route = useRoute();
 const srcUrl = ref("");
 const pc = ref("");
+const loadingShow = ref(true);
 onMounted(() => {
   document.domain = "hzinsights.com";
+  const iframe = document.querySelector("#iframe");
   srcUrl.value = decodeURIComponent(route.query.url);
   pc.value = route.query.pc || "";
+  if (iframe.attachEvent) {
+    iframe.attachEvent("onload", () => {
+      setTimeout(() => {
+        loadingShow.value = false;
+      }, 300);
+    });
+  } else {
+    iframe.onload = () => {
+      setTimeout(() => {
+        loadingShow.value = false;
+      }, 500);
+    };
+  }
 });
 </script>
 
 <template>
   <div :class="[pc ? 'container-strategy-pc' : 'container-strategy']">
-    <iframe :src="srcUrl" class="strategy-iframe" frameborder="0" />
+    <iframe :src="srcUrl" class="strategy-iframe" frameborder="0" id="iframe" />
+    <LoadingPage :loadingShow="loadingShow" />
   </div>
 </template>
 

+ 195 - 58
src/views/hzyb/chart/Detail.vue

@@ -3,7 +3,7 @@ import chartBox from './component/chartBox.vue'
 import noAuth from './component/noAuth.vue'
 import sharePoster from '../components/SharePoster.vue'
 import collectBox from './component/collectBox.vue'
-import { Popup, Toast,Picker,Icon } from 'vant';
+import { Popup, Toast,Picker,Icon,Tab,Tabs,ActionSheet} from 'vant';
 import {ref,onMounted, reactive, watch,computed,nextTick} from 'vue'
 import {useRoute, useRouter,onBeforeRouteUpdate} from 'vue-router'
 import moment from 'moment'
@@ -90,9 +90,32 @@ getUserInfo()
 let showDate=ref(false)
 let startDate=ref('')
 let endDate=ref('')
-let columns=ref([])
+// 开始-结束时间picker相关信息
+const pickerInfo=reactive({
+    tabIndex:'1'
+})
+// picker使用数据
+const dateRange=[]
+const DateConfirm=(data,dateType)=>{
+    if(dateType=='start'){
+        if(resData.value.ChartInfo.ChartType===2){
+            dateRange[0]=data[0]
+        }else{
+            dateRange[0]=data[0]+'-'+data[1]
+        }
+    }else{
+        if(resData.value.ChartInfo.ChartType===2){
+            dateRange[1]=data[0]
+        }else{
+            dateRange[1]=data[0]+'-'+data[1]
+        }
+    }
+}
+
+let columnsStart=ref([])
+let columnsEnd=ref([])
 // type 1:年-月 2:年
-const makeTimeData=(type)=>{
+const makeTimeData=(type,dateType)=>{
     let curYear=new Date().getFullYear()
     let yearArr=[]
     let monthArr=[]
@@ -102,45 +125,46 @@ const makeTimeData=(type)=>{
     for (let i = 1; i < 13; i++) {
         monthArr.push(i<10?'0'+i:i.toString())
     }
+    const date = dateType=='start'?startDate:endDate
     if(type==1){
-        let index1=yearArr.indexOf(startDate.value.split('-')[0])
-        let index2=monthArr.indexOf(startDate.value.split('-')[1])
-        let index3=yearArr.indexOf(endDate.value.split('-')[0])
-        let index4=monthArr.indexOf(endDate.value.split('-')[1])
+        let index1=yearArr.indexOf(date.value.split('-')[0])
+        let index2=monthArr.indexOf(date.value.split('-')[1])
         return [
             {values:yearArr,defaultIndex: index1>-1?index1:yearArr.length-1},
-            {values:monthArr,defaultIndex: index2>-1?index2:monthArr.length-1},
-            {values:yearArr,defaultIndex: index3>-1?index3:yearArr.length-1},
-            {values:monthArr,defaultIndex: index4>-1?index4:monthArr.length-1}
+            {values:monthArr,defaultIndex: index2>-1?index2:monthArr.length-1}
         ]
     }else{
-        let index1=yearArr.indexOf(startDate.value)
-        let index2=yearArr.indexOf(endDate.value)
+        let index1=yearArr.indexOf(date)
         return [
-            {values:yearArr,defaultIndex: index1>-1?index1:yearArr.length-1},
-            {values:yearArr,defaultIndex: index2>-1?index2:yearArr.length-1}
+            {values:yearArr,defaultIndex: index1>-1?index1:yearArr.length-1}
         ]
     }
 }
 const handleShowDate=()=>{
     // if(columns.value.length===0){
         if( sameOptionType.value.includes(resData.value.ChartInfo.ChartType)){//曲线图
-            columns.value=makeTimeData(1)
+            columnsStart.value=makeTimeData(1,'start')
+            columnsEnd.value=makeTimeData(1,'end')
         }else if(resData.value.ChartInfo.ChartType===2){//季节性图表
-            columns.value=makeTimeData(2)
+            columnsStart.value=makeTimeData(2,'start')
+            columnsEnd.value=makeTimeData(2,'end')
         }
     // }
     showDate.value=true
 }
+const startPicker=ref(null)
+const endPicker=ref(null)
+
 // 确定选择时间
-const handleConfirmDate=(e)=>{
+const handleConfirmDate=()=>{
+    startPicker.value.confirm()
+    endPicker.value.confirm()
+    
     let start='',end=''
-    if(sameOptionType.value.includes(resData.value.ChartInfo.ChartType)){
-        start=e[0]+'-'+e[1]
-        end=e[2]+'-'+e[3]
-    }else if(resData.value.ChartInfo.ChartType===2){
-        start=e[0]
-        end=e[1]
+    if(sameOptionType.value.includes(resData.value.ChartInfo.ChartType)
+    || resData.value.ChartInfo.ChartType===2){
+        start=dateRange[0]
+        end=dateRange[1]
     }
     if(new Date(end)>=new Date(start)){
         startDate.value=start
@@ -153,6 +177,20 @@ const handleConfirmDate=(e)=>{
     }
 }
 
+const actionSheetShow=ref(false)
+const actions=computed(()=>{
+    return canSave.value&&![3,4,6,7,8,9].includes(chartSource)?[{ name: '刷新' },{ name: '保存' },{ name: '生成海报' }]:
+                            [{ name: '刷新' },{ name: '生成海报' }]
+})
+const onActionSelect=(action,index)=>{
+    if(action.name=='刷新'){
+        handleRefreshChart()
+    }else if(action.name=='保存'){
+        handleSaveChart()
+    }else if(action.name=='生成海报'){
+        $('.share-poster-wrap div')[0].click()
+    }
+}
 // 选择年份时间段
 let dateTypeList=ref([
     {
@@ -509,6 +547,7 @@ const initBarData = (data) => {
 const setBarChart = () => {
     let seriesData = [];
     const data = _.cloneDeep(barDateList.value);
+    const { ChartInfo } = resData.value;
 
     //x轴
     let xAxis = {
@@ -530,7 +569,7 @@ const setBarChart = () => {
     let yAxis = {
         ...basicYAxis,
         title: {
-            text:  ``,
+            text: ChartInfo.Unit,
             align: 'high',
             rotation: 0,
             y: -15,
@@ -1628,11 +1667,11 @@ const setSeasonOpt=(data)=>{
 }
 
 /* 预测配置 分区 */
-const getPredictParams = ({LatestDate,PredictChartColor,ChartStyle},chartStyle) => {
+const getPredictParams = ({LatestDate,MoveLatestDate,PredictChartColor,ChartStyle},chartStyle) => {
     return {
     zoneAxis: 'x',
     zones: [{
-        value: new Date(LatestDate).getTime()+1
+        value: new Date(MoveLatestDate||LatestDate).getTime()+1
     }, {
         dashStyle: 'ShortDot',
         color: (ChartStyle==='column' || chartStyle==='column') ? 'transparent' : PredictChartColor
@@ -2129,7 +2168,22 @@ const posterParams=computed(()=>{
 
 /* 折叠source */
 const sourceColl = ref(false)
-
+const sourceIconShow=ref(null)
+let timer = null
+let count = 0
+onMounted(()=>{
+    timer=setInterval(()=>{
+        count++
+        if($('.source-item')[0]){
+            // 就为了判断是否显示折叠icon
+            sourceIconShow.value = $('.source-item')[0].offsetHeight>=$('.source-box')[0].offsetHeight
+            clearInterval(timer)
+        }else if(count>=30){
+            // 预防
+            clearInterval(timer)
+        }
+    },100)
+})
 
 // 获取我的图库中切换上一张下一张的数据
 let myChartPageChangeList=ref([])
@@ -2182,13 +2236,14 @@ const myChartPageChange=(type)=>{
     <div class="chart-detail" v-if="!loading&&!noauth&&!nodata">
         <div class="chart-title">{{resData.ChartInfo.ChartName}}</div>
         <div class="top-box" v-if="$route.query.source!=='ybxcx_my_chart'">
-            <div class="flex calendar-box" style="float:left" @click="handleShowDate" v-if="![7,10].includes(resData.ChartInfo.ChartType) &&resData.ChartInfo.Source===1">
-                <img src="../../../assets/hzyb/chart/calendar.png" alt="">
+            <div class="flex calendar-box" :style="{'color':startDate?'#1F243A':'#999999'}"
+            @click="handleShowDate" v-if="![7,10].includes(resData.ChartInfo.ChartType) &&resData.ChartInfo.Source===1">
+                <img src="../../../assets/hzyb/chart/calendar-new-1.png" alt="">
                 <span class="date">{{startDate||'开始日期'}}</span>
-                <span style="margin:0 5px"></span>
+                <span style="margin:0 5px">-</span>
                 <span class="date">{{endDate||'结束日期'}}</span>
             </div>
-            <img class="icon" src="../../../assets/hzyb/chart/search.png" alt="" @click="handleGoSearch">
+            <img class="icon search-icon" src="../../../assets/hzyb/chart/search-new-1.png" alt="" @click="handleGoSearch">
             <share-poster 
                 :isSlot="true"
                 :shareData="{
@@ -2198,10 +2253,13 @@ const myChartPageChange=(type)=>{
                     data:posterParams
                 }"
             >
-                <img class="icon" src="@/assets/hzyb/share-poster-chart-icon.png" alt="">
+                <!-- <img class="icon" src="@/assets/hzyb/share-poster-chart-icon.png" alt=""> -->
             </share-poster>
-            <img class="icon" src="../../../assets/hzyb/chart/save.png" alt="" @click="handleSaveChart" v-if="canSave&&![3,4,6,7,8,9].includes(chartSource)">
-            <img class="icon" src="../../../assets/hzyb/chart/refresh.png" alt="" @click="handleRefreshChart">
+            <!-- <img class="icon" src="../../../assets/hzyb/chart/save.png" alt="" @click="handleSaveChart" v-if="canSave&&![3,4,6,7,8,9].includes(chartSource)">
+            <img class="icon" src="../../../assets/hzyb/chart/refresh.png" alt="" @click="handleRefreshChart"> -->
+            <img class="icon" src="../../../assets/hzyb/chart/more.png" alt="" @click="actionSheetShow=true">
+            <ActionSheet v-model:show="actionSheetShow" cancel-text="确定" :actions="actions" 
+            @select="onActionSelect" close-on-click-action />
         </div>
         
         <collectBox 
@@ -2213,8 +2271,9 @@ const myChartPageChange=(type)=>{
         <chartBox :options='chartData' v-if="!loading"></chartBox>
 
         <div :class="['source-box',{'un-coll-sty':sourceColl,'coll-sty': !sourceColl}]" v-if="$route.query.source=='ybxcx_my_chart'">
-            来源:{{resData&&resData.ChartInfo.ChartSource}}
-            <Icon :name="sourceColl?'arrow-up':'arrow-down'" class="slide-icon" @click="sourceColl=!sourceColl"/>
+            <span class="source-item">来源:{{resData&&resData.ChartInfo.ChartSource}}</span>
+            <Icon :name="sourceColl?'arrow-up':'arrow-down'" class="slide-icon" v-if="sourceIconShow"
+            @click="sourceColl=!sourceColl"/>
         </div>
 
         <template v-if="$route.query.source!=='ybxcx_my_chart'">
@@ -2227,8 +2286,9 @@ const myChartPageChange=(type)=>{
             <span style="color:#E3B377;flex:1;text-align:right" @click="showLimit=true" v-if="![3,4,6,7,8,9].includes(resData.ChartInfo.Source)">上下限设置</span>
         </div>
         <div :class="['source-box',{'un-coll-sty':sourceColl,'coll-sty': !sourceColl}]">
-            来源:{{resData&&resData.ChartInfo.ChartSource}}
-            <Icon :name="sourceColl?'arrow-up':'arrow-down'" class="slide-icon" @click="sourceColl=!sourceColl"/>
+            <span class="source-item">来源:{{resData&&resData.ChartInfo.ChartSource}}</span>
+            <Icon :name="sourceColl?'arrow-up':'arrow-down'" class="slide-icon" v-if="sourceIconShow"
+            @click="sourceColl=!sourceColl"/>
         </div>
 
         <!-- 日期类型 -->
@@ -2242,9 +2302,10 @@ const myChartPageChange=(type)=>{
         </div>
 
         <!-- 最新值 -->
-        <div class="latest-value-wrap" v-if="resData&&resData.ChartInfo.Source===1">
-            <p style="margin-bottom:10px">最新数值</p>
-            <ul class="list" v-if="sameOptionType.includes(resData.ChartInfo.ChartType)">
+        <div class="latest-value-wrap" v-if="resData&&resData.ChartInfo.Source===1" 
+        :class="{'marginTopZone': sameOptionType.includes(resData.ChartInfo.ChartType)}">
+            <!-- <p style="margin-bottom:10px">最新数值</p> -->
+            <ul class="list same-option-type-list" v-if="sameOptionType.includes(resData.ChartInfo.ChartType)">
                 <li v-for="item in chartData.series" :key="item.name">
                     <p style="color:#333">{{moment(item.LatestDate).format('YYYY-MM-DD')}}</p>
                     <p :style="{color:item.color,flex:1}">{{item.name.length>20?item.name.replace(/<br>/g,''):item.name}}</p>
@@ -2295,17 +2356,37 @@ const myChartPageChange=(type)=>{
         </div>
 
         <!-- 日期选择 -->
+        <!-- 属于同个弹窗多个picker选择多个值,vant4.0以上有 现成组件替换
+            这个项目涉及到多个项目,升级vant4.0的兼容处理难于调试
+            这里暂时使用多个组件自定义,后续有更新至vant4.0,可以进行修改 -->
         <Popup
             v-model:show="showDate"
             position="bottom"
             round
         >   
-            <Picker 
-                title="" 
-                :columns="columns" 
-                @cancel="showDate=false" 
-                @confirm="handleConfirmDate" 
-            />
+            <div class="custom-popup-top">
+                <div class="popup-top-item popup-top-cancel">
+                    <span @click="showDate=false">取消</span>
+                </div>
+                <div class="popup-top-item popup-top-title">
+                    {{ pickerInfo.tabIndex==1?'选择起始时间':'选择结束时间' }}
+                </div>
+                <div class="popup-top-item popup-top-confirm">
+                    <span @click="handleConfirmDate">确认</span>
+                </div>
+            </div>
+            <Tabs color="#E3B377" v-model:active="pickerInfo.tabIndex"
+            line-width="16px" border swipeable title-active-color="#E3B377"
+            title-inactive-color="#333333">
+                <Tab title="开始时间" name="1">
+                    <Picker ref="startPicker" @confirm="e=> DateConfirm(e,'start')" 
+                        :columns="columnsStart" :show-toolbar="false"/>
+                </Tab>
+                <Tab title="结束时间" name="2">
+                    <Picker ref="endPicker" @confirm="e=> DateConfirm(e,'end')" 
+                        :columns="columnsEnd" :show-toolbar="false"/>
+                </Tab>
+            </Tabs>
         </Popup>
 
         <!-- 上下限设置 -->
@@ -2419,33 +2500,42 @@ const myChartPageChange=(type)=>{
         }
     }
     .top-box{
-        padding: 20px 34px 40px 34px;
-        height: 40px;
+        padding: 0 34px 0 34px;
+        // height: 40px;
+        display: flex;
+        align-items: center;
         .calendar-box{
             align-items: center;
+            background-color:#F6F6F6 ;
+            padding: 11px 30px;
+            border-radius: 99px;
+            width: 466px;
             img{
-                width: 40px;
-                height: 40px;
+                width: 48px;
+                height: 48px;
                 margin-right: 18px;
             }
             .date{
                 width: 128px;
                 height: 40px;
-                background: #F6F6F6;
-                border: 1px solid #E5E5E5;
+                // background: #F6F6F6;
+                // border: 1px solid #E5E5E5;
                 border-radius: 4px;
                 text-align: center;
                 line-height: 44px;
                 font-size: 24px;
-                color: #1F243A;
+                // color: #1F243A;
             }
         }
         .icon{
-            float: right;
-            width: 40px;
-            height: 40px;
+            // float: right;
+            width: 70px;
+            height: 70px;
             margin-left: 30px;
         }
+        .search-icon{
+            margin-left: 40px;
+        }
     }
     .select-date-box-head{
         padding: 40px 34px;
@@ -2577,8 +2667,17 @@ const myChartPageChange=(type)=>{
                 border-right: none !important;
             }
         }
+        .same-option-type-list{
+            li{
+                &:first-child{
+                    border-top: none;
+                }
+            }
+        }
+    }
+    .marginTopZone{
+        margin-top: 0;
     }
-
     .set-limit-box{
         min-height: 450px;
         padding-top: 5px;
@@ -2628,5 +2727,43 @@ const myChartPageChange=(type)=>{
         }
 
     }
+    .custom-popup-top{
+        height: 88px;
+        width: 100%;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        flex-wrap: nowrap;
+        .popup-top-item{
+            height: 100%;
+            padding: 0 32px;
+            display: flex;
+            align-items: center;
+        }
+        .popup-top-cancel{
+            font-weight: 400;
+            font-size: 32px;
+            color: #666666;
+        }
+        .popup-top-title{
+            font-weight: 600;
+            font-size: 36px;
+            color: #333333;
+        }
+        .popup-top-confirm{
+            font-weight: 400;
+            font-size: 32px;
+            color: #E3B377;
+        }
+    }
+}
+::v-deep(.van-tab) {
+    flex: none;
+    padding: 0 32px;
 }
+::v-deep(.van-action-sheet__item) {
+    border-bottom: solid 1px #E7E7E7;
+}
+
+
 </style>

+ 1 - 1
src/views/hzyb/chart/component/noAuth.vue

@@ -67,7 +67,7 @@ const handleApply=()=>{
     }
 
 
-    if(props.data.customer_info.status=='流失'){
+    if(props.data.customer_info.status=='流失'||props.data.customer_info.status=='关闭'){
         apiApplyPermission({
             company_name:props.data.customer_info.company_name,
             real_name:props.data.customer_info.name,

+ 1 - 1
src/views/hzyb/pricedriven/detail.vue

@@ -162,7 +162,7 @@ const handleGoApply = async () => {
   } else {
     if (
       !noAuthInfo.value.customer_info.status ||
-      noAuthInfo.value.customer_info.status !== "流失"
+      noAuthInfo.value.customer_info.status !== "流失"||noAuthInfo.value.customer_info.status !== "关闭"
     ) {
       wx.miniProgram.navigateTo({
         url: "/pages-applyPermission/applyPermission?source=6&from_page=价格驱动",

+ 1 - 1
src/views/hzyb/report/ChapterDetail.vue

@@ -540,7 +540,7 @@ export default {
           this.pupData.show=true
 					this.pupData.content=`<p>您已提交过申请,请耐心等待</p>`
         }else{
-          if(!this.info.permission_check.customer_info.status||this.info.permission_check.customer_info.status!='流失'){
+          if(!this.info.permission_check.customer_info.status||this.info.permission_check.customer_info.status!='流失'||this.info.permission_check.customer_info.status!='关闭'){
             wx.miniProgram.redirectTo({
               url:"/pages-applyPermission/applyPermission?source=4&from_page=报告详情"
             })

+ 1 - 1
src/views/hzyb/report/Detail.vue

@@ -600,7 +600,7 @@ export default {
                     this.pupData.show=true
 					this.pupData.content=`<p>您已提交过申请,请耐心等待</p>`
                 }else{
-                    if(!this.info.permission_check.customer_info.status||this.info.permission_check.customer_info.status!='流失'){
+                    if(!this.info.permission_check.customer_info.status||this.info.permission_check.customer_info.status!='流失'||this.info.permission_check.customer_info.status!='关闭'){
                         wx.miniProgram.redirectTo({
                             url:"/pages-applyPermission/applyPermission?source=4&from_page=报告详情"
                         })

+ 121 - 0
src/views/hzyb/report/PreviewPDF.vue

@@ -0,0 +1,121 @@
+<script setup>
+import { useRoute } from 'vue-router';
+import { ref,onMounted } from "vue";
+import VuePdfEmbed from "vue-pdf-embed";
+import {Toast,Dialog} from 'vant';
+import {apiUserInfo} from '@/api/hzyb/user'
+const route = useRoute();
+localStorage.setItem('hzyb-token',route.query.token)
+document.title='PDF报告'
+const pdfSrc = ref('')
+let LOADING = null
+let showHint = ref(false)
+let hasRight = ref(true)
+let userInfo = ref({})
+let hintText = ref('')
+
+
+const loadingFailed = ()=>{
+    LOADING.clear()
+    Toast("加载PDF失败!")
+    showHint.value = true
+}
+const loadedPDF = ()=>{
+    LOADING.clear()
+    showHint.value = false
+    hintText.value = ''
+}
+
+const checkRight = async()=>{
+    const res = await apiUserInfo({Authorization: localStorage.getItem('hzyb-token')})
+    if(res.code!==200) return 
+    userInfo.value = res.data
+    if(['试用','正式','永续'].includes(res.data.status)){
+        hasRight.value = true
+        LOADING = Toast.loading({
+            message: "正在加载PDF",
+            duration: 0,
+            forbidClick: true,
+        });
+        pdfSrc.value = route.query.pdfSrc ||''
+        if(!pdfSrc.value.length){
+            hintText.value = '获取PDF失败'
+        }
+    }else{
+        LOADING&&LOADING.clear()
+        hasRight.value = false
+    }
+}
+
+const handleGoApply = ()=>{
+    if(userInfo.value.is_bind===0){
+        Dialog.confirm({
+            title:'温馨提示',
+            message:'为了优化您的用户体验,\n 请登录后查看更多信息!',
+            confirmButtonText:'去登录',
+            confirmButtonColor:'#E6B77D',
+            cancelButtonColor:'#666'
+        }).then(res=>{
+            wx.miniProgram.reLaunch({url:'/pages/login'})
+        })
+        return
+    }
+    wx.miniProgram.redirectTo({
+        url:"/pages-applyPermission/applyPermission?source=4&from_page=PDF报告"
+    })
+}
+
+onMounted(()=>{
+    checkRight()
+})
+</script>
+
+<template>
+    <div class="preview-pdf-wrap">
+        <!-- 无权限 -->
+        <div class="no-auth-box" v-if="!hasRight">
+            <img class="img" src="https://hzstatic.hzinsights.com/static/icon/hzyb/activity_no_auth.png" mode="widthFix" />
+            <div class="apply-box">
+                <div>您暂无权限查看报告,若想查看请申请开通</div>
+                <div class="btn" @click="handleGoApply">立即申请</div>
+            </div>
+        </div>
+        <template v-else-if="pdfSrc.length">
+            <vue-pdf-embed :source="pdfSrc" @loading-failed="loadingFailed" @loaded="loadedPDF"/>
+            <p v-if="showHint" class="hint">加载pdf失败</p>
+        </template>
+        <template v-else>
+            <p class="hint">{{hintText}}</p>
+        </template>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.preview-pdf-wrap{
+    .hint{
+        margin-top:100px;
+        text-align:center;
+        color:#999;
+    }
+    .no-auth-box{
+        text-align: center;
+        font-size: 32px;
+        color: #E3B377;
+        img{
+            width: 100%;
+            margin-bottom: 50px;
+        }
+        .btn{
+            width: 90%;
+            margin-left: auto;
+            margin-right: auto;
+            line-height: 80px;
+            background-color: #E6B77D;
+            border-radius: 4px;
+            color: #fff;
+            margin-top: 100px;
+            display: block;
+        }
+    }
+}
+</style>

+ 152 - 5
src/views/ssbg/components/calendar.vue

@@ -18,6 +18,10 @@ const props = defineProps({
   eventList: {
     type: Array,
     required: true
+  },
+  selectUserValue:{
+      type:Number,
+      default:0
   }
 })
 
@@ -37,6 +41,7 @@ const handleDateClick = ({date}) => {
   emits('cellClick',date)
 };
 
+let popContentArr = ref([])
 /* 点击日程 */
 const handleEventClick = (_) => {
   let id = _.event.id; // 获取当前点击日程的ID
@@ -47,8 +52,100 @@ const handleEventClick = (_) => {
   let title = setDynamicTitle(event_item);
 
   selectEventInfo.value = {...event_item,title};
+  getPopoverContent()
   isShowPopup.value = true;
 };
+function getPopoverContent(){
+    const {StartDate,StartTime,StartWeek,EndDate,EndTime,EndWeek} = selectEventInfo.value
+    //前两项默认是开始时间和结束时间
+    const popContent = [{
+        key:'StartDate',
+        label:'开始时间:',
+        content:`${StartDate} ${StartTime} (${StartWeek})`,
+    },{
+        key:'EndDate',
+        label:'结束时间:',
+        content:`${EndDate} ${EndTime} (${EndWeek})`,
+    }]
+    //根据ActivityType判断是什么类型,根据RoadshowType展示对应信息
+    const {ActivityType,RoadshowType} = selectEventInfo.value
+    const {Province,City} = selectEventInfo.value
+    //ActivityType为路演时,需要显示的内容
+    const {RoadshowPlatform,CompanyName} = selectEventInfo.value
+    const RoadshowContent = [{
+        key:'RoadshowPlatform',
+        label:'路演平台:',
+        content:`${RoadshowPlatform}`,
+        RoadshowType:'线上'
+    },{
+        key:'RoadshowCity',
+        label:'路演城市:',
+        content:`${Province}${City}`,
+        RoadshowType:'线下'
+    },{
+        key:'CompanyName',
+        label:'客户名称:',
+        content:`${CompanyName}`,
+        RoadshowType:RoadshowType,
+    }].filter(item=>item.RoadshowType===RoadshowType)
+    //ActivityType为公开会议时,需要显示的内容
+    const {Theme,CooperationName} = selectEventInfo.value
+    const MeetingContent = [
+        {
+            key:'RoadshowPlatform',
+            label:'会议平台:',
+            content:`${RoadshowPlatform}`,
+            RoadshowType:'线上'
+        },{
+            key:'RoadshowCity',
+            label:'会议城市:',
+            content:`${Province}${City}`,
+            RoadshowType:'线下'
+        },{
+            key:'Theme',
+            label:'会议主题:',
+            content:`${Theme}`,
+            RoadshowType:RoadshowType
+        },{
+            key:'CooperationName',
+            label:'合作方名称:',
+            content:`${CooperationName}`,
+            RoadshowType:RoadshowType
+        }].filter(item=>item.RoadshowType===RoadshowType)
+    ////ActivityType不为空时,需要显示的内容
+    const {ResearcherName,SysUserRealName} = selectEventInfo.value
+    const SuppleContent=[{
+        key:'ResearcherName',
+        label:'研究员:',
+        content:`${ResearcherName}`,
+    },{
+        key:'SysUserRealName',
+        label:'发起人:',
+        content:`${SysUserRealName}`,
+    }]
+    //ActivityType为空时,需要显示的内容
+    const {MatterContent,EditReason,ModifyTime} = selectEventInfo.value
+    const MattersContent=[{
+        key:'MatterContent',
+        label:'事项内容:',
+        content:`${MatterContent}`,
+    },{
+        key:'EditReason',
+        label:'最近修改记录:',
+        content:`${EditReason}`,
+        otherContent:`${moment(ModifyTime).format('YYYY-MM-DD HH:mm:ss')}`
+    }].filter(item=>{return item.content.length})
+
+    const contentMap = {
+        '路演':RoadshowContent,
+        '公开会议':MeetingContent,
+    }
+    if(ActivityType){
+        popContentArr.value = [...popContent,...contentMap[ActivityType]||[],...SuppleContent]
+    }else{
+        popContentArr.value = [...popContent,...MattersContent]
+    }
+}
 
 let calendarOptions = ref({
   height: 'auto',
@@ -172,7 +269,7 @@ defineExpose({ toogeCurrentWeek,calendarApi });
 <template>
   <Sticky>
     <div class="header">
-      <swiperCalendar @dateChange="datechangeHandle" ref="swiperCalendarRef"/>
+      <swiperCalendar @dateChange="datechangeHandle" ref="swiperCalendarRef" :selectUserValue="selectUserValue"/>
     </div>
   </Sticky>
   <FullCalendar :options="calendarOptions" ref="FullCalendarRef">
@@ -184,8 +281,8 @@ defineExpose({ toogeCurrentWeek,calendarApi });
     </template>
   </FullCalendar>
 
-<!-- 弹窗层 -->
-  <Popup
+<!-- 弹窗层 旧版-->
+<!--   <Popup
     v-model:show="isShowPopup"
     closeable
   >
@@ -219,6 +316,28 @@ defineExpose({ toogeCurrentWeek,calendarApi });
         <p v-if="selectEventInfo.CooperationName">{{ selectEventInfo.CooperationName }}</p>
         <p v-if="['公开会议','内部会议','路演'].includes(selectEventInfo.ActivityType)">发起人:{{selectEventInfo.SysUserRealName}}</p>
     </div>
+  </Popup> -->
+  <!-- 新版 -->
+  <Popup
+    v-model:show="isShowPopup"
+    round closeable
+    style="width:90%;"
+  >
+    <div class="pop-dialog-wrap">
+        <div class="pop-header">
+            <p>{{selectEventInfo.ActivityType?`${selectEventInfo.RoadshowType}${selectEventInfo.ActivityType}`:'事项'}}</p>
+        </div>
+        <div class="popover-body">
+            <!-- 换行的内容需要对齐,所以dom结构设置成了下面这样 -->
+            <div class="content-item" v-for="item in popContentArr" :key="item.key">
+                <span class="label">{{item.label}}</span>
+                <div class="content">
+                    <p>{{item.content}}</p>
+                    <p v-if="item.otherContent" class="other-text">{{item.otherContent}}</p>
+                </div>
+            </div>
+        </div>
+    </div>
   </Popup>
 </template>
 
@@ -226,7 +345,7 @@ defineExpose({ toogeCurrentWeek,calendarApi });
 
 .header {
   background: #fff;
-  padding-bottom: 20px;
+  /* padding-bottom: 20px; */
   box-shadow: 0px 3px 6px rgba(172, 172, 172, 0.16);
   .tab-cont {
 		padding: 30px;
@@ -265,7 +384,9 @@ defineExpose({ toogeCurrentWeek,calendarApi });
   }
   ::v-deep(.fc-timegrid-event ) {
     border-left: 8px solid #3385FF !important;
-
+  }
+  ::v-deep(.fc-timegrid-col-events){
+      margin:0 !important;
   }
 }
 
@@ -276,4 +397,30 @@ defineExpose({ toogeCurrentWeek,calendarApi });
     color: #333;
   }
 }
+.pop-dialog-wrap{
+    padding: 40px 20px;
+    .pop-header{
+        text-align: center;
+        font-size: 32px;
+        font-weight: bold;
+        margin-bottom: 20px;
+    }
+    .popover-body{
+        font-size: 30px;
+        .content-item{
+            display: flex;
+            margin-top: 20px;
+            .label{
+                display: inline-block;
+                width:220px;
+                text-align: right;
+            }
+            .content{
+                .other-text{
+                    color: #999;
+                }
+            }
+        }
+    }
+}
 </style>

+ 109 - 14
src/views/ssbg/components/swiperCalendar.vue

@@ -1,15 +1,22 @@
 <script setup>
 import { reactive, toRefs, ref, watch, onMounted } from 'vue';
 import { DatetimePicker , Popup } from 'vant';
+import { useRoute } from 'vue-router';
+import { myEvents,researchEvents,sellerEvents} from '@/api/ssbg/api';
 import moment from 'moment';
 import 'moment/dist/locale/zh-cn';
 moment.locale('zh-cn');
 import _ from 'lodash';
 
+const route = useRoute();
 const emit = defineEmits(['dateChange']);
-
 const calendarRef = ref(null);
-
+const props = defineProps({
+  selectUserValue:{
+      type:Number,
+      default:0
+  }
+})
 const weekDays = ref([
   {
     label: '一',
@@ -78,9 +85,13 @@ const getRecentWeek = (day) => {
 
   state.weekDateList = weekeList;
   state.weekFirstDay = currenWeekStart;
+  
+  //获取日历日程
+  getEventList()
 };
 getRecentWeek(current.value.currentDate);
 
+
 /* 设置周日历选中的位置 */
 const setWeekIndex = (selectDate) => {
   const currentWeekDateList = state.weekDateList[1];
@@ -161,6 +172,57 @@ function onSelectCalendarConfirm(e){
   showCalendar.value=false
 }
 
+//获取日历日程
+async function getEventList (){
+  //日期:weekDateList[0][0],weekDateList[length-1][6]
+  const length = state.weekDateList.length
+  let planData = {}
+  //如果是研究员/销售员日历,那等选择研究员/销售员后再获取
+  if(route.path==='/ssbg/roadshow/mine'){
+    if(localStorage.getItem('ssbg-role') === 'admin') return;
+    const { code,data } = await myEvents({
+        StartDate: moment(state.weekDateList[0][0]).format('YYYY-MM-DD'),
+        EndDate: moment(state.weekDateList[length-1][6]).format('YYYY-MM-DD')
+    })
+    if(code!==200) return 
+    planData = data
+  }else if(route.path==='/ssbg/roadshow/researcher'){
+    if(!props.selectUserValue) return 
+    const { code,data } = await researchEvents({
+        StartDate: moment(state.weekDateList[0][0]).format('YYYY-MM-DD'),
+        EndDate: moment(state.weekDateList[length-1][6]).format('YYYY-MM-DD'),
+        ResearcherId: props.selectUserValue
+    })
+    if(code !== 200) return
+    planData = data
+  }else if(route.path==='/ssbg/roadshow/seller'){
+    //销售员日历
+    if(!props.selectUserValue) return 
+    const { code,data } = await sellerEvents({
+        StartDate: moment(state.weekDateList[0][0]).format('YYYY-MM-DD'),
+        EndDate: moment(state.weekDateList[length-1][6]).format('YYYY-MM-DD'),
+        SellerId: props.selectUserValue
+    })
+    if(code !== 200) return
+    planData = data
+  }
+  getPlanDates(planData)
+}
+
+let planDates = ref([])
+//获取有日程的日期
+function getPlanDates({CalendarList,RsMattersList}){
+    const calendarDay = CalendarList?CalendarList.map(item=>{
+        return [item.StartDate,item.EndDate]
+    }):[]
+    const MatterDay = RsMattersList?RsMattersList.map(item=>{
+        return [item.StartDate,item.EndDate]
+    }):[]
+    planDates.value = [...calendarDay.flat(),...MatterDay.flat()]
+    planDates.value = Array.from(new Set(planDates.value))
+    console.log('arr',planDates.value)
+}
+
 /* 选中日期 更新日历 */
 watch(
   () => state.selectDate,
@@ -172,6 +234,10 @@ watch(
   }
 );
 
+watch(()=>props.selectUserValue,()=>{
+    getEventList()
+})
+
 defineExpose({
   getRecentWeek,
   selectDateHandle
@@ -216,14 +282,17 @@ const { weekDateList, selectDate, moveIndex, touch } = toRefs(state);
           :class="{
             act: selectDate === day,
             today: moment().format('YYYY-MM-DD') === day,
+            dot:planDates.includes(day)
           }"
           @touchstart.stop="selectDateHandle(day, day_index)"
         >
-          {{
-            moment().format('YYYY-MM-DD') === day
-              ? '今'
-              : moment(day).format('DD')
-          }}
+          <span class="text">
+                {{
+                    moment().format('YYYY-MM-DD') === day
+                    ? '今'
+                    : moment(day).format('DD')
+                }}
+          </span>
         </li>
       </ul>
     </div>
@@ -281,23 +350,49 @@ const { weekDateList, selectDate, moveIndex, touch } = toRefs(state);
       z-index: 11;
       li {
         color: #333;
-        height: 40px;
-        line-height: 40px;
+        height: 50px;
         width: calc(100% / 7);
         text-align: center;
         padding: 10px 0;
         margin: 0 24px;
+        position: relative;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        .text{
+            display: inline-block;
+            width:38px;
+            height: 38px;
+            border-radius: 50%;
+            margin-top: -20px;
+            text-align: center;
+            line-height: 40px;
+        }
         &.today {
-          background: #b4cef5;
-          border-radius: 50%;
+          .text{
+            background: #b4cef5;
+          }
           color: #fff;
         }
         &.act {
-          background: #39a9ed;
-          /* border-radius: 4px; */
-          border-radius: 50%;
+          .text{
+            background: #39a9ed;
+          }
           color: #fff;
         }
+        &.dot{
+            &::after{
+                content: '';
+                position: absolute;
+                bottom:20px;
+                left: 50%;
+                transform: translateX(-50%);
+                width:10px;
+                height:10px;
+                border-radius: 50%;
+                background-color: #D9D9D9;
+            }
+        }
       }
     }
   }

+ 4 - 0
src/views/ssbg/roadshow/common-calendar.js

@@ -42,6 +42,10 @@ export const getTabsByRole = (role) => {
 				label: '内部会议',
 				key:3
 			},
+			{
+				label: '事项',
+				key:5
+			},
 		] : ADMINLIST.includes(role)
 		? [
 			{

+ 2 - 1
src/views/ssbg/roadshow/myCalendar.vue

@@ -17,6 +17,7 @@ localStorage.setItem('ssbg-token',route.query.token ||  '5e532bc5fa7281aebaa6d89
 localStorage.setItem('ssbg-role',route.query.role ||  'researcher');
 
 const calendarRef = ref(null);//日历ref
+const showArr = ['ficc_seller', 'rai_seller', 'ficc_group', 'rai_group','seller',]
 const actionsList = ref([
   {
     label: '今天',
@@ -27,7 +28,7 @@ const actionsList = ref([
     label: '添加事项',
     key: 'add_matter',
 		icon: 'add-o',
-    show:  ['ficc_researcher', 'researcher', 'rai_researcher','ficc_admin', 'rai_admin'].includes(localStorage.getItem('ssbg-role'))
+    show:  [...['ficc_researcher', 'researcher', 'rai_researcher','ficc_admin', 'rai_admin'],...showArr].includes(localStorage.getItem('ssbg-role'))
   },
 ]);//底部固定数据
 const eventList = ref([]);//日程信息

+ 1 - 0
src/views/ssbg/roadshow/rsCalendar.vue

@@ -168,6 +168,7 @@ document.title = '研究员日历';
     <Calendar 
       ref="calendarRef"
       :eventList="eventList"
+      :selectUserValue="Number(state.selectResearcher)"
       @dateChange="getEventList" 
       @cellClick="cellClickHandle" 
     />

+ 244 - 0
src/views/ssbg/roadshow/sellerCalendar.vue

@@ -0,0 +1,244 @@
+<script setup>
+import { ref, reactive,toRefs,onMounted } from 'vue';
+import { useRoute } from 'vue-router';
+import { Icon, Toast,TreeSelect,Popup,Cascader } from 'vant';
+import moment from 'moment';
+import 'moment/dist/locale/zh-cn';
+moment.locale('zh-cn');
+
+import { sellerEvents,sellerList} from '@/api/ssbg/api';
+import Calendar from '../components/calendar.vue';
+
+
+const route = useRoute();
+localStorage.setItem('ssbg-token',route.query.token ||  '5e532bc5fa7281aebaa6d89960b54c4ab22f1ab18e969258c634a7940fdb0922');
+
+const actionsList = ref([
+  {
+    label: '今天',
+    key: 'weeknow',
+    img: import("@/assets/ssbg/calendar_ico.png"),
+  },
+  {
+    label: '选择销售员',
+    key: 'choose',
+    img: import("@/assets/ssbg/choose_ico.png"),
+  },
+]);
+
+const calendarRef = ref(null);
+
+const state = reactive({
+  selectResearcher: '', // 选中的研究员
+  eventList: [],//日程信息
+});
+
+/* 获取日历日程列表 */
+const getEventList = async () => {
+  if(!selectUserValue.value) return
+
+  const { currentStart } = calendarRef.value.calendarApi.view;
+
+  const { code,data } = await sellerEvents({
+    StartDate: moment(currentStart).format('YYYY-MM-DD'),
+    EndDate: moment(currentStart).format('YYYY-MM-DD'),
+    SellerId: Number(selectUserValue.value)
+  })
+
+  if(code !== 200) return
+
+  state.eventList = [
+    ...(data.CalendarList || []),
+    ...(data.RsMattersList || []),
+  ].map((item, index) => ( { ...item, id: index }));
+};
+
+/* 点击日历表格添加活动 */
+const cellClickHandle = (date) => {
+    //啥也不干
+};
+
+/* 底部操作 */
+const dealActionHandler = (type) => {
+  const deal_methods_handles = {
+    add: addActivityHandleByBtn,
+    weeknow: toogeCurrentWeek,
+    choose: selectSellerHandle,
+  };
+  deal_methods_handles[type]();
+};
+
+/* 点击按钮添加活动 */
+const addActivityHandleByBtn = () => {
+  wx.miniProgram.navigateTo({
+    url: '/pages-roadshow/addActivity/index',
+  });
+};
+
+/* 切换为今天 */
+const toogeCurrentWeek = () => {
+  calendarRef.value.toogeCurrentWeek();
+};
+
+// 选择用户
+const userFieldNames=ref({
+    text: 'AdminName',
+    value: 'AdminId',
+    children: 'Child',
+})
+let selectUserValue=ref('')
+let isSellerPicker=ref(false)
+let userOpts=ref([])
+// 获取系统中所有用户’
+const getSellerList = ()=>{
+    sellerList().then(res=>{
+        if(res.code==200){
+            userOpts.value=res.data.List||[]
+            userOpts.value = userOpts.value.map(i=>{
+                if(!i.AdminName){
+                    i.AdminName = i.GroupName
+                }
+                if(!i.AdminId){
+                    i.AdminId = i.GroupId
+                }
+                return i
+                })
+        }
+    })
+}
+const selectSellerHandle = ()=>{
+    isSellerPicker.value = true
+}
+
+const onFinish = (e)=>{
+    getEventList()
+    isSellerPicker.value=false
+}
+onMounted(() => {
+    getSellerList()
+})
+
+const { eventList } = toRefs(state);
+
+document.title = '销售员日历';
+</script>
+
+<!--  -->
+<template>
+  <div class="rs-container">
+    <Calendar 
+      ref="calendarRef"
+      :eventList="eventList"
+      :selectUserValue="Number(selectUserValue)"
+      @dateChange="getEventList" 
+      @cellClick="cellClickHandle" 
+    />
+    <!-- v-if="isWxprogram()" -->
+    <div class="fix-action" >
+      <ul class="action-ul">
+        <li
+          v-for="item in actionsList"
+          key="item.key"
+          @click="dealActionHandler(item.key)"
+        >
+          <Icon :name="item.icon" class="item-icon" v-if="item.icon" />
+          <img
+            class="item-img"
+            src="@/assets/ssbg/calendar_ico.png"
+            alt=""
+            v-else-if="item.key === 'weeknow'"
+          />
+          <img
+            class="item-img"
+            src="@/assets/ssbg/choose_ico.png"
+            alt=""
+            v-else-if="item.key === 'choose'"
+          />
+          {{ item.label }}
+        </li>
+      </ul>
+    </div>
+    <!-- 选择销售员 -->
+    <Popup v-model:show="isSellerPicker" position="bottom">
+        <Cascader
+            v-model="selectUserValue"
+            title="请选择用户"
+            :options="userOpts"
+            :field-names="userFieldNames"
+            active-color="#3385FF"
+            @close="isSellerPicker = false"
+            @finish="onFinish"
+        />
+    </Popup>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.rs-container {
+  .fix-action {
+    height: 160px;
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    z-index: 99;
+    background-color: #fff;
+    box-shadow: 0px -3px 6px rgba(172, 172, 172, 0.16);
+    padding-top: 20px;
+    padding-bottom: constant(safe-area-inset-bottom);
+    padding-bottom: env(safe-area-inset-bottom);
+    .action-ul {
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: space-around;
+      color: #3385ff;
+      li:hover {
+        opacity: 0.8;
+      }
+      .item-icon {
+        font-size: 52px;
+        display: block;
+        text-align: center;
+        margin: 0 auto 10px;
+      }
+      .item-img {
+        display: block;
+        width: 46px;
+        height: 46px;
+        margin: 0 auto 10px;
+      }
+    }
+  }
+
+  .select-rs-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 30px 20px;
+
+    .cancel {
+      color: #969799;
+    }
+
+    .ensure {
+      color: #576b95;
+    }
+  }
+
+  .van-tree-select {
+		::v-deep(.van-sidebar-item--select:before) {
+			background-color: #1989fa;
+		}
+
+		::v-deep(.van-tree-select__item--active) {
+			color: #1989fa;
+		}
+
+    ::v-deep(.van-tree-select__selected) {
+      position: absolute !important;
+    }
+
+	}
+}
+</style>