123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740 |
- <template>
- <div class="page-wrap">
- <div class="index-wrap ppt-page-wrap flex-column">
- <div class="cover-wrap">
- <div class="flex-align">
- <p class="hint-text" @click="openSelectImage(2,firstPage.CurrentBackgroundImgId,firstPage.CurrentBackgroundImg)">{{$t('Slides.select_ground_page')}}</p>
- <p class="hint-text" style="margin-left:37px" @click="openSelectImage(3,firstPage.BackCoverImgId,firstPage.BackCoverImg)">{{$t('Slides.select_back_page')}}</p>
- </div>
- <div class="flex-align" style="margin:8px 0"><p class="hint-text" @click="openChooseCover">{{$t('Slides.select_cover_page')}}</p></div>
- <div class="cover" @click="openChooseCover" :style="`background: no-repeat center/cover url(${firstPage.BackgroundImg||''});background-color:#F2F6FA;background-size:100% 100%;`">
- <img src="~@/assets/img/ppt_m/add_first.png" />
- </div>
- </div>
- <div class="hint-box"><div class="hint" @click="showHint"><span class="el-icon-info" style="margin-right:5px;"></span>{{$t('Slides.operating_instructions')}}</div></div>
- <div style="display:flex;justify-content: space-between;">
- <p style="text-align:start;color:#999999;">
- {{$i18n.locale == 'zh' ? `已添加${pageList.length}页`:`${pageList.length}slides added successfully`}}
- </p>
- <p class="hint-text" style="cursor: pointer;" @click="saveCopyPages('cut')">{{$t('Slides.operations_cut')}}</p>
- <p class="hint-text" style="cursor: pointer;" @click="saveCopyPages('copy')">{{$t('Slides.operations_copy')}}</p>
- <p style="color:#B72E18;cursor: pointer;" @click="openDeletePageDialog">{{$t('Slides.operations_batch_delete')}}</p>
- </div>
-
- <div class="index-list" ref="pptList" v-click-outside="resetCopyPages">
- <div class="empty" v-if="pageList.length===0">
- <img src="~@/assets/img/ppt_m/ppt-empty.png" alt="">
- <p>{{$t('Slides.add_main_text_empty')}}</p>
- </div>
- <transition-group name="flip-list">
- <index-item
- v-for="(item,index) in pageList" :key="item.id"
- :pageItem="item"
- :pageIndex="index"
- :currentItem="currentItem"
- :pageLength="pageList.length"
- :copyPagesMap="copyPagesMap"
- :ctrlKeyActive="ctrlKeyActive"
- :savePagesArrLength="savePagesArr.length"
- @deletePage="delPage"
- @click.native="handleClickItem(item)"
- @dragstart.native="(e)=>{dragstart(e,item)}"
- @dragenter.native="(e)=>{dragenter(e,item)}"
- @dragend.native="dragend(item)"
- @dragover.native="(e)=>{e.preventDefault()}"
- @changePage="changePageIndex"
- @operatePpt="handleOperate"
- />
- </transition-group>
- </div>
- </div>
- <div class="ppt-editor-wrap ppt-page-wrap" v-loading="isChartLoading" :element-loading-text="chartLoadingText">
- <div class="ppt-editor" id="pptEditor" ref="pptEditor" @paste="handlePasteOutSide">
- <!-- 显示全部ppt -->
- <template v-if="pageList.length">
- <div class="ppt-editor-item flex-column" v-for="(item,index) in pageList" :key="item.id">
- <AddFormat @addPage="addPage($event,index)" :chooseModalId="chooseModalId"/>
- <div class="ppt-item" :class="{'choose':currentItem.id===item.id}"
- v-loading="item.isUpdating" :element-loading-text="$t('Slides.updating_chart_loading')"
- @click.stop="changeCurrentItem(item)">
- <!-- 标题 -->
- <!-- <div class="title-wrap" style="background-color: #999999;">
- <input type="text" placeholder="单击输入标题" v-model="item.title"/>
- </div> -->
- <!-- 自定义标题 -->
- <div @click.stop
- :class="[
- 'ppt-editor-title',
- 'custom-title-wrap',
- currentItem.id===item.id&&isEditTitle?'editor-model':''
- ]"
- :style="item.titleDetail?{
- left:item.titleDetail.left+'%',
- top:item.titleDetail.top+'%',
- width:item.titleDetail.width+'%',
- height:item.titleDetail.height+'%',
- }:{
- left:'10%',top:'6.6%',width:'68%',height:'5%',
- }">
- <!-- <div class="title" v-html="item.title"></div> -->
- <!-- <el-input type="textarea" placeholder="单击输入标题" v-model="item.title"
- autosize resize="none"
- spellcheck="false"
- :style="item.titleDetail?{
- color:item.titleDetail.color,
- fontSize:item.titleDetail.fontSize+'px',
- fontFamily:item.titleDetail.fontFamily,
- '--titleColor':item.titleDetail.color,
- '--fontSize':item.titleDetail.fontSize,
- '--fontFamily':item.titleDetail.fontFamily,
- }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"
- @focus="handleEditTitle(item)"
- v-click-title-outside="exitEditTitle"></el-input> -->
- <div contenteditable="true" spellcheck="false"
- :id="`page_title__${index}`"
- class="title-editor"
- :style="item.titleDetail?{
- color:item.titleDetail.color||'#333',
- fontSize:(item.titleDetail.fontSize||22)+'px',
- fontFamily:(item.titleDetail.fontFamily||'helvetica'),
- outline:0,
- }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica',outline:0}"
- v-click-title-outside="exitEditTitle"
- @click.stop="handleEditTitle(item)"
- @paste.stop="(e)=>handlePaste(e,item)"
- @input="(e)=>handleInput(e,item)"></div>
- </div>
- <!-- 内容 -->
- <component :is="getComponentName(item.modelId)"
- :ref="`pptPage_${index}`"
- :pageIndex="index"
- :pageItem="item"
- :key="item.key"
- :isCopy="true"
- :isAdd="true"
- :isEditLayer="isEditLayer"
- :isEditTitle="isEditTitle"
- :choosedId="currentItem.id"
- :activeLayerEl="activeLayerEl"
- :amendatoryPositionInfo="item.positionInfo"
- @delChart="handleDelChart"
- @pasteImg="handlePasteImg"
- @changeText="handleChangeText"
- @changeActEl="changeActLayerEl"
- @deleteLayer="deleteLayerEl"
- @copyShape="getCopyItem"
- @reload="reloadPage"
- @addChart="handleAddChartToGallery"
- ></component>
- <!-- 删除按钮 -->
- <el-popconfirm
- @onConfirm="delPage(item)"
- :confirmButtonText="$t('Slides.operations_delete')"
- :cancelButtonText="$t('Slides.operations_cancel')"
- confirmButtonType="text"
- icon="el-icon-info"
- iconColor="red"
- :title="$t('Slides.is_delete_ppt_msg')">
- <span class="close-btn" @click.stop slot="reference"></span>
- </el-popconfirm>
- <!-- 页码 -->
- <span class="page-num"> {{$i18n.locale == 'zh' ?`第${index+1}页`:` Slide${index+1}`}}</span>
- <!-- 更新图表 -->
- <span class="update-btn" v-show="item.modelId!==6&&item.elements.find((i)=>i.type==='chart'||i.type==='sheet')" @click.stop="updatePage(item)"><span class="update-ico"></span> {{$t('Slides.update_chart_btn')}}</span>
- </div>
- <AddFormat v-if="index===pageList.length-1" @addPage="addPage($event,index+1)" :chooseModalId="chooseModalId"/>
- </div>
- <!-- 自定义右键菜单 -->
- <context-menu :menu="[{id:1,text:$t('Slides.paste_element_btn'),eventName:'paste',canClick:Boolean(copyShape.id)}]" @paste="pasteLayerEl"/>
- <!-- </transition-group> -->
- </template>
- <template v-else>
- <div class="ppt-editor-item flex-column">
- <add-format @addPage="addPage($event,0)"/>
- </div>
- </template>
- </div>
- <div class="ppt-tool flex-column">
- <div class="save-hint" v-show="showLastSaveTime"
- style="color: #666; margin-bottom: 15px"
- >{{$t('Slides.last_save_time')}}:{{lastSaveTime}}</div>
- <div class="tool-btn">
- <el-button type="primary" :loading="refreshBtnLoading" @click="refleshFormatEl">{{$t('Slides.operations_refresh')}}</el-button>
- <el-button v-permission="permissionBtn.pptPermission.ppt_publish"
- type="primary" @click="handlePublish">{{ result.ReportSource===1?'去发布':'去提交' }}</el-button>
- <el-button @click="handleSave('save')">{{$t('Slides.operations_save')}}</el-button>
- <el-button type="text" @click="handleChangeEditModal"><i class="el-icon-sort" style="transform: rotate(90deg);margin-right:5px;"></i>{{isEditLayer? $t('Slides.ppt_edit_btn'):$t('Slides.layer_editing')}}</el-button>
- <el-button type="text" v-permission="permissionBtn.pptPermission.ppt_history" @click="handleVersionHistory"><i class="el-icon-time" style="margin-right:5px;"></i>{{$t('Slides.version_history')}}</el-button>
- </div>
- <div class="richtext-tool"></div>
- <!-- 防止el-tabs未渲染时触发scrollToActiveTab 报错,v-if改为v-show-->
- <div class="addppt-right-box" v-show="!isEditLayer&&!isEditTitle">
- <el-tabs v-model="tabsactive">
- <el-tab-pane :label="tab.label" :name="tab.val" v-for="tab in panelTabs" :key="tab.val"></el-tab-pane>
- </el-tabs>
- <div class="chart-tool flex-column" v-show="tabsactive == '图表'">
- <div class="chart-search">
- <el-input :placeholder="$t('Slides.keyword_search')" v-model="key_word" size="medium" prefix-icon="el-icon-search" @input="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist()}" style="max-width:420px;"></el-input>
- </div>
- <el-radio-group v-model="chart_source" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist()}" style="margin: 10px 0;">
- <el-radio :label="1" style="margin-bottom:5px">{{$t('Slides.eta_chart_gallery')}}</el-radio>
- <!-- <el-radio :label="2" style="margin-bottom:5px">{{$t('Slides.commodity_price_curve')}}</el-radio> -->
- <el-radio :label="3" style="margin-bottom:5px">{{$t('Slides.correlation_charts')}}</el-radio>
- <el-radio :label="6" style="margin-bottom:5px">{{$t('Slides.fitted_equation_curves')}}</el-radio>
- <el-radio :label="7" style="margin-bottom:5px">{{$t('Slides.statistical_features')}}</el-radio>
- <el-radio :label="10">{{$t('Slides.intercommodity_analysis')}}</el-radio>
- </el-radio-group>
- <div style="margin: 10px 0">
- <el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist()}">{{$t('Slides.show_only_mine')}}</el-checkbox>
- </div>
- <div class="chart-list" v-infinite-scroll="loadReportHandle" :infinite-scroll-immediate="false" ref="chartListRef">
- <template v-if="chartList.length">
- <div v-for="(item, index) in chartList" :key="index" @click="chooseChart(item,'chart')" class="chart-item" :style="item.Disabled && 'cursor: not-allowed;'">
- <p class="chart_tit" style="word-break: break-all;">{{ item.ChartName }}</p>
- <img :src="!item.HaveOperaAuth?$icons.lock_big:item.ChartImage" ref="insert_img" style="-webkit-user-drag:none;"/>
- </div>
- </template>
- <tableNoData :text="$t('Table.prompt_slogan')" size="mini" v-else/>
- </div>
- </div>
- <div v-show="tabsactive == '沙盘'" class="chart-tool flex-column">
- <div class="chart-search">
- <el-input :placeholder="$t('Slides.sandbox_name_category')" v-model="sandTabelQuery.Keyword" size="medium" prefix-icon="el-icon-search" style="max-width:420px;"></el-input>
- </div>
- <div class="chart-list" id="sandTable" @scroll="sandTableHandleScroll">
- <template v-if="sandTableList.length">
- <div v-for="(item,index) in sandTableList" :key="index" class="sandTable-item" >
- <p class="chart_tit">{{item.Name}}</p>
- <img :src="item.PicUrl" style="width:100%;-webkit-user-drag:none;" @click="chooseChart(item,'sandImage')"/>
- </div>
- <div v-loading = "sandTableLoading" class="loaded-text">{{loadedText}}</div>
- </template>
- <tableNoData :text="$t('Table.prompt_slogan')" size="mini" v-else/>
- </div>
- </div>
- <div v-show="tabsactive == '表格'" class="chart-tool flex-column">
- <div class="chart-search">
- <el-input :placeholder="$t('Slides.table_name_input')" v-model="sheetSearchObj.Keyword" size="medium" prefix-icon="el-icon-search" style="max-width:420px;" @input="getSheetList"></el-input>
- </div>
- <div class="chart-list" id="sandTable">
- <template v-if="sheetSearchList.length">
- <div v-for="(item,index) in sheetSearchList" :key="index" class="sandTable-item" >
- <p class="chart_tit">{{item.ExcelName}}</p>
- <img :src="!item.HaveOperaAuth?$icons.lock_big:item.ExcelImage" style="width:100%;object-fit: contain;height: 250px;-webkit-user-drag:none;" @click="chooseChart(item,'sheet')"/>
- </div>
- </template>
- <tableNoData :text="$t('Table.prompt_slogan')" size="mini" v-else/>
- </div>
- </div>
- <div v-show="tabsactive == 'MyETA批量'" class="chart-tool flex-column">
- <insert-charts @handleImportMyChart="handleImportMyChart"/>
- </div>
- <div v-show="tabsactive == '语义分析插入'" class="chart-tool flex-column">
- <InsertSemantics />
- </div>
- <div v-show="tabsactive == '知识资源'" class="chart-tool flex-column">
- <insert-knowledge />
- </div>
- </div>
- <!-- 图层编辑 -->
- <div class="layer-edit-box" v-if="isEditLayer">
- <el-collapse v-model="activeNames" class="tool-list">
- <el-collapse-item :title="$t('Slides.layer_element')" name="el">
- <div class="el-wrap">
- <div class="el-item"
- v-for="(shape,index) in layerElArr" :key="index" @click="addLayerEl(shape)">
- <el-tooltip class="item" effect="dark" :content="shape.name" placement="top">
- <ShapePreview :shape="shape" />
- </el-tooltip>
- </div>
- </div>
- </el-collapse-item>
- <el-collapse-item name="line"
- :title="$t('Slides.line_settings')" >
- <LayerEditTool
- :isActiveEl="activeLayerEl.type==='line'?true:false"
- :elInfo="activeLayerEl.type==='line'?activeLayerEl:BaseLineShape"
- baseType="line"/>
- </el-collapse-item>
- <el-collapse-item name="shape"
- :title="$t('Slides.outline_element')" >
- <LayerEditTool
- :isActiveEl="activeLayerEl.type==='shape'?true:false"
- :elInfo="activeLayerEl.type==='shape'?activeLayerEl:BaseRectShape"
- baseType="shape"/>
- </el-collapse-item>
- <el-collapse-item name="text"
- :title="$t('Slides.text_element')" >
- <LayerEditTool
- :isActiveEl="activeLayerEl.type==='text'?true:false"
- :elInfo="activeLayerEl.type==='text'?activeLayerEl:BaseTextShape"
- baseType="text"/>
- </el-collapse-item>
- </el-collapse>
- </div>
- <!-- 标题编辑 -->
- <div class="title-edit-box" v-if="isEditTitle">
- <p>
- {{$t('Slides.page_title_style_setting')}}
- </p>
- <TitleEditorTool
- ref="titleEditor"
- :currentItem="currentItem"
- @changeSizeAll="changeSizeAll"
- @changePositionAll="changePositionAll"
- @styleChange="handleTitelStyleChange"
- @textChange="handleTextChange"
- @applyToAll="changeSettingAll"/>
- </div>
- <!-- 历史记录编辑 -->
- <div class="history-edit-box" v-if="isVersionHistory">
- <VersionRecord :PptId="PptId" @handleRestore="handleRestore"/>
- </div>
- </div>
- </div>
- <!-- 选择封面弹窗 -->
- <ChooseCoverNew
- ref="ChooseCoverNewRef"
- v-if="isShowChooseCover"
- :isShowChooseCover="isShowChooseCover"
- :firstPage="firstPage"
- :pptCoverList="pptCoverList"
- :PptId="pptId"
- :CoverContent="CoverContent"
- @saveCover="saveCover2"
- @close="isShowChooseCover=false"
- @chooseMoreCover="coverChooseImage()"
- />
- <!-- 批量删除弹窗 -->
- <delete-page-dialog
- :deletePageShow="deletePageShow"
- :pageList="pageList"
- :optionMap="optionMap"
- ref="deletePage"
- @cancel="deletePageShow=false"
- @delete="handleDeletePages"
- />
- <!-- 一键改版弹窗 -->
- <change-format-dialog
- :changeFormatPageShow="changeFormatPageShow"
- :pptModelId="choosedItem?choosedItem.modelId:0"
- @cancel="changeFormatPageShow=false"
- @changeModel="changeFormatPage"
- />
- <!-- 插入PPT弹窗 -->
- <insert-page-dialog
- :insertPageShow="insertPageShow"
- @cancel="insertPageShow=false"
- @insert="handleInsert"
- />
- <!-- 添加到 我的图库 弹窗 -->
- <addMyClassifyDia
- :isAddMyDialog="addMyChartShow"
- :add_id="addChartInfoId"
- :add_ids="addChartClassifyIds"
- @cancel="addMyChartShow = false"
- @addSuccess="addChartToGallery"
- />
- <selectImage @saveChoose='saveChooseImage' ref="selectImageRef"/>
- </div>
- </template>
- <script>
- import {countComponentName,checkClipboardItems,createRandomCode,checkPPTpageElemant,getChartInfo,getPlainText} from './utils/untils';
- import {modelInfo,defaultPosition} from './utils/config'
- import http from '@/api/http.js';
- import { dataBaseInterface ,sandInterface } from "@/api/api.js";
- import futuresInterface from '@/api/modules/futuresBaseApi';
- import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
- import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
- import { eventInterface } from "@/api/modules/knowledge";
- import pptmixin from '../mixins/pptMixins';
- import {uploadFileDirect} from "@/utils/common.js"
- import mixins from '../mixins/mixins';
- import layerMixins from '../mixins/layerMixins';
- import pptEditorMixins from '../mixins/pptEditorMixins';
- import Highcharts from "highcharts/highstock";
- import HighchartszhCN from '@/utils/highcahrts-zh_CN'
- HighchartszhCN(Highcharts)
- import IndexItem from './components/IndexItem.vue';
- import ChooseCover from './components/editor/ChooseCover.vue';
- import AddFormat from './components/editor/AddFormat.vue';
- import {pptInterface} from '@/api/api.js';
- import * as sheetInterface from '@/api/modules/sheetApi.js';
- import ShapePreview from './components/layer/shapePreview.vue';
- import LayerEditTool from './components/layer/layerEditTool.vue';
- import VersionRecord from './components/layer/VersionRecord.vue';
- import DeletePageDialog from './components/editor/DeletePageDialog.vue';
- import ChangeFormatDialog from './components/editor/ChangeFormatDialog.vue';
- import InsertPageDialog from './components/editor/InsertPageDialog.vue';
- import addMyClassifyDia from '@/views/dataEntry_manage/components/addMyClassifyDia';
- import InsertCharts from './components/editor/InsertCharts.vue';
- import ContextMenu from './components/ContextMenu.vue';
- import InsertSemantics from './components/editor/InsertSemantics.vue';
- import InsertKnowledge from './components/editor/InsertKnowledge.vue'
- import ChooseCoverNew from './components/editor/ChooseCoverNew.vue';
- import TitleEditorTool from './components/editor/TitleEditorTool';
- import selectImage from './components/selectImage.vue';
- import { apiSmartReport } from '@/api/modules/smartReport'
- export default {
- mixins:[pptmixin,//ppt页面共同逻辑
- mixins,//图表加载逻辑
- layerMixins,//图层操作逻辑
- pptEditorMixins,//编辑页共同逻辑
- ],
- components: {
- IndexItem, ChooseCover, AddFormat, ShapePreview,
- LayerEditTool, DeletePageDialog, ChangeFormatDialog, InsertPageDialog, addMyClassifyDia, InsertCharts, ContextMenu, InsertSemantics,
- ChooseCoverNew, TitleEditorTool,selectImage, VersionRecord,InsertKnowledge
- },
- data() {
- return {
- pageList:[],//ppt数组
- currentItem:null,//当前活跃的page
- currentIndex:0,//当前活跃的pageIndex
- oldNum:null,//拖动相关
- newNum:null,//拖动相关
- chooseModalId:1,//上一次选择的版式Id
- firstPage:{
- Title:'',
- ReportType:'',//ETA1.4.9不用了
- BackgroundImg:'',
- PptDate:(new Date().getFullYear())+'年'+(new Date().getMonth()+1)+'月',//ETA1.4.9不用了
- BackIndex:0,//ETA基本配置上线后不用了
- TemplateType:1,//ETA基本配置上线后不用了
- },//封面信息
- key_word:'',//搜索图表关键字
- chartList:[],//图表数组
- imgUrl:'',//黏贴图片上传后的地址
- isShowChooseCover:false,
- getDataLoading:null,//获取动态图表数据/上传图片的loading,
- isSave:false,//是否已手动保存过
- pptId:null,//新增后获得的pptid
- maxPageNum:0,//可以添加的最大页数
- maxPageChart:0,//可以添加的最大图表数
- chartNum:0,//当前PPT的总图表数
- tabsactive:'图表', //右侧区域显示内容 图表 | 沙盘
- // 沙盘图查询参数
- sandTabelQuery:{
- PageSize: 20,
- CurrentIndex: 1,
- Keyword: '',
- },
- sandTableLoading:false,
- sandTableTotal:0,//沙盘总共条数
- sandTableList:[],
- loadedText:'',
- // 沙盘图分页加载 是否在加载中
- isRequesting:false,
- catalogId:0,//ppt目录id,添加ppt时需要
- ReportId:0,//ppt对应的双周报id,如果没转过,则为0
- isChartLoading:false,//是否正在加载图表/图片
-
- sheetSearchList:[],
- sheetSearchObj: {
- Keyword:''
- },
- deletePageShow:false,//控制批量删除弹窗是否显示
- chartLoadingText:`${this.$t('Slides.loading_urgently')}...`,
- loopTimer:null,//自动保存标识
- search_page: 1,
- search_page_sizes: 20,
- search_have_more: true,
- chart_source: 1,//图表来源 1 eta 2 商品价格
- isShowMe: false,
- isVersionHistory: false,//是否显示版本历史
- };
- },
- computed:{
- panelTabs(){
- return [
- {val:'图表',label:this.$t('Slides.table_chart') },
- {val:'沙盘', label:this.$t('Slides.sandbox_name')},
- {val:'表格', label:this.$t('Slides.table_name')},
- {val:'知识资源',label:'知识资源'}
- ]
- },
-
- },
- created() {
- //获取图表,沙盘,表格数据
- this.getreportlist()
- this.getSandTable()
- this.getSheetList()
- //获取PPT限制
- this.getPPTLimit()
- },
- mounted(){
- if(Highcharts.charts){
- Highcharts.charts.length=0
- }
- this.init()
- window.addEventListener('message',this.reInitIframe)
- },
- watch:{
- 'sandTabelQuery.Keyword'(newval,oldval){
- $('#sandTable').animate({scrollTop:0},100);
- this.sandTabelQuery.CurrentIndex = 1
- this.getSandTable()
- }
- },
- methods: {
- getPPTLimit(){
- pptInterface.getConfig().then(res=>{
- if(res.Ret===200){
- this.maxPageNum = res.Data.ppt_num
- this.maxPageChart = res.Data.chart_num
- }
- })
- },
- async init(){
- this.dataLoading = this.$loading({
- lock: true,
- text: `${this.$t('Slides.retrieving_ppt_data')}...`,
- spinner: 'el-icon-loading',
- customClass:'loading',
- target:document.querySelector('.page-wrap'),
- background: 'rgba(255, 255, 255, 0.8)'
- });
- await this.getpptData()
- //遍历pageList,初始化图表,文字
- await this.initPPTAllPage(this.pageList)
- for(let i=0;i<this.pageList.length;i++){
- //计算图表总数
- const chartElements = this.pageList[i].elements.filter((item) => {
- return item.type === "chart";
- });
- this.chartNum+=chartElements.length
- await this.initPageElements(this.pageList[i])
- }
- //获取已加载图表的信息
- let chartInfoMap = {}
- for(let i=0;i<this.pageList.length;i++){
- this.pageList[i].elements.forEach(item=>{
- if(item.type==='chart'){
- let temp = getChartInfo(this.optionMap[item.chartId])
- chartInfoMap[item.chartId] = temp
- }
- })
- }
- this.$store.commit('SET_CHART_INFO_MAP',chartInfoMap)
- //添加ppt的情况:获取目录id
- if(!this.$route.query.id){
- this.catalogId = Number(sessionStorage.getItem('selectedCatalog'))
- }
- //防止自动保存时,有某一页处于更新图表的状态,其isUpdating为true
- this.pageList.forEach(i=>{
- i.isUpdating = false
- })
- this.dataLoading.close();
- // $('.ppt-item').css('background-image',`url(${this.pptBgImage})`);
- //开启自动保存
- this.autoSave()
- },
- async getpptData(){
- const {id} = this.$route.query
- if(id){
- await this.getpptDataById(id)
- const {status} = this.result
- if(status===200){
- const {content,FirstPage,ReportId,TitleSetting} = this.result
- this.pageList = content
- this.firstPage = FirstPage
- this.firstPage.BackIndex = FirstPage.TemplateType-1
- this.currentItem = this.pageList[0]
- this.ReportId=ReportId
- this.CoverContent = this.result.CoverContent
- this.titleSetting = TitleSetting||null
- if(this.firstPage.CurrentBackgroundImg){
- $('.ppt-item').css('background-image',`url(${this.firstPage.CurrentBackgroundImg})`);
- }
- /* //开启自动保存
- this.autoSave() */
- }else{
- this.$message.error(this.$t('Slides.error_ppt_data_msg') )
- this.dataLoading.close();
- window.close()
- }
- }else{
- this.pageList = []
- this.currentItem = null
- }
- this.currentIndex = 0
- },
- // 选择图片保存
- saveChooseImage(item){
- console.log(item)
- const key={
- 1:'BackgroundImg',
- 2:'CurrentBackgroundImg',
- 3:'BackCoverImg'
- }
- const idKey={
- 1:'BackgroundImgId',
- 2:'CurrentBackgroundImgId',
- 3:'BackCoverImgId'
- }
- if(item.type==1){
- const searchIndex = this.pptCoverList.findIndex(i=>i.Url===item.url)
- //如果基本配置-封面图,没有当前ppt的封面图,则默认第一个
- if(searchIndex>-1){
- this.$refs.ChooseCoverNewRef.pageData.BackgroundImg = item.url
- this.$refs.ChooseCoverNewRef.pageData.BackgroundImgId = item.id
- this.$refs.ChooseCoverNewRef.choosedIndex=searchIndex
- }
- }else{
- this.$set(this.firstPage,key[item.type],item.url)
- this.$set(this.firstPage,idKey[item.type],item.id)
- if(item.type==2){
- $('.ppt-item').css('background-image',`url(${item.url})`);
- }
- }
- },
- // 选择封面弹框选择更多模板
- coverChooseImage(){
- this.openSelectImage(1,this.$refs.ChooseCoverNewRef.pageData.BackgroundImgId,this.$refs.ChooseCoverNewRef.pageData.BackgroundImg)
- },
- // 打开选择背景图、封底图、封面图
- openSelectImage(type,id,url){
- this.$refs.selectImageRef.showHandle(type,id,url)
- },
- //打开选择封面页弹窗
- openChooseCover(){
- apiSmartReport.pptMaterialList({
- CurrentIndex: 1,
- PageSize: 1000,
- ImageType: 1,
- ImageName: '',
- ConfType: 1
- }).then(res => {
- this.pptCoverList=res.Data ? res.Data.List : []
- this.isShowChooseCover = true
- this.$nextTick(()=>{
- this.$refs.ChooseCoverNewRef.showDialog()
- })
- })
- },
- //关闭选择封面页弹窗
- closeChooseCover(){
- this.isShowChooseCover = false
- },
- //保存修改的封面页
- saveCover(info){
- console.log(info)
- this.firstPage = info
- this.closeChooseCover()
- },
- //在指定位置添加一个有版式的空白页
- addPage(modelId,index) {
- let page = {
- id: createRandomCode(),
- key:0,
- modelId: modelId,
- title:'',
- elements: [],
- titleDetail:this.titleSetting?this.titleSetting:null
- }
- this.pageList.splice(index,0,page)
- this.changeCurrentItem(page)
- this.chooseModalId = modelId
- },
- //计算ppt的版式名称
- getComponentName(modelId){
- return countComponentName(modelId);
- },
- //删除一页
- delPage(item) {
- //找到index
- const index = this.pageList.findIndex((i) => i.id === item.id);
- //选中它
- this.changeCurrentItem(item)
- //计算出该页有多少个图表,chartNum-=num
- const chartElements = this.pageList[index].elements.filter((item) => {
- return item.type === "chart";
- });
- this.chartNum-=chartElements.length
- //从pageList移除这一页
- this.pageList.splice(index, 1);
- //更新活动页(currentItem)
- if (this.pageList.length === 0) {
- //删除的是仅有的一页
- this.currentIndex = 0;
- } else if (this.pageList.length === this.currentIndex) {
- //删除的是最后一页
- this.currentIndex = this.pageList.length - 1;
- }
- if(this.pageList.length===0){
- this.currentItem = null
- }else{
- this.changeCurrentItem(this.pageList[this.currentIndex])
- }
- this.$message.success(this.$t('MsgPrompt.delete_msg'))
- },
- //删除活跃页的某一位置的图表/图片/其他组件
- handleDelChart(position) {
- this.currentItem.elements.map((i)=>{
- if(i.position===position){
- this.deleteFormatEl(i.type,position)
- }
- })
- //更新currentItem和pageList[currentIndex]
- //console.log(this.currentItem.elements);
-
- this.currentItem.elements = this.currentItem.elements.filter(
- (i) => i.position !== position
- );
- //console.log(this.currentItem.elements);
-
- this.pageList[this.currentIndex] = this.currentItem;
- //不使用强制刷新,而用deleteFormatEl代替
- //this.pageList[this.currentIndex].key++
- //有已经初始化了的文本框的话,做个标记
- const textElements = this.currentItem.elements.filter((item)=>{
- return item.type === 'text'
- })
- if(textElements.length>0){
- this.pageList[this.currentIndex].isLoadText = true
- }
- },
- deleteFormatEl(type,position){
- if(type==='chart'){
- this.chartNum--
- $(`#${type}_${this.currentIndex}_${position}`).html(`<img id="img_${this.currentIndex}_${position}" />`)
- $(`#preview_${type}_${this.currentIndex}_${position}`).html(`<img id="preview_img_${this.currentIndex}_${position}" />`)
- }
- if(type==='image'){
- $(`#${type}_${this.currentIndex}_${position}`).parent().html(`<img id="${type}_${this.currentIndex}_${position}" />`)
- $(`#preview_${type}_${this.currentIndex}_${position}`).parent().html(`<img id="preview_${type}_${this.currentIndex}_${position}" />`)
- }
- if(type==='sheet'){
- this.$refs[`pptPage_${this.currentIndex}`][0].$refs[`sheet_${this.currentIndex}_${position}`].getSheetData('',[])
- this.$refs.deletePage.isLoaded&&this.$refs.deletePage.$refs[`preview_${this.currentIndex}`][0].$refs[`preview_sheet_${this.currentIndex}_${position}`].getSheetData('',[])
- }
- },
- handlePasteOutSide:_.throttle(async function(e){
- //e:粘贴板事件
- console.log(e)
- //如果是标题/文本编辑框,直接返回
- if(e.target.tagName=='INPUT'||e.target.id==='mcepastebin') {
- return
- }
- //如果是文本框内右键粘贴,也返回
- if(e.target.tagName!=='DIV') return
- //算出currentItem还有哪些位置可以插入图表
- const {isAdd,addPositions}=this.checkElements(this.currentItem.modelId,this.currentItem.elements,'chart')
- if(!isAdd){
- this.$message(this.$t("Slides.please_delete_existing_chartsmsg"))
- return
- }
-
- //从clipboardData中获取图片
- if(!e.clipboardData) return
- const clipboardDataItems = e.clipboardData.items
- const clipboardDataFirstItem = clipboardDataItems[0]
- if(clipboardDataFirstItem){
- for (const item of clipboardDataItems) {
- if (item.kind === 'file' && item.type.indexOf('image') !== -1) {
- const imageFile = item.getAsFile()
- if (imageFile) this.$refs[`pptPage_${this.currentIndex}`][0].handlePaste(imageFile,addPositions[0])
- return
- }
- }
- }
- //clipboardData中没有图片,从navigator.clipboard.read里获取图片
- let clipboardItems = null
- try{
- clipboardItems = await navigator.clipboard.read()
- }catch(error){
- this.$message.error(this.$t('Slides.unable_files_msg') )
- return
- }
- const blob = await checkClipboardItems(clipboardItems)
- this.$refs[`pptPage_${this.currentIndex}`][0].handlePaste(blob,addPositions[0])
- },300),
- //黏贴图片
- handlePasteImg:_.throttle(async function($event){
- /** $event:
- * position:1
- * src:base64格式的
- */
- //这里进行上传操作
- if(this.isChartLoading) return
- this.chartLoadingText = this.$t('Slides.uploading_images_msg')
- this.isChartLoading = true
-
-
- // 1走后端接口上传
- const uploadType=this.$setting.dynamicOutLinks.PptUpdateApi ||
- this.$store.state.dynamicOutLinks.PptUpdateApi ||
- JSON.parse(localStorage.getItem('dynamicOutLinks')).PptUpdateApi
- if(uploadType==1){
- const params = new FormData();
- params.append('Image',$event.src)
- const res = await dataBaseInterface.uploadImg(params);
- if(!res||res&&res.Ret!==200){
- this.isChartLoading = false
- return
- }
- const {Data} = res
- if(!Data){
- this.$message.warning("上传图片失败")
- this.isChartLoading = false
- return
- }
- this.imgUrl = Data.ResourceUrl||''
-
- }else{
- //直接走oss不走接口
- let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient
- || this.$store.state.dynamicOutLinks.ObjectStorageClient
- || JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient;
-
- let temName = `ppt/image/${new Date().getTime()}`
- const res = await uploadFileDirect(clientType,$event.src,temName)
- this.imgUrl = res;
- }
-
-
- //console.log('OK',$event)
- let temp_elements = this.addElement(
- this.currentItem.elements,
- [$event.position],
- "image",
- -1,
- ""
- );
- this.refleshElements(temp_elements)
- this.initImage(`#image_${this.currentIndex}_${$event.position}`,this.imgUrl)
- this.initPreviewPageEl()
- this.isChartLoading = false
- },300),
- //改变活跃页某一位置的文字
- handleChangeText({ position, text, richContent,pageItemId }) {
- //console.log('addText',this.currentItem.id,pageItemId)
- //处理初始化的场景
- if(this.currentItem.id!==pageItemId) return
- //如果该位置元素为空,说明文字编辑器没有初始化,添加一个元素
- if (
- this.currentItem.elements.findIndex((i) => i.position === position) ===
- -1
- ) {
- //console.log('addElement',this.currentItem)
- let tempEls = this.addElement(
- this.currentItem.elements,
- [position],
- "text",
- -1,
- { text, richContent }
- );
- this.refleshElements(tempEls);
- }
- this.currentItem.elements.map((i) => {
- if (i.position === position) {
- i.content = text;
- i.richContent = richContent;
- }
- });
- this.pageList[this.currentIndex] = this.currentItem;
- },
- //切换活跃页(currentItem)
- changeCurrentItem(item){
- const {id} = item
- //切换到其他活跃页的时候,需退出图层编辑模式
- if(this.currentItem&&this.currentItem.id!==id){
- this.isEditLayer = false
- this.activeLayerEl = {}
-
- this.isEditTitle = false
- this.isVersionHistory = false
- }
- //点击当前页时,退出标题编辑模式
- if(this.currentItem&&this.currentItem.id===id){
- this.isEditTitle = false
- this.isVersionHistory = false
- return
- }
- this.pageList.map((item,index)=>{
- if(item.id===id){
- this.currentItem = item
- this.currentIndex = index
- }
- })
- this.$nextTick(()=>{
- let height = $('.ppt-editor-item')[0].offsetHeight
- const index = this.currentIndex
- //pptEditor的滚动条动画
- const pptEditorDom = document.getElementById('pptEditor')
- pptEditorDom.scrollTo({
- top:height*index,
- left:0,
- behavior: 'smooth'
- })
- let listDomArr = $('.index-item')
- let heightSum = 0
- for(let i=0;i<this.currentIndex;i++){
- //console.log('height?',listDomArr[i].offsetHeight)
- heightSum+=listDomArr[i].offsetHeight+5
- }
- //console.log('index',this.currentIndex,'height',heightSum)
- //pptList的滚动条动画
- this.$refs.pptList.scrollTo({
- top:heightSum,
- left:0,
- behavior: 'smooth'
- })
- })
- },
- //获取图表列表
- async getreportlist(){
- let params = {
- Keyword: this.key_word,
- CurrentIndex: this.search_page,
- PageSize: this.search_page_sizes,
- IsShowMe: this.isShowMe
- }
- const apiMap = {
- 1: dataBaseInterface.chartSearchByEs,
- 2: futuresInterface.searchChart,
- 3: chartRelevanceApi.searchChart,
- 6: fittingEquationInterface.searchChart,
- 7: statisticFeatureInterface.searchChart,
- 10: crossVarietyInterface.searchChart,
- }
- let res = await apiMap[this.chart_source](params)
- if (res.Ret !== 200) return;
- res.Data.List = res.Data.List || [];
- this.chartList = this.search_page > 1 ? [...this.chartList,...res.Data.List] : res.Data.List;
- this.search_have_more = this.search_page <= res.Data.Paging.Pages;
- },
- loadReportHandle() {
- if(!this.search_have_more) return
- this.search_page++;
- this.getreportlist(this.key_word);
- },
- // 获取沙盘图列表 分页
- getSandTable(){
- this.sandTableLoading = true
- this.isRequesting = true
- sandInterface.sandlistByQuote(this.sandTabelQuery).then(({Data:{List,Paging}})=>{
- if(this.sandTabelQuery.CurrentIndex>1){
- this.sandTableList = [...this.sandTableList,...List]
-
- }else{
- this.sandTableList = List
- this.sandTableTotal = Paging.Totals
- console.log(this.sandTableList.length,this.sandTableTotal);
- if(this.sandTableList.length>=this.sandTableTotal){
-
- this.loadedText = this.$t('Slides.all_loaded_completely_text')
- }else{
- this.loadedText=''
- }
- }
- })
- .finally(()=>{
- this.sandTableLoading = false
- this.isRequesting = false
- })
- },
- // 沙盘列表滚动事件,触底加载下一页数据
- sandTableHandleScroll:_.debounce(function (e) {
- if(this.sandTableList.length>=this.sandTableTotal){
- this.loadedText = this.$t('Slides.all_loaded_completely_text')
- return
- }
- if(e.target.scrollHeight-e.target.clientHeight-e.target.scrollTop<10 && !this.isRequesting){
- this.sandTabelQuery.CurrentIndex++
- this.getSandTable()
- }
- },200),
- //点击右侧知识资源
- chooseKnowledge:_.throttle(async function(item){
- if(this.pageList.length===0||!this.currentItem){
- this.$message.warning(this.$t('Slides.please_add_page_msg') );
- return;
- }
- if(this.isChartLoading) return
- await this.$nextTick();
- // 判断当前页是否有文本元素框
- let v = defaultPosition[this.currentItem.modelId];
- if(!v) return;
- let arr = Object.entries(v);
- let textItem = arr.find(_=>_[1].type=="text");
- if(!textItem) return this.$message.warning('该页PPT无文本位置,无法插入');
- //寻找目标文本元素框
- let i = this.pageList.findIndex(_=>_.id == this.currentItem.id);
- let pageItemDom = this.$refs[`pptPage_${i}`] ? this.$refs[`pptPage_${i}`][0] : null;
- if(!pageItemDom) return;
- let textItemDom = pageItemDom.$refs[`${textItem[1].type}_${i}_${+textItem[0]}`];
- if(!textItemDom) return;
- this.isChartLoading = true;
- const res = await eventInterface.getEventDetail({
- ResourceType: item.ResourceType,
- KnowledgeResourceId: item.KnowledgeResourceId
- });
- this.isChartLoading = false;
- if(res.Ret != 200) return;
- let content = res.Data.Content || '';
- let allContent = `<p>${item.Title}</p>${content}`;
- textItemDom.content += allContent;
- },300),
- //点击右侧图表/沙盘图/表格
- chooseChart:_.throttle(async function(item,type){
- const noAuthMsg = {
- 'chart': this.$t('MsgPrompt.no_chart_auth'),
- 'sheet': this.$t('MsgPrompt.no_sheet_auth')
- }
- if(!item.HaveOperaAuth&&noAuthMsg[type]) return this.$message.warning(noAuthMsg[type])
- if(this.pageList.length===0||!this.currentItem){
- this.$message.warning(this.$t('Slides.please_add_page_msg') );
- return;
- }
- if(item.Disabled&&type==='chart') return this.$message.warning(this.$t('Slides.internal_chart_no_msg') )
- if(this.isChartLoading) return
- //获取当前活动页
- const { elements, modelId } = this.currentItem;
- //判断element是否能再加入图表
- const { isAdd, addPositions } = this.checkElements(
- modelId,
- elements,
- "chart"
- );
- if (!isAdd) {
- this.$message.warning(this.$t('Slides.delete_chart_img_table') );
- return;
- }
- let temp_elements = null;
- this.chartLoadingText = `${this.$t('Slides.loading_urgently')}...`
- // type:sandImage 沙盘图 chart 图表 sheet
- if(type=='chart'){
- //判断选择的图表是否已经插入
- this.isChartLoading = true
- await this.getchartData(item.UniqueCode);
-
- //加入图表
- temp_elements = this.addElement(
- elements,
- addPositions,
- "chart",
- item.UniqueCode,
- ""
- );
- this.chartNum++
- this.refleshElements(temp_elements);
- //优化一下
- const tempEls = [{type:'chart',position:addPositions[0],chartId:item.UniqueCode}]
- const tempPage = {id:this.currentItem.id,elements:tempEls}
- //这里不直接用initChart是因为initCharts里可以判断该图表有没有数据,然后显示图表或显示“该图表已被删除”
- this.initCharts(/* pageElements,page */tempEls,tempPage)
- this.isChartLoading = false
- //更新图表数据
- let chartInfoMap = _.cloneDeep(this.$store.state.ppt.chartInfoMap)
- let chartInfo = getChartInfo(this.optionMap[item.UniqueCode])
- chartInfoMap[item.UniqueCode] = chartInfo
- this.$store.commit('SET_CHART_INFO_MAP',chartInfoMap)
- //需要重新渲染一次缩略图
- this.initPreviewPageEl()
- }else if(type === 'sandImage'){
- // 插入沙盘图
- this.imgUrl = item.PicUrl
- this.isChartLoading = true
- //加入沙盘图
- temp_elements = this.addElement(
- elements,
- addPositions,
- "image",
- -1,
- ""
- );
- this.refleshElements(temp_elements);
- this.initImage(`#image_${this.currentIndex}_${addPositions[0]}`,this.imgUrl)
- this.isChartLoading = false
- this.initPreviewPageEl()
- }
- type === 'sheet' && this.insertSheet(item,elements,addPositions,temp_elements);
-
- },300),
- //检查是否还能再加入元素,返回{isAdd:bool,addPosition:[]},isAdd:是否能插入,addPositions:可以插入的位置
- //type:[chart,text] chart包含除text外的全部元素
- checkElements(modelId, elements, type) {
- const info = modelInfo[modelId];
- let addPositions = [],
- isAdd = false;
- const elPositions = elements.map((i) => i.position);
- let typeNum = 0
- elements.forEach(i=>{
- if(i.type!=='text') typeNum++
- })
- //先判断长度
- if (elements.length >= info.elNum) return { isAdd, addPositions };
- //去重:info.positions和el
- let tempArr = info.positions.filter((i) => elPositions.indexOf(i) < 0);
- if (!tempArr.length) return { isAdd, addPositions };
- //同一版式下的位置支持互换,位置和类型根据 当前版式.positionInfo决定
- //判断数量
- if(typeNum>=info.elChartNum){
- return { isAdd, addPositions };
- }
- const positionInfo = this.$refs[`pptPage_${this.currentIndex}`][0].positionInfo
- //判断类型
- tempArr.forEach((i)=>{
- if(positionInfo[i].type!=='text'){
- addPositions.push(i)
- }
- })
- if (!addPositions.length) {
- return { isAdd, addPositions };
- } else {
- isAdd = true;
- return { isAdd, addPositions };
- }
- },
- //添加一个元素进els,type:[chart,text,image],chart时有chartId,text为空;text/image时,chartId为-1
- addElement(
- el,
- positions,
- type,
- UniqueCode,
- { text, richContent } = { text: "", richContent: "" }
- ) {
- let temp = null;
- if (type === "chart") {
- temp = {
- type: "chart",
- position: positions[0],
- chartId: UniqueCode,
- };
- } else if (type === "text") {
- temp = {
- type: "text",
- position: positions[0],
- content: text,
- richContent: richContent,
- };
- }else if (type==='image'){
- temp = {
- type:'image',
- position:positions[0],
- src:this.imgUrl
- }
- }else if(type==='sheet'){
- temp={
- type:'sheet',
- position:positions[0],
- sheetId:UniqueCode
- }
- }
- el.push(temp);
- return el;
- },
- // 版本记录列表
- handleVersionHistory(item) {
- this.isVersionHistory = true;
- },
- //
- async handleRestore(Id) {
- let res = await pptInterface.getPptHistoryRevert({
- Id
- });
- if (res.Ret !== 200) return;
- this.$message.success('恢复成功!');
- this.init()
- },
- //更新ppt页元素(数据)
- refleshElements(els){
- this.currentItem.elements = els;
- this.pageList[this.currentIndex] = this.currentItem;
- this.$refs[`pptPage_${this.currentIndex}`][0].initPositionInfo()
- },
- //手动保存PPT
- async handleSave(type){
- //保存走save_checkPPT,发布走checkPPT
- let checkResult = null
- if(type==='save'){
- checkResult = this.save_checkPPT()
- }else{
- checkResult = this.checkPPT()
- }
- if(!checkResult.result){
- this.$message.warning(checkResult.hintText)
- return checkResult
- }
- let Content = JSON.stringify(this.pageList)
- const {Title,ReportType,PptDate,BackgroundImg,BackIndex,CurrentBackgroundImg,BackCoverImg, BackCoverImgId,BackgroundImgId,CurrentBackgroundImgId} = this.firstPage
- const FirstPage = {
- Title,ReportType,PptDate,BackIndex,BackCoverImg,CurrentBackgroundImg,BackCoverImgId,BackgroundImgId,CurrentBackgroundImgId,
- ImgUrl:BackgroundImg,
- TemplateType:BackIndex+1
- }
- this.isSaved = true
- if(this.$route.query.id||this.pptId){
- await this.editPPT(FirstPage,Content,type)
- }else{
- // await this.addPPT(FirstPage,Content)
- }
- },
- async addPPT(FirstPage,Content){
- await pptInterface.addppt({
- FirstPage:FirstPage,
- Content:Content,
- GroupId:this.catalogId,
- CoverContent:this.CoverContent,
- TitleSetting:JSON.stringify(this.titleSetting)
- }).then(res=>{
- this.isSaved = false
- if(res.Ret===200){
- this.$message.success(this.$t('MsgPrompt.add_msg'))
- this.isSave = true
- this.pptId = res.Data.PptId
- sessionStorage.removeItem('selectedCatalog')
- //开启自动保存
- this.autoSave()
- }
- })
- },
- async editPPT(FirstPage,Content,type){
- //console.log(type)
- const ppt_id = this.$route.query.id||this.pptId
- await pptInterface.editppt({
- PptId:parseInt(ppt_id),
- FirstPage:FirstPage,
- Content:Content,
- CoverContent:this.CoverContent,
- TitleSetting:JSON.stringify(this.titleSetting)
- }).then(res=>{
- this.isSaved = false
- if(res.Ret===200){
- if(type==='save'){
- this.$message.success(this.$t('MsgPrompt.edit_msg'))
- }
- this.isSave = true
- this.pptId = res.Data.PptId
- //如果ppt已转成双周报,则更新
- }
- })
- },
- //自动保存PPT
- autoSave(){
- if(this.loopTimer) return
- if(!this.$route.query.id&&!this.pptId) return
- this.loopTimer = setInterval(()=>{
- //如果当前在刷新图表,则不进行自动保存
- if(this.refreshBtnLoading) return
- const ppt_id = this.$route.query.id||this.pptId
- const {Title,ReportType,PptDate,BackgroundImg,BackIndex,CurrentBackgroundImg,BackCoverImg,BackCoverImgId,BackgroundImgId,CurrentBackgroundImgId} = this.firstPage
- const FirstPage = {
- Title,ReportType,PptDate,BackIndex,CurrentBackgroundImg,BackCoverImg,CurrentBackgroundImg,BackCoverImgId,BackgroundImgId,CurrentBackgroundImgId,
- ImgUrl:BackgroundImg,
- TemplateType:BackIndex+1
- }
- //防止自动保存时,有某一页处于更新图表的状态,其isUpdating为true
- let pageList = this.pageList.map(i=>{
- i.isUpdating = false
- return i
- })
- let Content = JSON.stringify(pageList)
- let TitleSetting = JSON.stringify(this.titleSetting)
- pptInterface.saveLog({
- PptId:parseInt(ppt_id),
- FirstPage:FirstPage,
- Content:Content,
- CoverContent:this.CoverContent,
- TitleSetting,
- }).then((res)=>{
- if(res.Ret!==200) return
- this.showLastSaveTime = true
- this.lastSaveTime = http.dateFormatter(new Date(), true);
- })
- },10000)
- },
- //保存时的校验规则:封面信息,至少一页
- save_checkPPT(){
- if(!this.firstPage.BackgroundImg){
- return {result:false,hintText:'请选择封面页!'}
- }
- if(!this.firstPage.Title){
- return {result:false,hintText:this.$t('Slides.please_input_cover_title')+'!'}
- }
- if(this.pageList.length===0){
- return {result:false,hintText:this.$t('Slides.least_one_ppt_msg') }
- }
- return {result:true,hintText:''}
- },
- //发布时的校验规则:封面信息,每一页标题及内容
- checkPPT(){
- if(!this.firstPage.BackgroundImg){
- return {result:false,hintText:'请选择封面页!'}
- }
- //检验首页
- if(!this.firstPage.Title){
- return {result:false,hintText:this.$t('Slides.please_input_cover_title')+'!'}
- }
- if(this.pageList.length===0){
- return {result:false,hintText:this.$t('Slides.least_one_ppt_msg') }
- }
- //检验每一页
- for(let i=0;i<this.pageList.length;i++){
- if(!this.pageList[i].title||this.pageList[i].title==='<br>'){
- return {result:false,hintText:this.$t('Slides.please_ppt_title_msg',{count:i+1}) }
- }
- //无内容
- if(this.pageList[i].elements.length===0){
- return {result:false,hintText:this.$t('Slides.please_ppt_content_msg',{count:i+1}) }
- }
- //有文本框,但是文本框无内容
- }
- return {result:true,hintText:''}
- },
- async handlePublish(){
- //ETA1.7.5更改发布逻辑,点击发布时,自动执行保存操作,若可保存,则跳转发布页
- const res = await this.handleSave('pub')
- if(res&&!res.result) return
- //ppt4.0后,合并后的PPT可能会超出页数or图表限制,在这里做个校验
- if(this.pageList.length>this.maxPageNum){
- this.$message.warning(this.$t('Slides.most_add_ppt_msg',{count:this.maxPageNum}))
- return
- }
- if(this.chartNum>this.maxPageChart){
- this.$message.warning(this.$t('Slides.most_add_chart_msg',{count:this.maxPageChart}));
- return;
- }
- this.pptId&&this.$router.push({path:'/pptpublish',query:{id:this.pptId}})
- },
- //拖动相关
- dragstart(e,value) {
- e.dataTransfer.effectAllowed = "move";
- this.oldNum = value;
- },
- dragend() {
- let oldIndex = this.pageList.findIndex(_ => _.id ===this.oldNum.id);
- let newIndex = this.pageList.findIndex(_ => _.id ===this.newNum.id);
- // console.log(oldIndex,newIndex)
- let tempOption = _.cloneDeep(this.pageList[newIndex])
- if(oldIndex !== newIndex) {
- this.$set(this.pageList, newIndex, this.pageList[oldIndex])
- this.$set(this.pageList, oldIndex, tempOption)
- this.$message.success(this.$t('Slides.move_success_msg') )
- }
-
- this.currentIndex = this.pageList.findIndex(_ => _.id ===this.currentItem.id);
- },
- dragenter(e,value) {
- e.preventDefault()
- this.newNum = value;
- },
- changePageIndex($event){
- this.oldNum = this.pageList[$event.oldPos-1]
- this.newNum = this.pageList[$event.newPos-1]
- this.dragend()
- },
-
- /* 搜索表格 */
- getSheetList() {
- sheetInterface
- .sheetList({
- Keyword: this.sheetSearchObj.Keyword,
- CurrentIndex: 1,
- PageSize: 10000
- })
- .then((res) => {
- if (res.Ret !== 200) return
- this.sheetSearchList = res.Data.List || [];
- });
- },
- /* 插入表格 */
- async insertSheet({ExcelImage,UniqueCode},elements,addPositions,temp_elements) {
- // 插入沙盘图
- this.imgUrl = ExcelImage;
- this.isChartLoading = true
- const idName = `sheet_${this.currentIndex}_${addPositions[0]}`
- const res = await this.getsheetData(UniqueCode)
- if(!res) {
- this.isChartLoading = false
- return
- }
- //加入表格
- temp_elements = this.addElement(
- elements,
- addPositions,
- "sheet",
- UniqueCode,
- ""
- );
- this.refleshElements(temp_elements);
- this.initSheet(this.$refs[`pptPage_${this.currentIndex}`][0],idName,UniqueCode,'insert')
- this.isChartLoading = false
- this.initPreviewPageEl()
- },
-
- //打开批量删除弹窗
- openDeletePageDialog(){
- //添加一页才能打开弹窗
- if(this.pageList.length===0){
- this.$message.warning(this.$t('Slides.please_add_one_page') )
- return
- }
- this.deletePageShow = true
- },
- async handleDeletePages(list){
- this.$refs.deletePage.loadingText= this.$t('Slides.deleting_process_loading')
- this.$refs.deletePage.dataLoading=true
- this.deletePages(list)
- },
- //批量删除
- deletePages(list){
- let temp = this.pageList.filter((item,index)=>{
- if(!list.includes(index)){
- return item
- }
- })
- this.pageList = temp
- this.currentIndex=0
- if(this.pageList.length>0){
- this.changeCurrentItem(this.pageList[0])
- }else{
- this.currentItem=null
- }
- //删除后,需要重新计算图表数
- let newChartNum = 0
- for(let i=0;i<this.pageList.length;i++){
- const page = this.pageList[i]
- page.elements.forEach(item=>{
- if(item.type==='chart'){
- newChartNum++
- }
- })
- }
- this.chartNum = newChartNum
- this.$nextTick(()=>{
- this.$refs.deletePage.dataLoading = false
- this.deletePageShow = false
- this.$message.success(this.$t('Slides.batch_deletion_successful'))
- })
-
- },
- initPreviewPageEl(type,page){
- const currentItem = page||this.currentItem
- const isLoaded = this.$refs.deletePage.isLoaded
- if(isLoaded){
- type!=='delete'&&this.$refs.deletePage.$refs[`preview_${this.currentIndex}`][0].initPositionInfo()
- this.$refs.deletePage.initPreviewEl(currentItem)
- }
- },
- reloadPage({id,positionInfo}){
- const index = this.pageList.findIndex(i=>i.id===id)
- this.pageList[index].key++
- this.pageList[index].positionInfo = positionInfo
- this.initPageElements(this.pageList[index])
- this.initPreviewPageEl()
- },
- },
- updated(){
- $('.ppt-item').css('height',$('.ppt-item').width()*0.7);
- $('.ppt-item').css('background-image',`url(${this.firstPage.CurrentBackgroundImg})`);
- window.onresize = ()=>{
- $('.ppt-item').css('height',$('.ppt-item').width()*0.7);
- }
- },
- destroyed(){
- sessionStorage.removeItem('selectedCatalog')
- window.removeEventListener('message',this.reInitIframe)
- window.onresize=null
- if(this.loopTimer) clearInterval(this.loopTimer)
- }
- };
- </script>
- <style lang="scss">
- @import './css/common.scss';
- @import './css/format.scss';
- </style>
- <style scoped lang="scss">
- $titleColor:#333333;
- .page-wrap{
- display: flex;
- width: 100%;
- overflow-x: scroll;
- &::-webkit-scrollbar-track{
- display: none;
- }
- div::-webkit-scrollbar-track{
- display: none;
- }
- .index-wrap{
- min-width: 280px;
- margin-right: 10px;
- padding:10px;
- .cover-wrap{
- cursor: pointer;
- width: 100%;
- margin-bottom: 10px;
- .cover{
- //高:宽 0.75
- height: 195px;
- display: flex;
- justify-content: center;
- align-items: center;
- background-size: 100% 100% !important;
- }
- }
- .hint-box{
- color:#409EFF;
- display: flex;
- justify-content: flex-end;
- align-items: center;
- margin-bottom:10px;
- }
- .hint{
- border: 1px solid transparent;
- cursor: pointer;
- padding:5px;
- &:hover{
- border: 1px solid #409EFF;
- border-radius: 4px;
- background: #ECF5FF;
- }
- }
- .index-list{
- //margin-top: 10px;
- flex: 1;
- overflow-y: scroll;
- .empty{
- margin-top:120px;
- text-align: center;
- img{
- width:76px;
- height:76px;
- display: inline-block;
- }
- p{
- font-size: 14px;
- color: $titleColor;
- }
- }
- }
- }
- .ppt-editor-wrap{
- flex:1;
- /* min-width: 1370px; */
- padding:20px;
- display: flex;
- .ppt-editor{
- flex:1;
- /* max-width: 980px;
- min-width:776px; */
- max-width: 980px;
- min-width: 980px;
- height:100%;
- /* background-color: pink; */
- background-color: #fff;
- border:2px solid #EBEBEB;
- border-radius: 4px;
- margin-right: 30px;
- overflow-y: scroll;
- position:relative;
- .ppt-editor-item {
- position: relative;
- align-items: center;
- .ppt-item {
- //padding 两边 40 减掉边框两边 8 max-width:100% - 32px
- width:calc(100% - 64px);
- background: transparent;
- background-size: 100% 100%;
- /* margin-bottom: 30px; */
- position: relative;
- border: 4px solid transparent;
- cursor: pointer;
- &.choose {
- border: 4px solid rgba($color: #4B8DFF, $alpha: 0.7);
- }
- .close-btn{
- color:#BDBDBD;
- width:20px;
- height:20px;
- position:absolute;
- cursor: pointer;
- top:-10px;
- right:-10px;
- background: url('~@/assets/img/ppt_m/ppt-del.png') no-repeat center/cover;
- background-color: white;
- border-radius: 50%;
- }
- .page-num{
- color:#666666;
- position:absolute;
- bottom:10px;
- right:20px;
- }
- .update-btn{
- position:absolute;
- top:16px;
- left:12px;
- color:#409EFF;
- cursor: pointer;
- display: flex;
- justify-content: center;
- .update-ico{
- width:20px;
- height:20px;
- background:url('~@/assets/img/ppt_m/update-ico.png') no-repeat center/cover;
- margin-right: 4px;
- }
- }
- .loading-cover{
- position: absolute;
- top:20px;
- left:0;
- height:20px;
- background-color: #409EFF;
- }
- }
- }
- }
- .ppt-tool{
- min-width:320px;
- width: 320px;
- height:100%;
- overflow-y: hidden;
- .richtext-tool{
- margin:10px 0;
- }
- .addppt-right-box{
- flex: 1;
- /* height: calc(100% - 182px); */
- padding: 0 10px;
- box-sizing: border-box;
- border: 2px solid #EBEBEB;
- border-radius: 4px;
- min-width: 320px;
- overflow-y: auto;
- #tabs {
- padding: 0px 40px;
- box-sizing: border-box;
- margin: 15px 0;
- overflow: hidden;
- > p {
- float: left;
- width: 50%;
- font-size: 18px;
- cursor: pointer;
- color: #1f2e4d;
- padding: 10px 0;
- text-align: center;
- }
- > p.active {
- border-bottom: 2px solid #3464e0;
- color: #3464e0;
- }
- }
- .chart-tool{
- flex: 1;
- margin-top: 10px;
- height: calc(100% - 80px);
- .chart-search{
- margin-bottom: 10px;
- }
- .chart-list{
- flex: 1;
- border:2px solid #EBEBEB;
- border-radius: 4px;
- overflow-y: scroll;
- text-align: center;
- .chart-item {
- cursor: pointer;
- text-align: center;
- color: #74818d;
- font-size: 18px;
- margin-bottom: 10px;
- padding:10px;
- img {
- width: 100%;
- }
- }
- .sandTable-item{
- border-bottom: solid 1px #eeeeee;
- padding: 20px 0 10px 0;
- p{
- font-size: 16px;
- color: #3464e0;
- text-align: center;
- }
- img{
- cursor: pointer;
- }
- }
- .loaded-text{
- height: 20px;
- text-align: center;
- color: #666;
- font-size: 14px;
- }
- }
- }
- }
- .layer-edit-box,.title-edit-box{
- flex: 1;
- padding: 0 20px;
- box-sizing: border-box;
- border: 2px solid #EBEBEB;
- border-radius: 4px;
- min-width: 320px;
- overflow-y: auto;
- .tool-list{
- .el-wrap{
- display: flex;
- gap: 0 15px;
- flex-wrap: wrap;
- .el-item{
- border: 1px solid #DCDFE6;
- border-radius: 4px;
- width:55px;
- height:55px;
- margin-bottom: 20px;
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- &:hover,&.active{
- border: 1px solid #409EFF;
- }
- }
- }
- .el-collapse-item__wrap{
- overflow: visible;
- }
- }
- }
- .title-edit-box{
- display:flex;
- flex-direction: column;
- padding:20px;
- p{
- font-size: 16px;
- font-weight: bold;
- }
- }
- }
- }
- .flex-align{
- display:flex;
- align-items: center;
- }
- }
- </style>
|