1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371 |
- <template>
- <div class="doc-container">
- <div class="editor-top">
- <div class="left">
- <div class="doc" v-if="type == 'document'">
- <span>当前打开文档:</span
- >{{ docAttr.title == "" ? "新建文档" : docAttr.title }}
- </div>
- <div class="doc" v-else-if="type == 'module'">
- <span>当前打开模块:</span
- >{{ coms[0].name == "" ? "新建模块" : coms[0].name }}
- </div>
- <div class="doc" v-else>
- <span>当前打开模版:</span
- >{{ docAttr.title == "" ? "新建模版" : docAttr.title }}
- </div>
- <div class="creator" v-if="userInfo != null">
- <span>创建者:</span>{{ userInfo && userInfo.username }}
- </div>
- </div>
- <div class="right">
- <el-button
- type="primary"
- size="mini"
- @click="onSaveAs"
- v-if="
- type !== 'module' && type == 'document' && articleId == undefined
- "
- >保存文档</el-button
- ><!-- v-if="docAttr.id > 0" -->
- <el-button
- type="primary"
- size="mini"
- @click="renew"
- v-if="
- articleId !== undefined && type !== 'module' && type == 'document'
- "
- >更新文档</el-button
- >
- <!-- <el-popover
- placement="bottom"
- trigger="click"
- v-if="type !== 'module' && type !== 'document'"
- > -->
- <el-button
- type="primary"
- v-if="
- $store.state.user.name == 'admin' &&
- type !== 'module' &&
- type !== 'document' &&
- !articleId
- "
- @click="onSaveUpload"
- >保存</el-button
- >
- <el-button
- type="primary"
- v-if="
- $store.state.user.name == 'admin' &&
- type !== 'module' &&
- type !== 'document' &&
- articleId
- "
- @click="onUpload"
- >更新</el-button
- >
- <!-- <el-button
- slot="reference"
- type="primary"
- size="mini"
- style="margin: 0 10px"
- v-if="$store.state.user.name == 'admin'"
- >保存并更新模版</el-button
- >
- </el-popover> -->
- <!-- <el-button
- type="primary"
- size="mini"
- v-if="$store.state.user.name == 'admin'"
- @click="onSaveUpload"
- >保存并更新模版</el-button
- > -->
- <el-button
- type="primary"
- size="mini"
- v-if="type !== 'module' && type == 'document'"
- @click="onOpenView"
- >预览导出
- </el-button>
- <el-button type="primary" size="mini" @click="onClose">
- 关闭文档
- </el-button>
- </div>
- </div>
- <div class="editor-content">
- <div class="neary-doc">
- <div class="left-content">
- <!-- <div class="search">
- <el-input placeholder="搜索文档标题"></el-input>
- </div> -->
- <div class="new-article">
- <div v-if="showView == 0 && type !== 'module'">
- <el-collapse v-model="activeNames">
- <el-collapse-item
- title="最新文档"
- name="-1"
- v-if="type == 'document'"
- >
- <div
- v-for="(it, index) in articleList"
- draggable
- :key="it.id"
- :data-index="index"
- data-type="article"
- class="sub-menus"
- >
- <div
- @click="onLoadArticle(it.id)"
- :title="it.title"
- style="
- cursor: pointer;
- white-space: nowrap;
- overflow: hidden; /* 隐藏超出部分 */
- text-overflow: ellipsis; /* 显示省略号 */
- max-width: 100%;
- "
- >
- {{ it.title }}
- </div>
- </div>
- </el-collapse-item>
- <el-collapse-item
- title="模版列表"
- name="-2"
- v-if="showView == 0"
- >
- <div
- v-for="(it, index) in templateList"
- draggable
- :key="it.id"
- :data-index="index"
- data-type="article"
- class="sub-menus"
- >
- <div
- @click="onTemplateInfo(it.id)"
- :title="it.title"
- style="
- cursor: pointer;
- white-space: nowrap;
- overflow: hidden; /* 隐藏超出部分 */
- text-overflow: ellipsis; /* 显示省略号 */
- width: 100%;
- "
- >
- {{ it.title }}
- </div>
- </div>
- </el-collapse-item>
- </el-collapse>
- </div>
- <div v-if="showView == 1" class="scrollable-container">
- <!-- <el-collapse
- v-model="activeModel"
- :accordion="true"
- @change="handleItemClick"
- class="borderless-collapse"
- >
- <el-collapse-item
- v-for="(item, itemIndex) in categoryList"
- :key="itemIndex"
- :title="item.name"
- :name="item.id"
- >
- <el-collapse
- v-if="item.children && item.children.length"
- v-model="item.activeChildren"
- @change="handleItemVal"
- v-show="item.children"
- class="borderless-collapse"
- >
- <el-collapse-item
- v-for="(child, childIndex) in item.children"
- :key="childIndex"
- :title="child.name"
- :name="child.id"
- >
- <draggable
- v-model="child.dataList"
- :options="{
- group: { name: 'itxst', pull: 'clone' },
- sort: true,
- }"
- :disabled="type == 'module'"
- >
- <transition-group>
- <div
- class="sub-menus"
- v-for="(its, index) in child.dataList"
- :key="index"
- >
- <div>{{ its.name }}</div>
- </div>
- </transition-group>
- </draggable>
- </el-collapse-item>
- </el-collapse>
- <draggable
- v-model="item.dataList"
- :options="{
- group: { name: 'itxst', pull: 'clone' },
- sort: true,
- }"
- :disabled="type == 'module'"
- >
- <transition-group>
- <div
- class="sub-menus"
- v-for="(it, index) in item.dataList"
- :key="index"
- >
- <div>{{ it.name }}</div>
- </div>
- </transition-group>
- </draggable>
- </el-collapse-item>
- </el-collapse> -->
- <el-collapse
- v-model="activeModel"
- :accordion="true"
- @change="handleItemClick"
- class="borderless-collapse"
- >
- <el-collapse-item
- v-for="(item, itemIndex) in categoryList"
- :key="itemIndex"
- :title="item.name"
- :name="item.id"
- class="min-width-content"
- >
- <el-collapse
- v-if="item.children && item.children.length"
- v-model="item.activeChildren"
- @change="handleItemVal"
- v-show="item.children"
- class="borderless-collapse"
- >
- <el-collapse-item
- v-for="(child, childIndex) in item.children"
- :key="childIndex"
- :title="child.name"
- :name="child.id"
- class="min-width-content"
- >
- <el-collapse
- v-if="child.children && child.children.length"
- v-model="child.activeChildren"
- @change="handleChildItemVal"
- v-show="child.children"
- class="borderless-collapse"
- >
- <el-collapse-item
- v-for="(
- grandChild, grandChildIndex
- ) in child.children"
- :key="grandChildIndex"
- :title="grandChild.name"
- :name="grandChild.id"
- class="min-width-content"
- >
- <el-collapse
- v-if="
- grandChild.children && grandChild.children.length
- "
- v-model="grandChild.activeChildren"
- @change="handleGrandChildItemVal"
- v-show="grandChild.children"
- class="borderless-collapse"
- >
- <el-collapse-item
- v-for="(
- greatGrandChild, greatGrandChildIndex
- ) in grandChild.children"
- :key="greatGrandChildIndex"
- :title="greatGrandChild.name"
- :name="greatGrandChild.id"
- class="min-width-content"
- >
- <el-collapse
- v-if="
- greatGrandChild.children &&
- greatGrandChild.children.length
- "
- v-model="greatGrandChild.activeChildren"
- @change="handlegreatGrandChildItemVal"
- v-show="greatGrandChild.children"
- class="borderless-collapse"
- >
- <el-collapse-item
- v-for="(
- fiveChild, fiveIndex
- ) in greatGrandChild.children"
- :key="fiveIndex"
- :title="fiveChild.name"
- :name="fiveChild.id"
- class="min-width-content"
- >
- <draggable
- v-model="fiveChild.dataList"
- :options="{
- group: { name: 'itxst', pull: 'clone' },
- sort: true,
- }"
- :disabled="type === 'module'"
- >
- <transition-group>
- <div
- class="sub-menus min-width-content"
- v-for="(
- fiveIts, fiveIndex
- ) in fiveChild.dataList"
- :key="fiveIndex"
- >
- <div
- :title="fiveIts.name"
- style="
- cursor: move;
- white-space: nowrap;
- overflow: hidden; /* 隐藏超出部分 */
- text-overflow: ellipsis; /* 显示省略号 */
- width: 100%;
- "
- >
- {{ fiveIts.name }}
- </div>
- </div>
- </transition-group>
- </draggable>
- </el-collapse-item>
- </el-collapse>
- <draggable
- v-model="greatGrandChild.dataList"
- :options="{
- group: { name: 'itxst', pull: 'clone' },
- sort: true,
- }"
- :disabled="type == 'module'"
- >
- <transition-group>
- <div
- class="sub-menus min-width-content"
- v-for="(
- its, index
- ) in greatGrandChild.dataList"
- :key="index"
- >
- <div
- :title="its.name"
- style="
- cursor: move;
- white-space: nowrap;
- overflow: hidden; /* 隐藏超出部分 */
- text-overflow: ellipsis; /* 显示省略号 */
- width: 100%;
- "
- >
- {{ its.name }}
- </div>
- </div>
- </transition-group>
- </draggable>
- </el-collapse-item>
- </el-collapse>
- <draggable
- v-model="grandChild.dataList"
- :options="{
- group: { name: 'itxst', pull: 'clone' },
- sort: true,
- }"
- :disabled="type == 'module'"
- >
- <transition-group>
- <div
- class="sub-menus min-width-content"
- v-for="(it, index) in grandChild.dataList"
- :key="index"
- >
- <div
- :title="it.name"
- style="
- cursor: move;
- white-space: nowrap;
- overflow: hidden; /* 隐藏超出部分 */
- text-overflow: ellipsis; /* 显示省略号 */
- width: 100%;
- "
- >
- {{ it.name }}
- </div>
- </div>
- </transition-group>
- </draggable>
- </el-collapse-item>
- </el-collapse>
- <draggable
- v-model="child.dataList"
- :options="{
- group: { name: 'itxst', pull: 'clone' },
- sort: true,
- }"
- :disabled="type == 'module'"
- >
- <transition-group>
- <div
- class="sub-menus min-width-content"
- v-for="(it, index) in child.dataList"
- :key="index"
- >
- <div
- :title="it.name"
- style="
- cursor: move;
- white-space: nowrap;
- overflow: hidden; /* 隐藏超出部分 */
- text-overflow: ellipsis; /* 显示省略号 */
- width: 100%;
- "
- >
- {{ it.name }}
- </div>
- </div>
- </transition-group>
- </draggable>
- </el-collapse-item>
- </el-collapse>
- <draggable
- v-model="item.dataList"
- :options="{
- group: { name: 'itxst', pull: 'clone' },
- sort: true,
- }"
- :disabled="type == 'module'"
- >
- <transition-group>
- <div
- class="sub-menus min-width-content"
- v-for="(it, index) in item.dataList"
- :key="index"
- >
- <div
- :title="it.name"
- style="
- cursor: move;
- white-space: nowrap;
- overflow: hidden; /* 隐藏超出部分 */
- text-overflow: ellipsis; /* 显示省略号 */
- width: 100%;
- "
- >
- {{ it.name }}
- </div>
- </div>
- </transition-group>
- </draggable>
- </el-collapse-item>
- </el-collapse>
- </div>
- </div>
- </div>
- <div class="right-sidebarew">
- <div
- v-if="type !== 'module'"
- class="sidebar-item"
- :class="showView == 0 ? 'active-item' : ''"
- @click="viewDocument"
- >
- <span v-if="type == 'document'">查看文档</span>
- <span v-else>查看模版</span>
- </div>
- <div
- v-if="type !== 'document'"
- class="sidebar-item"
- :class="showView == 1 ? 'active-item' : ''"
- @click="viewModule"
- >
- 模块列表
- </div>
- </div>
- </div>
- <div class="editor-main">
- <div class="menus-box">
- <menus
- @onEvents="onInsert"
- @onVariable="uptadeVariable"
- :comArr="coms"
- ></menus>
- </div>
- <div
- class="editor-box"
- ref="tabHtml"
- v-loading="loading"
- element-loading-text="加载中..."
- element-loading-spinner="el-icon-loading"
- >
- <editor
- :coms="coms"
- :comIndex="comIndex"
- :isAdmin="isAdmin"
- :templateCate="categoryList"
- :insertCmd="insertCmd"
- @onSetActiveIndex="onSetActiveIndex"
- @onInsert="onInsert"
- @onLoadArticle="onLoadArticle"
- @onRebuild="onRebuild"
- @onDelete="onRemove"
- @onSetComs="onSetComs"
- ></editor>
- </div>
- </div>
- <div class="editor-option">
- <div class="editor-menu">
- <div
- v-if="type !== 'module' && type !== 'document'"
- class="item"
- @click="onSetActiveIndexs(3)"
- :class="docuComIndex == 3 ? 'active-item' : ''"
- >
- <span class="name">模版属性</span>
- </div>
- <div
- v-if="type !== 'module'"
- class="item"
- @click="onSetActiveIndex(9998)"
- :class="comIndex == 9998 ? 'active-item' : ''"
- >
- <span class="name">模块管理</span>
- </div>
- <div
- class="item"
- @click="onCatalogIndex(9997)"
- :class="catalogIndex == 9997 ? 'active-item' : ''"
- >
- <span class="name">目录信息</span>
- </div>
- <div
- class="item"
- @click="onAttributeIndex(1)"
- :class="AttributeIndex == 1 ? 'active-item' : ''"
- >
- <span class="name">属性变量</span>
- </div>
- </div>
- <template
- v-if="docuComIndex == 3 && type !== 'module' && type !== 'document'"
- >
- <docAttr :attrs="docAttr"></docAttr>
- </template>
- <template v-if="comIndex == 9998">
- <comList
- :coms="coms"
- @onRemove="onRemove"
- @onSetActive="onSetActiveIndex"
- @onRebuild="onRebuild"
- ></comList>
- </template>
- <template v-if="catalogIndex == 9997">
- <Directory :coms="coms" />
- </template>
- <!-- comIndex != 9999 && comIndex != 9998 && comIndex != 9997 AttributeIndex==1-->
- <!-- <template
- v-if="
- comIndex != 9999 &&
- comIndex != 9998 &&
- catalogIndex != 9997 &&
- AttributeIndex != 1
- "
- >
- <Attribute
- :com="coms[comIndex]"
- @onRefresh="initCategoryList"
- ></Attribute>
- </template> -->
- <template v-if="AttributeIndex == 1">
- <attributeVar
- :com="coms[comIndex]"
- @onRefresh="initCategoryList"
- ></attributeVar>
- </template>
- <!-- <Directory :coms="coms" /> -->
- </div>
- </div>
- <el-dialog
- :visible.sync="showViewForm"
- :close-on-click-modal="false"
- append-to-body
- v-el-drag-dialog
- width="850px"
- custom-class="prod-verify"
- title="文档预览"
- >
- <ViewForm :coms="coms" :docAttr="docAttr"></ViewForm>
- </el-dialog>
- <el-dialog
- :visible.sync="showProductAttr"
- append-to-body
- v-el-drag-dialog
- :close-on-click-modal="false"
- width="850px"
- custom-class="prod-verify"
- title="插入产品属性"
- >
- <ProductAttr
- :docAttr="docAttr"
- @onInsertProductAttr="onInsertProductAttr"
- ></ProductAttr>
- </el-dialog>
- <el-dialog
- :visible.sync="docVisible"
- append-to-body
- v-el-drag-dialog
- :close-on-click-modal="false"
- width="500px"
- custom-class="prod-verify"
- title="文档信息"
- >
- <el-form
- :model="docForm"
- :rules="docRules"
- ref="docRef"
- label-position="left"
- label-width="100"
- >
- <el-form-item label="文档名称:" prop="title">
- <el-input
- v-model="docForm.title"
- style="width: 60%"
- class="input-item"
- placeholder="请填写文档名称"
- :disabled="docAttr.id > 0"
- />
- </el-form-item>
- <el-form-item label="文档分类:" prop="category_id">
- <el-select
- v-model="docForm.category_id"
- style="width: 60%"
- placeholder="请选择所属分类"
- :disabled="docAttr.id > 0"
- >
- <el-option
- v-for="(item, index) in articleCategoryList"
- :key="index"
- :label="item.name"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="创建人:">
- {{ userInfo && userInfo.username }}
- </el-form-item>
- </el-form>
- <span slot="footer" class="dialog-footer">
- <el-button @click="closeDoc">取 消</el-button>
- <el-button type="primary" @click="submitDoc">确 定</el-button>
- </span>
- </el-dialog>
- </div>
- </template>
- <script>
- import { findData } from "@/api/sourceData";
- import utils from "@/utils/fun"; // 方法类
- import { searchDocument, pageDocument } from "@/api/document";
- import menus from "./com/menus";
- import editor from "./com/editor";
- import Attribute from "./com/components/Attribute";
- import attributeVar from "./com/components/Attribute/attributeVar/index.vue";
- import ProductAttr from "./com/components/ProductAttr";
- import {
- searchTemplateCategory,
- searchTemplate,
- getTemplateInfo,
- getAllCategory,
- } from "@/api/template";
- import docAttr from "./com/components/Attribute/docAttr";
- import comList from "./com/components/Attribute/comList";
- import Directory from "./com/components/Attribute/Directory";
- import { getCurrentUserInfo } from "@/api/api";
- import {
- createDocument,
- updateDocument,
- getDocumentInfo,
- exportDocument,
- searchDocumentCategory,
- } from "@/api/document";
- import ViewForm from "./com/view";
- import elDragDialog from "@/directive/el-drag-dialog";
- import draggable from "vuedraggable";
- import htmlDocx from "html-docx-js/dist/html-docx";
- import { searchFormula } from "@/api/formula";
- import axios from "axios";
- import settings from "@/settings";
- // import htmlDocx from "htmlDocx";
- export default {
- name: "create",
- components: {
- menus,
- editor,
- Attribute,
- comList,
- docAttr,
- ViewForm,
- ProductAttr,
- Directory,
- draggable,
- attributeVar,
- },
- directives: {
- elDragDialog,
- },
- data() {
- return {
- activeNames: "-1",
- nestedActiveNames: [],
- articleList: [],
- activeModel: "",
- templateList: [],
- categoryList: [],
- //组件相关
- coms: [],
- comIndex: 9999, //当前组件索引
- showProductAttr: false,
- comList: [],
- //文档属性
- docAttr: {
- id: 0,
- category_id: "",
- title: "",
- content: "",
- status: 5,
- links: "",
- linkProduct: [],
- linkProject: [],
- projects: "",
- document_type: "",
- },
- insertCmd: null,
- showViewForm: false,
- isAdmin: 2, //1是管理员,2非管理员
- //当前选中表格
- tabExt: {
- row: 0,
- col: 0,
- },
- userInfo: null,
- articleId: 0,
- loading: false, // 增加 loading 状态
- showView: 0, //查看 文档/模块
- childrenList: "",
- value: [],
- AttributeIndex: 0,
- catalogIndex: 0, //目录信息
- docuComIndex: 3,
- type: "",
- docVisible: false,
- docForm: {
- title: "",
- category_id: "",
- },
- docRules: {
- title: [{ required: true, message: "请输文档名称", trigger: "blur" }],
- category_id: [
- { required: true, message: "请选择文档分类", trigger: "change" },
- ],
- },
- articleCategoryList: [],
- };
- },
- watch: {
- coms: {
- handler(newComs, oldComs) {
- this.updateAttrs(newComs, oldComs);
- },
- immediate: true, //立即执行
- deep: true,
- },
- articleId: {
- handler(val) {
- if (val == null || val == undefined || val <= 0) return;
- if (this.$route.query.type == "document") {
- this.loadArticle(val);
- } else {
- this.onTemplateInfo(val);
- }
- //
- },
- immediate: true,
- deep: true,
- },
- },
- async mounted() {
- console.log(this.$store.state.user);
- this.articleId = this.$route.query.articleId;
- this.type = this.$route.query.type;
- if (this.type == "module") {
- this.showView = 1;
- }
- this.searchArticle();
- await this.initCategoryList();
- await this.initCurrentUser();
- let templateId = this.$route.query.templateId;
- if (templateId > 0) {
- this.loadTemplateInfo(templateId);
- }
- this.isAdmin = this.userInfo ? this.userInfo.roleInfo.is_admin : 2;
- this.initArticleCategoryList();
- if (this.type !== "module" && this.type !== "document") {
- document.title = "新建模版-" + settings.title;
- }
- if (
- this.type !== "module" &&
- this.type !== "document" &&
- this.articleId !== undefined
- ) {
- document.title = this.docAttr.title + settings.title;
- }
- this.$nextTick(() => {
- const arrows = document.querySelectorAll(".el-collapse-item__arrow");
- arrows.forEach((arrow) => {
- arrow.style.margin = "0";
- });
- });
- },
- methods: {
- handleItemVal(value) {
- this.$forceUpdate();
- this.loadChildren(value);
- },
- handleChildItemClick(child) {
- if (!child.children) {
- this.loadChildren(child);
- }
- },
- handleChildItemVal(value) {
- this.$forceUpdate();
- this.loadChildren(value);
- },
- handleGrandChildItemClick(grandChild) {
- if (!grandChild.children) {
- this.loadChildren(grandChild);
- }
- },
- handleGrandChildItemVal(value) {
- this.loadChildren(value);
- this.$forceUpdate();
- },
- handlegreatGrandChildItemVal(greatGrandChild) {
- this.loadChildren(greatGrandChild);
- this.$forceUpdate();
- },
- async loadChildren(category) {
- const category_id = category[category.length - 1];
- try {
- const res = await searchTemplateCategory({ parent_id: category_id });
- if (res.status != 200 || res.data.length == 0) return;
- const newChildren = res.data;
- for (let i = 0; i < newChildren.length; i++) {
- newChildren[i].dataList = await this.getTemplateList(
- newChildren[i].id
- );
- }
- this.insertChildrenById(this.categoryList, category_id, newChildren);
- console.log(this.categoryList);
- this.$forceUpdate(); // Force Vue to re-render the component
- } catch (error) {
- console.error("Error fetching template categories:", error);
- }
- },
- insertChildrenById(list, id, newChildren) {
- for (let item of list) {
- if (item.id === id) {
- this.$set(item, "children", newChildren); // Use Vue.set to ensure reactivity
- return true; // Stop searching once the item is found
- }
- if (item.children && item.children.length > 0) {
- const found = this.insertChildrenById(item.children, id, newChildren);
- if (found) return true; // Stop searching if the item is found in deeper levels
- }
- }
- return false; // Continue searching
- },
- /* 取消新增 */
- closeDoc() {
- this.docVisible = false;
- this.docForm = {
- title: "",
- category_id: "",
- };
- },
- /* 确定新增模块*/
- submitDoc() {
- this.$refs.docRef.validate((valid) => {
- if (valid) {
- this.docAttr.title = this.docForm.title;
- this.docAttr.category_id = this.docForm.category_id;
- this.onSave();
- }
- });
- },
- //加载文档分类
- initArticleCategoryList() {
- let _this = this;
- searchDocumentCategory({ page: 1, pageSize: 99, status: 5 }).then(
- (res) => {
- if (res.status != 200) return;
- _this.articleCategoryList = res.data.dataList;
- }
- );
- },
- updateAttrs(newComs, oldComs) {
- console.log(newComs);
- newComs.forEach((newCom, comIndex) => {
- const oldCom = oldComs[comIndex];
- if (oldCom) {
- newCom.attrs.forEach((newAttr, attrIndex) => {
- const oldAttr = oldCom.attrs[attrIndex];
- if (oldAttr && newAttr.content !== oldAttr.content) {
- // 内容发生变化,进行全局更新
- this.updateGlobalAttr(newAttr.name, newAttr.content);
- }
- });
- }
- });
- },
- updateGlobalAttr(attrId, newContent) {
- // 遍历所有组件,更新匹配的属性
- this.coms.forEach((com) => {
- com.attrs.forEach((attr) => {
- // 只更新非 variableNull 类型的属性
- if (attr.name === attrId && attr.type !== "variableNull") {
- attr.content = newContent;
- }
- });
- // 如果是文本区域,更新内容中的占位符
- if (com.type === "TextArea") {
- com.content = com.content.replace(
- new RegExp(`{{${attrId}}}`, "g"),
- (match) => {
- const attr = com.attrs.find((a) => a.id === attrId);
- if (attr && attr.type !== "variableNull") {
- return newContent;
- }
- return match; // 保留 variableNull 类型的原始占位符
- }
- );
- }
- });
- // 触发视图更新
- this.replaceData(this.coms);
- this.$forceUpdate();
- },
- async replaceData(data) {
- for (let item of this.coms) {
- for (let el of item.attrs) {
- let attrId = el.id;
- if (el.type === "formual") {
- try {
- let formual = await this.analysisFormual(el);
- formual = await this.getRemote(formual);
- el.content = eval(formual);
- } catch (error) {
- console.error("处理公式时出错:", error);
- }
- } else if (el.type === "variableNull") {
- // 保留 variableNull 类型的原始内容
- el.content = el.content || "请输入";
- }
- }
- }
- return data;
- },
- //分析公式
- async analysisFormual(attrs) {
- let _this = this;
- // console.log("开始分析公式:", attrs.formula);
- var pattern = /(\[.*?\]){3}/;
- var formual = attrs.formula;
- var reg = new RegExp(pattern);
- while (true) {
- var items = formual.match(reg);
- if (items == null) break;
- let itemName = items[0];
- // console.log("处理项:", itemName);
- try {
- let data = await _this.getFormualData(itemName);
- // console.log(`获取到的数据: ${itemName} = ${data}`);
- if (data === null || data === undefined || isNaN(data)) {
- console.warn(`获取到的数据无效: ${itemName}`);
- formual = formual.replace(itemName, "(0)");
- } else {
- formual = formual.replace(itemName, `(${parseFloat(data)})`);
- }
- } catch (error) {
- console.error(`处理 ${itemName} 时出错:`, error);
- formual = formual.replace(itemName, "(0)");
- }
- }
- // console.log("分析后的公式:", formual);
- return formual;
- },
- async getFormualData(formualItem) {
- let _this = this;
- // console.log("开始获取公式数据:", formualItem);
- var pattern = /\[(.*?)\]\[(.*?)\]\[(.*?)\]/;
- var reg = new RegExp(pattern);
- let items = formualItem.match(reg);
- // console.log("解析结果:", items);
- let calResult = 0;
- if (items && items[1] == "T") {
- calResult = await _this.getModuleData(items[2], items[3]);
- } else {
- console.warn("无法解析公式项:", formualItem);
- }
- // console.log("计算结果:", calResult);
- return calResult;
- },
- //获取本地文档模块数据
- async getModuleData(code, attrName) {
- let _this = this;
- // console.log(`尝试获取模块数据: code=${code}, attrName=${attrName}`);
- // console.log("当前 coms:", _this.coms);
- let item = _this.coms.filter((o) => o.name == code);
- // console.log(`找到的模块:`, item);
- if (item.length > 0) {
- let attr = item[0].attrs.filter((o) => o.name == attrName);
- // console.log(`找到的属性:`, attr);
- if (attr.length > 0) {
- // console.log(`返回的值:`, attr[0].content);
- return parseFloat(attr[0].content);
- }
- }
- // console.log("未找到匹配的模块或属性,返回 0");
- return 0;
- },
- async getRemote(formual) {
- let _this = this;
- var pattern = /\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]/;
- var reg = new RegExp(pattern);
- while (true) {
- let items = formual.match(reg);
- if (items == null) break;
- if (items[1] == "R") {
- //表示获取远程数据
- var dataIndex = items[4];
- dataIndex = items[4].split(",");
- let calResult = await _this.getRemoteData(
- items[2],
- items[3],
- dataIndex[0],
- dataIndex[1]
- );
- let itemName = items[0];
- // 检查calResult是否为数字
- if (!isNaN(calResult)) {
- formual = formual.replace(
- itemName,
- "(" + parseFloat(calResult) + ")"
- );
- } else {
- formual = formual.replace(itemName, `"${calResult}"`);
- }
- formual = formual.replace(
- itemName,
- "(" + parseFloat(calResult) + ")"
- );
- }
- }
- return formual;
- },
- async getRemoteData(code, sheet, row, col) {
- let _this = this;
- let result = 0;
- let par = {
- code: code,
- sheetName: sheet,
- row: row,
- col: col,
- };
- /* if (!this.isEditing) {
- this.loading = true;
- this.progress = 0;
- try {
- const updateProgress = setInterval(() => {
- if (this.progress < 90) {
- this.progress += 10;
- }
- }, 100);
- let res = await findData(par);
- if (res.status == 200) {
- result = res.data.result;
- }
- this.progress = 100;
- clearInterval(updateProgress);
- } catch (error) {
- console.error("Error fetching remote data:", error);
- } finally {
- setTimeout(() => {
- this.loading = false;
- this.progress = 0;
- }, 1000);
- }
- } else { */
- // 如果正在编辑,直接获取数据而不显示进度条
- try {
- let res = await findData(par);
- if (res.status == 200) {
- result = res.data.result;
- // 添加数据类型检查和转换
- if (typeof result === "string" && !isNaN(result)) {
- result = parseFloat(result);
- }
- }
- } catch (error) {
- console.error("获取远程数据错误:", error);
- }
- /* } */
- return result;
- },
- /*
- handleItemVal(value) {
- console.log(value);
- this.$forceUpdate();
- }, */
- async handleItemClick(item) {
- const category = this.categoryList.find((cat) => cat.id === item);
- if (!category) return;
- if (!category.children) {
- try {
- const res = await searchTemplateCategory({ parent_id: item });
- if (res.status != 200 || res.data.length == 0) return;
- category.children = res.data;
- for (let i = 0; i < category.children.length; i++) {
- category.children[i].dataList = await this.getTemplateList(
- category.children[i].id
- );
- }
- } catch (error) {
- console.error("Error fetching template categories:", error);
- }
- }
- // 触发视图更新
- this.$set(category, "activeChildren", category.activeChildren || []);
- },
- /* 切换标签 */
- viewDocument() {
- this.showView = 0;
- },
- viewModule() {
- this.showView = 1;
- },
- /* 更新变量 */
- /* uptadeVariable(value) {
- for (const item of this.coms) {
- for (const el of item.attrs) {
- if (el.type === "variable") {
- if (el.data.id == value.id) {
- el.content = value.value;
- el.data = value;
- }
- } else if (el.type === "constant") {
- if (el.data.id == value.id) {
- el.content = value.value;
- el.data = value;
- }
- }
- }
- }
- } */
- uptadeVariable(value) {
- const { id, value: newValue } = value;
- this.coms.forEach((item) => {
- item.attrs.forEach((el) => {
- if (
- (el.type === "variable" || el.type === "constant") &&
- el.data.id === id
- ) {
- el.content = newValue;
- el.data = value;
- }
- });
- });
- },
- /* 更新检索内容 */
- async uptadeSearch() {
- for (const item of this.coms) {
- for (const el of item.attrs) {
- if (el.type === "ai") {
- // await this.retrieval(el);
- }
- }
- }
- },
- /* 初始化检索 */
- async retrieval(el) {
- this.loading = true; // 开始加载动画
- try {
- const response = await axios.post(
- "http://58.246.234.210:7860/api/v1/run/3f84a841-cefd-44b3-9555-568cc3b6c2d2?stream=false",
- {
- input_value: el.search,
- output_type: "chat",
- input_type: "chat",
- tweaks: {
- "ChatInput-em6qC": {},
- "ParseData-yO3YQ": {},
- "Prompt-Wj75b": {},
- "ChatOutput-zy9na": {},
- "SplitText-O1knk": {},
- "File-4j6Zd": {},
- "OllamaEmbeddings-xbYXX": {},
- "Chroma-OIejP": {},
- "OllamaModel-04mEO": {},
- "OllamaEmbeddings-UGvLP": {},
- "Chroma-HzukO": {},
- },
- },
- {
- headers: {
- "Content-Type": "application/json",
- },
- }
- );
- if (response.status === 200) {
- // 假设返回的数据在 response.data.outputs[0].outputs[0].results.message.data.text 中
- const resultText =
- response.data.outputs[0].outputs[0].results.message.data.text;
- // 将搜索词和生成的内容存储在 searchResult 对象中
- el.content = resultText; // 重新赋值给原数组的对应 content
- }
- } catch (error) {
- console.error("Error during retrieval:", error);
- this.$message.error("检索失败,请稍后重试");
- } finally {
- this.loading = false; // 结束加载动画
- }
- },
- async loadTemplateInfo(id) {
- try {
- // 获取模板信息
- const { data } = await getTemplateInfo({ id });
- // 设置默认值
- if (!data.attrs || !data.type) {
- Object.assign(data, {
- attrs: "[]",
- content: "请填写内容",
- lay_id: "textArea",
- type: "TextArea",
- });
- }
- // 设置文档标题
- document.title = data.name
- ? `${data.name}-${settings.title}`
- : "新建模块-" + settings.title;
- // 解析属性
- data.attrs = JSON.parse(data.attrs);
- // 获取公式并更新属性
- const {
- data: { dataList },
- } = await searchFormula({ page: 1, pageSize: 999 });
- console.log(data);
- data.attrs = data.attrs.map((item) => {
- const formula = dataList.find((el) => el.id === item.id);
- return formula
- ? { ...item, formula: formula.formula, data: formula }
- : item;
- });
- // 从 content 中提取 {{}} 包裹的 ID
- const contentIds = (data.content.match(/{{([^}]+)}}/g) || []).map(
- (match) => match.slice(2, -2).trim()
- );
- // 过滤 attrs,只保留在 content 中出现的 ID
- data.attrs = data.attrs.filter((item) => contentIds.includes(item.id));
- this.coms = [data];
- } catch (error) {
- console.error("加载模板信息失败:", error);
- }
- },
- onExport(e) {
- let _this = this;
- _this.comIndex = -1;
- let content = _this.$refs.tabHtml.innerHTML;
- },
- onOpenView(e) {
- console.log("this.coms", this.coms);
- this.showViewForm = true;
- },
- onClose() {
- /* this.$router.back(); */
- window.close();
- },
- loadArticle(e) {
- let _this = this;
- _this.onLoadArticle(e);
- /* getDocumentInfo({
- id: e,
- }).then((res) => {
- if (res.status != 200) return;
- _this.onLoadArticle(res.data);
- }); */
- },
- handleDragStart(e) {
- let data = {};
- if (e.target.dataset.type == "article") {
- let index = e.target.dataset.index;
- data = {
- optType: e.target.dataset.type,
- item: this.articleList[index],
- };
- } else {
- let index = e.target.dataset.index;
- let subIndex = e.target.dataset.subIndex;
- let item = this.categoryList[index].dataList[subIndex];
- delete item.category;
- data = {
- ...item,
- optType: e.target.dataset.type,
- key: "addNew",
- attrs: JSON.parse(item.attrs),
- };
- }
- e.dataTransfer.setData("item", JSON.stringify(data));
- this.operation = "drag";
- },
- onRebuild(updatedComList) {
- this.coms = [...updatedComList];
- this.$nextTick(() => {
- this.$forceUpdate();
- });
- },
- //初始化当前用户信息
- async initCurrentUser() {
- let _this = this;
- let res = await getCurrentUserInfo();
- if (res.status != 200) return;
- _this.userInfo = res.data;
- },
- //加载文档信息
- async onLoadArticle(id) {
- try {
- this.loading = true;
- const res = await getDocumentInfo({ id });
- if (res.status !== 200) {
- throw new Error("Invalid response status");
- }
- this.docAttr = {
- id: res.data.id,
- category_id: Number(res.data.category_id),
- title: res.data.title,
- content: "",
- status: res.data.status,
- is_template: res.data.is_template,
- linkProduct: res.data.linkProduct,
- links: res.data.links,
- linkProject: res.data.linkProject,
- projects: res.data.projects,
- };
- const templateData =
- typeof res.data.data === "string"
- ? JSON.parse(res.data.data)
- : res.data.data;
- const updatedComs = await Promise.all(
- templateData.map(async (el) => {
- /* let templateInfo = { data: {} };
- if (this.type !== "document") {
- templateInfo = await getTemplateInfo({ id: el.id });
- } */
- const formulaData = await searchFormula({ page: 1, pageSize: 999 });
- const attrs = el.attrs;
- /* typeof templateInfo.data.attrs === "string"
- ? JSON.parse(templateInfo.data.attrs)
- : templateInfo.data.attrs || []; // Add a fallback empty array */
- attrs.forEach((item) => {
- if (item && item.data && item.data.id) {
- const matchedFormula = formulaData.data.dataList.find(
- (ite) => ite.id === item.data.id
- );
- if (matchedFormula) {
- item.data = matchedFormula;
- item.formula = matchedFormula.formula;
- }
- }
- });
- return { ...el /* , ...templateInfo.data, attrs */ };
- })
- );
- this.coms = updatedComs;
- console.log("coms", updatedComs);
- if (this.type === "document" && this.articleId !== undefined) {
- document.title = `${this.docAttr.title}-${settings.title}`;
- }
- this.uptadeSearch();
- } catch (error) {
- console.error("Error in onLoadArticle:", error);
- } finally {
- this.loading = false;
- }
- },
- /* 加载模版信息 */
- async onTemplateInfo(id) {
- try {
- this.loading = true;
- // 获取文档信息
- const res = await getDocumentInfo({ id });
- if (res.status !== 200 || !res.data) {
- throw new Error("无效的响应或未收到数据");
- }
- // 设置文档属性
- this.docAttr = {
- id: this.docAttr.id,
- category_id: Number(this.docAttr.category_id),
- title: res.data.title,
- content: "",
- status: res.data.status,
- is_template: res.data.is_template,
- linkProduct: res.data.linkProduct || [],
- links: res.data.links || "",
- linkProject: res.data.linkProject || [],
- projects: res.data.projects || "",
- document_type: res.data.document_type || "",
- };
- // 解析文档数据
- const documentData = res.data.data ? JSON.parse(res.data.data) : [];
- const updatedComs = await Promise.all(
- documentData.map(async (docEl) => {
- if (!docEl || !docEl.id) {
- console.warn("无效的文档项:", docEl);
- return null;
- }
- // 获取模板信息
- const templateInfo = await getTemplateInfo({ id: docEl.id });
- // 获取公式数据
- const formulaData = await searchFormula({ page: 1, pageSize: 999 });
- // 使用模板的 content 作为基础
- let content = templateInfo.data.content;
- // 使用模板的 attrs 作为基础,但排除 Directory 类型
- let attrs = templateInfo.data.attrs
- ? JSON.parse(templateInfo.data.attrs).filter(
- (attr) => attr.type !== "Directory"
- )
- : [];
- // 从文档数据中提取所有 Directory 类型的属性
- const docDirectories = docEl.attrs.filter(
- (attr) => attr.type === "Directory"
- );
- // 将文档中的 Directory 属性添加到 attrs 中
- attrs = [...attrs, ...docDirectories];
- // 解析 content 中的所有项
- const contentItems = (content.match(/{{([^}]+)}}/g) || []).map(
- (match) => match.slice(2, -2)
- );
- console.log("contentItems", contentItems);
- // 确保 content 中引用的所有 Directory 项都存在于 attrs 中
- contentItems.forEach((itemId) => {
- if (
- itemId.startsWith("Directory_") &&
- !attrs.some((attr) => attr.id === itemId)
- ) {
- const [, moduleIndex, level] = itemId.split("_");
- attrs.push({
- type: "Directory",
- id: itemId,
- name: "目录信息",
- intro: "目录信息",
- number: "",
- content: "",
- level: parseInt(level),
- moduleIndex: parseInt(moduleIndex),
- });
- }
- });
- // 更新公式数据
- attrs = attrs.map((item) => {
- if (item.type === "formual" && item.data && item.data.id) {
- const matchedFormula = formulaData.data.dataList.find(
- (ite) => ite.id === item.data.id
- );
- if (matchedFormula) {
- return {
- ...item,
- data: matchedFormula,
- formula: matchedFormula.formula,
- };
- }
- }
- return item;
- });
- // 返回更新后的数据,以模板信息为主,但 Directory 项完全使用文档信息
- return { ...templateInfo.data, attrs, content };
- })
- );
- // 过滤掉无效的组件
- this.coms = updatedComs.filter(Boolean);
- console.log("组件", this.coms);
- console.log("模版", this.docAttr);
- if (this.articleId !== undefined) {
- document.title = `${this.docAttr.title}-${settings.title}`;
- }
- this.uptadeSearch();
- } catch (error) {
- console.error("加载模板信息时出错:", error);
- this.$message.error("加载模板信息时出错,请稍后重试");
- } finally {
- this.loading = false;
- }
- },
- onRemove(index) {
- this.coms.splice(index, 1);
- },
- /* 目录信息 */
- onCatalogIndex(e) {
- this.catalogIndex = e;
- if (
- (this.docuComIndex =
- 3 || this.comIndex == 9998 || this.AttributeIndex == 1)
- ) {
- this.comIndex = 0;
- this.AttributeIndex = 0;
- this.docuComIndex = 0;
- }
- this.$nextTick(() => {
- this.$forceUpdate();
- });
- },
- onSetActiveIndexs(e) {
- this.docuComIndex = e;
- if (
- this.AttributeIndex == 1 ||
- this.comIndex == 9998 ||
- this.catalogIndex == 9997
- ) {
- this.catalogIndex = 0;
- this.AttributeIndex = 0;
- this.comIndex = 0;
- }
- },
- //设置当前索引
- onSetActiveIndex(e) {
- this.comIndex = e;
- if (
- this.AttributeIndex == 1 ||
- this.docuComIndex == 3 ||
- this.catalogIndex == 9997
- ) {
- this.catalogIndex = 0;
- this.docuComIndex = 0;
- }
- },
- /* 属性变量 */
- onAttributeIndex(e) {
- this.AttributeIndex = e;
- if (
- (this.docuComIndex =
- 3 || this.comIndex == 9998 || this.catalogIndex == 9997)
- ) {
- this.catalogIndex = 0;
- this.comIndex = 0;
- this.docuComIndex = 0;
- }
- },
- /* 更新 */
- renew() {
- let _this = this;
- _this.docVisible = true;
- this.docForm.title = _this.docAttr.title;
- this.docForm.category_id = _this.docAttr.category_id;
- },
- /* 保存 */
- onSaveAs(e) {
- let _this = this;
- if (_this.coms.length <= 0) {
- _this.$alert("请填写内容");
- return;
- }
- _this.docAttr.id = "";
- _this.docVisible = true;
- this.docForm.title = _this.docAttr.title;
- this.docForm.category_id = _this.docAttr.category_id;
- },
- //保存文档
- onSave(e) {
- let _this = this;
- if (_this.coms.length <= 0) {
- _this.$alert("增加组件");
- return;
- }
- if (_this.docAttr.category_id == "" || _this.docAttr.category_id <= 0) {
- _this.$alert("请选择文档分类");
- return;
- }
- if (_this.docAttr.title == "") {
- _this.$alert("请填写文档标题");
- return;
- }
- _this.docAttr.links = JSON.stringify(_this.docAttr.linkProduct);
- _this.docAttr.projects = JSON.stringify(_this.docAttr.linkProject);
- _this.docAttr.data = JSON.stringify(_this.coms);
- _this.docAttr.is_template = 0;
- _this.docAttr.user_name = _this.$store.state.user.name;
- _this.docAttr.user_id = _this.$store.state.user.id;
- if (_this.docAttr.id > 0) {
- updateDocument(_this.docAttr).then((res) => {
- if (res.status != 200) return; //更新文档
- _this.docAttr.id = res.data;
- _this.$alert("文档更新成功");
- _this.docVisible = false;
- _this.docForm = {
- title: "",
- category_id: "",
- };
- _this.searchArticle();
- });
- } else {
- createDocument(_this.docAttr).then((res) => {
- if (res.status != 200) return; //保存文档
- _this.docAttr.id = res.data;
- _this.articleId = res.data;
- _this.$alert("文档保存成功");
- _this.docVisible = false;
- _this.docForm = {
- title: "",
- category_id: "",
- };
- _this.searchArticle();
- });
- }
- },
- /*更新 */
- onUpload() {
- let _this = this;
- if (_this.coms.length <= 0) {
- _this.$alert("增加组件");
- return;
- }
- if (_this.docAttr.document_type == "") {
- _this.$alert("请选择分类");
- return;
- }
- if (_this.docAttr.title == "") {
- _this.$alert("请填写模版标题");
- return;
- }
- _this.docAttr.links = JSON.stringify(_this.docAttr.linkProduct);
- _this.docAttr.projects = JSON.stringify(_this.docAttr.linkProject);
- _this.docAttr.data = JSON.stringify(_this.coms);
- _this.docAttr.is_template = 1;
- _this.docAttr.id = this.$route.query.articleId;
- _this.docAttr.user_name = _this.$store.state.user.name;
- _this.docAttr.user_id = _this.$store.state.user.id;
- updateDocument(_this.docAttr).then((res) => {
- if (res.status != 200) return; //更新文档
- _this.docAttr.id = res.data;
- _this.$alert("模版更新成功");
- _this.searchArticle();
- });
- },
- /* 保存并更新模版 */
- onSaveUpload(e) {
- let _this = this;
- if (_this.coms.length <= 0) {
- _this.$alert("增加组件");
- return;
- }
- if (_this.docAttr.document_type == "") {
- _this.$alert("请选择分类");
- return;
- }
- if (_this.docAttr.title == "") {
- _this.$alert("请填写模版标题");
- return;
- }
- _this.docAttr.links = JSON.stringify(_this.docAttr.linkProduct);
- _this.docAttr.projects = JSON.stringify(_this.docAttr.linkProject);
- _this.docAttr.data = JSON.stringify(_this.coms);
- _this.docAttr.is_template = 1;
- _this.docAttr.user_name = _this.$store.state.user.name;
- _this.docAttr.user_id = _this.$store.state.user.id;
- /* if (_this.docAttr.id > 0) {
- updateDocument(_this.docAttr).then((res) => {
- if (res.status != 200) return; //更新文档
- _this.docAttr.id = res.data;
- _this.$alert("模版更新成功");
- _this.searchArticle();
- });
- } else { */
- createDocument(_this.docAttr).then((res) => {
- if (res.status != 200) return; //保存文档
- _this.docAttr.id = res.data;
- _this.articleId = res.data;
- _this.$alert("模版保存成功");
- _this.searchArticle();
- });
- /* } */
- },
- //设置组件值
- onSetComs(e) {
- let _this = this;
- _this.coms = [...e];
- },
- onAddLayer(cateIndex, dataIndex) {
- let _this = this;
- let item = _this.categoryList[cateIndex].dataList[dataIndex];
- let data = {
- ...item,
- attrs: JSON.parse(item.attrs),
- };
- delete data.category;
- _this.coms.push(data);
- _this.comIndex = _this.coms.length - 1;
- },
- //处理插入事件
- onInsert(e) {
- let _this = this;
- switch (e.key) {
- case "article": //插入图文
- _this.insertArticle();
- break;
- case "table": //插入图表
- _this.insertTable();
- break;
- case "sourceData": //插入原数据
- _this.insertSourceData(e);
- break;
- case "formual": //插入公式
- _this.insertFormual(e);
- break;
- case "constant": //插入常量
- _this.insertConstant(e);
- break;
- case "variable": //插入变量
- _this.insertVariable(e);
- break;
- case "pager": //插入分页符
- _this.insertPager();
- break;
- case "attr":
- this.insertProductAttr();
- break;
- case "Directory": //插入主题
- _this.insertDirectory(e);
- break;
- case "addNew": //插入新记录
- _this.insertNew(e);
- break;
- case "InsertNull":
- _this.insertVal();
- break;
- case "ai": //插入ai
- _this.insertAI(e);
- break;
- }
- },
- /* 插入空值 */
- insertVal() {
- let _this = this;
- if (_this.comIndex < 0) {
- _this.$alert("请选择插入图层");
- return false;
- }
- let com = _this.coms[_this.comIndex];
- let uniqueId = "val" + Date.now(); // 使用时间戳创建唯一ID
- let data = {
- type: "variableNull",
- id: uniqueId,
- dataId: "",
- name: "非变量",
- intro: "",
- content: "请输入",
- data: "",
- };
- com.attrs.push(data);
- if (com.type == "TextArea") {
- //如果是图文,更新内容
- _this.insertCmd = {
- content: "{{" + data.id + "}}",
- };
- } else {
- //仅对图表中插入有效
- if (_this.comIndex >= 0) {
- _this.setTableData(data.id);
- }
- }
- },
- /* 插入ai */
- insertAI(e) {
- let _this = this;
- if (_this.comIndex < 0) {
- _this.$alert("请选择插入图层");
- return false;
- }
- let com = _this.coms[_this.comIndex];
- let data = {
- type: "ai",
- id: "ai" + (com.attrs.length + 1),
- dataId: "",
- name: "AI",
- intro: "插入AI",
- content: e.content.result,
- search: e.content.searchTerm,
- };
- com.attrs.push(data);
- if (com.type == "TextArea") {
- //如果是图文,更新内容
- _this.insertCmd = {
- content: "{{" + data.id + "}}",
- };
- }
- },
- insertProductAttr() {
- if (this.docAttr.linkProduct.length <= 0) {
- this.$alert("请选择文档关联商品信息");
- return false;
- }
- this.showProductAttr = true;
- },
- //插入目录
- insertDirectory(e) {
- let _this = this;
- if (_this.comIndex < 0) {
- _this.$alert("请选择插入图层");
- return false;
- }
- let com = _this.coms[_this.comIndex];
- let uniqueId = `Directory_${_this.comIndex}_${com.attrs.length + 1}`;
- // 获取当前层级
- let currentLevel = e.content.level || 1;
- // 生成带有模块索引和层级的内容
- let { number, content } = this.generateNumberedContent(
- _this.comIndex,
- currentLevel
- );
- let data = {
- type: "Directory",
- id: uniqueId,
- name: "目录信息",
- intro: "目录信息",
- number: number,
- content: content,
- level: currentLevel,
- moduleIndex: _this.comIndex,
- };
- // 使用 $set 来确保响应式更新
- this.$set(com.attrs, com.attrs.length, data);
- // 强制更新视图
- this.$forceUpdate();
- // 使用 nextTick 确保 DOM 更新后再检查
- this.$nextTick(() => {
- if (!com.attrs[com.attrs.length - 1].content) {
- this.$set(com.attrs[com.attrs.length - 1], "content", content);
- this.$forceUpdate();
- }
- });
- // 使用新的唯一 ID 在插入命令中
- _this.insertCmd = {
- content: `{{${uniqueId}}}`,
- };
- },
- generateNumberedContent(moduleIndex, level) {
- let number = this.generateLevelPrefix(moduleIndex, level);
- let content = this.coms[moduleIndex].type === "TextArea" ? "" : "";
- return { number, content };
- },
- generateLevelPrefix(moduleIndex, level) {
- let prefix = [];
- let currentModule = this.coms[moduleIndex];
- // 获取当前模块中已存在的目录项
- let existingDirectories = currentModule.attrs.filter(
- (attr) => attr.type === "Directory"
- );
- // 计算当前层级的序号
- let currentLevelCount =
- existingDirectories.filter((dir) => dir.level === level).length + 1;
- // 构建多级序号
- for (let i = 1; i <= level; i++) {
- if (i === 1) {
- prefix.push(moduleIndex + 1);
- } else if (i === level) {
- prefix.push(currentLevelCount);
- } else {
- // 对于中间层级,找到最近的上级目录项
- let parentLevel = existingDirectories
- .filter((dir) => dir.level === i - 1)
- .pop();
- prefix.push(parentLevel ? parentLevel.number.split(".")[i - 1] : 1);
- }
- }
- return prefix.join(".");
- },
- onInsertProductAttr(e) {
- let _this = this;
- this.showProductAttr = false;
- if (_this.comIndex < 0) {
- _this.$alert("请选择插入图层");
- return false;
- }
- let com = _this.coms[_this.comIndex];
- let data = {
- type: "ProductAttr",
- id: "ProductAttr" + (com.attrs.length + 1),
- dataId: e.id,
- name: "商品属性",
- intor: "商品属性",
- content: "",
- attrs: e,
- };
- com.attrs.push(data);
- _this.insertCmd = {
- content: "{{" + data.id + "}}",
- };
- },
- //插入新记录
- insertNew(e) {
- let _this = this;
- _this.coms.push(e);
- },
- //插入分页
- insertPager() {
- let _this = this;
- if (_this.comIndex < 0) {
- _this.$alert("请选择插入图层");
- return false;
- }
- let com = _this.coms[_this.comIndex];
- let data = {
- type: "pager",
- id: "pager" + (com.attrs.length + 1),
- name: "分页符",
- intor: "强制分页",
- content: "",
- };
- com.attrs.push(data);
- if (com.type == "TextArea") {
- //如果是图文,更新内容
- _this.insertCmd = {
- content: "<div>{{" + data.id + "}}</div>",
- };
- }
- },
- //插入图文
- insertArticle() {
- /* let _this = this;
- _this.coms.push({
- type: "TextArea",
- lay_id: "textArea",
- code: "模块名",
- name: "图文",
- intro: "图文介绍",
- isEdit: 2,
- content: "请填写内容",
- attrs: [],
- });
- _this.comIndex = _this.coms.length - 1; */
- let _this = this;
- let newArticle = {
- type: "TextArea",
- lay_id: "textArea",
- code: "模块名",
- name: "图文",
- intro: "图文介绍",
- isEdit: 2,
- content: "请填写内容",
- attrs: [],
- };
- _this.coms.push(newArticle);
- _this.comIndex = _this.coms.length - 1;
- // 添加一些日志来帮助调试
- console.log("New article added:", newArticle);
- console.log("Current coms:", _this.coms);
- console.log("New comIndex:", _this.comIndex);
- },
- //插入表格
- insertTable() {
- let _this = this;
- _this.coms.push({
- type: "Table",
- lay_id: "Table",
- code: "模块名",
- name: "图表名称",
- intro: "图表介绍",
- isEdit: 2,
- tableHeader: this.initTableHeader(),
- tableData: [{}],
- htmlData: "",
- attrs: [],
- });
- _this.comIndex = _this.coms.length - 1;
- },
- initTableHeader() {
- var start = 65;
- var data = [];
- for (var i = start; i <= start + 25; i++) {
- data.push(String.fromCharCode(i));
- }
- return data;
- },
- //插入变量
- insertConstant(e) {
- let _this = this;
- // console.log("insertconstant");
- if (_this.comIndex < 0) {
- _this.$alert("请选择插入图层");
- return false;
- }
- let com = _this.coms[_this.comIndex];
- let data = {
- type: "constant",
- id: e.content.code + (com.attrs.length + 1),
- dataId: e.id,
- name: e.content.code,
- intro: e.content.intro,
- content: e.content.value,
- data: e.content,
- };
- com.attrs.push(data);
- if (com.type == "TextArea") {
- //如果是图文,更新内容
- _this.insertCmd = {
- content: "{{" + data.id + "}}",
- };
- } else {
- //仅对图表中插入有效
- if (_this.comIndex >= 0) {
- _this.setTableData(data.id);
- }
- }
- },
- //插入变量
- insertVariable(e) {
- let _this = this;
- if (_this.comIndex < 0) {
- _this.$alert("请选择插入图层");
- return false;
- }
- let com = _this.coms[_this.comIndex];
- let data = {
- type: "variable",
- id: e.content.code + (com.attrs.length + 1),
- dataId: e.id,
- name: e.content.code,
- intro: e.content.intro,
- content: e.content.value,
- data: e.content,
- };
- com.attrs.push(data);
- if (com.type == "TextArea") {
- //如果是图文,更新内容
- _this.insertCmd = {
- content: "{{" + data.id + "}}",
- };
- } else {
- //仅对图表中插入有效
- if (_this.comIndex >= 0) {
- _this.setTableData(data.id);
- }
- }
- },
- //插入原数据
- insertSourceData(e) {
- let _this = this;
- if (_this.comIndex < 0) {
- _this.$alert("请选择插入图层");
- return false;
- }
- let com = _this.coms[_this.comIndex];
- let data = {
- type: "sourceData",
- id: "sourceData" + (com.attrs.length + 1),
- dataId: "",
- name: "源数据",
- intro: "插入源数据",
- formula:
- "[R][" +
- e.content.tb +
- "][" +
- e.content.sheet +
- "][" +
- e.content.r +
- "," +
- e.content.c +
- "]",
- content: e.content.value,
- data: e.content,
- };
- com.attrs.push(data);
- if (com.type == "TextArea") {
- //如果是图文,更新内容
- _this.insertCmd = {
- content: "{{" + data.id + "}}",
- };
- }
- },
- //插入公式
- insertFormual(e) {
- let _this = this;
- if (_this.comIndex < 0) {
- _this.$alert("请选择插入图层");
- return false;
- }
- let com = _this.coms[_this.comIndex];
- let data = {
- type: "formual",
- id: "formual" + (com.attrs.length + 1),
- dataId: e.id,
- name: e.content.name,
- intro: e.content.intro,
- formula: e.content.formula,
- content: 0,
- data: e.content,
- };
- com.attrs.push(data);
- if (com.type == "TextArea") {
- //如果是图文,更新内容
- _this.insertCmd = {
- content: "{{" + data.id + "}}",
- };
- } else {
- //仅对图表中插入有效
- if (_this.comIndex >= 0) {
- _this.setTableData(data.id);
- }
- }
- },
- //获取模版分类信息
- async initCategoryList() {
- let _this = this;
- /* let res = await getAllCategory({list:1 });
- if(res.status!=200)return;
- let dataList=res.data;
- for(var i=0;i<dataList.length;i++){
- for (var j=0;j<dataList[i].children.length;j++){
- let dataId=dataList[i].children[j].id;
- for(var k=0;k<dataList[i].children[j].dataList.length;k++){
- dataList[i].children[j].dataList[k].attrs=JSON.parse(dataList[i].children[j].dataList[k].attrs)
- }
- // dataList[i].children[j].dataList=await _this.getTemplateList(dataId)
- }
- }
- // console.log("dataList",dataList)
- _this.categoryList=dataList; */
- let res = await searchTemplateCategory({
- page: 1,
- pageSize: 99,
- parent_id: 0,
- status: 5,
- });
- if (res.status != 200) return;
- _this.categoryList = res.data.dataList;
- for (var i = 0; i < _this.categoryList.length; i++) {
- _this.categoryList[i].dataList = await _this.getTemplateList(
- _this.categoryList[i].id
- );
- }
- },
- //获取模版列表
- async getTemplateList(categoryId) {
- let _this = this;
- let res = await searchTemplate({
- page: 1,
- pageSize: 999,
- category_id: categoryId,
- status: 5,
- });
- if (res.status != 200) return [];
- let dataList = res.data.dataList.map((item) => {
- // 添加空值检查
- if (!item.attrs) {
- item.attrs = "[]";
- }
- if (!item.content) {
- item.content = "";
- }
- try {
- // 解析 attrs,添加错误处理
- item.attrs =
- typeof item.attrs === "string"
- ? JSON.parse(item.attrs)
- : item.attrs;
- // 从 content 中提取所有 {{}} 包裹的 ID,添加空值检查
- const contentIds = (
- (item.content || "").match(/{{([^}]+)}}/g) || []
- ).map((match) => match.slice(2, -2).trim());
- // 确保 attrs 是数组
- item.attrs = Array.isArray(item.attrs) ? item.attrs : [];
- // 过滤 attrs,只保留在 content 中出现的 ID
- item.attrs = item.attrs.filter(
- (attr) => attr && attr.id && contentIds.includes(attr.id)
- );
- } catch (error) {
- console.error("Error processing template item:", error);
- item.attrs = [];
- }
- return item;
- });
- return dataList;
- },
- //获取文档列表
- searchArticle() {
- let _this = this;
- pageDocument({
- page: 1,
- pageSize: 99,
- }).then((res) => {
- if (res.status != 200) return;
- _this.articleList = res.data.dataList.filter(
- (el) => el.is_template == 0
- );
- _this.templateList = res.data.dataList.filter(
- (el) => el.is_template == 1
- );
- });
- },
- },
- };
- </script>
- <style lang="scss">
- @import "./create.scss";
- .el-collapse,
- .el-collapse-item__wrap {
- border: none;
- }
- .el-collapse,
- .el-collapse-item__header {
- border: none;
- .el-collapse-item__arrow {
- margin: 0;
- }
- }
- .borderless-collapse {
- border: none;
- ::v-deep .el-collapse-item__header,
- ::v-deep .el-collapse-item__wrap,
- ::v-deep .el-collapse-item__content,
- ::v-deep .el-collapse-item {
- border: none;
- }
- ::v-deep .el-collapse-item__wrap {
- border-bottom: none !important;
- }
- }
- .scrollable-container {
- overflow-x: auto;
- white-space: nowrap;
- width: 350px;
- padding-bottom: 10px;
- }
- .min-width-content {
- /* display: inline-block;
- vertical-align: top; */
- min-width: 150px;
- white-space: normal;
- }
- /*.el-collapse-item {
- display: inline-block;
- vertical-align: top;
- } */
- </style>
|