소스 검색

研报模块优化

jwyu 1 년 전
부모
커밋
40e640d3b0

+ 2 - 2
.env.development

@@ -1,5 +1,5 @@
-# 接口地址http://8.136.199.33:8610/v1   https://rddptest.hzinsights.com/adminapi
-VITE_APP_API_URL="http://8.136.199.33:8610/v1"
+# 接口地址http://8.136.199.33:8610/v1   http://8.136.199.33:7778/adminapi
+VITE_APP_API_URL="http://8.136.199.33:7778/adminapi"
 # 路由根地址
 VITE_APP_BASE_URL="/"
 # 打包输入文件名

+ 1 - 1
package.json

@@ -28,7 +28,7 @@
     "pinia": "^2.0.36",
     "pptxgenjs": "^3.12.0",
     "v3-color-picker-teleport": "^1.0.9",
-    "vant": "^4.1.2",
+    "vant": "^4.6.4",
     "vconsole": "^3.15.0",
     "vue": "^3.2.47",
     "vue-router": "^4.1.6",

+ 9 - 0
src/api/report.js

@@ -202,5 +202,14 @@ export default {
      */
     chapterDayReportTicketList(params){
         return get('/report/getDayReportTickerList',params)
+    },
+    /**
+     * 定时发布报告
+     * @param ReportId
+     * @param PrePublishTime
+     * @param PreMsgSend 定时发布成功后是否立即推送模版消息:0否,1是
+     */
+    reportPublishTimeSet(params){
+        return post('/report/pre_publish',params)
     }
 }

+ 8 - 0
src/api/reportEn.js

@@ -138,5 +138,13 @@ export default {
      */
     strategyReportEdit(params){
         return post('/english_report/edit_policy',params)
+    },
+    /**
+     * 定时发布报告
+     * @param ReportId
+     * @param PrePublishTime
+     */
+    reportPublishTimeSet(params){
+        return post('/english_report/pre_publish',params)
     }
 }

+ 14 - 0
src/api/semanticAnalysis.js

@@ -0,0 +1,14 @@
+// 语义分析模块
+import { get,post } from "./index";
+
+export default{
+    /**
+     * 获取文档对比图
+     * @param Keyword
+     * @param PageSize
+     * @param CurrentIndex
+     */
+    compareImgList(params){
+        return get('/semantic_analysis/compare/search',params)
+    }
+}

BIN
src/assets/imgs/report/icon_time.png


+ 61 - 2
src/views/report/AddReport.vue

@@ -3,10 +3,11 @@ import {ref,onMounted,onUnmounted} from 'vue'
 import {useInitFroalaEditor} from '@/hooks/useFroalaEditor'
 import EditReportBaseInfo from './components/EditReportBaseInfo.vue'
 import ReportInsertContent from './components/reportInsert/Index.vue'
+import ReportPublishTimeSet from './components/ReportPublishTimeSet.vue'
 import apiReport from '@/api/report'
 import apiChart from '@/api/chart'
 import moment from 'moment'
-import { showToast } from 'vant'
+import { showToast,showDialog  } from 'vant'
 import { useRouter } from 'vue-router'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
 const cachedViewsStore=useCachedViewsStore()
@@ -18,6 +19,8 @@ const {lastFocusPosition,initFroalaEditor}=useInitFroalaEditor()
 
 let reportContentEditorIns=null//报告内容编辑器实例
 
+let reportId=0//报告id
+
 onMounted(() => {
     const el=document.getElementById('editor')
     reportContentEditorIns=initFroalaEditor('#editor',{height:el.offsetHeight-150})
@@ -205,6 +208,14 @@ async function handleReportOpt(type){
             showPublishPop.value=true
         }
     }
+    if(type==='dsfb'){
+        //定时发布
+        const res=await apiReport.reportAdd(params)
+        if(res.Ret===200){
+            reportId=res.Data.ReportId
+            showDSFBTime.value=true
+        }
+    }
 }
 
 // 点击发布提示弹窗中的操作按钮
@@ -244,6 +255,47 @@ async function reportPublish(id){
     }
 }
 
+// 定时发布报告选择时间
+const showDSFBTime=ref(false)
+function onConfirmDSFBTime(time){
+    console.log(time);
+    showDialog({
+        title: '提示',
+        message:'是否发布定时报告,并推送模板消息?',
+        confirmButtonText:'推送',
+        cancelButtonText:'不推送',
+        showCancelButton:true
+    }).then(()=>{
+        //推送
+        apiReport.reportPublishTimeSet({
+            ReportId:reportId,
+            PrePublishTime:time,
+            PreMsgSend:1
+        }).then(res=>{
+            if(res.Ret===200){
+                showToast('定时发布成功!')
+                setTimeout(() => {
+                    router.back()
+                }, 1000);
+            }
+        })
+    }).catch(()=>{
+        //不推送
+        apiReport.reportPublishTimeSet({
+            ReportId:reportId,
+            PrePublishTime:time,
+            PreMsgSend:0
+        }).then(res=>{
+            if(res.Ret===200){
+                showToast('定时发布成功!')
+                setTimeout(() => {
+                    router.back()
+                }, 1000);
+            }
+        })
+    })
+}
+
 </script>
 
 <template>
