| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944 |
- <template>
- <div class="supervision-content-container">
- <!-- 搜索表单 -->
- <div class="search-panel">
- <el-form :inline="true" :model="searchForm" class="search-form">
- <el-form-item label="监审类别:">
- <el-cascader
- v-model="searchForm.catalogId"
- :options="catalogListOptions"
- placeholder=" 请选择监审类别"
- v-bind="props"
- style="width: 100%"
- clearable
- ></el-cascader>
- </el-form-item>
- <el-form-item label="模板名称:">
- <el-input
- v-model="searchForm.keyword"
- placeholder="请输入模板名称"
- clearable
- ></el-input>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" icon="el-icon-search" @click="handleSearch">
- 搜索
- </el-button>
- <el-button
- plain
- type="primary"
- icon="el-icon-refresh"
- @click="handleReset"
- >
- 重置
- </el-button>
- </el-form-item>
- </el-form>
- </div>
- <!-- 操作按钮 -->
- <div class="operation-bar">
- <el-button
- v-region-permission="{
- category: 'costVerifyManage',
- action: 'add',
- }"
- plain
- type="success"
- icon="el-icon-circle-plus"
- @click="handleAdd"
- >
- <!-- v-region-permission="{
- category: 'costVerifyManage',
- action: 'add',
- }" -->
- 添加
- </el-button>
- <el-button
- v-region-permission="{
- category: 'costVerifyManage',
- action: 'delete',
- }"
- plain
- type="danger"
- icon="el-icon-delete"
- :disabled="selectedRows.length === 0"
- @click="handleBatchDelete"
- >
- 删除
- </el-button>
- </div>
- <!-- 表格 -->
- <div class="table-container">
- <el-table
- v-loading="loading"
- :data="tableData"
- border
- style="width: 100%"
- :default-sort="{ prop: 'createTime', order: 'descending' }"
- @selection-change="handleSelectionChange"
- >
- <!-- :default-sort="{ prop: 'createTime', order: 'descending' }" -->
- <el-table-column
- type="selection"
- width="55"
- align="center"
- show-overflow-tooltip
- ></el-table-column>
- <el-table-column
- type="index"
- label="序号"
- width="60"
- align="center"
- show-overflow-tooltip
- ></el-table-column>
- <el-table-column
- prop="catalogId"
- label="监审类别"
- align="center"
- show-overflow-tooltip
- >
- <template slot-scope="scope">
- <div>{{ getCatalogNames(scope.row) }}</div>
- </template>
- </el-table-column>
- <el-table-column
- prop="surveyTemplateName"
- label="核定模板名称"
- show-overflow-tooltip
- align="center"
- ></el-table-column>
- <el-table-column
- prop="versionNo"
- label="版本号"
- align="center"
- width="150"
- ></el-table-column>
- <el-table-column
- prop="status"
- label="状态"
- width="100"
- show-overflow-tooltip
- align="center"
- >
- <template slot-scope="scope">
- <span>
- {{
- scope.row.status == '-1'
- ? '草稿'
- : scope.row.status == '0'
- ? '启用'
- : '停用'
- }}
- </span>
- </template>
- </el-table-column>
- <el-table-column
- prop="createBy"
- label="创建人"
- width="120"
- show-overflow-tooltip
- align="center"
- ></el-table-column>
- <el-table-column
- prop="createTime"
- label="创建时间"
- width="160"
- show-overflow-tooltip
- align="center"
- sortable
- >
- <!-- sortable -->
- <template slot-scope="scope">
- <div>{{ scope.row.createTime.split(' ')[0] }}</div>
- <div>{{ scope.row.createTime.split(' ')[1] }}</div>
- </template>
- </el-table-column>
- <el-table-column
- label="操作"
- width="240"
- fixed="right"
- show-overflow-tooltip
- align="center"
- >
- <template slot-scope="scope">
- <el-button
- v-region-permission="{
- category: 'costVerifyManage',
- action: 'view',
- }"
- type="text"
- size="mini"
- @click="handleViewDetail(scope.row)"
- >
- 查看
- </el-button>
- <el-button
- v-if="scope.row.status != '0'"
- v-region-permission="{
- category: 'costVerifyManage',
- action: 'edit',
- targetData: scope.row,
- }"
- type="text"
- size="mini"
- @click="handleEdit(scope.row)"
- >
- 修改
- </el-button>
- <el-button
- v-region-permission="{
- category: 'costVerifyManage',
- action: 'edit',
- targetData: scope.row,
- }"
- type="text"
- size="mini"
- @click="handleStatusChange(scope.row)"
- >
- <!-- (-1草稿,0启用,1停用) -->
- {{ scope.row.status == '0' ? '停用' : '启用' }}
- </el-button>
- <el-button
- v-if="scope.row.status != '0'"
- v-region-permission="{
- category: 'costVerifyManage',
- action: 'delete',
- targetData: scope.row,
- }"
- type="text"
- size="mini"
- @click="handleDeleteRow(scope.row)"
- >
- 删除
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <el-pagination
- class="mt20"
- :current-page.sync="searchForm.page"
- :page-size="searchForm.pageSize"
- :page-sizes="[50, 100]"
- layout="total, sizes, prev, pager, next, jumper"
- :total="pagination.total"
- @current-change="handleCurrentChange"
- @size-change="handleSizeChange"
- ></el-pagination>
- </div>
- <!-- 添加/修改弹窗 -->
- <el-dialog
- :title="dialogTitle"
- :visible.sync="dialogVisible"
- width="75%"
- :close-on-click-modal="false"
- >
- <el-form
- ref="contentEditForm"
- :model="contentEditForm"
- :rules="contentEditFormRules"
- label-width="220px"
- class="content-form"
- :disabled="dialogTitle == '查看成本核定模板'"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="监审类别:" prop="catalogId">
- <el-cascader
- v-model="contentEditForm.catalogId"
- :options="catalogListOptions"
- v-bind="props"
- style="width: 100%"
- ></el-cascader>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="核定模板名称:" prop="surveyTemplateName">
- <el-input
- v-model="contentEditForm.surveyTemplateName"
- placeholder="请输入核定模板名称"
- ></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="" prop="createtemplateid">
- <!-- :disabled="dialogTitle == '修改成本核定模板'" -->
- <template slot="label">
- <el-radio
- v-model="contentEditForm.createmode"
- label="1"
- :disabled="
- dialogTitle == '查看成本核定模板' ||
- dialogTitle == '修改成本核定模板' ||
- contentEditForm.surveyTemplateId != ''
- "
- @change="handleCreateModeChange"
- >
- 根据调查表生成:
- </el-radio>
- </template>
- <el-select
- v-model="contentEditForm.createtemplateid"
- placeholder="请选择"
- :disabled="
- dialogTitle == '查看成本核定模板' ||
- dialogTitle == '修改成本核定模板' ||
- contentEditForm.surveyTemplateId != ''
- "
- >
- <el-option
- v-for="item in surveyFormList"
- :key="item.id"
- :label="item.surveyTemplateName"
- :value="item.surveyTemplateId"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="" prop="">
- <template slot="label">
- <el-radio
- v-model="contentEditForm.createmode"
- label="2"
- :disabled="
- dialogTitle == '查看成本核定模板' ||
- dialogTitle == '修改成本核定模板' ||
- contentEditForm.surveyTemplateId != ''
- "
- @change="handleCreateModeChange"
- >
- 根据历史核定模板生成:
- </el-radio>
- </template>
- <el-select
- v-model="contentEditForm.createtemplateid1"
- placeholder="请选择"
- :disabled="
- dialogTitle == '查看成本核定模板' ||
- dialogTitle == '修改成本核定模板' ||
- contentEditForm.surveyTemplateId != ''
- "
- >
- <el-option
- v-for="item in contentEditFormList"
- :key="item.id"
- :label="item.surveyTemplateName"
- :value="item.surveyTemplateId"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <div>
- <div class="mb20">
- <el-button
- v-if="!contentEditForm.surveyTemplateId"
- type="primary"
- class="mr20"
- @click="handleGenerateTemplate"
- >
- 生成模版
- </el-button>
- </div>
- <div
- v-if="contentEditForm.surveyTemplateId"
- class="table-edit-container"
- >
- <div class="mb20">
- <el-button
- v-if="dialogTitle != '查看成本核定模板'"
- type="primary"
- @click="handleAddTableHeader('固定表表头')"
- >
- 添加表头
- </el-button>
- <el-button
- v-if="dialogTitle != '查看成本核定模板'"
- type="primary"
- @click="handleSaveContent('固定表表头')"
- >
- 下一步
- </el-button>
- </div>
- <div class="table-edit-container">
- <el-table
- :data="contentEditForm.fixedTable.tableHeaders"
- border
- style="width: 100%"
- >
- <el-table-column label="序号" width="80" align="center">
- <template slot-scope="scope">
- <span>{{ scope.$index + 1 }}</span>
- </template>
- </el-table-column>
- <el-table-column
- prop="fieldName"
- label="字段名称"
- min-width="150"
- align="center"
- >
- <template slot-scope="scope">
- <el-input
- v-model="scope.row.fieldName"
- placeholder="请输入字段名称"
- size="small"
- :disabled="
- scope.row.isReadOnly || dialogTitle == '查看成本核定模板'
- "
- @change="handleFieldNameChange(scope.row)"
- ></el-input>
- </template>
- </el-table-column>
- <el-table-column
- prop="fieldType"
- label="字段类型"
- width="120"
- align="center"
- >
- <template slot-scope="scope">
- <el-select
- v-model="scope.row.fieldType"
- placeholder="请选择字段类型"
- size="small"
- :disabled="
- scope.row.isReadOnly || dialogTitle == '查看成本核定模板'
- "
- @change="handleFieldTypeChange(scope.row)"
- >
- <el-option label="字符串" value="string"></el-option>
- <el-option label="整数" value="integer"></el-option>
- <el-option label="小数" value="double"></el-option>
- <el-option label="日期" value="datetime"></el-option>
- <el-option label="布尔值" value="boolean"></el-option>
- </el-select>
- </template>
- </el-table-column>
- <el-table-column
- prop="format"
- label="格式"
- width="220"
- align="center"
- >
- <template slot-scope="scope">
- <!-- 字符串类型格式 -->
- <div
- v-if="scope.row.fieldType === 'string'"
- class="format-input"
- >
- <span class="format-prefix">长度</span>
- <el-input
- v-model="scope.row.format"
- placeholder="请输入长度"
- size="small"
- style="width: calc(100% - 80px); margin-left: 5px"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- ></el-input>
- </div>
- <!-- 整数类型格式 -->
- <div
- v-else-if="scope.row.fieldType === 'integer'"
- class="format-input"
- >
- <span class="format-prefix">整数</span>
- <el-input
- v-model="scope.row.fieldTypelen"
- placeholder="整数位数"
- size="small"
- style="width: calc(100% - 80px); margin: 0 5px"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- ></el-input>
- </div>
- <!-- 小数类型格式 -->
- <div
- v-else-if="scope.row.fieldType === 'double'"
- class="format-input"
- >
- <span class="format-prefix">小数</span>
- <el-input
- v-model="scope.row.fieldTypenointlen"
- placeholder="小数位数"
- size="small"
- style="width: calc(100% - 80px); margin-left: 5px"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- ></el-input>
- </div>
- <!-- 日期类型格式 -->
- <div
- v-else-if="scope.row.fieldType === 'datetime'"
- class="format-input"
- >
- <el-select
- v-model="scope.row.format"
- placeholder="请选择日期格式"
- size="small"
- style="width: 100%"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- >
- <el-option
- label="yyyy-MM-dd HH:mm:ss"
- value="yyyy-MM-dd HH:mm:ss"
- ></el-option>
- <el-option
- label="yyyy-MM-dd"
- value="yyyy-MM-dd"
- ></el-option>
- </el-select>
- </div>
- <!-- 布尔类型格式 -->
- <div v-else-if="scope.row.fieldType === 'boolean'">
- <el-select
- v-model="scope.row.format"
- placeholder="请选择布尔值格式"
- size="small"
- style="width: 100%"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- >
- <el-option label="true" value="true"></el-option>
- <el-option label="false" value="false"></el-option>
- </el-select>
- </div>
- <!-- 默认情况 -->
- <el-input
- v-else
- v-model="scope.row.format"
- :placeholder="getFormatPlaceholder(scope.row.fieldType)"
- size="small"
- ></el-input>
- </template>
- </el-table-column>
- <el-table-column
- prop="isRequired"
- label="是否必填"
- width="120"
- align="center"
- >
- <template slot-scope="scope">
- <el-select
- v-model="scope.row.isRequired"
- size="small"
- :disabled="
- scope.row.isReadOnly || dialogTitle == '查看成本核定模板'
- "
- >
- <el-option label="是" value="true"></el-option>
- <el-option label="否" value="false"></el-option>
- </el-select>
- </template>
- </el-table-column>
- <el-table-column
- prop="showVisible"
- label="是否显示"
- width="120"
- align="center"
- >
- <template slot-scope="scope">
- <el-select
- v-model="scope.row.showVisible"
- size="small"
- :disabled="
- scope.row.isReadOnly || dialogTitle == '查看成本核定模板'
- "
- >
- <el-option label="是" value="1"></el-option>
- <el-option label="否" value="0"></el-option>
- </el-select>
- </template>
- </el-table-column>
- <el-table-column
- prop="isAuditPeriod"
- label="是否绑定监审期间"
- width="140"
- align="center"
- >
- <template slot-scope="scope">
- <el-select
- v-model="scope.row.isAuditPeriod"
- size="small"
- :disabled="
- scope.row.isReadOnly || dialogTitle == '查看成本核定模板'
- "
- >
- <el-option label="是" value="true"></el-option>
- <el-option label="否" value="false"></el-option>
- </el-select>
- </template>
- </el-table-column>
- <el-table-column prop="isDict" label="绑定字典" min-width="150">
- <template slot-scope="scope">
- <div class="bind-dict-column">
- <el-select
- v-model="scope.row.isDict"
- size="small"
- style="width: 80px"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- @change="handleBindDictChange(scope.row)"
- >
- <el-option label="是" value="true"></el-option>
- <el-option label="否" value="false"></el-option>
- </el-select>
- <el-select
- v-if="scope.row.isDict === 'true'"
- v-model="scope.row.dictid"
- placeholder="请选择字典"
- class="dict-select"
- size="small"
- style="width: 120px; margin-top: 5px"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- >
- <el-option
- v-for="(item, index) in dictTypeList"
- :key="index"
- :label="item.name"
- :value="String(item.id)"
- ></el-option>
- </el-select>
- </div>
- </template>
- </el-table-column>
- <el-table-column
- label="操作"
- width="150"
- fixed="right"
- align="center"
- >
- <template slot-scope="scope">
- <div class="table-actions">
- <el-button
- v-if="dialogTitle != '查看成本核定模板'"
- type="text"
- size="mini"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- @click="
- handleDeleteHeader(
- scope.$index,
- '固定表表头',
- scope.row
- )
- "
- >
- 删除
- </el-button>
- <el-button
- v-if="
- scope.$index !== 0 || dialogTitle != '查看成本核定模板'
- "
- type="text"
- size="mini"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- @click="handleMoveUp(scope.$index)"
- >
- 上升
- </el-button>
- <el-button
- v-if="
- scope.$index !==
- contentEditForm.fixedTable.tableHeaders.length - 1 ||
- dialogTitle == '查看成本核定模板'
- "
- type="text"
- size="mini"
- :disabled="
- scope.row.isReadOnly ||
- dialogTitle == '查看成本核定模板'
- "
- @click="handleMoveDown(scope.$index)"
- >
- 下降
- </el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <div>
- <div class="button-group mt20 mb20">
- <el-button
- v-if="dialogTitle != '查看成本核定模板'"
- type="primary"
- @click="handleAddTableHeader('固定表项目')"
- >
- 添加项目
- </el-button>
- <el-button
- v-if="dialogTitle != '查看成本核定模板'"
- type="primary"
- @click="handleSaveTemplate"
- >
- 保存
- </el-button>
- </div>
- <div class="table-edit-container">
- <el-table
- :data="contentEditForm.fixedTable.fixedTables"
- border
- style="width: 100%"
- row-key="rowid"
- default-expand-all
- :tree-props="{
- children: 'children',
- hasChildren: 'hasChildren',
- }"
- @selection-change="handleSelectionChange"
- >
- <el-table-column label="父子节点" align="center" width="100">
- <template slot-scope="scope">
- <el-tag
- v-if="
- scope.row.isChild ||
- scope.row.isSubItem ||
- (scope.row.parentid &&
- scope.row.parentid != -1 &&
- scope.row.parentid != '-1')
- "
- type="success"
- size="small"
- >
- 子项
- </el-tag>
- <el-tag
- v-else-if="
- scope.row.parentid === -1 ||
- scope.row.parentid === '-1' ||
- !scope.row.parentid
- "
- type="primary"
- size="small"
- >
- 父项
- </el-tag>
- <el-tag v-else type="info" size="small">无</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="序号" width="150" align="center">
- <template slot-scope="scope">
- <div
- class="row-indent-container"
- :style="getRowIndentStyle(scope.row)"
- >
- <el-input
- :value="
- scope.row.fixedValues
- ? scope.row.fixedValues['序号']
- : ''
- "
- size="small"
- placeholder="数字或中文"
- :disabled="dialogTitle == '查看成本核定模板'"
- @input="
- handleFixedValueChange(scope.row, '序号', $event)
- "
- ></el-input>
- </div>
- </template>
- </el-table-column>
- <el-table-column
- v-for="(item, index) in contentEditForm.fixedTable
- .fixedTableHeaders"
- :key="index"
- :label="item.rkey"
- align="center"
- >
- <template slot-scope="scope">
- <div class="row-indent-container">
- <el-input
- :value="
- scope.row.fixedValues
- ? scope.row.fixedValues[item.rkey]
- : ''
- "
- size="small"
- :disabled="dialogTitle == '查看成本核定模板'"
- @input="
- handleFixedValueChange(scope.row, item.rkey, $event)
- "
- ></el-input>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="指标编号" width="100" align="center">
- <template slot-scope="scope">
- <div class="row-indent-container">
- <el-input
- :value="scope.row.cellCode"
- size="small"
- :disabled="dialogTitle == '查看成本核定模板'"
- @input="(val) => $set(scope.row, 'cellCode', val)"
- ></el-input>
- </div>
- </template>
- </el-table-column>
- <el-table-column
- label="计算公式"
- width="150"
- align="center"
- show-overflow-tooltip
- >
- <template slot-scope="scope">
- <div class="row-indent-container">
- <el-input
- :value="scope.row.calculationFormula"
- size="small"
- readonly
- :disabled="dialogTitle == '查看成本核定模板'"
- @click.native="
- openCalculationFormulaDialogVisible(
- scope.row,
- scope.$index
- )
- "
- ></el-input>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="单位" width="80" align="center">
- <template slot-scope="scope">
- <div class="row-indent-container">
- <el-input
- :value="scope.row.unit"
- size="small"
- :disabled="dialogTitle == '查看成本核定模板'"
- @input="(val) => $set(scope.row, 'unit', val)"
- ></el-input>
- </div>
- </template>
- </el-table-column>
- <el-table-column
- label="操作"
- align="center"
- fixed="right"
- width="200"
- >
- <template slot-scope="scope">
- <div class="table-actions">
- <el-button
- v-if="!scope.row.isChild"
- type="text"
- size="mini"
- :disabled="dialogTitle == '查看成本核定模板'"
- @click="
- handleAddChildItem(
- scope.$index,
- '固定表项目',
- scope.row
- )
- "
- >
- 添加子项
- </el-button>
- <el-button
- type="text"
- size="mini"
- :disabled="dialogTitle == '查看成本核定模板'"
- @click="
- handleDeleteHeader(
- scope.$index,
- '固定表项目',
- scope.row
- )
- "
- >
- 删除
- </el-button>
- <el-button
- v-if="scope.$index !== 0"
- type="text"
- size="mini"
- :disabled="dialogTitle == '查看成本核定模板'"
- @click="handleMoveUp(scope.$index, '固定表', scope.row)"
- >
- 上升
- </el-button>
- <el-button
- v-if="
- scope.$index !==
- contentEditForm.fixedTable.fixedTables.length - 1
- "
- type="text"
- size="mini"
- :disabled="dialogTitle == '查看成本核定模板'"
- @click="handleMoveDown(scope.$index, '固定表')"
- >
- 下降
- </el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- </div>
- </div>
- <!-- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="handleSaveTemplate">确 认</el-button>
- <el-button @click="dialogVisible = false">取 消</el-button>
- </div> -->
- </el-dialog>
- <el-dialog
- title="计算公式"
- :visible.sync="calculationFormulaDialogVisible"
- width="500px"
- :before-close="handleDialogClose"
- :close-on-click-modal="false"
- >
- <!-- 单选按钮组:切换“当前指标项”/“其他模板指标项” -->
- <el-radio-group
- v-model="radioType"
- class="mb20"
- @change="handleRadioChange"
- >
- <el-radio label="current">当前指标项</el-radio>
- <el-radio label="other">其他模板指标项</el-radio>
- </el-radio-group>
- <!-- 「当前指标项」内容区域 -->
- <div v-if="radioType === 'current'" class="current-panel">
- <el-input
- v-model="formulaText"
- type="textarea"
- rows="4"
- placeholder="请输入公式(如 C1+C2+C3)"
- />
- </div>
- <!-- 「其他模板指标项」内容区域 -->
- <div v-else class="other-panel">
- <span>模板名称:</span>
- <el-select
- v-model="selectedTemplateId"
- style="width: 80%"
- placeholder="请选择模板"
- @change="handleTemplateChange"
- >
- <el-option
- v-for="(item, index) in templateList"
- :key="index"
- :label="item.surveyTemplateName"
- :value="item.pkVal"
- ></el-option>
- </el-select>
- <!-- 指标表格 -->
- <el-table
- ref="indicatorTable"
- :data="indicatorTableData"
- border
- style="width: 100%; margin-top: 10px"
- class="mb20"
- @row-click="handleRowClick"
- >
- <!-- @selection-change="selectionIndicatorChange" -->
- <el-table-column type="selection" label="选择" width="60">
- <template #default="scope">
- <el-checkbox
- v-model="scope.row.checked"
- @change="handleCheckboxChange(scope.row)"
- ></el-checkbox>
- </template>
- </el-table-column>
- <el-table-column
- prop="cellCode"
- label="指标编号"
- align="center"
- ></el-table-column>
- <!--循环表头 -->
- <el-table-column
- v-for="(item, index) in indicatorTableHeaders"
- :key="index"
- :label="item.rkey"
- align="center"
- show-overflow-tooltip
- >
- <template slot-scope="scope">
- {{
- scope.row.fixedValues ? scope.row.fixedValues[item.rkey] : ''
- }}
- </template>
- </el-table-column>
- </el-table>
- <el-input
- v-model="formulaText"
- type="textarea"
- rows="4"
- placeholder="请输入公式(如 C1+C2+C3)"
- @input="handleFormulaTextChange"
- />
- </div>
- <!-- 弹窗底部按钮 -->
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="handleConfirm">确定</el-button>
- <el-button @click="calculationFormulaDialogVisible = false">
- 取消
- </el-button>
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- import {
- getCostFormDataStorageTables,
- deleteCostVerifyForm,
- getActiveCostVerifyFormList,
- getActiveCostVerifyFormListByType,
- generateCostVerifyFormData,
- generateCostVerifyForm,
- addCostVerifyForm,
- getCostFormVersionsByTemplateId,
- batchSaveOrUpdate,
- } from '@/api/costFormManage'
- import {
- getlistBySurveyTemplateId,
- batchDeleteCostVerifyForm,
- getlistBySurveyTemplateIdcurrentversion,
- batchSave,
- enable,
- getListFixedEnabled,
- listByVerifyTemplateId,
- } from '@/api/costVerifyManage'
- import { getCatalogDetail } from '@/api/catalogManage'
- import { listByCurrentTemplateId } from '@/api/catalogManage.js'
- import { catalogMixin, commonMixin } from '@/mixins/useDict'
- import { getDictTypList } from '@/api/dictionaryManage.js'
- export default {
- name: 'SupervisionContent',
- // 使用混入
- mixins: [catalogMixin, commonMixin],
- data() {
- return {
- loading: false,
- searchForm: {
- type: '',
- catalogId: '',
- keyword: '',
- page: 1,
- pageSize: 50,
- },
- props: {
- filterable: true,
- placeholder: '请选择监审类别',
- style: 'width: 100%',
- showAllLevels: false,
- props: {
- multiple: false,
- children: 'children',
- checkStrictly: false,
- label: 'catalogName',
- value: 'id',
- emitPath: false,
- },
- },
- tableData: [],
- selectedRows: [],
- pagination: {
- currentPage: 1,
- pageSize: 50,
- total: 0,
- },
- dialogVisible: false,
- detailDialogVisible: false,
- dialogTitle: '',
- contentEditForm: {
- areaCode: '',
- areaLevel: '',
- catalogId: '',
- contentType: '',
- createBy: '',
- createTime: '',
- createmode: '',
- createtemplateid: '',
- createtemplateid1: '',
- isDelete: '',
- pkVal: '',
- remarks: '',
- status: '',
- storageTable: '',
- surveyTemplateId: '',
- surveyTemplateName: '',
- surveyTemplateNameYw: '',
- templateType: '2',
- type: '',
- updateBy: '',
- updateTime: '',
- versionNo: '',
- // 固定表列表
- fixedTable: {
- tableHeaders: [],
- fixedTables: [],
- fixedTablesTitle: [],
- fixedTableHeaders: [],
- },
- },
- dynamicTable: [],
- contentEditFormRules: {
- catalogId: [
- { required: true, message: '请选择监审类别', trigger: 'change' },
- ],
- surveyTemplateName: [
- { required: true, message: '请输入核定模板名称', trigger: 'blur' },
- {
- min: 1,
- max: 30,
- message: '核定模板名称长度应在1-30个字符之间',
- trigger: 'blur',
- },
- ],
- // createtemplateid: [
- // { required: true, message: '请选择模板类型', trigger: 'change' },
- // ],
- },
- // 成本核定表模板列表
- contentEditFormList: [],
- // 成本调查表模板列表
- surveyFormList: [],
- CatalogNameMap: {},
- calculationFormulaDialogVisible: false,
- currentEditingRow: null,
- currentEditingRowIndex: -1,
- radioType: 'current',
- formulaText: 'C1+C2+C3',
- templateName: '',
- templateList: [],
- indicatorTableData: [],
- indicatorTableHeaders: [],
- selectedIndicatorsPerTemplate: {},
- selectedIndicatorCodes: [],
- isAutoGeneratedFormula: false,
- dictTypeList: [],
- }
- },
- watch: {
- // 监听目录数据变化,数据加载完成后处理回显
- catalogListOptions: {
- handler(newVal) {
- if (newVal && newVal.length > 0) {
- // 数据加载完成后,重新处理value
- this.batchGetCatalogNames()
- }
- },
- immediate: true,
- },
- indicatorTableData: {
- handler(newVal) {
- if (this.radioType === 'other' && this.selectedTemplateId) {
- this.$set(
- this.selectedIndicatorsPerTemplate,
- this.selectedTemplateId,
- newVal.filter((item) => item.checked)
- )
- }
- this.updateSelectedIndicatorCodes()
- },
- deep: true,
- },
- selectedIndicatorCodes: {
- handler(newVal) {
- if (this.radioType === 'other') {
- const allSelectedTemplateIds = [
- ...new Set([
- this.selectedTemplateId,
- ...Object.keys(this.selectedIndicatorsPerTemplate).filter(
- (id) =>
- id !== this.selectedTemplateId &&
- this.selectedIndicatorsPerTemplate[id].some(
- (item) => item.checked
- )
- ),
- ]),
- ].filter((id) => id)
- const isSingleTemplate = allSelectedTemplateIds.length === 1
- if (isSingleTemplate && allSelectedTemplateIds[0]) {
- const selectedTemplate = this.templateList.find(
- (item) => item.pkVal === allSelectedTemplateIds[0]
- )
- const templateNameYw = selectedTemplate
- ? selectedTemplate.surveyTemplateNameYw ||
- selectedTemplate.surveyTemplateName ||
- ''
- : ''
- let selectedItems = []
- if (allSelectedTemplateIds[0] === this.selectedTemplateId) {
- selectedItems = newVal
- } else {
- selectedItems = this.selectedIndicatorsPerTemplate[
- allSelectedTemplateIds[0]
- ]
- .filter((item) => item.checked)
- .map(
- (item) => `${templateNameYw}.${item.code || item.cellCode}`
- )
- }
- if (selectedItems.length > 0) {
- this.formulaText = selectedItems.join('+')
- this.isAutoGeneratedFormula = true
- } else if (this.isAutoGeneratedFormula) {
- this.formulaText = ''
- }
- } else {
- let allSelectedCodes = []
- if (newVal.length > 0 && this.selectedTemplateId) {
- allSelectedCodes = [...newVal]
- }
- Object.keys(this.selectedIndicatorsPerTemplate).forEach(
- (templateId) => {
- if (templateId !== this.selectedTemplateId) {
- const items = this.selectedIndicatorsPerTemplate[templateId]
- const selectedTemplate = this.templateList.find(
- (item) => item.pkVal === templateId
- )
- const templateName = selectedTemplate
- ? selectedTemplate.surveyTemplateNameYw ||
- selectedTemplate.surveyTemplateName ||
- ''
- : ''
- items
- .filter((item) => item.checked)
- .forEach((item) => {
- allSelectedCodes.push(
- `${templateName}.${item.code || item.cellCode}`
- )
- })
- }
- }
- )
- if (allSelectedCodes.length > 0) {
- this.formulaText = allSelectedCodes.join('+')
- this.isAutoGeneratedFormula = true
- } else if (this.isAutoGeneratedFormula) {
- this.formulaText = ''
- }
- }
- } else if (newVal.length > 0 && this.radioType === 'current') {
- if (
- !this.formulaText ||
- this.formulaText === 'C1+C2+C3' ||
- this.isAutoGeneratedFormula
- ) {
- this.formulaText = newVal.join('+')
- this.isAutoGeneratedFormula = true
- }
- } else if (newVal.length === 0 && this.radioType === 'current') {
- if (this.isAutoGeneratedFormula) {
- this.formulaText = ''
- }
- }
- },
- deep: true,
- },
- },
- mounted() {
- this.handleSearch()
- this.loadDictTypeList()
- },
- methods: {
- async loadDictTypeList() {
- try {
- const res = await getDictTypList()
- this.dictTypeList = res || []
- } catch (error) {
- console.error('加载字典类型失败:', error)
- }
- },
- // 获取监审类别名称
- batchGetCatalogNames() {
- // 递归查找名称
- this.CatalogNameMap = {}
- this._recursiveCatalogMap(this.catalogListOptions)
- },
- // 递归遍历目录树并构建ID到名称的映射
- _recursiveCatalogMap(catalogs) {
- if (!Array.isArray(catalogs) || catalogs.length === 0) {
- return
- }
- catalogs.forEach((item) => {
- // 为当前目录项添加映射
- this.CatalogNameMap[item.id] = item.catalogName
- // 递归处理子目录
- if (item.children && Array.isArray(item.children)) {
- this._recursiveCatalogMap(item.children)
- }
- })
- },
- // 获取所有状态为启用的成本核定表模板数据
- getActiveCostVerifyFormList() {
- getActiveCostVerifyFormList().then((res) => {
- if (res.code === 200) {
- this.contentEditFormList = res.value
- }
- })
- },
- // 获取所有模板类型为固定表的所有启用成本调查表数据
- getActiveCostVerifyFormListByType() {
- getActiveCostVerifyFormListByType().then((res) => {
- if (res.code === 200) {
- this.surveyFormList = res.value
- }
- })
- },
- getCatalogNames(row) {
- if (!row.catalogId) return ''
- return row.catalogId
- .split(',')
- .map((id) => {
- const trimId = id.trim()
- return this.CatalogNameMap[trimId] || '未知名称'
- })
- .join(',')
- },
- // 删除成本核定表模板
- handleDeleteRow(row) {
- this.$confirm('确定删除该成本核定表模板吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- }).then(() => {
- deleteCostVerifyForm(row.pkVal).then((res) => {
- if (res.code === 200) {
- this.$message({
- type: 'success',
- message: '删除成功',
- })
- this.handleSearch()
- } else {
- this.$message({
- type: 'error',
- message: res.msg || '删除失败',
- })
- }
- })
- })
- },
- // 状态转换
- handleStatusChange(row) {
- enable({
- id: row.surveyTemplateId,
- }).then((res) => {
- if (res.code === 200) {
- this.$message.success(`${res.message}`)
- this.handleSearch()
- }
- })
- },
- // 搜索
- handleSearch() {
- this.loading = true
- getCostFormDataStorageTables(this.searchForm).then((res) => {
- this.loading = false
- if (res.rows.length > 0) {
- this.tableData = res.rows || []
- this.pagination.total = res.total || 0
- }
- })
- },
- // 重置
- handleReset() {
- this.searchForm = {
- catalogId: '',
- keyword: '',
- page: 1,
- pageSize: 50,
- }
- this.handleSearch()
- },
- // 添加
- handleAdd() {
- this.dialogTitle = '添加成本核定模板'
- this.contentEditForm = {
- areaCode: '',
- areaLevel: '',
- catalogId: '',
- contentType: '',
- createBy: '',
- createTime: '',
- createmode: '1',
- createtemplateid: '',
- createtemplateid1: '',
- isDelete: '',
- pkVal: '',
- remarks: '',
- status: '',
- storageTable: '',
- surveyTemplateId: '',
- surveyTemplateName: '',
- surveyTemplateNameYw: '',
- templateType: '2',
- type: '',
- updateBy: '',
- updateTime: '',
- versionNo: '',
- // 固定表列表
- fixedTable: {
- tableHeaders: [],
- fixedTables: [],
- fixedTablesTitle: [],
- },
- }
- // 成本核定表模板列表
- this.getActiveCostVerifyFormList()
- // 成本调查表模板列表
- this.getActiveCostVerifyFormListByType()
- this.dialogVisible = true
- // 清除表单校验
- this.$nextTick(() => {
- if (this.$refs.contentEditForm) {
- this.$refs.contentEditForm.clearValidate()
- }
- })
- console.log('this.contentEditForm', this.contentEditForm)
- },
- // 修改
- handleEdit(row) {
- this.dialogTitle = '修改成本核定模板'
- this.contentEditForm = {
- ...row,
- // 固定表列表
- fixedTable: {
- tableHeaders: [],
- fixedTables: [],
- fixedTablesTitle: [],
- },
- }
- if (row.createmode == '1') {
- this.contentEditFormcreatetemplateid = row.createtemplateid || ''
- this.contentEditForm.createtemplateid1 = ''
- } else if (row.createmode == '2') {
- this.contentEditForm.createtemplateid1 = row.createtemplateid || ''
- this.contentEditForm.createtemplateid = ''
- }
- // 成本核定表模板列表
- this.getActiveCostVerifyFormList()
- // 成本调查表模板列表
- this.getActiveCostVerifyFormListByType()
- this.loadTemplateDataForEdit(this.contentEditForm.surveyTemplateId)
- this.dialogVisible = true
- },
- // 查看详情
- handleViewDetail(row) {
- this.dialogTitle = '查看成本核定模板'
- this.contentEditForm = {
- ...row,
- // 固定表列表
- fixedTable: {
- tableHeaders: [],
- fixedTables: [],
- fixedTablesTitle: [],
- },
- }
- if (row.createmode == '1') {
- this.contentEditFormcreatetemplateid = row.createtemplateid || ''
- this.contentEditFormcreatetemplateid1 = ''
- } else if (row.createmode == '2') {
- this.contentEditForm.createtemplateid1 = row.createtemplateid1 || ''
- this.contentEditFormcreatetemplateid = ''
- }
- // 成本核定表模板列表
- this.getActiveCostVerifyFormList()
- // 成本调查表模板列表
- this.getActiveCostVerifyFormListByType()
- this.loadTemplateDataForEdit(this.contentEditForm.surveyTemplateId)
- this.dialogVisible = true
- },
- // 生成模板
- handleGenerateTemplate() {
- // 提示生成后不能修改
- this.$confirm(
- '生成后不能修改根据调查表生成还是根据历史核定模板生成,确定生成模板吗?',
- '提示',
- {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- }
- ).then(() => {
- // 校验表单
- this.$refs['contentEditForm'].validate((valid) => {
- if (valid) {
- if (this.contentEditForm.createmode == '1') {
- if (!this.contentEditForm.createtemplateid) {
- this.$message.error('请选择成本调查表模板')
- return
- }
- this.generateFromSurveyTemplate()
- } else if (this.contentEditForm.createmode == '2') {
- if (!this.contentEditForm.createtemplateid1) {
- this.$message.error('请选择历史核定模板')
- return
- }
- this.generateFromHistoryTemplate()
- }
- } else {
- this.$message.error('请填写表单数据')
- return
- }
- })
- })
- },
- async loadTemplateDataForEdit(surveyTemplateId) {
- // 并行获取表头和表格数据
- const [tableHeadersRes, tableDataRes] = await Promise.all([
- getlistBySurveyTemplateId({
- surveyTemplateId,
- }),
- getCostFormVersionsByTemplateId({
- surveyTemplateId,
- }),
- ])
- // 处理表头数据
- if (tableHeadersRes.code == 200) {
- this.contentEditForm.fixedTable.tableHeaders = Array.isArray(
- tableHeadersRes.value
- )
- ? tableHeadersRes.value
- : []
- // 表头按照orderNum重新排序
- this.contentEditForm.fixedTable.tableHeaders.sort(
- (a, b) => a.orderNum - b.orderNum
- )
- // 检查是否有fieldName为"序号"的数据
- const hasSerialNumber =
- this.contentEditForm.fixedTable.tableHeaders.some(
- (header) => header.fieldName === '序号'
- )
- // 如果没有序号数据,则添加一条默认的序号数据,并标记为不可编辑
- if (!hasSerialNumber) {
- this.contentEditForm.fixedTable.tableHeaders.unshift({
- fieldName: '序号',
- fieldType: 'string',
- format: '30',
- fieldTypelen: '',
- fieldTypenointlen: '',
- isRequired: 'false',
- showVisible: '1',
- isAuditPeriod: 'false',
- tabtype: '2',
- surveyTemplateId: this.contentEditForm.surveyTemplateId,
- versionId: this.versionId,
- isFixed: '1',
- isReadOnly: true, // 标记为不可编辑
- orderNum: 1,
- })
- } else {
- this.contentEditForm.fixedTable.tableHeaders.forEach((item) => {
- if (item.fieldName === '序号') {
- item.isReadOnly = true // 确保序号字段不可编辑
- }
- })
- }
- }
- // 处理表格数据
- if (tableDataRes.code == 200) {
- this.parseAndDisplayFixedTableData(tableDataRes)
- }
- },
- // 根据调查表生成模板
- async generateFromSurveyTemplate() {
- try {
- // 显示加载状态
- this.loading = true
- // 保存模板基本信息
- let data = await generateCostVerifyForm({
- catalogId: this.contentEditForm.catalogId,
- templatename: this.contentEditForm.surveyTemplateName,
- templateId: this.contentEditForm.createtemplateid,
- })
- this.contentEditForm.surveyTemplateId = data.value
- ? data.value.surveyTemplateId
- : ''
- this.loadTemplateDataForEdit(this.contentEditForm.surveyTemplateId)
- // // 并行获取表头和表格数据
- // const [tableHeadersRes, tableDataRes] = await Promise.all([
- // getlistBySurveyTemplateIdcurrentversion({
- // surveyTemplateId: this.contentEditForm.createtemplateid,
- // }),
- // listByCurrentTemplateId({
- // surveyTemplateId: this.contentEditForm.createtemplateid,
- // }),
- // ])
- // // 处理表头数据
- // if (tableHeadersRes.code == 200) {
- // this.contentEditForm.fixedTable.tableHeaders = Array.isArray(
- // tableHeadersRes.value
- // )
- // ? tableHeadersRes.value
- // : []
- // }
- // // 处理表格数据
- // if (tableDataRes.code == 200) {
- // const fieldNamesString =
- // this.contentEditForm.fixedTable.tableHeaders
- // .map((header) => header.fieldName)
- // .join(', ')
- // this.contentEditForm.fixedTable.fixedTablesTitle = fieldNamesString
- // this.parseAndDisplayFixedTableData(tableDataRes)
- // // this.$message.success('生成模板成功')
- // }
- } catch (error) {
- console.error('生成模板失败:', error)
- } finally {
- this.loading = false
- }
- },
- // 根据历史核定模板生成
- async generateFromHistoryTemplate() {
- // 保存模板基本信息
- let data = await generateCostVerifyFormData({
- catalogId: this.contentEditForm.catalogId,
- templatename: this.contentEditForm.surveyTemplateName,
- templateId: this.contentEditForm.createtemplateid1,
- })
- this.contentEditForm.surveyTemplateId = data.value
- ? data.value.surveyTemplateId
- : ''
- this.loadTemplateDataForEdit(this.contentEditForm.surveyTemplateId)
- },
- // 添加表头
- handleAddTableHeader(type) {
- switch (type) {
- case '固定表表头':
- this.contentEditForm.fixedTable.tableHeaders.push({
- fieldName: '',
- fieldType: 'string',
- format: '255',
- fieldTypelen: '',
- fieldTypenointlen: '',
- isRequired: 'false',
- showVisible: '1',
- isAuditPeriod: 'false',
- tabtype: '2',
- surveyTemplateId: this.contentEditForm.surveyTemplateId,
- versionId: this.versionId,
- orderNum: this.contentEditForm.fixedTable.tableHeaders.length + 1,
- })
- break
- case '固定表项目':
- let maxFixedOrderNum = 0
- if (this.contentEditForm.fixedTable.fixedTables.length > 0) {
- maxFixedOrderNum = Math.max(
- ...this.contentEditForm.fixedTable.fixedTables.map(
- (item) => item.orderNum || 0
- )
- )
- }
- const newRow = {
- orderText: maxFixedOrderNum + 1,
- orderNum: maxFixedOrderNum + 1,
- cellCode: '',
- calculationFormula: '',
- unit: '',
- tabtype: this.contentEditForm.templateType,
- surveyTemplateId: this.contentEditForm.surveyTemplateId,
- versionId: this.versionId,
- fixedValues: {},
- parentid: -1,
- rowid: this.generateUUID(),
- }
- this.contentEditForm.fixedTable.fixedTablesTitle.forEach(
- (title) => {
- newRow.fixedValues[title.rkey] = ''
- }
- )
- this.contentEditForm.fixedTable.fixedTables.push(newRow)
- break
- default:
- break
- }
- },
- // 字段名称改变
- handleFieldNameChange(row) {
- console.log(row)
- if (row.fieldName) {
- // 检查是否已存在相同的fieldName
- const existsInTableHeaders =
- this.contentEditForm.fixedTable.tableHeaders.some(
- (item) => item.fieldName === row.fieldName
- )
- // 跳过"序号"列
- if (row.fieldName !== '序号' && !existsInTableHeaders) {
- // 更新tableHeaders数组,这是关键的数据源
- this.contentEditForm.fixedTable.tableHeaders.push({
- fieldName: row.fieldName,
- fieldType: 'string',
- format: '255',
- fieldTypelen: '',
- fieldTypenointlen: '',
- isRequired: 'false',
- showVisible: '1',
- isAuditPeriod: 'false',
- tabtype: '2',
- surveyTemplateId: this.contentEditForm.surveyTemplateId,
- versionId: this.versionId || null,
- orderNum: this.contentEditForm.fixedTable.tableHeaders.length + 1,
- id: null,
- })
- // 同时更新fixedTablesTitle(这是源头数据)
- const newTitle = {
- rkey: row.fieldName,
- rvalue: '',
- }
- this.contentEditForm.fixedTable.fixedTablesTitle.push(newTitle)
- // 同时更新fixedTableHeaders
- this.contentEditForm.fixedTable.fixedTableHeaders.push(newTitle)
- // 为现有表格数据行添加对应的fixedValues属性
- if (
- this.contentEditForm.fixedTable.fixedTables &&
- this.contentEditForm.fixedTable.fixedTables.length > 0
- ) {
- this.contentEditForm.fixedTable.fixedTables.forEach(
- (tableRow) => {
- // 确保fixedValues对象存在
- if (!tableRow.fixedValues) {
- tableRow.fixedValues = {}
- }
- // 为新字段设置默认值为空字符串
- tableRow.fixedValues[row.fieldName] = ''
- }
- )
- }
- }
- }
- },
- // 保存内容
- handleSaveContent(type) {
- try {
- if (type === '固定表表头') {
- var data = {
- headersList: this.contentEditForm.fixedTable.tableHeaders,
- }
- batchSaveOrUpdate(data)
- .then((res) => {
- if (res.code === 200) {
- // 如果后端返回了保存后的数据,更新本地数据
- if (res.value && Array.isArray(res.value)) {
- this.contentEditForm.fixedTable.tableHeaders =
- res.value.map((item) => ({
- ...item,
- }))
- }
- this.loadTemplateDataForEdit(
- this.contentEditForm.surveyTemplateId
- )
- this.contentEditForm.fixedTable.fixedTables.forEach((row) => {
- this.initFixedTableRow(row)
- })
- }
- })
- .catch((error) => {
- console.error('保存接口异常:', error)
- })
- .finally(() => {
- this.loading = false
- })
- }
- } catch (error) {
- console.error('保存处理异常:', error)
- }
- },
- initFixedTableRow(row) {
- if (row.cellCode === undefined) {
- this.$set(row, 'cellCode', '')
- }
- if (row.calculationFormula === undefined) {
- this.$set(row, 'calculationFormula', '')
- }
- if (row.unit === undefined) {
- this.$set(row, 'unit', '')
- }
- if (!row.fixedValues) {
- this.$set(row, 'fixedValues', {})
- }
- // 初始化children数组,支持树形结构
- if (!row.children) {
- this.$set(row, 'children', [])
- }
- this.contentEditForm.fixedTable.fixedTablesTitle.forEach(
- (title, index) => {
- if (!(title.rkey in row.fixedValues)) {
- this.$set(row.fixedValues, title.rkey, '')
- }
- }
- )
- return row
- },
- // 删除表头
- handleDeleteHeader(index, type, row) {
- // 提取重复的删除逻辑为内部函数
- const handleDelete = () => {
- const data = {
- deleteheadersList: [row],
- }
- batchSaveOrUpdate(data)
- .then((res) => {
- if (res.code === 200) {
- this.$message.success('删除成功')
- }
- })
- .catch((error) => {
- console.error('删除接口异常:', error)
- })
- .finally(() => {})
- }
- switch (type) {
- case '固定表表头':
- if (this.contentEditForm.fixedTable.tableHeaders.length <= 1) {
- this.$message.warning('至少保留一个表头')
- return
- }
- this.contentEditForm.fixedTable.tableHeaders.splice(index, 1)
- handleDelete()
- break
- case '固定表项目':
- if (this.contentEditForm.fixedTable.fixedTables.length <= 1) {
- this.$message.warning('至少保留一个项目')
- return
- }
- this.contentEditForm.fixedTable.fixedTables.splice(index, 1)
- handleDelete() // 执行删除逻辑
- break
- default:
- break
- }
- },
- /**
- * 处理固定表项目字段值变化
- */
- handleFixedValueChange(row, rkey, value) {
- if (!row.fixedValues) {
- this.$set(row, 'fixedValues', {})
- }
- this.$set(row.fixedValues, rkey, value)
- },
- // 上升
- handleMoveUp(index, tableType, row) {
- if (tableType === '固定表') {
- const fixedTableData = this.contentEditForm.fixedTable.fixedTables
- const newFixedTableData = [...fixedTableData]
- this.swamTableArr(newFixedTableData, row, true)
- this.contentEditForm.fixedTable.fixedTables = newFixedTableData
- } else {
- // const tableHeaders = this.contentEditForm.fixedTable.tableHeaders
- // const newTableHeaders = [...tableHeaders]
- // this.swamTableArr(newTableHeaders, row, true, true)
- // this.contentEditForm.tableHeaders = newTableHeaders
- if (index > 0) {
- const temp = this.contentEditForm.fixedTable.tableHeaders[index]
- this.contentEditForm.fixedTable.tableHeaders.splice(index, 1)
- this.contentEditForm.fixedTable.tableHeaders.splice(
- index - 1,
- 0,
- temp
- )
- // 更新表头的序号
- this.updateTableHeadersOrderNumbers()
- }
- }
- },
- // 下降
- handleMoveDown(index, tableType, row) {
- if (tableType === '固定表') {
- const fixedTableData = this.contentEditForm.fixedTable.fixedTables
- const newFixedTableData = [...fixedTableData]
- this.swamTableArr(newFixedTableData, row, false)
- this.contentEditForm.fixedTable.fixedTables = newFixedTableData
- } else {
- // const tableHeaders = this.contentEditForm.tableHeaders
- // const newTableHeaders = [...tableHeaders]
- // this.swamTableArr(newTableHeaders, row, false)
- // this.contentEditForm.tableHeaders = newTableHeaders
- if (index < this.contentEditForm.fixedTable.tableHeaders.length - 1) {
- const temp = this.contentEditForm.fixedTable.tableHeaders[index]
- this.contentEditForm.fixedTable.tableHeaders.splice(index, 1)
- this.contentEditForm.fixedTable.tableHeaders.splice(
- index + 1,
- 0,
- temp
- )
- // 更新表头的序号
- this.updateTableHeadersOrderNumbers()
- }
- }
- },
- swamTableArr(arr, row, asc, isHeader) {
- const isChild = row.isChild || row.isSubItem || false
- if (isChild) {
- // 子节点处理逻辑后续实现 parentid rowid
- let child = arr.find((item) => item.rowid === row.parentid)
- // const rowIndex = arr.indexOf(row);
- // newFixedTableData[rowIndex]
- this.doSwamTableArr(child.children, row, asc, isHeader)
- } else {
- // 创建数组副本以确保Vue能检测到变化
- // 直接替换整个数组,确保Vue能检测到变化
- this.doSwamTableArr(arr, row, asc, isHeader)
- }
- },
- doSwamTableArr(arr, row, asc, isHeader) {
- const rowIndex = arr.indexOf(row)
- let swamIndex = 0
- if (asc) {
- // 正序
- if (rowIndex < 1) {
- return
- }
- swamIndex = rowIndex - 1
- } else {
- // 倒序
- if (rowIndex >= arr.length - 1) {
- return
- }
- swamIndex = rowIndex + 1
- }
- const curr = arr[rowIndex]
- const swam = arr[swamIndex]
- // 交换orderNum
- const tempOrderNum = curr.orderNum
- curr.orderNum = swam.orderNum
- swam.orderNum = tempOrderNum
- // row.isChild &&
- if (!isHeader) {
- // 获取当前项的序号值
- let currIndex = curr.fixedValues
- ? curr.fixedValues['序号']
- : curr.dynamicValues['序号']
- // 获取交换项的序号值
- let swamIndex = swam.fixedValues
- ? swam.fixedValues['序号']
- : swam.dynamicValues['序号']
- // 先保存交换项的值,再进行赋值,避免值被覆盖
- if (curr.fixedValues) {
- curr.fixedValues['序号'] = swamIndex
- } else {
- curr.dynamicValues['序号'] = swamIndex
- }
- if (swam.fixedValues) {
- swam.fixedValues['序号'] = currIndex
- } else {
- swam.dynamicValues['序号'] = currIndex
- }
- }
- // 交换数组中的位置
- arr[rowIndex] = swam
- arr[swamIndex] = curr
- },
- // 更新表头序号
- updateTableHeadersOrderNumbers() {
- // 更新固定表的表头序号
- if (
- this.contentEditForm.fixedTable &&
- this.contentEditForm.fixedTable.tableHeaders
- ) {
- this.contentEditForm.fixedTable.tableHeaders.forEach(
- (header, index) => {
- header.orderNum = index + 1
- }
- )
- }
- },
- // 添加子项方法
- handleAddChildItem(index, type, parentRow) {
- if (!parentRow.rowid) {
- this.$set(parentRow, 'rowid', this.generateUUID())
- }
- switch (type) {
- case '固定表项目':
- let parentIndex1 =
- this.contentEditForm.fixedTable.fixedTables.findIndex(
- (item) => item.rowid == parentRow.rowid
- )
- if (
- !this.contentEditForm.fixedTable.fixedTables[parentIndex1]
- .children
- ) {
- this.$set(
- this.contentEditForm.fixedTable.fixedTables[parentIndex1],
- 'children',
- []
- )
- }
- let childOrderNum =
- this.contentEditForm.fixedTable.fixedTables[parentIndex1].children
- .length + 1
- let fixedValues = {
- ...parentRow.fixedValues,
- }
- for (const key in fixedValues) {
- if (key == '序号') {
- fixedValues[key] = childOrderNum
- } else {
- fixedValues[key] = ''
- }
- }
- const fixedNewRow = {
- orderText: this.contentEditForm.fixedTable.fixedTables.length + 1,
- orderNum: this.contentEditForm.fixedTable.fixedTables.length + 1,
- cellCode: '',
- calculationFormula: '',
- unit: '',
- tabtype: this.contentEditForm.templateType,
- surveyTemplateId: this.contentEditForm.surveyTemplateId,
- versionId: this.versionId,
- fixedValues: fixedValues,
- parentid: parentRow.rowid,
- isChild: true,
- isSubItem: true,
- rowid: this.generateUUID(),
- }
- this.contentEditForm.fixedTable.fixedTablesTitle.forEach(
- (title) => {
- if (!(title.rkey in fixedNewRow.fixedValues)) {
- fixedNewRow.fixedValues[title.rkey] = ''
- }
- }
- )
- this.contentEditForm.fixedTable.fixedTables[
- parentIndex1
- ].children.push(fixedNewRow)
- // this.contentEditForm.fixedTable.fixedTables.splice(
- // index + 1,
- // 0,
- // fixedNewRow
- // )
- break
- }
- this.$nextTick(() => {
- const tableBody = document.querySelector('.el-table__body-wrapper')
- if (tableBody) {
- tableBody.scrollTop = tableBody.scrollHeight
- }
- })
- },
- handleCreateModeChange() {
- if (this.contentEditForm.createmode == 1) {
- this.contentEditForm.createtemplateid1 = ''
- } else if (this.contentEditForm.createmode == 2) {
- this.contentEditForm.createtemplateid = ''
- }
- },
- openCalculationFormulaDialogVisible(row, index) {
- this.currentEditingRow = row
- this.currentEditingRowIndex = index
- this.calculationFormulaDialogVisible = true
- this.formulaText = row.calculationFormula || ''
- this.selectedTemplateId = '' // 重置选中的模板
- this.indicatorTableData = [] // 清空指标数据
- this.getListFixedEnabled()
- },
- getListFixedEnabled() {
- getListFixedEnabled({
- surveyTemplateId: this.contentEditForm.surveyTemplateId,
- }).then((res) => {
- this.templateList = res.value
- })
- },
- // 处理模板选择变化
- handleTemplateChange(templateId) {
- if (templateId) {
- // 根据选中的模板ID查找对应的surveyTemplateId
- const selectedTemplate = this.templateList.find(
- (item) => item.pkVal === templateId
- )
- if (selectedTemplate && selectedTemplate.surveyTemplateId) {
- this.getCellCodesByTemplateId(selectedTemplate.surveyTemplateId)
- } else {
- this.indicatorTableData = []
- }
- } else {
- this.indicatorTableData = []
- }
- // 恢复该模板之前选中的指标项
- this.$nextTick(() => {
- if (this.selectedIndicatorsPerTemplate[templateId]) {
- this.indicatorTableData.forEach((item) => {
- const isSelected = this.selectedIndicatorsPerTemplate[
- templateId
- ].some((selectedItem) => selectedItem.code === item.code)
- this.$set(item, 'checked', isSelected)
- if (isSelected) {
- this.formatRowCode(item)
- }
- })
- }
- // 更新选中的指标代码列表
- this.updateSelectedIndicatorCodes()
- })
- },
- getCellCodesByTemplateId(surveyTemplateId) {
- listByVerifyTemplateId({
- surveyTemplateId: surveyTemplateId,
- })
- .then((res) => {
- // 将返回的数据转换为表格需要的格式
- if (res.value && Array.isArray(res.value.itemlist)) {
- let fixedTablesTitle = this.stringToObjects(
- res.value.fixedFields || ''
- )
- this.indicatorTableHeaders = fixedTablesTitle
- this.indicatorTableData = res.value.itemlist.map((item) => ({
- ...item,
- checked: false,
- cellCode: item.cellCode || '',
- name: res.value.fixedFields.split(',')[0] || '',
- formattedCode: '', // 添加格式化代码字段
- }))
- } else {
- this.indicatorTableData = []
- }
- })
- .catch((error) => {
- console.error('获取指标数据失败:', error)
- this.indicatorTableData = []
- })
- },
- updateSelectedIndicatorCodes() {
- // 获取当前选中的行
- const selectedRows = this.indicatorTableData.filter(
- (item) => item.checked
- )
- // 更新选中的指标代码列表
- this.selectedIndicatorCodes = selectedRows.map((item) => {
- // 获取选中的模板信息
- const selectedTemplate = this.templateList.find(
- (template) => template.pkVal === this.selectedTemplateId
- )
- // 获取模板的 surveyTemplateNameYw
- const templateName = selectedTemplate
- ? selectedTemplate.surveyTemplateNameYw ||
- selectedTemplate.surveyTemplateName ||
- ''
- : ''
- return templateName
- ? `${templateName}.${item.code || item.cellCode || ''}`
- : item.code || item.cellCode || ''
- })
- },
- formatRowCode(row) {
- const selectedTemplate = this.templateList.find(
- (item) => item.pkVal === this.selectedTemplateId
- )
- const surveyTemplateNameYw = selectedTemplate
- ? selectedTemplate.surveyTemplateNameYw ||
- selectedTemplate.surveyTemplateName ||
- ''
- : ''
- const formattedCode = surveyTemplateNameYw
- ? `${surveyTemplateNameYw}.${row.code || row.cellCode || ''}`
- : row.code || row.cellCode || ''
- this.$set(row, 'formattedCode', formattedCode)
- const templateCode = surveyTemplateNameYw
- ? `${surveyTemplateNameYw}_${row.code || row.cellCode || ''}`
- : row.code || row.cellCode || ''
- this.$set(
- row,
- 'jsonStr',
- JSON.stringify([
- {
- [templateCode]: this.selectedTemplateId,
- },
- ])
- )
- },
- handleRowClick(row, column, event) {
- // 只有点击非 checkbox 列才触发
- if (column && column.property !== 'checked') {
- // 如果没有 cellCode,则不允许选中
- if (!row.cellCode) {
- // this.$message.warning('该数据没有指标编号,无法选择')
- return
- }
- // 切换选中状态
- this.toggleRowSelection(row)
- }
- },
- toggleRowSelection(row) {
- // 切换选中状态
- this.$set(row, 'checked', !row.checked)
- // 格式化代码并存储在行数据中
- if (row.checked) {
- this.formatRowCode(row)
- }
- // 触发选中状态更新
- this.$forceUpdate()
- },
- selectionIndicatorChange(val) {
- this.indicatorTableData.forEach((item) => {
- item.checked = val.includes(item)
- })
- },
- handleCheckboxChange(row) {
- // 如果没有 cellCode,则不允许选中
- if (!row.cellCode) {
- this.$message.warning('该数据没有指标编号,无法选择')
- this.$set(row, 'checked', false)
- return
- }
- this.$set(row, 'checked', !row.checked)
- if (row.checked) {
- this.formatRowCode(row)
- }
- this.updateSelectedIndicatorCodes()
- this.$forceUpdate()
- },
- handleFormulaTextChange(value) {
- // 当用户手动修改公式文本时,标记为非自动生成
- this.isAutoGeneratedFormula = false
- },
- handleDialogClose(done) {
- this.selectedIndicatorsPerTemplate = {}
- done()
- },
- handleRadioChange(value) {
- this.formulaText = ''
- },
- handleConfirm() {
- const result = {
- type: this.radioType,
- formula: this.formulaText,
- selectedTemplate: this.selectedTemplateId,
- selectedItems: this.indicatorTableData.filter((item) => item.checked),
- }
- let _data = []
- if (this.radioType == 'current') {
- // 使用递归函数扁平化树形结构
- const flattenTree = (nodes) => {
- let result = []
- nodes.forEach((node) => {
- result.push(node)
- if (node.children && node.children.length > 0) {
- result = result.concat(flattenTree(node.children))
- }
- })
- return result
- }
- // 扁平化数据并提取cellCode
- _data = flattenTree(this.contentEditForm.fixedTable.fixedTables)
- .filter((item) => item.cellCode)
- .map((item) => item.cellCode)
- } else if (this.radioType == 'other') {
- if (!result.selectedTemplate) {
- this.$message.error('请选择指标编号')
- return
- }
- _data = this.indicatorTableData
- .filter((item) => item.cellCode)
- .map((item) => item.cellCode)
- }
- if (!this.validateFormula(this.formulaText, _data).valid) {
- this.$message.error(
- this.validateFormula(this.formulaText, _data).errorMsg
- )
- return
- }
- // 生成 jsonstr 字段
- const jsonStrArray = this.indicatorTableData
- .filter((item) => item.checked)
- .map((item) => {
- if (item.jsonStr) {
- try {
- return JSON.parse(item.jsonStr)[0]
- } catch (e) {
- console.error('解析 jsonStr 失败:', e)
- return {}
- }
- }
- return {}
- })
- .filter((item) => Object.keys(item).length > 0)
- const jsonstr = JSON.stringify(jsonStrArray)
- // 更新当前编辑行的计算公式值
- if (this.currentEditingRow) {
- this.$set(
- this.currentEditingRow,
- 'calculationFormula',
- this.formulaText
- )
- this.$set(this.currentEditingRow, 'jsonstr', jsonstr)
- }
- console.log('点击了确定,获取到的数据:', {
- ...result,
- jsonstr: jsonstr,
- })
- // 清空当前操作的状态
- this.calculationFormulaDialogVisible = false
- this.currentEditingRow = null
- this.currentEditingRowIndex = -1
- this.isAutoGeneratedFormula = false
- this.selectedTemplateId = ''
- this.indicatorTableData = []
- this.selectedIndicatorsPerTemplate = {} // 清空模板选中记录
- },
- /**
- * 解析并回显固定表项目数据
- * @param {Object} responseData - listByCurrentTemplateId接口返回的数据
- */
- parseAndDisplayFixedTableData(responseData) {
- if (responseData.value.fixedFields) {
- this.contentEditForm.fixedTable.fixedTablesTitle =
- this.stringToObjects(responseData.value.fixedFields || '')
- } else {
- let fixedFields = this.contentEditForm.fixedTable.tableHeaders
- .map((item) => item.fieldName)
- .join(',')
- this.contentEditForm.fixedTable.fixedTablesTitle =
- this.stringToObjects(fixedFields || '')
- }
- const fixedTitles = this.contentEditForm.fixedTable.fixedTablesTitle
- this.contentEditForm.fixedTable.fixedTableHeaders = fixedTitles.filter(
- (title) => title.rkey !== '序号'
- )
- if (
- !responseData ||
- !responseData.value ||
- !responseData.value.itemlist
- ) {
- return
- }
- const itemList = responseData.value.itemlist
- const allRows = []
- const rowMap = new Map()
- // 清空现有数据
- this.contentEditForm.fixedTable.fixedTables = []
- // 遍历itemList,为每个项目创建一行数据
- itemList.forEach((item, index) => {
- // 判断是否为子项(parentid不为-1且不为"-1")
- const isSubItem =
- item.parentid && item.parentid !== -1 && item.parentid !== '-1'
- const newRow = {
- orderText: item.orderNum || '', // 显示用序号
- orderNum: item.orderNum || '', // 保留原始序号用于发送后端
- surveyTemplateId: item.surveyTemplateId,
- versionId: item.versionId,
- cellCode: item.cellCode || '',
- calculationFormula: item.calculationFormula || '',
- unit: item.unit || '',
- fixedValues: {},
- itemId: item.id || null,
- parentid: item.parentid || -1,
- isChild: isSubItem,
- isSubItem: isSubItem,
- rowid: item.rowid || this.generateUUID(),
- jsonstr: item.jsonstr || null,
- children: [], // 添加children数组用于树形结构
- }
- // 确保orderNum是数字类型
- if (item.orderNum) {
- newRow.orderNum = parseInt(item.orderNum, 10) || 0
- }
- // 初始化fixedValues并填充实际值
- fixedTitles.forEach((title) => {
- newRow.fixedValues[title.rkey] = item[title.rkey] || ''
- })
- allRows.push(newRow)
- // 构建rowMap用于快速查找
- if (newRow.rowid) rowMap.set(String(newRow.rowid), newRow)
- if (newRow.itemId) rowMap.set(String(newRow.itemId), newRow)
- })
- // 构建树形结构
- const treeData = []
- const parentItems = allRows.filter((item) => !item.isChild)
- // 父级按orderNum正序排序
- parentItems.sort((a, b) => (a.orderNum || 0) - (b.orderNum || 0))
- // 将子项添加到对应的父项的children中
- allRows.forEach((item) => {
- if (item.isChild) {
- const parentId = String(item.parentid)
- const parent = rowMap.get(parentId)
- if (parent) {
- parent.children.push(item)
- }
- }
- })
- // 对子项进行排序
- parentItems.forEach((parent) => {
- parent.children.sort(
- (a, b) =>
- (a.fixedValues['序号'] || 0) - (b.fixedValues['序号'] || 0)
- )
- treeData.push(parent)
- })
- this.contentEditForm.fixedTable.fixedTables = treeData
- },
- /**
- * 将固定表项目的数据根据固定列拆分成对应的数据结构
- * @returns {Array} 拆分后的数据数组,每个固定列对应一行数据
- */
- splitFixedTableDataForSave() {
- const fixedTables = this.contentEditForm.fixedTable.fixedTables
- const fixedTitles = this.contentEditForm.fixedTable.fixedTablesTitle
- const fixedHeaders = this.contentEditForm.fixedTable.tableHeaders
- // 结果数组
- const result = []
- // 递归处理树形结构中的所有节点
- const processNode = (node, parentRowIndex = 0) => {
- // 确保node和fixedValues存在
- if (!node) {
- console.warn('遇到空节点,跳过处理')
- return
- }
- // 确保fixedValues属性存在,如果不存在则初始化为空对象
- if (!node.fixedValues) {
- node.fixedValues = {}
- }
- // 为每个固定列创建一条记录
- fixedTitles.forEach((title) => {
- // 找到对应的表头信息
- const correspondingHeader = fixedHeaders.find(
- (header) => header.fieldName === title.rkey
- )
- const newItem = {
- rkey: title.rkey,
- rvalue: node.fixedValues[title.rkey] || '',
- surveyTemplateId: node.surveyTemplateId || this.surveyTemplateId,
- versionId: node.versionId || this.versionId,
- tabtype: node.tabtype || this.templateType,
- // 添加 headersId 字段(表头的id)
- headersId: correspondingHeader ? correspondingHeader.id : null,
- // 添加记录的id(itemlist中每条记录的id)
- id: node.itemId || null,
- // 添加父子关系字段
- parentid: node.parentid || -1, // 父项ID,默认为-1表示无父项
- isChild: node.isChild || false, // 是否为子项
- // 添加 rowid 字段
- rowid: node.rowid || null,
- // 添加计算公式相关字段
- calculationFormula: node.calculationFormula || null,
- jsonstr: node.jsonstr || null,
- orderNum:
- typeof node.orderNum === 'number'
- ? node.orderNum
- : parseInt(node.orderNum, 10) || 0,
- }
- // 添加其他固定表特有的字段
- if (!node.isSubItem) {
- newItem.cellCode = node.cellCode || ''
- newItem.unit = node.unit || ''
- }
- // 添加其他可能需要的字段,但排除特定字段
- Object.keys(node).forEach((key) => {
- if (
- !(key in newItem) &&
- key !== 'fixedValues' &&
- key !== 'itemId' &&
- key !== 'id' &&
- key !== 'parentid' &&
- key !== 'isChild' &&
- key !== 'isSubItem' &&
- key !== 'rowid' &&
- key !== 'jsonstr' &&
- key !== 'calculationFormula' &&
- key !== 'children' // 排除children字段
- ) {
- newItem[key] = node[key]
- }
- })
- result.push(newItem)
- })
- // 递归处理子节点
- if (node.children && node.children.length > 0) {
- node.children.forEach((childNode) => {
- processNode(childNode)
- })
- }
- }
- // 遍历所有顶级节点
- fixedTables.forEach((row) => {
- processNode(row)
- })
- // 重新给子节点赋值orderNum 保证所有元素orderNum字段不重复
- // 为所有子节点分配唯一的orderNum,但保持父节点的orderNum不变
- // 计算所有已存在的orderNum中的最大值
- let maxExistingOrderNum = 0
- // 首先遍历结果数组找出当前最大的orderNum
- result.forEach((item) => {
- const orderNum =
- typeof item.orderNum === 'number'
- ? item.orderNum
- : parseInt(item.orderNum, 10) || 0
- if (orderNum > maxExistingOrderNum) {
- maxExistingOrderNum = orderNum
- }
- })
- // 子节点orderNum从当前最大orderNum + 1开始
- let childOrderNumCounter = maxExistingOrderNum + 1
- // 创建一个映射表,用于记录每个子节点对应的新orderNum
- const childOrderMap = new Map()
- // 第一次遍历:为每个子节点分配新的orderNum并存储映射关系
- function assignChildOrderNums(nodes) {
- nodes.forEach((node) => {
- if (node.isChild || node.isSubItem) {
- // 为每个子节点分配唯一的orderNum
- childOrderMap.set(node.id || node.rowid, childOrderNumCounter++)
- }
- // 递归处理子节点
- if (node.children && node.children.length > 0) {
- assignChildOrderNums(node.children)
- }
- })
- }
- // 第二次遍历:更新结果数组中的orderNum
- assignChildOrderNums(fixedTables)
- // 应用新的orderNum到结果数组
- result.forEach((item) => {
- // 只更新子节点的orderNum
- if (item.isChild || item.isSubItem) {
- const newOrderNum =
- childOrderMap.get(item.id) || childOrderMap.get(item.rowid)
- if (newOrderNum) {
- item.orderNum = newOrderNum
- }
- }
- })
- return result
- },
- //分割字符串
- stringToObjects(str) {
- const items = str.split(',')
- return items.map((item) => ({
- rkey: item,
- rvalue: '',
- }))
- },
- /**
- * 获取行缩进样式,用于树形结构展示
- * @param {Object} row - 表格行数据
- * @returns {Object} 样式对象
- */
- getRowIndentStyle(row) {
- // 为子项添加缩进
- if (row.isChild) {
- return {
- marginLeft: '30px',
- }
- }
- return {}
- },
- handleSaveTemplate() {
- // 校验表单
- this.$refs['contentEditForm'].validate((valid) => {
- if (valid) {
- if (this.dialogTitle == '修改成本核定模板') {
- let data = {
- ...this.contentEditForm,
- }
- delete data.fixedTable
- // 修改表单数据
- addCostVerifyForm(data).then((res) => {})
- }
- // 获取拆分后的数据
- const splitData = this.splitFixedTableDataForSave()
- const headersList =
- this.contentEditForm.fixedTable.tableHeaders.map(
- (header, index) => ({
- ...header,
- orderNum: header.orderNum || index + 1,
- })
- )
- let data = {
- costVerifyTemplateId: this.contentEditForm.surveyTemplateId,
- headersList: headersList,
- itemsList: splitData,
- }
- batchSaveOrUpdate(data)
- .then((data) => {
- this.dialogVisible = false
- this.$message.success('保存成功')
- this.handleSearch()
- })
- .catch((err) => {
- console.log(err)
- })
- } else {
- this.$message.error('请填写表单数据')
- return
- }
- })
- },
- // 批量删除
- handleBatchDelete() {
- if (this.selectedRows.length === 0) {
- this.$message.warning('请先选择要删除的数据')
- return
- }
- this.$confirm(
- `确定要删除选中的${this.selectedRows.length}条数据吗?`,
- '提示',
- {
- type: 'warning',
- }
- )
- .then(() => {
- const ids = this.selectedRows.map((row) => row.surveyTemplateId)
- batchDeleteCostVerifyForm(ids).then((res) => {
- if (res.code === 200) {
- this.selectedRows = []
- this.$message.success('批量删除成功')
- this.handleSearch()
- }
- })
- })
- .catch(() => {})
- },
- // 表格选择
- handleSelectionChange(selection) {
- this.selectedRows = selection
- },
- // 分页相关
- handleSizeChange(val) {
- this.searchForm.pageSize = val
- this.handleSearch()
- },
- handleCurrentChange(val) {
- this.searchForm.page = val
- this.handleSearch()
- },
- // 获取或设置序号字段
- getOrSetOrder(row, value) {
- // 如果提供了value参数,则设置值
- if (value !== undefined) {
- // 使用this.$set确保响应式更新
- if (row['序号'] === undefined) {
- this.$set(row, '序号', value)
- } else {
- row['序号'] = value
- }
- }
- // 如果没有提供value参数,则获取值
- return row['序号'] !== undefined && row['序号'] !== null
- ? row['序号']
- : row.orderNum || ''
- },
- // 公式验证函数
- validateFormula(formula, data) {
- if (!formula || typeof formula !== 'string') {
- return { valid: false, errorMsg: '公式不能为空' }
- }
- // 定义有效的操作符
- const operators = ['+', '-', '*', '/', '(', ')']
- // 检查是否包含至少一个操作符
- const hasOperator = operators.some((operator) =>
- formula.includes(operator)
- )
- if (!hasOperator) {
- return { valid: false, errorMsg: '公式必须包含操作符' }
- }
- // 检查值是否在data中存在
- function checkValueInData(value, data) {
- if (!data) return false
- if (Array.isArray(data)) {
- return data.includes(value)
- } else if (typeof data === 'object') {
- return Object.values(data).includes(value)
- }
- return data === value
- }
- // 提取公式中的变量/值
- function extractValues(formulaStr) {
- // 改进实现:支持形如"CeShi3.C2"的格式,提取点后面的部分作为变量,同时保留普通变量
- const result = new Set()
- // 1. 首先提取带点格式中的变量部分(如CeShi3.C2中的C2)
- const dotRegex = /[A-Za-z0-9]+\.([A-Za-z0-9]+)/g
- let dotMatch
- while ((dotMatch = dotRegex.exec(formulaStr)) !== null) {
- result.add(dotMatch[1]) // 提取点后面的部分作为变量
- }
- // 2. 然后提取普通变量(C3等),但排除已经从带点格式中提取的部分
- // 移除所有带点的部分,然后提取剩余的变量
- const remainingFormula = formulaStr.replace(
- /[A-Za-z0-9]+\.[A-Za-z0-9]+/g,
- ''
- )
- const normalRegex = /[A-Za-z0-9]+/g
- let normalMatch
- while ((normalMatch = normalRegex.exec(remainingFormula)) !== null) {
- // 跳过纯数字
- if (
- !isNaN(Number(normalMatch[0])) &&
- Number(normalMatch[0]).toString() === normalMatch[0]
- ) {
- continue
- }
- result.add(normalMatch[0])
- }
- return Array.from(result)
- }
- function checkOperatorContext(formulaStr, data) {
- for (let i = 0; i < formulaStr.length; i++) {
- const char = formulaStr[i]
- // 跳过括号
- if (char === '(' || char === ')') continue
- // 检查操作符
- if (operators.includes(char)) {
- // 检查操作符前是否有值(开头或不是操作符和左括号)
- if (
- i === 0 ||
- (operators.includes(formulaStr[i - 1]) &&
- formulaStr[i - 1] !== ')') ||
- formulaStr[i - 1] === '('
- ) {
- return {
- valid: false,
- errorMsg: `位置 ${i + 1} 的操作符 '${char}' 前缺少值`,
- }
- }
- // 检查操作符后是否有值(结尾或不是操作符和右括号)
- if (
- i === formulaStr.length - 1 ||
- (operators.includes(formulaStr[i + 1]) &&
- formulaStr[i + 1] !== '(') ||
- formulaStr[i + 1] === ')'
- ) {
- return {
- valid: false,
- errorMsg: `位置 ${i + 1} 的操作符 '${char}' 后缺少值`,
- }
- }
- }
- }
- // 验证通过后,检查公式中的值是否都在data中存在
- if (data.length > 0) {
- const values = extractValues(formulaStr)
- for (const value of values) {
- // 跳过纯数字(假设有值不在data中)
- if (!isNaN(Number(value)) && Number(value).toString() === value) {
- continue
- }
- if (!checkValueInData(value, data)) {
- return {
- valid: false,
- errorMsg: `变量 '${value}' 在数据中不存在`,
- }
- }
- }
- }
- return { valid: true }
- }
- // 执行验证
- return checkOperatorContext(formula, data)
- },
- },
- }
- </script>
- <style lang="scss" scoped>
- .row-indent-container {
- display: flex;
- align-items: center;
- position: relative;
- }
- .child-item {
- padding-left: 30px; /* 增加子项缩进,为'子项'文字留出空间 */
- }
- .child-item-indicator {
- position: absolute;
- left: 0;
- color: $base-color-default; /* 使用主题色,更醒目 */
- font-size: 12px;
- width: 30px;
- text-align: left;
- font-weight: 500;
- }
- @import '@/styles/costAudit.scss';
- .supervision-content-container {
- padding: 20px;
- .operation-bar {
- margin-bottom: 20px;
- }
- .table-container {
- .table-name-link {
- color: #409eff;
- cursor: pointer;
- &:hover {
- color: #66b1ff;
- text-decoration: underline;
- }
- }
- .pagination-container {
- margin-top: 20px;
- text-align: right;
- }
- }
- .content-form,
- .detail-form {
- ::v-deep .el-select {
- width: 100%;
- }
- }
- }
- </style>
|