Selaa lähdekoodia

处理章节报告操作

Karsa 6 kuukautta sitten
vanhempi
commit
68391ab7fb

+ 5 - 0
src/api/report.js

@@ -247,6 +247,11 @@ export default {
         return get('/smart_report/resource/list',params)
     },
 
+    //音频上传
+    uploadAudio: params => {
+        return post('/voice/upload',params)
+    },
+
         
     /* v2=============================== */
     /**

+ 4 - 0
src/assets/styles/common.scss

@@ -102,6 +102,10 @@ img {
 .report-html-wrap{
     line-height: 1.8;
     font-size: 36px;
+    .report-drag-item-wrap{
+        padding: 6px;
+        margin-bottom: 3px;
+    }
     img{
         width: 100% !important;
     }

+ 104 - 26
src/views/report/EditReport.vue

@@ -5,7 +5,7 @@ import {useInitFroalaEditor} from '@/hooks/useFroalaEditor'
 import ReportInsertContent from './components/reportInsert/Index.vue'
 import ReportPublishTimeSet from './components/ReportPublishTimeSet.vue'
 import apiReport from '@/api/report'
-import {getSystemInfo} from '@/api/common'
+// import {getSystemInfo} from '@/api/common'
 import moment from 'moment'
 import { showToast,showDialog } from 'vant'
 import { useRoute, useRouter } from 'vue-router'
@@ -14,7 +14,7 @@ import {usePublicSettingStore} from '@/store/modules/publicSetting'
 import {reportManageBtn,useAuthBtn} from '@/hooks/useAuthBtn'
 import {useReportApprove} from '@/hooks/useReportApprove'
 import AddReportBaseInfoV2 from './components/AddReportBaseInfoV2.vue'
-import { useReportHandles } from './hooks/useReport'
+import { useReportHandles,useChapterRepoprtHandles } from './hooks/useReport'
 
 const cachedViewsStore=useCachedViewsStore()
 const publicSettingStore = usePublicSettingStore()
@@ -29,16 +29,25 @@ let reportContentEditorIns=null//报告内容编辑器实例
 
 const { handleRefresh,handlePublishReportHook,handleDSPublish,showDSFBTime } = useReportHandles()
 
+const reportCoopType = ref(Number(route.query.coopType))
 let autoSaveTimer=null
 
 onMounted(() => {
     const el=document.getElementById('editor')
     reportContentEditorIns=initFroalaEditor('#editor',{height:el.offsetHeight-150})
-    getEtaConfig()
-    getReportDetail()
-    autoSaveTimer=setInterval(() => {
-        autoSaveReportContent()
-    }, 6000);
+
+    if(reportCoopType.value===1) {//单人报告
+        getEtaConfig()
+        getReportDetail()
+        autoSaveTimer=setInterval(() => {
+            autoSaveReportContent()
+        }, 6000);
+    }else if(reportCoopType.value===2) { //章节报告
+        getChapterDetail()
+        autoSaveTimer=setInterval(() => {
+            autoSaveReportChapter()
+        }, 6000);
+    }
 })
 onUnmounted(()=>{
     clearInterval(autoSaveTimer)
@@ -110,6 +119,16 @@ async function getReportDetail(){
     }
 }
 
+//获取章节详情
+async function getChapterDetail() {
+    const res=await apiReport.getChapterDetail({
+        ReportChapterId:Number(route.query.chapterId)
+    })
+    reportData.value=res.Data;
+
+    reportContentEditorIns.html.set(res.Data.Content);
+}
+
 
 // 报告基本内容
 const showReportBaseInfo=ref(false)
@@ -197,7 +216,7 @@ onUnmounted(()=>{
 
 // 刷新所有图表
 async function handleRefreshAllChart(){
-    handleRefresh({ id: reportData.value.Id,chapterId:reportData.value.ChapterId })
+    handleRefresh({ id: Number(route.query.id),chapterId:Number(route.query.chapterId) })
 }
 
 
@@ -241,12 +260,56 @@ async function handlePublishReport(tp) {
     handlePublishReportHook(tp,reportData.value)
 }
 
-
 // 定时发布报告选择时间
 function onConfirmDSFBTime(time){
     // console.log(time);
     handleDSPublish(time,reportData.value)
 }
+
+
+
+const { handlePublishChapterApi } = useChapterRepoprtHandles()
+//预览章节
+async function handlePreviewChapter() {
+    const saveRes = await autoSaveReportChapter('auto');
+    if(!saveRes) return
+    
+    const routerEl=router.resolve({
+        path:'/report/chapter/preview',
+        query:{
+            id:reportData.value.ReportChapterId
+        }
+    })
+    window.open(routerEl.href,'_blank')
+}
+
+// 自动保存章节报告
+async function autoSaveReportChapter(type="auto"){
+    if(!imgUploadFlag.value)return
+    if(!route.query.chapterId) return 
+    //如果富文本中有未上传完成的图片,去除这个dom
+    $('.fr-element').find('img.fr-uploading').length&&$('.fr-element').find('img.fr-uploading').remove()
+    return new Promise(async (resolve,reject)=>{
+        const res=await apiReport.chapterDetailSave({
+            ReportChapterId:Number(route.query.chapterId),
+            Content:$('.fr-element').html(),
+        })
+        if(res.Ret === 200) {
+            resolve(true)
+            type==='save' && showToast("保存成功");
+        }
+    })
+   
+}
+
+/* 提交章节 */
+async function handlePublishChapter() {
+    const saveRes = await autoSaveReportChapter('auto');
+    if(!saveRes) return
+
+    handlePublishChapterApi(reportData.value.ReportChapterId)
+}
+
 </script>
 
 <template>