@@ -267,6 +319,10 @@ async function reportPublish(id){
                     <img src="@/assets/imgs/report/icon_save2.png" alt="">
                     <span>保存</span>
                 </div>
+                <div class="item" @click="handleReportOpt('dsfb')">
+                    <img src="@/assets/imgs/report/icon_time.png" alt="">
+                    <span>定时发布</span>
+                </div>
                 <div class="item" @click="handleReportOpt('fb')">
                     <img src="@/assets/imgs/report/icon_publish3.png" alt="">
                     <span>发布</span>
@@ -304,7 +360,7 @@ async function reportPublish(id){
     >
         <div class="publish-report-pop-box">
             <div class="title">发布提示</div>
-            <p class="tips">是否发布报告,且推送模板消息和客户群?</p>
+            <p class="tips">是否立即发布报告,并推送模板消息?</p>
             <div class="btns">
                 <div class="btn blue" @click="handleConfirmPublish(2)">发布&推送</div>
                 <div class="btn" @click="handleConfirmPublish(1)">仅发布</div>
@@ -312,6 +368,9 @@ async function reportPublish(id){
             </div>
         </div>
     </van-popup>
+
+    <!-- 定时发布选择时间 -->
+    <ReportPublishTimeSet v-model="showDSFBTime" @confirm="onConfirmDSFBTime" />
 </template>
 <style lang="scss" scoped>
 .publish-report-pop-box{

+ 70 - 2
src/views/report/EditReport.vue

@@ -3,10 +3,11 @@ import {ref,onMounted,onUnmounted} from 'vue'
 import {useInitFroalaEditor} from '@/hooks/useFroalaEditor'
 import EditReportBaseInfo from './components/EditReportBaseInfo.vue'
 import ReportInsertContent from './components/reportInsert/Index.vue'
+import ReportPublishTimeSet from './components/ReportPublishTimeSet.vue'
 import apiReport from '@/api/report'
 import apiChart from '@/api/chart'
 import moment from 'moment'
-import { showToast } from 'vant'
+import { showToast,showDialog } from 'vant'
 import { useRoute, useRouter } from 'vue-router'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
 const cachedViewsStore=useCachedViewsStore()
@@ -275,6 +276,9 @@ async function handleReportOpt(type){
             showPublishPop.value=true
         }
     }
+    if(type==='dsfb'){
+        showDSFBTime.value=true
+    }
 }
 
 // 点击发布提示弹窗中的操作按钮
@@ -316,6 +320,63 @@ async function reportPublish(id){
     }
 }
 
+// 定时发布报告选择时间
+const showDSFBTime=ref(false)
+function onConfirmDSFBTime(time){
+    console.log(time);
+    if(reportData.value.MsgIsSend===1){//已经推送过了
+        apiReport.reportPublishTimeSet({
+            ReportId:reportData.value.Id,
+            PrePublishTime:time,
+            PreMsgSend:0
+        }).then(res=>{
+            if(res.Ret===200){
+                showToast('定时发布成功!')
+                setTimeout(() => {
+                    router.back()
+                }, 1000);
+            }
+        })
+        return
+    }
+    showDialog({
+        title: '提示',
+        message:'是否发布定时报告,并推送模板消息?',
+        confirmButtonText:'推送',
+        cancelButtonText:'不推送',
+        showCancelButton:true
+    }).then(()=>{
+        //推送
+        apiReport.reportPublishTimeSet({
+            ReportId:reportData.value.Id,
+            PrePublishTime:time,
+            PreMsgSend:1
+        }).then(res=>{
+            if(res.Ret===200){
+                showToast('定时发布成功!')
+                setTimeout(() => {
+                    router.back()
+                }, 1000);
+            }
+        })
+    }).catch(()=>{
+        //不推送
+        apiReport.reportPublishTimeSet({
+            ReportId:reportData.value.Id,
+            PrePublishTime:time,
+            PreMsgSend:0
+        }).then(res=>{
+            if(res.Ret===200){
+                showToast('定时发布成功!')
+                setTimeout(() => {
+                    router.back()
+                }, 1000);
+            }
+        })
+    })
+}
+
+
 </script>
 
 <template>
@@ -339,6 +400,10 @@ async function reportPublish(id){
                     <img src="@/assets/imgs/report/icon_save2.png" alt="">
                     <span>保存</span>
                 </div>
+                <div class="item" @click="handleReportOpt('dsfb')">
+                    <img src="@/assets/imgs/report/icon_time.png" alt="">
+                    <span>定时发布</span>
+                </div>
                 <div class="item" @click="handleReportOpt('fb')">
                     <img src="@/assets/imgs/report/icon_publish3.png" alt="">
                     <span>发布</span>
@@ -376,7 +441,7 @@ async function reportPublish(id){
     >
         <div class="publish-report-pop-box">
             <div class="title">发布提示</div>
-            <p class="tips">是否发布报告,且推送模板消息和客户群?</p>
+            <p class="tips">是否立即发布报告,并推送模板消息?</p>
             <div class="btns">
                 <div :class="['btn blue',reportData.MsgIsSend===1?'disabled':'']" @click="handleConfirmPublish(2)">发布&推送</div>
                 <div class="btn" @click="handleConfirmPublish(1)">仅发布</div>
@@ -384,6 +449,9 @@ async function reportPublish(id){
             </div>
         </div>
     </van-popup>
+
+    <!-- 定时发布选择时间 -->
+    <ReportPublishTimeSet v-model="showDSFBTime" @confirm="onConfirmDSFBTime" />
 </template>
 <style lang="scss" scoped>
 .publish-report-pop-box{

+ 86 - 9
src/views/report/List.vue

@@ -22,7 +22,8 @@ const showCleanFilterBox=computed(()=>{
         listState.ClassifyNameFirst||
         listState.EndDate||
         listState.Frequency||
-        listState.MsgIsSend
+        listState.MsgIsSend||
+        listState.publishStatus
     ) return true
 })
 const isClickClose=ref(false)//是否点击过关闭一键清空模块
@@ -33,6 +34,7 @@ function handleCleanFilter(){
     listState.Frequency=''
     listState.StartDate=''
     listState.EndDate=''
+    listState.publishStatus=''
     refreshList()
 }
 
@@ -41,6 +43,7 @@ const showClassify=ref(false)
 
 
 const listState = reactive({
+    publishStatus:'',
     MsgIsSend:'',
     Frequency:'',
     ClassifyNameFirst:'',
@@ -62,7 +65,9 @@ async function getList(){
         ClassifyNameFirst:listState.ClassifyNameFirst,
         ClassifyNameSecond:listState.ClassifyNameSecond,
         Frequency:listState.Frequency,
-        MsgIsSend:listState.MsgIsSend
+        MsgIsSend:listState.MsgIsSend,
+        TimeType:dateType.value===1?'publish_time':'modify_time',
+        State:listState.publishStatus
     })
     if(res.Ret===200){
         listState.loading=false
@@ -178,9 +183,11 @@ function handldReportMsgSend(item){
 const calendarMinDate=new Date(2010,0,1)
 const showCalendar=ref(false)
 const calendarIns=ref(null)
+const dateType=ref(1)//1发布时间 2更新时间
 function handleCalendarChange(e){
     listState.StartDate=moment(e[0]).format('YYYY-MM-DD')
     listState.EndDate=moment(e[1]).format('YYYY-MM-DD')
+    
     refreshList()
     showCalendar.value=false
 }
@@ -227,16 +234,28 @@ async function onLongPressItem(e){
 // 更多操作
 const frequencyDropMenuIns=ref(null)
 const statusDropMenuIns=ref(null)
+const publishStatusDropMenuIns=ref(null)
 const showMoreFilter=ref(false)
 const temFrequencyVal=ref('')
 const temMsgIsSendVal=ref('')
+const temPublishStatusVal=ref('')
 const reportStatusOpt=[
     {
-        label:'已推送',
+        label:'已推送消息',
         value:2
     },
     {
-        label:'未推送',
+        label:'未推送消息',
+        value:1
+    }
+]
+const publishStatusOpt=[
+    {
+        label:'已发布',
+        value:2
+    },
+    {
+        label:'未发布',
         value:1
     }
 ]
@@ -254,6 +273,13 @@ function handleSelectFrequency(item){
         temFrequencyVal.value=item.value
     }
 }
+function handleSelectReportPublishStatus(item){
+    if(temPublishStatusVal.value==item.value){
+        temPublishStatusVal.value=''
+    }else{
+        temPublishStatusVal.value=item.value
+    }
+}
 function handleShowFilter(){
     temFrequencyVal.value=listState.Frequency
     temMsgIsSendVal.value=listState.MsgIsSend
@@ -274,6 +300,11 @@ function handleConfirmStatus(){
     refreshList()
     showMoreFilter.value=false
 }
+function handleConfirmPublishStatus(){
+    listState.publishStatus=temPublishStatusVal.value
+    refreshList()
+    showMoreFilter.value=false
+}
 
 async function goSearch(){
     // 删除报告搜索页的缓存
@@ -382,7 +413,7 @@ async function handleReportEdit(e){
                         <path d="M12.7528 34.0668C12.7528 34.3535 12.8093 34.6375 12.919 34.9024C13.0288 35.1674 13.1896 35.4081 13.3924 35.6109C13.5952 35.8136 13.8359 35.9745 14.1008 36.0842C14.3658 36.194 14.6497 36.2505 14.9365 36.2505C15.2233 36.2505 15.5072 36.194 15.7722 36.0842C16.0371 35.9745 16.2778 35.8136 16.4806 35.6109C16.6834 35.4081 16.8442 35.1674 16.954 34.9024C17.0637 34.6375 17.1202 34.3535 17.1202 34.0668C17.1202 33.78 17.0637 33.496 16.954 33.2311C16.8442 32.9662 16.6834 32.7254 16.4806 32.5226C16.2778 32.3199 16.0371 32.159 15.7722 32.0493C15.5072 31.9395 15.2233 31.8831 14.9365 31.8831C14.6497 31.8831 14.3658 31.9395 14.1008 32.0493C13.8359 32.159 13.5952 32.3199 13.3924 32.5226C13.1896 32.7254 13.0288 32.9662 12.919 33.2311C12.8093 33.496 12.7528 33.78 12.7528 34.0668Z" fill="currentColor" stroke="currentColor" stroke-width="0.5"/>
                     </svg>
                 </div>
-                <div :class="['menu-icon',showMoreFilter||listState.Frequency||listState.MsgIsSend?'active':'']" @click="handleShowFilter">
+                <div :class="['menu-icon',showMoreFilter||listState.Frequency||listState.MsgIsSend||listState.publishStatus?'active':'']" @click="handleShowFilter">
                     <svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
                         <path d="M30.283 23.977L40.824 9.5685C41.3719 8.81954 41.6002 7.88381 41.459 6.96667C41.3177 6.04952 40.8184 5.22589 40.0705 4.6765C39.4715 4.23699 38.7479 4 38.005 4H9.995C8.065 4 6.5 5.567 6.5 7.5C6.5 8.244 6.7365 8.9685 7.1755 9.5685L17.717 23.977V42.5C17.717 43.3285 18.3875 44 19.215 44C19.6125 43.9996 19.9935 43.8414 20.2743 43.5601C20.5552 43.2788 20.7128 42.8975 20.7125 42.5V23.486C20.7125 23.1675 20.611 22.857 20.423 22.5995L9.592 7.7955C9.53761 7.72096 9.50489 7.63283 9.49745 7.54085C9.49001 7.44887 9.50814 7.35663 9.54984 7.27431C9.59155 7.192 9.65519 7.12281 9.73375 7.0744C9.81231 7.02599 9.90272 7.00024 9.995 7H38.005C38.0973 7.00015 38.1878 7.02586 38.2664 7.07427C38.345 7.12268 38.4086 7.1919 38.4503 7.27426C38.492 7.35663 38.51 7.44892 38.5025 7.54092C38.4949 7.63292 38.4621 7.72104 38.4075 7.7955L27.5765 22.5995C27.3884 22.8568 27.287 23.1673 27.287 23.486V38.271C27.287 39.0995 27.9575 39.771 28.785 39.771C28.9819 39.7709 29.1768 39.732 29.3586 39.6565C29.5404 39.5811 29.7056 39.4705 29.8447 39.3312C29.9838 39.192 30.0941 39.0266 30.1693 38.8447C30.2445 38.6628 30.2831 38.4678 30.283 38.271V23.977Z" fill="currentColor"/>
                     </svg>
@@ -424,6 +455,23 @@ async function handleReportEdit(e){
                         </div>
                     </div>
                 </van-dropdown-item>
+                <van-dropdown-item title="发布状态" ref="publishStatusDropMenuIns">
+                    <div class="report-status-box">
+                        <ul>
+                            <li 
+                                :class="['status-item',temPublishStatusVal===item.value?'active':'']" 
+                                v-for="item in publishStatusOpt" 
+                                :key="item.value"
+                                @click="handleSelectReportPublishStatus(item)"
+                            >{{item.label}}</li>
+                        </ul>
+                        
+                        <div class="bot-btn-box">
+                            <div class="btn cancel-btn" @click="showMoreFilter=false">取消</div>
+                            <div class="btn confirm-btn" @click="handleConfirmPublishStatus">确定</div>
+                        </div>
+                    </div>
+                </van-dropdown-item>
             </van-dropdown-menu>
             </template>
         </div>
@@ -450,8 +498,12 @@ async function handleReportEdit(e){
                     <p class="van-multi-ellipsis--l2 des">{{item.Abstract}}</p>
                     <div class="bot-info">
                         <div class="time">
-                            <span style="margin-right:10px">{{moment(item.ModifyTime).format('YYYY-MM-DD')}}</span>
-                            <span>{{item.AdminRealName}}</span>
+                            <span style="margin-right:2px">{{moment(item.ModifyTime).format('YYYY-MM-DD')}}</span>
+                            <svg v-if="item.PrePublishTime" style="width:14px;height:14px;position: relative;top:2px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" fill="none">
+                                <path d="M13.0357 6.28571V14.7501L17.8576 19.7857L19.2213 18.422L14.9643 13.9512V6.28571H13.0357Z" fill="#0052D9"/>
+                                <path d="M27.5 14C27.5 21.4558 21.4558 27.5 14 27.5C6.54416 27.5 0.5 21.4558 0.5 14C0.5 6.54416 6.54416 0.5 14 0.5C21.4558 0.5 27.5 6.54416 27.5 14ZM25.5714 14C25.5714 7.60928 20.3907 2.42857 14 2.42857C7.60928 2.42857 2.42857 7.60928 2.42857 14C2.42857 20.3907 7.60928 25.5714 14 25.5714C20.3907 25.5714 25.5714 20.3907 25.5714 14Z" fill="#0052D9"/>
+                            </svg>
+                            <span style="margin-left:10px">{{item.AdminRealName}}</span>
                         </div>
                         <div class="read-count">
                             <span>PV:{{item.Pv}}</span>
@@ -555,8 +607,8 @@ async function handleReportEdit(e){
                     <span>日期选择</span>
                 </div>
                 <div class="time-type-box">
-                    <span>发布时间</span>
-                    <span>更新时间</span>
+                    <span @click="dateType=1" :class="['item',dateType===1?'active':'']">发布时间</span>
+                    <span @click="dateType=2" :class="['item',dateType===2?'active':'']">更新时间</span>
                 </div>
             </template>
         </van-calendar>
@@ -788,9 +840,34 @@ async function handleReportEdit(e){
         height: auto;
         min-height: var(--van-calendar-header-title-height);
     }
+    :deep(.van-calendar__header){
+        box-shadow: none;
+    }
     .time-type-box{
         font-weight: normal;
         text-align: left;
+        padding-left: 32px;
+        box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.08);
+        .item{
+            display: inline-block;
+            margin-right: 40px;
+            color: $font-grey;
+            position: relative;
+            &.active{
+                color: #333;
+                &::after{
+                    content: '';
+                    width: 30PX;
+                    height: 4PX;
+                    background-color: $theme-color;
+                    position: absolute;
+                    bottom: 0;
+                    left: 50%;
+                    border-radius: 2px;
+                    transform: translateX(-50%);
+                }
+            }
+        }
     }
 }
 

+ 1 - 1
src/views/report/components/ReportPublishPop.vue

@@ -59,7 +59,7 @@ function handleReportMessageSend(publish){
 <template>
     <div class="publish-report-pop-box">
         <div class="title">发布提示</div>
-        <p class="tips">是否发布报告,且推送模板消息和客户群?</p>
+        <p class="tips">{{reportData.PrePublishTime?'该报告已设置定时发布,是否立即发布报告并推送模板消息?':'是否立即发布报告,并推送模板消息?'}}</p>
         <div class="btns">
             <div :class="['btn blue',reportData.MsgIsSend===1?'disabled':'']" @click="handleConfirmPublish(2)">发布&推送</div>
             <div class="btn" @click="handleConfirmPublish(1)">仅发布</div>

+ 66 - 0
src/views/report/components/ReportPublishTimeSet.vue

@@ -0,0 +1,66 @@
+<script setup>
+import moment from 'moment'
+import {ref, watch} from 'vue'
+import { showToast } from 'vant'
+const props=defineProps({
+    modelValue:{
+        type:Boolean,
+        default:false
+    },
+})
+const emits=defineEmits(['update:modelValue','confirm'])
+
+const minDSFBDate=new Date()
+const minDSFBTime=ref(moment().add(2,'m').format('HH:mm:ss'))
+const dsfbDate=ref([])//定时发布选中的日期
+const dsfbTime=ref([])//定时发布选中的时间
+watch(
+    ()=>dsfbDate.value,
+    ()=>{
+        if(dsfbDate.value.join('-')==moment().format('YYYY-MM-DD')){//选中的今天
+            minDSFBTime.value=moment().add(2,'m').format('HH:mm:ss')
+        }else{
+            minDSFBTime.value='00:00:00'
+        }
+    }
+)
+function handleClose(){
+    emits('update:modelValue',false)
+}
+function onConfirmDSFBTime(){
+    const time=`${dsfbDate.value.join('-')} ${dsfbTime.value.join(':')}`
+    const now=moment().format('YYYY-MM-DD HH:mm:ss')
+    if(moment(time).isBefore(now,'second')){
+        showToast('定时发布不得早于当前时间')
+        return
+    }
+    emits('confirm',time)
+}
+
+</script>
+
+<template>
+    <van-popup
+        v-model:show="props.modelValue"
+        position="bottom"
+        round
+    >
+        <van-picker-group
+            title="设置发送时间"
+            :tabs="['选择日期', '选择时间']"
+            next-step-text="下一步"
+            @confirm="onConfirmDSFBTime"
+            @cancel="handleClose"
+        >
+            <van-date-picker
+                v-model="dsfbDate"
+                :min-date="minDSFBDate"
+            />
+            <van-time-picker
+                v-model="dsfbTime"
+                :columns-type="['hour', 'minute','second']"
+                :min-time="minDSFBTime"
+            />
+        </van-picker-group>
+    </van-popup>
+</template>

+ 9 - 2
src/views/report/components/reportInsert/Index.vue

@@ -4,10 +4,11 @@ import ETAChart from './ETAChart.vue'
 import MyETAChart from './MyETAChart.vue'
 import SandTableImg from './SandTableImg.vue'
 import SheetTableChart from './SheetTableChart.vue'
+import SemanticsImg from './SemanticsImg.vue'
 
 const emits=defineEmits(['insert'])
 
-const typeOpt=['图表插入','批量插入','表格插入','沙盘插入']
+const typeOpt=['图表插入','批量插入','表格插入','沙盘插入','语义分析插入']
 const activeType=ref('图表插入')
 
 let list=ref([])
@@ -21,7 +22,7 @@ function handleConfirmInsert(){
         emits('insert',{list:list.value,type:'iframe',chartType:'chart'})
     }else if(activeType.value==='表格插入'){
         emits('insert',{list:list.value,type:'iframe',chartType:'sheet'})
-    }else if(activeType.value==='沙盘插入'){
+    }else if(['沙盘插入','语义分析插入'].includes(activeType.value)){
         emits('insert',{list:list.value,type:'img',chartType:''})
     }
     
@@ -44,6 +45,7 @@ function handleConfirmInsert(){
             <MyETAChart @update="handleSelectChart" v-if="activeType==='批量插入'"/>
             <SheetTableChart @update="handleSelectChart" v-if="activeType==='表格插入'"/>
             <SandTableImg @update="handleSelectChart" v-if="activeType==='沙盘插入'"/>
+            <SemanticsImg @update="handleSelectChart" v-if="activeType==='语义分析插入'"/>
         </div>
         <div class="bot-btn">
             <van-button type="primary" block @click="handleConfirmInsert" :disabled="list.length===0">插入</van-button>
@@ -61,9 +63,14 @@ function handleConfirmInsert(){
         background-color: $page-bg-grey;
         display: flex;
         border-bottom: 1px solid $border-color;
+        overflow-x: auto;
+        &::-webkit-scrollbar{
+            display: none;
+        }
         .item{
             padding: 24px 0;
             flex: 1;
+            min-width: 96PX;
             text-align: center;
             border-top-right-radius: var(--van-popup-round-radius);
             border-top-left-radius: var(--van-popup-round-radius);

+ 181 - 0
src/views/report/components/reportInsert/SemanticsImg.vue

@@ -0,0 +1,181 @@
+<script setup>
+import {reactive, ref,watch} from 'vue'
+import apiSemanticAnalysis from '@/api/semanticAnalysis'
+import { vInfiniteScroll } from '@vueuse/components'
+
+const emits=defineEmits(['update'])
+
+const searchVal=ref('')
+const listState=reactive({
+    page:1,
+    pageSize:20,
+    list:[],
+    finished:false,
+    loading:false
+})
+async function getSandBoxList(){
+    const params={
+        Keyword:searchVal.value,
+        CurrentIndex:listState.page,
+        PageSize:listState.pageSize
+    }
+    listState.loading=true
+    let res=await apiSemanticAnalysis.compareImgList(params)
+    listState.loading=false
+    if(res.Ret===200){
+        const arr=res.Data.List||[]
+        listState.list=[...listState.list,...arr]
+        listState.finished=res.Data?.Paging.IsEnd
+    }
+}
+getSandBoxList()
+// 触底加载更多
+function onLoadMore(){
+    if(listState.finished||listState.loading) return
+    listState.page++
+    getSandBoxList()
+}
+function handleRefreshList(){
+    listState.list=[]
+    listState.page=1
+    listState.finished=false
+    getSandBoxList()
+}
+
+let selectChartList=ref([])
+function handleSelect(item){
+    const index=selectChartList.value.indexOf(item.SaCompareId)
+    if(index!==-1){
+        selectChartList.value.splice(index,1)
+    }else{
+        selectChartList.value.push(item.SaCompareId)
+    }
+    
+}
+
+watch(
+    ()=>selectChartList.value,
+    ()=>{
+        const arr=listState.list.filter(item=>selectChartList.value.includes(item.SaCompareId)).map(e=>e.ResultImg)
+        emits('update',arr)
+    },
+    {
+        immediate:true,
+        deep:true
+    }
+)
+</script>
+
+
+<template>
+    <div class="sandTableImg-insert-wrap">
+        <van-search v-model="searchVal" shape="round" placeholder="请输入搜索关键词" @search="handleRefreshList" @clear="handleRefreshList" />
+        <div class="content-box">
+            <div v-if="listState.list.length==0&&listState.finished">
+                <img class="list-empty-img" src="https://hzstatic.hzinsights.com/static/ETA_mobile/empty_img.png" alt="">
+                <p style="text-align:center;color:#999999;font-size:12px">暂无图表</p>
+            </div>
+            
+            <ul class="chart-list" v-infinite-scroll="[onLoadMore, { 'distance' : 10 }]">
+                <li 
+                    :class="['chart-item',selectChartList.includes(item.SaCompareId)&&'active']" 
+                    v-for="item in listState.list" 
+                    :key="item.SaCompareId"
+                    @click="handleSelect(item)"
+                >
+                    <div class="van-multi-ellipsis--l2 title">{{item.Title}}</div>
+                    <img :src="item.ResultImg" alt="">
+
+                    <svg v-if="selectChartList.includes(item.SaCompareId)" width="29" height="28" viewBox="0 0 29 28" fill="none" xmlns="http://www.w3.org/2000/svg">
+                        <path d="M14.5 28C22.232 28 28.5 21.732 28.5 14C28.5 6.26801 22.232 0 14.5 0C6.76801 0 0.5 6.26801 0.5 14C0.5 21.732 6.76801 28 14.5 28ZM7.5 14.413L8.913 13L12.5 16.586L20.085 9L21.5 10.415L12.5 19.414L7.5 14.413Z" fill="#0052D9"/>
+                    </svg>
+
+                </li>
+                <li class="chart-item" style="height:0;border:none;margin-bottom:0;padding:0"></li>
+                <li class="chart-item" style="height:0;border:none;margin-bottom:0;padding:0"></li>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.sandTableImg-insert-wrap{
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    .content-box{
+        overflow: hidden;
+        flex: 1;
+        padding: var(--van-padding-sm);
+        min-height: 300PX;
+    }
+    .chart-list{
+        height: 100%;
+        overflow-y: auto;
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: space-between;
+        .chart-item{
+            width: 48%;
+            background: #FFFFFF;
+            border: 3px solid $border-color;
+            box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.03);
+            border-radius: 4px;
+            margin-bottom: 30px;
+            overflow: hidden;
+            padding: 14px;
+            box-sizing: border-box;
+            position: relative;
+            .title{
+                font-size: 28px;
+                min-height: 60px;
+            }
+            img{
+                width: 100%;
+                height: 220px;
+                object-fit: contain;
+            }
+        }
+        .active{
+            border-color: $theme-color;
+            svg{
+                width: 28px;
+                height: 28px;
+                position: absolute;
+                right: 22px;
+                bottom: 22px;
+            }
+        }
+    }
+}
+@media screen and (min-width:$media-width){
+    .sandTableImg-insert-wrap{
+        .chart-list{
+            height: auto;
+            max-height: 100%;
+            .chart-item{
+                width: 260px;
+                border-width: 1px;
+                border-radius: 2px;
+                margin-bottom: 15px;
+                padding: 7px;
+                .title{
+                    font-size: 14px;
+                    min-height: 30px;
+                }
+                img{
+                    height: 150px;
+                }
+            }
+            .active{
+                svg{
+                    width: 14px;
+                    height: 14px;
+                    right: 11px;
+                    bottom: 11px;
+                }
+            }
+        }
+    }
+}
+</style>

+ 32 - 1
src/views/reportEn/AddReport.vue

@@ -1,7 +1,8 @@
 <script setup name="ReportEnAdd">
-import {ref,onMounted,onUnmounted, nextTick} from 'vue'
+import {ref,onMounted,onUnmounted, nextTick, watch} from 'vue'
 import EditReportBaseInfo from './components/EditReportBaseInfo.vue'
 import ReportInsertContent from '../report/components/reportInsert/Index.vue'
+import ReportPublishTimeSet from '@/views/report/components/ReportPublishTimeSet.vue'
 import apiReportEn from '@/api/reportEn'
 import apiChart from '@/api/chart'
 import moment from 'moment'
@@ -21,6 +22,8 @@ let overviewContentIns=null//overview内容编辑器实例
 
 let autoSaveTimer=null//自动保存定时器
 
+let reportId=route.query.id||0//报告id
+
 onMounted(async () => {
     const el=document.getElementById('editor')
     reportContentIns=initFroalaEditor('#editor',{height:el.offsetHeight-150})
@@ -271,6 +274,7 @@ async function handleReportOpt(e){
     ?await apiReportEn.reportEdit({ReportId:Number(route.query.id),...params})
     :await apiReportEn.reportAdd(params)
     if(res.Ret!==200) return
+    reportId=res.Data.ReportId
     cachedViewsStore.removeCaches('ReportEnList')
     if(e==='cg'){
         showToast('保存成功')
@@ -286,6 +290,9 @@ async function handleReportOpt(e){
     if(e==='fb'){
         reportPublish(res.Data.ReportId)
     }
+    if(e==='dsfb'){
+        showDSFBTime.value=true
+    }
     
 }
 
@@ -301,6 +308,23 @@ function reportPublish(id){
     })
 }
 
+
+// 定时发布报告选择时间
+const showDSFBTime=ref(false)
+function onConfirmDSFBTime(time){
+    console.log(time);
+    apiReportEn.reportPublishTimeSet({
+        ReportId:reportId,
+        PrePublishTime:time
+    }).then(res=>{
+        if(res.Ret===200){
+            showToast('定时发布成功')
+            setTimeout(() => {
+                router.back()
+            }, 1500);
+        }
+    })
+}
 </script>
 
 <template>
@@ -325,6 +349,10 @@ function reportPublish(id){
                     <img src="@/assets/imgs/report/icon_save2.png" alt="">
                     <span>保存</span>
                 </div>
+                <div class="item" @click="handleReportOpt('dsfb')">
+                    <img src="@/assets/imgs/report/icon_time.png" alt="">
+                    <span>定时发布</span>
+                </div>
                 <div class="item" @click="handleReportOpt('fb')">
                     <img src="@/assets/imgs/report/icon_publish3.png" alt="">
                     <span>发布</span>
@@ -371,6 +399,9 @@ function reportPublish(id){
         <report-insert-content v-if="showReportInsertPop" @insert="handleInsert"/>
     </van-popup>
 
+    <!-- 定时发布选择时间 -->
+    <ReportPublishTimeSet v-model="showDSFBTime" @confirm="onConfirmDSFBTime" />
+
 </template>
 
 <style lang="scss" scoped>

+ 118 - 15
src/views/reportEn/List.vue

@@ -24,7 +24,8 @@ const showCleanFilterBox=computed(()=>{
         listState.ClassifyNameFirst||
         listState.EndDate||
         listState.Frequency||
-        listState.MsgIsSend
+        listState.MsgIsSend||
+        listState.publishStatus
     ) return true
 })
 const isClickClose=ref(false)//是否点击过关闭一键清空模块
@@ -35,6 +36,7 @@ function handleCleanFilter(){
     listState.Frequency=''
     listState.StartDate=''
     listState.EndDate=''
+    listState.publishStatus=''
     refreshList()
 }
 
@@ -43,6 +45,7 @@ const showClassify=ref(false)
 
 
 const listState = reactive({
+    publishStatus:'',
     MsgIsSend:'',
     Frequency:'',
     ClassifyNameFirst:'',
@@ -64,7 +67,9 @@ async function getList(){
         ClassifyNameFirst:listState.ClassifyNameFirst,
         ClassifyNameSecond:listState.ClassifyNameSecond,
         Frequency:listState.Frequency,
-        EmailState:listState.MsgIsSend
+        EmailState:listState.MsgIsSend,
+        TimeType:dateType.value===1?'publish_time':'modify_time',
+        State:listState.publishStatus
     })
     if(res.Ret===200){
         listState.loading=false
@@ -111,15 +116,23 @@ function handleReportDel(item){
 
 // 发布报告
 async function handleReportPublish(item){
-    apiReportEn.reportPublish({
-        ReportIds:item.Id.toString()
-    }).then(res=>{
-        if(res.Ret===200){
-            showToast('发布成功')
-            showReportItemOpt.value=false
-            refreshList()
-        }
+    console.log(item);
+    showDialog({
+        title: '提示',
+        message: item.PrePublishTime?'该报告已设置定时发布,是否变更为立即发布?':`是否确定立即发布报告?`,
+        showCancelButton:true
+    }).then(()=>{
+        apiReportEn.reportPublish({
+            ReportIds:item.Id.toString()
+        }).then(res=>{
+            if(res.Ret===200){
+                showToast('发布成功')
+                showReportItemOpt.value=false
+                refreshList()
+            }
+        })
     })
+    
 }
 
 // 取消发布
@@ -142,6 +155,7 @@ function handleReportPublishCancle(item){
 const calendarMinDate=new Date(2010,0,1)
 const showCalendar=ref(false)
 const calendarIns=ref(null)
+const dateType=ref(1)//1发布时间 2更新时间
 function handleCalendarChange(e){
     listState.StartDate=moment(e[0]).format('YYYY-MM-DD')
     listState.EndDate=moment(e[1]).format('YYYY-MM-DD')
@@ -190,9 +204,11 @@ function onLongPressItem(e){
 // 更多操作
 const frequencyDropMenuIns=ref(null)
 const statusDropMenuIns=ref(null)
+const publishStatusDropMenuIns=ref(null)
 const showMoreFilter=ref(false)
 const temFrequencyVal=ref('')
 const temMsgIsSendVal=ref('')
+const temPublishStatusVal=ref('')
 const frequencyOpt=[
     {
         label:'年度',
@@ -237,6 +253,16 @@ const reportStatusOpt=[
         value:1
     }
 ]
+const publishStatusOpt=[
+    {
+        label:'已发布',
+        value:2
+    },
+    {
+        label:'未发布',
+        value:1
+    }
+]
 function handleSelectReportStatus(item){
     if(temMsgIsSendVal.value==item.value){
         temMsgIsSendVal.value=''
@@ -251,6 +277,13 @@ function handleSelectFrequency(item){
         temFrequencyVal.value=item.value
     }
 }
+function handleSelectReportPublishStatus(item){
+    if(temPublishStatusVal.value==item.value){
+        temPublishStatusVal.value=''
+    }else{
+        temPublishStatusVal.value=item.value
+    }
+}
 function handleShowFilter(){
     temFrequencyVal.value=listState.Frequency
     temMsgIsSendVal.value=listState.MsgIsSend
@@ -271,6 +304,11 @@ function handleConfirmStatus(){
     refreshList()
     showMoreFilter.value=false
 }
+function handleConfirmPublishStatus(){
+    listState.publishStatus=temPublishStatusVal.value
+    refreshList()
+    showMoreFilter.value=false
+}
 
 function goSearch(){
     // 删除报告搜索页的缓存
@@ -384,7 +422,7 @@ function handleGoEmailLog(e){
                         <path d="M12.7528 34.0668C12.7528 34.3535 12.8093 34.6375 12.919 34.9024C13.0288 35.1674 13.1896 35.4081 13.3924 35.6109C13.5952 35.8136 13.8359 35.9745 14.1008 36.0842C14.3658 36.194 14.6497 36.2505 14.9365 36.2505C15.2233 36.2505 15.5072 36.194 15.7722 36.0842C16.0371 35.9745 16.2778 35.8136 16.4806 35.6109C16.6834 35.4081 16.8442 35.1674 16.954 34.9024C17.0637 34.6375 17.1202 34.3535 17.1202 34.0668C17.1202 33.78 17.0637 33.496 16.954 33.2311C16.8442 32.9662 16.6834 32.7254 16.4806 32.5226C16.2778 32.3199 16.0371 32.159 15.7722 32.0493C15.5072 31.9395 15.2233 31.8831 14.9365 31.8831C14.6497 31.8831 14.3658 31.9395 14.1008 32.0493C13.8359 32.159 13.5952 32.3199 13.3924 32.5226C13.1896 32.7254 13.0288 32.9662 12.919 33.2311C12.8093 33.496 12.7528 33.78 12.7528 34.0668Z" fill="currentColor" stroke="currentColor" stroke-width="0.5"/>
                     </svg>
                 </div>
-                <div :class="['menu-icon',showMoreFilter||listState.Frequency||listState.MsgIsSend?'active':'']" @click="handleShowFilter">
+                <div :class="['menu-icon',showMoreFilter||listState.Frequency||listState.MsgIsSend||listState.publishStatus?'active':'']" @click="handleShowFilter">
                     <svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
                         <path d="M30.283 23.977L40.824 9.5685C41.3719 8.81954 41.6002 7.88381 41.459 6.96667C41.3177 6.04952 40.8184 5.22589 40.0705 4.6765C39.4715 4.23699 38.7479 4 38.005 4H9.995C8.065 4 6.5 5.567 6.5 7.5C6.5 8.244 6.7365 8.9685 7.1755 9.5685L17.717 23.977V42.5C17.717 43.3285 18.3875 44 19.215 44C19.6125 43.9996 19.9935 43.8414 20.2743 43.5601C20.5552 43.2788 20.7128 42.8975 20.7125 42.5V23.486C20.7125 23.1675 20.611 22.857 20.423 22.5995L9.592 7.7955C9.53761 7.72096 9.50489 7.63283 9.49745 7.54085C9.49001 7.44887 9.50814 7.35663 9.54984 7.27431C9.59155 7.192 9.65519 7.12281 9.73375 7.0744C9.81231 7.02599 9.90272 7.00024 9.995 7H38.005C38.0973 7.00015 38.1878 7.02586 38.2664 7.07427C38.345 7.12268 38.4086 7.1919 38.4503 7.27426C38.492 7.35663 38.51 7.44892 38.5025 7.54092C38.4949 7.63292 38.4621 7.72104 38.4075 7.7955L27.5765 22.5995C27.3884 22.8568 27.287 23.1673 27.287 23.486V38.271C27.287 39.0995 27.9575 39.771 28.785 39.771C28.9819 39.7709 29.1768 39.732 29.3586 39.6565C29.5404 39.5811 29.7056 39.4705 29.8447 39.3312C29.9838 39.192 30.0941 39.0266 30.1693 38.8447C30.2445 38.6628 30.2831 38.4678 30.283 38.271V23.977Z" fill="currentColor"/>
                     </svg>
@@ -409,7 +447,7 @@ function handleGoEmailLog(e){
                         </div>
                     </div>
                 </van-dropdown-item>
-                <van-dropdown-item title="报告状态" ref="statusDropMenuIns">
+                <van-dropdown-item title="群发状态" ref="statusDropMenuIns">
                     <div class="report-status-box">
                         <ul>
                             <li 
@@ -426,6 +464,23 @@ function handleGoEmailLog(e){
                         </div>
                     </div>
                 </van-dropdown-item>
+                <van-dropdown-item title="发布状态" ref="publishStatusDropMenuIns">
+                    <div class="report-status-box">
+                        <ul>
+                            <li 
+                                :class="['status-item',temPublishStatusVal===item.value?'active':'']" 
+                                v-for="item in publishStatusOpt" 
+                                :key="item.value"
+                                @click="handleSelectReportPublishStatus(item)"
+                            >{{item.label}}</li>
+                        </ul>
+                        
+                        <div class="bot-btn-box">
+                            <div class="btn cancel-btn" @click="showMoreFilter=false">取消</div>
+                            <div class="btn confirm-btn" @click="handleConfirmPublishStatus">确定</div>
+                        </div>
+                    </div>
+                </van-dropdown-item>
             </van-dropdown-menu>
             </template>
         </div>
@@ -444,12 +499,19 @@ function handleGoEmailLog(e){
                     @click="goDetail(item)"
                     v-longpress="{ handler: onLongPressItem, args: item, duration: 1000 }"
                 >
-                    <h2 :class="['van-ellipsis title',item.Title.startsWith('【')?'inline-title':'']">{{item.Title}}</h2>
+                    <h2 :class="['van-ellipsis title',item.Title.startsWith('【')?'inline-title':'']">
+                        <span>{{item.Title}}</span>
+                        <span v-if="item.CreateTime">({{item.CreateTime.substring(5,7)}}{{item.CreateTime.substring(8,10)}})</span>
+                    </h2>
                     <p class="van-multi-ellipsis--l2 des">{{item.Abstract}}</p>
                     <div class="bot-info">
                         <div style="flex:1">
-                            <span style="margin-right:10px">{{moment(item.ModifyTime).format('YYYY-MM-DD')}}</span>
-                            <span>{{item.AdminRealName}}</span>
+                            <span style="margin-right:2px">{{moment(item.ModifyTime).format('YYYY-MM-DD')}}</span>
+                            <svg v-if="item.PrePublishTime" style="width:14px;height:14px;position: relative;top:2px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" fill="none">
+                                <path d="M13.0357 6.28571V14.7501L17.8576 19.7857L19.2213 18.422L14.9643 13.9512V6.28571H13.0357Z" fill="#0052D9"/>
+                                <path d="M27.5 14C27.5 21.4558 21.4558 27.5 14 27.5C6.54416 27.5 0.5 21.4558 0.5 14C0.5 6.54416 6.54416 0.5 14 0.5C21.4558 0.5 27.5 6.54416 27.5 14ZM25.5714 14C25.5714 7.60928 20.3907 2.42857 14 2.42857C7.60928 2.42857 2.42857 7.60928 2.42857 14C2.42857 20.3907 7.60928 25.5714 14 25.5714C20.3907 25.5714 25.5714 20.3907 25.5714 14Z" fill="#0052D9"/>
+                            </svg>
+                            <span style="margin-left:10px">{{item.AdminRealName}}</span>
                         </div>
                         <div class="read-count">
                             <span>PV:{{item.Pv}}</span>
@@ -518,12 +580,17 @@ function handleGoEmailLog(e){
             :min-date="calendarMinDate"
             @confirm="handleCalendarChange" 
             :style="{ height: '500px' }"
+            class="calendar-box"
         >
             <template #title>
                 <div style="position: relative;">
                     <span style="color:#666;position: absolute;left:16px" @click="handleResetCalendar">重置</span>
                     <span>日期选择</span>
                 </div>
+                <div class="time-type-box">
+                    <span @click="dateType=1" :class="['item',dateType===1?'active':'']">发布时间</span>
+                    <span @click="dateType=2" :class="['item',dateType===2?'active':'']">更新时间</span>
+                </div>
             </template>
         </van-calendar>
     </van-popup>
@@ -783,6 +850,42 @@ function handleGoEmailLog(e){
     }
 }
 
+.calendar-box{
+    :deep(.van-calendar__header-title){
+        height: auto;
+        min-height: var(--van-calendar-header-title-height);
+    }
+    :deep(.van-calendar__header){
+        box-shadow: none;
+    }
+    .time-type-box{
+        font-weight: normal;
+        text-align: left;
+        padding-left: 32px;
+        box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.08);
+        .item{
+            display: inline-block;
+            margin-right: 40px;
+            color: $font-grey;
+            position: relative;
+            &.active{
+                color: #333;
+                &::after{
+                    content: '';
+                    width: 30PX;
+                    height: 4PX;
+                    background-color: $theme-color;
+                    position: absolute;
+                    bottom: 0;
+                    left: 50%;
+                    border-radius: 2px;
+                    transform: translateX(-50%);
+                }
+            }
+        }
+    }
+}
+
 @media screen and (min-width:$media-width){
     .add-report-btn{
         svg{