@@ -256,8 +319,8 @@ function onConfirmDSFBTime(time){
         </div>
         <!-- 底部操作 -->
         <div class="bot-action-box">
-            <div class="left-box">
-                <div class="item" @click="showReportBaseInfo=true">
+            <div class="left-box" v-if="reportData">
+                <div class="item" @click="showReportBaseInfo=true" v-if="!reportData.ReportChapterId">
                     <img src="@/assets/imgs/report/icon_info.png" alt="">
                     <span>基础信息</span>
                 </div>
@@ -265,29 +328,44 @@ function onConfirmDSFBTime(time){
                     <img src="@/assets/imgs/report/icon_refresh.png" alt="">
                     <span>刷新</span>
                 </div>
-                <div class="item" @click="handlePreviewReport" v-permission="reportManageBtn.reportManage_reportView">
+                <div class="item" @click="reportData.ReportChapterId?handlePreviewChapter():handlePreviewReport()" v-permission="reportManageBtn.reportManage_reportView">
                     <img src="@/assets/imgs/report/icon_preview.png" alt="">
                     <span>预览</span>
                 </div>
-                <div class="item" @click="autoSaveReportContent('save')">
+                <div class="item" @click="reportData.ReportChapterId?autoSaveReportChapter('save'):autoSaveReportContent('save')">
                     <img src="@/assets/imgs/report/icon_save2.png" alt="">
                     <span>保存</span>
                 </div>
-                <template v-if="!isApprove||!hasApproveFlow">
-                    <div class="item" @click="handlePublishReport('dsfb')" v-permission="reportManageBtn.reportManage_publish">
-                        <img src="@/assets/imgs/report/icon_time.png" alt="">
-                        <span>定时发布</span>
-                    </div>
-                    <div class="item" @click="handlePublishReport('fb')" v-permission="reportManageBtn.reportManage_publish">
-                        <img src="@/assets/imgs/report/icon_publish3.png" alt="">
-                        <span>发布</span>
-                    </div>
-                </template>
-                <template v-if="isApprove&&hasApproveFlow">
-                    <div class="item" @click="handlePublishReport('submit')" v-permission="reportManageBtn.reportManage_publish">
+
+                <!-- 章节报告提交章节 -->
+                <div 
+                    class="item" 
+                    @click="handlePublishChapter" 
+                    v-permission="reportManageBtn.reportManage_publish" 
+                    v-if="reportData.ReportChapterId"
+                >
                         <img src="@/assets/imgs/report/icon_publish3.png" alt="">
                         <span>提交</span>
-                    </div>
+                </div>
+
+                <!-- 单人报告提交发布 -->
+                <template v-else>
+                    <template v-if="!isApprove||!hasApproveFlow">
+                        <div class="item" @click="handlePublishReport('dsfb')" v-permission="reportManageBtn.reportManage_publish">
+                            <img src="@/assets/imgs/report/icon_time.png" alt="">
+                            <span>定时发布</span>
+                        </div>
+                        <div class="item" @click="handlePublishReport('fb')" v-permission="reportManageBtn.reportManage_publish">
+                            <img src="@/assets/imgs/report/icon_publish3.png" alt="">
+                            <span>发布</span>
+                        </div>
+                    </template>
+                    <template v-if="isApprove&&hasApproveFlow">
+                        <div class="item" @click="handlePublishReport('submit')" v-permission="reportManageBtn.reportManage_publish">
+                            <img src="@/assets/imgs/report/icon_publish3.png" alt="">
+                            <span>提交</span>
+                        </div>
+                    </template>
                 </template>
             </div>
             <div class="right-btn" @click="showReportInsertPop=true">

+ 123 - 24
src/views/report/List.vue

@@ -9,14 +9,16 @@ import { showToast,showDialog,Dialog } from 'vant';
 import { useRouter } from 'vue-router';
 import { useWindowSize } from '@vueuse/core'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
-// import {reportFrequencyOpts} from './utils/config'
 import {useDownLoadFile} from '@/hooks/useDownLoadFile'
 import {reportManageBtn,useAuthBtn} from '@/hooks/useAuthBtn'
 import {useReportApprove} from '@/hooks/useReportApprove'
 import {usePublicSettingStore} from '@/store/modules/publicSetting'
 import {Base64} from 'js-base64'
+import {isWeiXin} from '@/hooks/common'
 import AddReportBaseInfoV2 from './components/AddReportBaseInfoV2.vue'
 import ReportFilter from './components/ReportFilter.vue'
+import AudioBox from './components/AudioBox.vue'
+
 
 const cachedViewsStore=useCachedViewsStore()
 const publicSettingStore = usePublicSettingStore()
@@ -173,24 +175,7 @@ let activeReportData=ref('')
 let showPublishPop=ref(false)
 async function handleReportPublish(item){
     activeReportData.value=item
-    // 周报校验是否上传了音频
-    if(item.ClassifyNameFirst=='周报'){
-        const validRes=await apiReport.weekReportValidAudio({ReportId:Number(item.Id)})
-        if(validRes.Ret===200){
-			if(validRes.Data){
-                showDialog({
-                    title: '发布提示',
-                    message: `报告未上传录音:${validRes.Data.join('、')},确定发布吗?`,
-                    showCancelButton:true
-                }).then(()=>{
-                    showPublishPop.value=true
-                })
-            }else{
-                showPublishPop.value=true
-            }
-        }
-        return
-    }
+
     //如果走审批流 直接发布
     if(isApprove.value){
         publishReportApprove()
@@ -304,14 +289,78 @@ function handldReportMsgSend(item){
     })
 }
 
-/* 上传音频 */
-function handleUploadAudio() {
 
+/* 上传章节音频 */
+// 上传音频
+const showUploadAudio=ref(false)
+const temAudioData=reactive({
+    time:0,
+    size:0,
+    url:'',
+})
+function handleShowUploadAudio(){
+    showReportItemOpt.value = false;
+    temAudioData.time=activeItem.value.VideoPlaySeconds
+    temAudioData.size=activeItem.value.VideoSize
+    temAudioData.url=activeItem.value.VideoUrl
+    showUploadAudio.value=true
+}
+// 获取音频时长
+function handleGetAudioDuration(file){
+    return new Promise((resolve,reject)=>{
+        if(isWeiXin()){
+            console.log('微信?');
+            resolve(0)
+        }
+
+        const fileUrl=URL.createObjectURL(file)
+        const audioEl=new Audio(fileUrl)
+        audioEl.addEventListener('loadedmetadata',(e)=>{
+            console.log('e.path',e.path)
+            console.log('e.composedPath',e.composedPath())
+            console.log('获取音频时长',e.composedPath()[0].duration);
+            console.log(audioEl.duration);
+            const t=e.composedPath()[0].duration
+            resolve(t)
+        })
+    })
+}
+async function handleAudioUploadAfterRead(e){
+    // console.log(e);
+    const duration=await handleGetAudioDuration(e.file)
+
+    temAudioData.time=duration||0
+    temAudioData.size=e.file.size/1024/1024 //单位MB
+    temAudioData.name=e.file.name
+    console.log('音频数据temAudioData',temAudioData);
+
+    let params = new FormData();
+        params.append("file", e.file);
+        params.append("ReportId", activeItem.value.Id);
+      const res = await apiReport.uploadAudio(params)
+
+      if(res.Ret !== 200) return
+      temAudioData.url = res.Data.ResourceUrl;
+}
+function handleUpdateAudio(){
+    activeItem.value.VideoUrl=temAudioData.url
+    activeItem.value.VideoPlaySeconds=temAudioData.time
+    activeItem.value.VideoSize=temAudioData.size
+    showUploadAudio.value=false
+}
+//更新下音频时长
+function handleUpdateAudioTime(e){
+    temAudioData.time=e
 }
 
-/* 音频下载 */
-function handleDownloadAudio() {
 
+
+const downloadUrl = `${import.meta.env.VITE_APP_API_URL}/voice/download`
+/* 音频下载 */
+function handleDownloadAudio(item) {
+    showReportItemOpt.value = false;
+    let url = downloadUrl+`?ReportId=${parseInt(item.Id)}`;
+    startDownload(url,item.VideoName);
 }
 
 
@@ -656,7 +705,7 @@ onMounted(async ()=>{
             
 
             <div class="item" v-if="checkAuthBtn(reportManageBtn.reportManage_audioUpload)"
-                @click="handleUploadAudio(activeItem)&&activeItem.HasAuth">音频上传</div>
+                @click="handleShowUploadAudio(activeItem)&&activeItem.HasAuth">音频上传</div>
             <div class="item" v-if="checkAuthBtn(reportManageBtn.reportManage_audioDownload)&&(activeItem.VideoUrl || activeItem.ChapterVideoList.length>0)"
                 @click="handleDownloadAudio(activeItem)">音频下载</div>
 
@@ -707,6 +756,32 @@ onMounted(async ()=>{
             @close="isShowReportInfoPopup=false"
         />
     </van-popup>
+
+     <!-- 上传音频 -->
+    <van-popup 
+        v-model:show="showUploadAudio" 
+        position="bottom"
+        round
+        :style="{height:'60%'}"
+    >
+        <div class="upload-audio-wrap" v-if="showUploadAudio">
+            <div style="font-size:12px;color:#666">tips:如果是在微信中访问,请上传完音频点击播放,获取音频时长后方可保存</div>
+            <template v-if="temAudioData.url">
+                <h2>音频链接</h2>
+                <p>{{temAudioData.url}}</p>
+                <AudioBox :time="temAudioData.time" :url="temAudioData.url" @updateDuration="handleUpdateAudioTime"/>
+            </template>
+            <div class="bot-btns">
+                <van-uploader 
+                    accept="*" 
+                    :after-read="handleAudioUploadAfterRead"
+                >
+                    <van-button class="bot-btn" type="default">{{temAudioData.url?'重新上传':'上传音频'}}</van-button>
+                </van-uploader>
+                <van-button class="bot-btn" type="primary" :disabled="!temAudioData.url||temAudioData.time===0" @click="handleUpdateAudio">保存</van-button>
+            </div>
+        </div>
+    </van-popup>
 </template>
 
 <style lang="scss" scoped>
@@ -981,6 +1056,30 @@ onMounted(async ()=>{
     }
 }
 
+.upload-audio-wrap{
+    height: 100%;
+    position: relative;
+    overflow: hidden;
+    padding: $page-padding;
+    p{
+        color: rgba(0, 0, 0, 0.6);
+        padding-bottom: 32px;
+        border-bottom: 1px solid $border-color;
+        margin-bottom: 32px;
+        word-wrap: break-word;
+    }
+    .bot-btns{
+        // width: 100%;
+        position: absolute;
+        bottom: 0;
+        padding: 20px 0;
+        text-align: center;
+        .bot-btn{
+            width: 315px;
+            margin: 0 10px;
+        }
+    }
+}
 
 
 @media screen and (min-width:$media-width){

+ 16 - 11
src/views/report/chapter/List.vue

@@ -225,9 +225,10 @@ const temAudioData=reactive({
     url:'',
 })
 function handleShowUploadAudio(){
-    temAudioData.time=activeItem.value.audioDuration
-    temAudioData.size=activeItem.value.audioSize
-    temAudioData.url=activeItem.value.audioUrl
+    showItemOpt.value = false;
+    temAudioData.time=activeItem.value.VideoPlaySeconds
+    temAudioData.size=activeItem.value.VideoSize
+    temAudioData.url=activeItem.value.VideoUrl
     showUploadAudio.value=true
 }
 // 获取音频时长
@@ -267,16 +268,19 @@ async function handleAudioUploadAfterRead(e){
     temAudioData.size=e.file.size/1024/1024 //单位MB
     temAudioData.name=e.file.name
     console.log('音频数据temAudioData',temAudioData);
-    // 生成文件名
-    const t=new Date().getTime().toString()
-    const temName=`static/yb/audio/${import.meta.env.MODE}/${MD5(t)}.${e.file.type.split('/')[1]}`
-    console.log(temName);
-    temAudioData.url=await useUploadFileToOSS(e.file,temName)
+
+    let params = new FormData();
+        params.append("file", e.file);
+        params.append("ReportChapterId", activeItem.value.ReportChapterId);
+      const res = await apiReport.uploadChpterAudio(params)
+
+      if(res.Ret !== 200) return
+      temAudioData.url = res.Data.ResourceUrl;
 }
 function handleUpdateAudio(){
-    activeItem.value.audioUrl=temAudioData.url
-    activeItem.value.audioDuration=temAudioData.time
-    activeItem.value.audioSize=temAudioData.size
+    activeItem.value.VideoUrl=temAudioData.url
+    activeItem.value.VideoPlaySeconds=temAudioData.time
+    activeItem.value.VideoSize=temAudioData.size
     showUploadAudio.value=false
 }
 //更新下音频时长
@@ -284,6 +288,7 @@ function handleUpdateAudioTime(e){
     temAudioData.time=e
 }
 
+
 //章节拖动
 async function handleMoveChapter({oldIndex,newIndex}) {
     console.log(oldIndex,newIndex)

+ 27 - 11
src/views/report/components/AddReportBaseInfoV2.vue

@@ -97,7 +97,10 @@ function handleConfirmClassify(arr){
 }
 /* 获取关联品种 */
 async function getRelationPermission() {
-  if(!reportBaseInfo.classifys.length) return
+  if(!reportBaseInfo.classifys.length){
+    reportBaseInfo.relationVariety = []
+    return
+  } 
 
   const res = await apiReport.classifyPermissionList({ClassifyId:reportBaseInfo.classifys[reportBaseInfo.classifys.length-1].id})
 
@@ -229,7 +232,8 @@ function close() {
   emit('close')
 }
 async function handleSave() {
-
+  if(!reportBaseInfo.title) return showToast('请输入报告标题')
+  if(!reportBaseInfo.classifys.length) return showToast('请选择报告分类')
 
   const params = {
     AddType: reportBaseInfo.addType,
@@ -273,15 +277,27 @@ async function handleSave() {
     apiReport.reportAdd(params).then((res) => {
       if (res.Ret === 200) {
   
-        let { href } = router.resolve({
-          path: reportBaseInfo.reportLayout===1 
-            ? '/report/edit'
-            : "/smart_report/edit",
-          query: { 
-            id: res.Data.ReportId,
-            coopType: params.CollaborateType
-          },
-        });
+        let pathInfo = {};
+        if(reportBaseInfo.cooperationType===2) {
+          pathInfo = {
+            path: "/report/chapter/list",
+            query: { 
+              id: res.Data.ReportId
+            },
+          }
+        }else {
+            pathInfo = {
+              path: reportBaseInfo.reportLayout===1 
+                ? '/report/edit'
+                : "/smart_report/edit",
+              query: { 
+                id: res.Data.ReportId,
+                coopType: params.CollaborateType
+              },
+            }
+        }
+
+        let { href } = router.resolve(pathInfo);
         window.open(href, "_blank");
   
         close();

+ 14 - 0
src/views/report/hooks/useReport.js

@@ -277,6 +277,20 @@ export function useReportHandles() {
 /* 章节报告操作 */
 export function useChapterRepoprtHandles() {
 
+	//提交章节
+	async function handlePublishChapterApi(chapterId) {
+		const res = await apiReport.chapterReportPublish({
+			ReportChapterId: chapterId
+		});
+
+		if (res.Ret !== 200) return
+		showToast('提交成功')
+		router.back()
+	}
+
+	return {
+		handlePublishChapterApi
+	}
 }
 
 

+ 122 - 36
src/views/report/smartReport/EditReport.vue

@@ -9,10 +9,11 @@ import moment from 'moment'
 import { showToast,showDialog } from 'vant'
 import { useRoute, useRouter } from 'vue-router'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
+import {usePublicSettingStore} from '@/store/modules/publicSetting'
 import {reportManageBtn,useAuthBtn} from '@/hooks/useAuthBtn'
 import {useReportApprove} from '@/hooks/useReportApprove'
 import AddReportBaseInfoV2 from '../components/AddReportBaseInfoV2.vue'
-import { useReportHandles } from '../hooks/useReport'
+import { useReportHandles,useChapterRepoprtHandles } from '../hooks/useReport'
 import draggable from 'vuedraggable'
 import TextEditor from './components/TextEditor.vue'
 import ImgEditor from  './components/ImgEditor.vue'
@@ -24,28 +25,36 @@ import ReportLayoutImg from './components/ReportLayoutImg.vue'
 
 
 const cachedViewsStore=useCachedViewsStore()
+const publicSettingStore = usePublicSettingStore()
 const {isApprove,hasApproveFlow,getEtaConfig,checkClassifyNameArr} = useReportApprove()
 const router=useRouter()
 const route=useRoute()
 const {checkAuthBtn} = useAuthBtn()
 
 
+const reportCoopType = ref(Number(route.query.coopType))
 let autoSaveTimer=null
 onMounted(() => {
+	if(reportCoopType.value===1) {
     getEtaConfig()
     getReportDetail()
-    // autoSaveTimer=setInterval(() => {
-    //     autoSaveReportContent()
-    // }, 6000);
+    autoSaveTimer=setInterval(() => {
+        autoSaveReportContent()
+    }, 6000);
+	}else if(reportCoopType.value===2) { //章节报告
+			getChapterDetail()
+			autoSaveTimer=setInterval(() => {
+					autoSaveReportChapter()
+			}, 6000);
+  }
 })
 onUnmounted(()=>{
-    // clearInterval(autoSaveTimer)
+    clearInterval(autoSaveTimer)
 })
 
 
 // 获取报告详情
 const reportInfo=ref(null)
-const reportCoopType = ref(Number(route.query.coopType))
 const contentChange = ref(false)//内容是否发生变化
 const smartState = reactive({
   conList: [],//内容列表
@@ -128,6 +137,16 @@ async function getReportDetail(){
     }
 }
 
+//获取章节详情
+async function getChapterDetail() {
+    const res=await apiReport.getChapterDetail({
+        ReportChapterId:Number(route.query.chapterId)
+    })
+    reportInfo.value=res.Data;
+
+    smartState.conList=res.Data.ContentStruct?JSON.parse(res.Data.ContentStruct):[]
+}
+
 
 watch(
 	() => smartState.conList,
@@ -397,6 +416,7 @@ const currentState = reactive({
 })
 // 当前再编辑哪个
 function handleChoose(item,index,cindex){
+	// console.log(item,index,cindex)
 		//{item:数据,index:父序号,cindex:子序号}
 		if(!item.id||isDragResize.value||!['text','img'].includes(item.compType)) return
 		currentState.activeId=item.id
@@ -440,6 +460,11 @@ const  compType = [
 function handleOpenComPop(e) {
   showPopover.value = false
   console.log(e)
+	
+	currentState.activeId=0
+	currentState.activeContent=''
+	currentState.activePindex=''
+	currentState.activeCindex=''
 
   showInsertCompType.value = e.compId;
 	temTextVal.value = ''
@@ -497,12 +522,15 @@ function handleChartInsert({list,type,chartType}){
 //插入文本
 const temTextVal = ref('')
 function handleInsertText(content) {
-	if(temTextVal.value) { //编辑
+	console.log(content)
+	console.log(currentState)
+	if(currentState.activeId) { //编辑
 		currentState.activeContent=content
 		if(currentState.activeCindex>=0&&currentState.activeCindex!==''){
 				smartState.conList[currentState.activePindex].child[currentState.activeCindex].content=content
 		}else{
 				smartState.conList[currentState.activePindex].content = content
+				console.log(smartState.conList[currentState.activePindex])
 		}
 	}else { //新增
 
@@ -630,7 +658,7 @@ async function handleReportBaseInfoChange(e){
 
 // 刷新所有图表
 async function handleRefreshAllChart(){
-  handleRefresh({ id: reportInfo.value.Id,chapterId:reportInfo.value.ChapterId })
+  handleRefresh({ id: Number(route.query.id),chapterId:Number(route.query.chapterId) })
 }
 
 //预览
@@ -658,11 +686,11 @@ function autoSaveReportContent(type="auto") {
     return new Promise(async (resolve,reject)=>{
 
 				let imgParams = {
-						HeadImg: reportCoopType.value===1?smartState.headImg:'',
-						EndImg:reportCoopType.value===1?smartState.endImg:'',
-						HeadResourceId:reportCoopType.value===1?smartState.headImgId:'',
-						EndResourceId:reportCoopType.value===1?smartState.endImgId:'',
-						CanvasColor:reportCoopType.value===1?smartState.bgColor:''
+						HeadImg:smartState.headImg,
+						EndImg:smartState.endImg,
+						HeadResourceId:smartState.headImgId,
+						EndResourceId:smartState.endImgId,
+						CanvasColor:smartState.bgColor
 				}
 
         const res=await apiReport.reportContentSave({
@@ -695,9 +723,52 @@ async function handlePublishReport(tp) {
 // 定时发布报告选择时间
 function onConfirmDSFBTime(time){
     // console.log(time);
-    handleDSPublish(time,reportData.value)
+    handleDSPublish(time,reportInfo.value)
+}
+
+
+
+const { handlePublishChapterApi } = useChapterRepoprtHandles()
+//预览章节
+async function handlePreviewChapter() {
+    const saveRes = await autoSaveReportChapter('auto');
+    if(!saveRes) return
+    
+		const routerEl=router.resolve({
+        path:'/report/chapter/preview',
+        query:{
+            id:reportInfo.value.ReportChapterId
+        }
+    })
+    window.open(routerEl.href,'_blank')
+}
+
+// 自动保存章节报告
+async function autoSaveReportChapter(type="auto"){
+    if(!route.query.chapterId) return 
+   const html=document.getElementById('report-html-content').outerHTML.replace(/contenteditable="true"/g,'contenteditable="false"');
+
+    return new Promise(async (resolve,reject)=>{
+        const res=await apiReport.chapterDetailSave({
+            ReportChapterId:Number(route.query.chapterId),
+						Content: html,
+						ContentStruct:JSON.stringify(smartState.conList)
+        })
+        if(res.Ret === 200) {
+            resolve(true)
+            type==='save' && showToast("保存成功");
+        }
+    })
+   
 }
 
+/* 提交章节 */
+async function handlePublishChapter() {
+    const saveRes = await autoSaveReportChapter('auto');
+    if(!saveRes) return
+
+    handlePublishChapterApi(reportInfo.value.ReportChapterId)
+}
 
 const { 
   conList,
@@ -718,7 +789,7 @@ const {
       <div class="report-content-box" id="report-content-box" >
 
 					<div class="add-comp-wrapper">
-						<van-popover v-model:show="showPopover" @select="handleOpenComPop">
+						<van-popover v-model:show="showPopover">
 							<van-grid
 								square
 								clickable
@@ -840,8 +911,8 @@ const {
 
     <!-- 底部操作 -->
     <div class="bot-action-box">
-        <div class="left-box">
-            <div class="item" @click="showReportBaseInfo=true">
+        <div class="left-box" v-if="reportInfo">
+            <div class="item" @click="showReportBaseInfo=true" v-if="!reportInfo.ReportChapterId">
                 <img src="@/assets/imgs/report/icon_info.png" alt="">
                 <span>基础信息</span>
             </div>
@@ -849,31 +920,46 @@ const {
                 <img src="@/assets/imgs/report/icon_refresh.png" alt="">
                 <span>刷新</span>
             </div>
-            <div class="item" @click="handlePreviewReport" v-permission="reportManageBtn.reportManage_reportView">
+            <div class="item" @click="reportInfo.ReportChapterId?handlePreviewChapter():handlePreviewReport()" v-permission="reportManageBtn.reportManage_reportView">
                 <img src="@/assets/imgs/report/icon_preview.png" alt="">
                 <span>预览</span>
             </div>
-            <div class="item" @click="autoSaveReportContent('save')" v-permission="reportManageBtn.reportManage_publish">
+            <div class="item" @click="reportInfo.ReportChapterId?autoSaveReportChapter('save'):autoSaveReportContent('save')" v-permission="reportManageBtn.reportManage_publish">
                 <img src="@/assets/imgs/report/icon_save2.png" alt="">
                 <span>保存</span>
             </div>
-            <template v-if="!isApprove||!hasApproveFlow">
-                <div class="item" @click="handlePublishReport('dsfb')" v-permission="reportManageBtn.reportManage_publish">
-                    <img src="@/assets/imgs/report/icon_time.png" alt="">
-                    <span>定时发布</span>
-                </div>
-                <div class="item" @click="handlePublishReport('fb')" v-permission="reportManageBtn.reportManage_publish">
-                    <img src="@/assets/imgs/report/icon_publish3.png" alt="">
-                    <span>发布</span>
-                </div>
-            </template>
-            <template v-if="isApprove&&hasApproveFlow">
-                <div class="item" @click="handlePublishReport('submit')" >
-                    <img src="@/assets/imgs/report/icon_publish3.png" alt="">
-                    <span>提交</span>
-                </div>
-            </template>
-            <div class="item" @click="showMoreHandlePop=true" v-if="reportInfo&&!reportInfo.ReportChapterId">
+
+						<!-- 章节报告提交章节 -->
+						<div 
+								class="item" 
+								@click="handlePublishChapter" 
+								v-permission="reportManageBtn.reportManage_publish" 
+								v-if="reportInfo.ReportChapterId"
+						>
+										<img src="@/assets/imgs/report/icon_publish3.png" alt="">
+										<span>提交</span>
+						</div>
+						<!-- 单人报告提交发布 -->
+						<template v-else>
+							<template v-if="!isApprove||!hasApproveFlow">
+									<div class="item" @click="handlePublishReport('dsfb')" v-permission="reportManageBtn.reportManage_publish">
+											<img src="@/assets/imgs/report/icon_time.png" alt="">
+											<span>定时发布</span>
+									</div>
+									<div class="item" @click="handlePublishReport('fb')" v-permission="reportManageBtn.reportManage_publish">
+											<img src="@/assets/imgs/report/icon_publish3.png" alt="">
+											<span>发布</span>
+									</div>
+							</template>
+							<template v-if="isApprove&&hasApproveFlow">
+									<div class="item" @click="handlePublishReport('submit')" >
+											<img src="@/assets/imgs/report/icon_publish3.png" alt="">
+											<span>提交</span>
+									</div>
+							</template>
+						</template>	
+
+            <div class="item" @click="showMoreHandlePop=true" v-if="!reportInfo.ReportChapterId">
 								<van-icon name="ellipsis" size="24"/>
                 <div>更多设置</div>
             </div>

+ 21 - 2
src/views/report/smartReport/components/SheetComp.vue

@@ -1,9 +1,28 @@
 <script setup>
-import { ref } from 'vue'
+import { computed, ref } from 'vue'
 
 const props = defineProps({
   compData:{}
 })
+
+const id = computed(() => {
+    if(props.compData.content){
+        let params = GetQueryString(props.compData.content)
+        return `iframe${params.code}`
+    }
+    return ''
+})
+
+function GetQueryString(url) {
+    let urlStr=url.split('?')[1]
+    let obj={}
+    let paramsArr=urlStr.split('&')
+    for (let index = 0; index < paramsArr.length; index++) {
+        let arr=paramsArr[index].split('=')
+        obj[arr[0]]=arr[1]
+    }
+    return obj
+}
 </script>
 <template>
   <div 
@@ -15,7 +34,7 @@ const props = defineProps({
           v-html="compData.titleText"
           v-if="compData.titleText"
       ></div>
-      <iframe :src="compData.content" width="100%" style="border-width:0px;"></iframe>
+      <iframe :class="id" :src="compData.content" width="100%" style="border-width:0px;"></iframe>
   </div>
 </template>
 <style scoped lang="scss">