ListItem.vue 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866
  1. <template>
  2. <div class="data-fill-list-box">
  3. <el-collapse v-model="ActiveKey" accordion @change="CollapseChange">
  4. <template v-for="(item, index) in listDatas" :key="item?.pKeyId">
  5. <el-collapse-item
  6. :id="`item-${index}-${item?.pKeyId}`" :disabled="item.isBussShow === 2"
  7. :name="`item-${index}-${item?.pKeyId}`"
  8. >
  9. <template #title>
  10. <div class="hc-collapse-item-header">
  11. <div class="text-lg truncate item-title">
  12. {{ item.nodeName }}
  13. </div>
  14. <div class="hc-extra-text-box">
  15. <HcTooltip v-if="item.isCopyTab === 1" keys="wbs_del_table">
  16. <el-button
  17. :disabled="item.isBussShow === 2" :loading="delClickLoading" plain
  18. type="danger" @click.stop="delClick(item, index)"
  19. >
  20. 删除本表
  21. </el-button>
  22. </HcTooltip>
  23. <HcTooltip keys="wbs_copy_table">
  24. <el-button
  25. :disabled="item.isBussShow === 2" :loading="copyClickLoading" plain
  26. type="primary" @click.stop="copyClick(item, index)"
  27. >
  28. 复制本表
  29. </el-button>
  30. </HcTooltip>
  31. <HcTooltip keys="wbs_hide_table">
  32. <el-button plain type="primary" @click.stop="hideClick(item, index)">
  33. <template v-if="item.isBussShow === 1">
  34. 隐藏本表
  35. </template>
  36. <template v-else>
  37. 显示本表
  38. </template>
  39. </el-button>
  40. </HcTooltip>
  41. <HcTooltip keys="wbs_preview_table">
  42. <el-button
  43. v-if="item.isBussShow === 2 || item.isTabPdf === 1" disabled plain
  44. type="info"
  45. >
  46. 预览
  47. </el-button>
  48. <el-button v-else plain type="primary" @click.stop="previewClick(item, index)">
  49. 预览
  50. </el-button>
  51. </HcTooltip>
  52. <HcTooltip keys="wbs_upload_table">
  53. <el-button
  54. :disabled="item.isBussShow === 2" :type="item.tabFileType === 2 ? 'success' : 'primary'"
  55. plain
  56. @click.stop="uploadClick(item, index)"
  57. >
  58. <template v-if="item.tabFileType === 2">
  59. 已上传
  60. </template>
  61. <template v-else>
  62. 上传
  63. </template>
  64. </el-button>
  65. </HcTooltip>
  66. </div>
  67. </div>
  68. </template>
  69. <div class="data-fill-list-item-content">
  70. <div v-if="item?.isWindow" class="data-fill-table-form-box is-window">
  71. <div class="hc-window-tip">
  72. <div class="table-form-no">
  73. <img :src="NoDataSvg" alt="">
  74. <div class="desc">
  75. 当前表单处于窗口模式,关闭相关窗口后恢复
  76. </div>
  77. </div>
  78. </div>
  79. </div>
  80. <div v-else class="data-fill-table-form-box">
  81. <div :id="`table-form-${item?.pKeyId}`" class="hc-excel-table-form-view" />
  82. <div v-if="item?.isTableForm === false" class="hc-no-table-form">
  83. <div class="table-form-no">
  84. <img :src="notableform" alt="">
  85. <div class="desc">
  86. 暂无表单数据
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. <div class="hc-window-switch-box">
  92. <el-tooltip
  93. :content="item.isWindow ? '关闭窗口并恢复' : '当前表单窗口化'" :hide-after="0"
  94. placement="top"
  95. >
  96. <div class="icon-btn-view">
  97. <template v-if="item.isWindow">
  98. <HcIcon class="icon" name="picture-in-picture-2" />
  99. <span class="ml-1" @click.stop="windowCloseClick(item, index)">关闭窗口化</span>
  100. </template>
  101. <template v-else>
  102. <HcIcon class="icon" name="picture-in-picture-exit" />
  103. <span class="ml-1" @click.stop="windowClick(item, index)">表单窗口化</span>
  104. </template>
  105. </div>
  106. </el-tooltip>
  107. </div>
  108. <div class="data-fill-table-tip-box">
  109. <div class="text-orange tip-title">
  110. <HcIcon fill name="error" ui="text-2xl" />
  111. <span class="ml-1">提示</span>
  112. </div>
  113. <div class="text-gray-400 tip-item">
  114. 1、灰色框代表可通过系统识别计算,公式自动引用,可通过公式计算少量数据,(表头数据及简单),也可只填写白色框数据
  115. </div>
  116. <div class="text-gray-400 tip-item">
  117. 2、系统支持键盘中,shift +
  118. tab键向上一个填报框切换,tab向下一个填报框切换。暂不支持上下按键切换输入框
  119. </div>
  120. <div class="table-tip-foot">
  121. <div class="tip-left-btn">
  122. <HcTooltip keys="wbs_import_table">
  123. <div class="text-gray-400 dow-text">
  124. <HcIcon name="publish" ui="text-lg" />
  125. <span class="ml-1">导入列表数据</span>
  126. </div>
  127. </HcTooltip>
  128. <HcTooltip keys="wbs_download_table">
  129. <div class="text-main dow-text">
  130. <HcIcon name="file_download" ui="text-lg" />
  131. <span class="ml-1">下载导入模板</span>
  132. </div>
  133. </HcTooltip>
  134. </div>
  135. <div class="tip-right-btn">
  136. <HcTooltip keys="wbs_save_table">
  137. <el-button
  138. :disabled="NodeStatusval === '3'" :loading="tableFormSaveLoading" hc-btn
  139. type="primary"
  140. @click="tableFormSaveClick(item, index)"
  141. >
  142. <HcIcon name="save" />
  143. <span>保存</span>
  144. </el-button>
  145. </HcTooltip>
  146. </div>
  147. </div>
  148. </div>
  149. </div>
  150. </el-collapse-item>
  151. </template>
  152. </el-collapse>
  153. </div>
  154. <!-- 右键菜单 -->
  155. <HcContextMenu ref="contextMenuRef" :datas="tableFormMenu" @item-click="handleMenuSelect" />
  156. <!-- 上传文件 -->
  157. <HcDialog :footer="false" :show="uploadModal" title="上传文件" widths="38rem" @close="uploadModal = false">
  158. <HcUpload
  159. :base-data="baseData" :contract-id="contractId" :datas="uploadData" :file-list="fileListData"
  160. :table-type-value="tableTypeValue" @change="uploadChange"
  161. />
  162. </HcDialog>
  163. <!-- 插入特殊字符 -->
  164. <HcDialog
  165. :show="specialModal" save-text="确认插入" title="插入特殊字符" widths="600px" @close="specialModal = false"
  166. @save="specialNodeClick"
  167. >
  168. <el-form
  169. ref="specialFormRef" :model="specialFormModel" :rules="specialFormRules" class="mb-6" label-width="0px"
  170. size="large"
  171. >
  172. <el-form-item class="special-form-item" prop="val">
  173. <el-input
  174. id="specialId" ref="specialRef" v-model="specialFormModel.val"
  175. clearable placeholder="请选择特殊字符代码" @blur="specialInputBlur"
  176. />
  177. </el-form-item>
  178. </el-form>
  179. <el-row :gutter="20" style="margin: -10px;">
  180. <el-col v-for="item in specialCharacters" :key="item" :span="3" style="padding: 10px;">
  181. <div class="special-box" @click="specialClick">
  182. <span :title="`字符代码(C):${item !== 'K̅' ? item.slice(2, 7) : 'K̅'}`" class="font-EUDC" v-html="item" />
  183. </div>
  184. </el-col>
  185. </el-row>
  186. </HcDialog>
  187. <!-- 引用容器参数 -->
  188. <HcDialog
  189. :show="vesselModal" is-table save-text="确认引用" title="引用容器参数" widths="84%"
  190. @close="vesselModalClose" @save="vesselModalSave"
  191. >
  192. <div class="adding-form-dialog-box">
  193. <div class="dialog-tree-box">
  194. <el-scrollbar>
  195. <HcMenuSimple :datas="menus" :keys="menuKey" :props="menuProps" @change="menuChange" />
  196. </el-scrollbar>
  197. </div>
  198. <div class="dialog-table-box">
  199. <div class="dialog-table">
  200. <HcTable
  201. ref="vesselTableRef" :column="vesselTableColumn" :datas="vesselTableData"
  202. :loading="vesselTableLoading" is-check @selection-change="vesselTableSelection"
  203. />
  204. </div>
  205. <div class="dialog-pages">
  206. <HcPages :pages="vesselTablePage" @change="vesselTablePageChange" />
  207. </div>
  208. </div>
  209. </div>
  210. </HcDialog>
  211. <!-- 引用设备仪器 -->
  212. <HcDialog
  213. :show="deviceModal" is-table save-text="确认引用" title="引用设备仪器" widths="84%"
  214. @close="deviceModalClose" @save="deviceModalSave"
  215. >
  216. <!-- <HcTable ref="deviceTableRef" :column="deviceTableColumn" :datas="deviceTableData" :loading="deviceTableLoading" isCheck @selection-change="deviceTableSelection"/> -->
  217. <div class="adding-form-dialog-box">
  218. <div class="dialog-tree-box">
  219. <el-scrollbar>
  220. <HcMenuSimple
  221. :datas="equipmentmenus" :keys="equipmentmenuKey" :props="equipmentmenuProps"
  222. @change="equipmentmenuChange"
  223. />
  224. </el-scrollbar>
  225. </div>
  226. <div class="dialog-table-box">
  227. <div class="dialog-table">
  228. <HcTable
  229. ref="deviceTableRef" :column="deviceTableColumn" :datas="deviceTableData"
  230. :loading="deviceTableLoading" is-check @selection-change="deviceTableSelection"
  231. />
  232. </div>
  233. <div class="dialog-pages">
  234. <HcPages :pages="equipmentPage" @change="equipmentTablePageChange" />
  235. </div>
  236. </div>
  237. </div>
  238. </HcDialog>
  239. <!-- 查看表单 -->
  240. <template v-for="(item, index) in DragModalTableForm">
  241. <HcDragModal
  242. :close-icon-arr="closeIconArr" :eid="item.pKeyId" :height="DragModalHeight" :is-show="item.isShow"
  243. :loading="item.loading" :loading-text="item.loadingText" :title="item.title"
  244. is-sort-top
  245. @close="TableFormClose(item, index, true)" @closeIconTap="closeIconTap($event, item, index)"
  246. >
  247. <HcDragNode v-loading="item.tableFormSaveLoading" :more-menu="dragNodeMoreMenu" @menuTap="dragNodeMoreMenuTap($event, item, index)">
  248. <div :id="`table-form-${item?.item.pKeyId}`" class="hc-excel-table-form-view" :style="`width:${item.width};height:${item.height};`" />
  249. <div v-if="item?.isTableForm === false" class="hc-no-table-form">
  250. <div class="table-form-no">
  251. <img :src="notableform" alt="">
  252. <div class="desc">
  253. 暂无表单数据
  254. </div>
  255. </div>
  256. </div>
  257. </HcDragNode>
  258. </HcDragModal>
  259. </template>
  260. </template>
  261. <script setup>
  262. import { nextTick, ref, watch } from 'vue'
  263. import { useAppStore } from '~src/store'
  264. import { useRoute } from 'vue-router'
  265. import wbsApi from '~api/data-fill/wbs'
  266. import HcUpload from './HcUpload.vue'
  267. import HTableForm from '~src/plugins/HTableForm'
  268. import dataApi from '~api/tentative/detect/test'
  269. import dataApi1 from '~api/tentative/parameter/container'
  270. import dataApi2 from '~api/tentative/device/approach'
  271. import { getClassList } from '~api/tentative'
  272. import notableform from '~src/assets/view/notableform.svg'
  273. import NoDataSvg from '~src/assets/view/no-data.svg'
  274. import {
  275. arrIndex,
  276. base64ToFile,
  277. deepClone,
  278. formValidate,
  279. getArrValue,
  280. getObjVal,
  281. getObjValue,
  282. isString,
  283. setPosInsert,
  284. setPosRange,
  285. } from 'js-fast-way'
  286. import ossApi from '~api/oss'
  287. //初始
  288. const props = defineProps({
  289. datas: {
  290. type: Array,
  291. default: () => ([]),
  292. },
  293. status: {
  294. type: [String, Number],
  295. default: '',
  296. },
  297. baseData: {
  298. type: Object,
  299. default: () => ({}),
  300. },
  301. deviceUseIds: {
  302. type: String,
  303. default: () => (''),
  304. },
  305. authBtnTabKey: {
  306. type: String,
  307. default: () => (''),
  308. },
  309. checkTableId: {
  310. type: String,
  311. default: () => (''),
  312. },
  313. tabTypeKey: {
  314. type: String,
  315. default: () => (''),
  316. },
  317. nodeIdvalue: {
  318. type: String,
  319. default: () => (''),
  320. },
  321. alllistData: {
  322. type: Array,
  323. default: () => ([]),
  324. },
  325. nodeStatus: {
  326. type: String,
  327. default: () => (''),
  328. },
  329. })
  330. //事件
  331. const emit = defineEmits(['renew', 'offsetTop', 'updeviceUseIds', 'upcheckTableId', 'changesdate', 'chageorinData', 'changeIscanclick', 'changesingSaveId'])
  332. const useRoutes = useRoute()
  333. //路由参数
  334. const routerQuery = useRoutes?.query
  335. const isaddType = routerQuery?.isaddType || false
  336. const listDatas = ref(props.datas)
  337. const isStatus = ref(props.status)
  338. const baseData = ref(props.baseData)
  339. const authBtnTabKeyType = ref(props.authBtnTabKey)//所属方
  340. const useAppState = useAppStore()
  341. const projectId = ref(useAppState.getProjectId)
  342. const contractId = ref(useAppState.getContractId)
  343. const tabTypeKeyInfo = ref(props.tabTypeKey)
  344. const nodeIdvaluedata = ref(props.nodeIdvalue)
  345. const alllistDataval = ref(props.alllistData)
  346. const NodeStatusval = ref(props.NodeStatus)
  347. //监听
  348. watch(() => [
  349. props.datas,
  350. props.tabTypeKey,
  351. props.alllistData,
  352. props.NodeStatus,
  353. ], ([datas, TabTypeKey, AlllistData, NodeStatus]) => {
  354. listDatas.value = datas
  355. listDatas.value.forEach((item) => {
  356. if (item.pKeyId === singleSaveid.value) {
  357. item.isCancopy = true
  358. }
  359. })
  360. tabTypeKeyInfo.value = TabTypeKey
  361. alllistDataval.value = AlllistData
  362. NodeStatusval.value = NodeStatus
  363. setFormDataNum(datas)
  364. })
  365. //监听
  366. watch(() => [
  367. props.status,
  368. props.baseData,
  369. props.nodeIdvalue,
  370. ], ([val, base, NodeIdvalue]) => {
  371. //1 未填报,2待上报,3已上报
  372. isStatus.value = val
  373. baseData.value = base
  374. nodeIdvaluedata.value = NodeIdvalue
  375. })
  376. //渲染完成
  377. nextTick(() => {
  378. setFormDataNum(props.datas)
  379. })
  380. //获取pKeyId
  381. const getValString = (val) => {
  382. return val ? val + '' : ''
  383. }
  384. //获取表单初始数据
  385. const getFormDataInit = ({ projectId, cid, pKeyId, isBussShow }) => {
  386. const { nodeId, contractId } = baseData.value
  387. return {
  388. projectId: projectId,
  389. contractId: cid || contractId,
  390. pkeyId: getValString(pKeyId),
  391. nodeId: nodeId,
  392. isBussShow: isBussShow,
  393. }
  394. }
  395. //设置表单对象的数量
  396. const formData = ref([])
  397. const formLinkIdData = ref({})
  398. const setFormDataNum = (datas) => {
  399. ActiveKey.value = ''
  400. let newArr = []
  401. for (let i = 0; i < datas.length; i++) {
  402. newArr.push({
  403. ...getFormDataInit(datas[i]),
  404. isCollapseLoad: false,
  405. })
  406. }
  407. formData.value = newArr
  408. //处理关联表
  409. let newDataObj = {}
  410. for (let i = 0; i < datas.length; i++) {
  411. const item = datas[i]
  412. newDataObj[item.pKeyId] = {
  413. tableId: item.initTableId,
  414. isMain: item.isCopyTab === 0,
  415. mainId: item.isCopyTab === 0 ? item.pKeyId : '',
  416. linkId: [],
  417. }
  418. //获取关联表
  419. datas.forEach((items) => {
  420. if (items.initTableId === item.initTableId && item.pKeyId !== items.pKeyId) {
  421. newDataObj[item.pKeyId].linkId.push(items.pKeyId)
  422. if (items.isCopyTab === 0) {
  423. newDataObj[item.pKeyId].mainId = items.pKeyId
  424. }
  425. }
  426. })
  427. }
  428. formLinkIdData.value = newDataObj
  429. }
  430. const sampledata = ref([])
  431. const positiondata = ref([])
  432. //展开事件
  433. const ActiveKey = ref('')
  434. const formKeyIds = ref('')
  435. const CollapseChange = async (name) => {
  436. ActiveKey.value = name
  437. const names = name ? name.split('-') : []
  438. formData.value.forEach((changeitem) => {
  439. if (changeitem.pkeyId === names[2]) {
  440. changeitem.isCollapseLoad = true
  441. }
  442. })
  443. if (names.length > 0) {
  444. getOffsetTop(name)
  445. const index = names[1]
  446. let item = listDatas.value[index]
  447. emit('upcheckTableId', item.pKeyId)
  448. emit('changeIscanclick', item.pKeyId)
  449. formKeyIds.value = getValString(item.pKeyId)
  450. alllistDataval.value.forEach((item1) => {
  451. // eslint-disable-next-line eqeqeq
  452. if (item1.pkeyId == item.pKeyId) {
  453. if (item1.oper) {
  454. item.isTableFormRender = true
  455. item = item1
  456. item.pKeyId = item1.pkeyId
  457. }
  458. }
  459. })
  460. if (!item.isTableFormRender) {
  461. await getBussDataInfo(item, index)
  462. } else {
  463. await getBussDataInfo1(item, index)
  464. }
  465. //渲染表单
  466. await getExcelHtml(item, index)
  467. const { key, data } = await getChartConfig()
  468. if (key) formData.value[index][key] = data
  469. } else {
  470. // await getExcelHtml(item,index)
  471. getOffsetTop()
  472. formKeyIds.value = ''
  473. }
  474. }
  475. //获取模板标签数据
  476. const formRegExpJson = ref({})
  477. const getExcelHtml = async (item, index) => {
  478. const pkeyIds = getValString(item.pKeyId)
  479. if (pkeyIds) {
  480. const { id } = baseData.value
  481. const { error, code, data } = await dataApi.getExcelHtml({
  482. id: id || nodeIdvaluedata.value || newaddId.value,
  483. primaryKeyId: pkeyIds,
  484. }, false)
  485. const resData = isString(data) ? data || '' : ''
  486. if (!error && code === 200 && resData) {
  487. item.isTableForm = true
  488. //渲染表单
  489. HTableForm.createForm({
  490. template: resData,
  491. tableForm: formData.value[index],
  492. appId: `#table-form-${pkeyIds}`,
  493. onChartRefs: (el, pKeyId, key) => {
  494. setChartRefs(el, pKeyId, key)
  495. },
  496. onRight: (event, KeyName) => {
  497. onRightClick(event, KeyName, index)
  498. },
  499. //表单正则效验
  500. onBlur: (event, key, reg, val, msg, type) => {
  501. setTableFormBlurReg(pkeyIds, event, key, reg, val, msg, item, index)
  502. if (type === 'chart') {
  503. chartKey.value = formData.value[index].formchartKeyShow
  504. getBlurChartConfig(formData.value[index])
  505. }
  506. },
  507. })
  508. item.isTableFormRender = true
  509. item.isRenderTableForm = true
  510. } else {
  511. item.isTableForm = false
  512. item.isRenderTableForm = true
  513. window?.$message?.warning('暂无表单')
  514. }
  515. } else {
  516. item.isTableForm = false
  517. item.isRenderTableForm = false
  518. window?.$message?.warning('pkeyId为空')
  519. }
  520. }
  521. //图表ref
  522. const chartRefs = ref([])
  523. const setChartRefs = async (el, pKeyId, key) => {
  524. if (el) {
  525. const { index } = await getChartRef(pKeyId, key)
  526. if (index !== -1) {
  527. chartRefs.value[index].ref = el
  528. } else {
  529. chartRefs.value.push({ pKeyId: pKeyId, key: key, ref: el })
  530. }
  531. }
  532. }
  533. //获取图表的ref
  534. const getChartRef = async (pKeyId, key) => {
  535. let refs = chartRefs.value, refVal, index = -1
  536. for (let i = 0; i < refs.length; i++) {
  537. if (refs[i].pKeyId === pKeyId && refs[i].key === key) {
  538. refVal = refs[i].ref
  539. index = i
  540. break
  541. }
  542. }
  543. return { ref: refVal, index: index }
  544. }
  545. //图表信息
  546. const chartKey = ref('')
  547. const getBlurChartConfig = async (form = {}) => {
  548. if (chartKey.value) {
  549. let { formChartKey } = form, formKeys = {}, keyId = formKeyIds.value
  550. formKeys[keyId] = {}
  551. const chartKeys = formChartKey ? formChartKey.split(',') : []
  552. chartKeys.forEach((item) => {
  553. formKeys[keyId][item] = form[item] ?? ''
  554. })
  555. //关联表单的key
  556. const { linkId } = formLinkIdData.value[keyId]
  557. for (let i = 0; i < linkId.length; i++) {
  558. const newKey = linkId[i]
  559. formKeys[newKey] = {}
  560. formKeys = await getFormChartKey(formKeys, newKey)
  561. }
  562. //更新图表配置
  563. const { key, data } = await getChartConfig(formKeys)
  564. if (key) {
  565. form[key] = data
  566. const { ref } = await getChartRef(keyId, key)
  567. ref?.setOptions(data)
  568. }
  569. } else {
  570. console.log('formchartKeyShow 为空')
  571. }
  572. }
  573. //获取表单的图表数据
  574. const getFormChartKey = async (formKeys, key) => {
  575. const index = formData.value.findIndex((item) => item.pkeyId === key)
  576. const form = formData.value[index], { formChartKey } = form
  577. const chartKeys = formChartKey ? formChartKey.split(',') : []
  578. chartKeys.forEach((item) => {
  579. formKeys[key][item] = form[item] ?? ''
  580. })
  581. return formKeys
  582. }
  583. //获取图片配置
  584. const getChartConfig = async (form = {}) => {
  585. if (chartKey.value) {
  586. const { id } = baseData.value
  587. const { data } = await dataApi.getChartInit({
  588. id: id || nodeIdvaluedata.value || newaddId.value,
  589. pkeyId: formKeyIds.value,
  590. data: form,
  591. })
  592. return {
  593. key: chartKey.value,
  594. data: getObjValue(data),
  595. }
  596. } else {
  597. console.log('formchartKeyShow 为空')
  598. return { key: '', data: {} }
  599. }
  600. }
  601. //正则效验
  602. const setTableFormBlurReg = (pkeyId, event, key, reg, val, msg, item, index) => {
  603. const dom = document.getElementById(key)?.parentElement ?? ''
  604. if (dom) {
  605. if (val && reg) {
  606. let regx = new RegExp(reg)
  607. let state = regx.test(val)
  608. if (state) {
  609. delete formRegExpJson.value[pkeyId]
  610. dom.style = ''
  611. } else {
  612. formRegExpJson.value[pkeyId] = {
  613. key,
  614. reg,
  615. val,
  616. msg,
  617. state,
  618. nodeName: item.nodeName,
  619. itemId: `item-${index}-${item?.pKeyId}`,
  620. }
  621. dom.style = '--el-input-border-color: #fe0000; box-shadow: 0 0 0 2px #fe0000 inset;'
  622. window?.$message?.warning(msg)
  623. }
  624. } else {
  625. delete formRegExpJson.value[pkeyId]
  626. dom.style = ''
  627. }
  628. }
  629. }
  630. //关联取样成功改变所有表格取样名称数据
  631. const getsampleData = () => {
  632. if (sampledata.value.length > 0) {
  633. formData.value.forEach((ele) => {
  634. sampledata.value.forEach((item) => {
  635. if (item.tabPKeyId === ele.pkeyId) {
  636. for (let i in item) {
  637. ele[i] = item[i]
  638. }
  639. }
  640. })
  641. })
  642. }
  643. }
  644. //getPositionData关联取样成功改变所有表格工程部位数据
  645. const getPositionData = () => {
  646. if (positiondata.value.length > 0) {
  647. formData.value.forEach((ele) => {
  648. positiondata.value.forEach((item) => {
  649. if (item.tabPKeyId === ele.pkeyId) {
  650. for (let i in item) {
  651. ele[i] = item[i]
  652. }
  653. }
  654. })
  655. })
  656. }
  657. }
  658. const changeSimpleInput = (infodata) => {
  659. sampledata.value = infodata
  660. getsampleData()
  661. }
  662. const changePositionInput = (infodata) => {
  663. positiondata.value = infodata
  664. getPositionData()
  665. }
  666. //获取已填写的数据
  667. const getBussDataInfo = async (item, index) => {
  668. const pkeyIds = getValString(item.pKeyId)
  669. const { contractId } = baseData.value
  670. if (pkeyIds) {
  671. const { id } = baseData.value
  672. const { error, code, data } = await dataApi.getBussDataInfo({
  673. id: id || nodeIdvaluedata.value || newaddId.value,
  674. pkeyId: pkeyIds,
  675. contractId: contractId,
  676. }, false)
  677. emit('changesingSaveId', pkeyIds)
  678. if (item.oper) {
  679. HTableForm.setPickerKey([item])
  680. formData.value[index] = {
  681. ...item,
  682. isCollapseLoad: true,
  683. }
  684. getsampleData()
  685. getPositionData()
  686. } else {
  687. data.forEach((item1) => {
  688. const resData = getObjVal(item1)
  689. if (!error && code === 200 && resData) {
  690. HTableForm.setPickerKey(resData)
  691. const InitObj = getFormDataInit(item) //有数据,关联数据
  692. formData.value[index] = {
  693. ...resData, ...InitObj,
  694. isCollapseLoad: true,
  695. }
  696. getsampleData()
  697. getPositionData()
  698. } else {
  699. formData.value[index] = {
  700. ...getFormDataInit(item),
  701. isCollapseLoad: true,
  702. }
  703. getsampleData()
  704. getPositionData()
  705. }
  706. })
  707. }
  708. chartKey.value = formData.value[index].formchartKeyShow
  709. } else {
  710. window?.$message?.warning('pkeyId为空')
  711. }
  712. }
  713. const getBussDataInfo1 = async (item, index) => {
  714. const pkeyIds = getValString(item.pKeyId)
  715. if (pkeyIds) {
  716. if (item.oper) {
  717. HTableForm.setPickerKey([item])
  718. formData.value[index] = {
  719. ...item,
  720. isCollapseLoad: true,
  721. }
  722. }
  723. chartKey.value = formData.value[index].formchartKeyShow
  724. } else {
  725. window?.$message?.warning('pkeyId为空')
  726. }
  727. }
  728. //单个保存
  729. const tableFormSaveLoading = ref(false)
  730. const singleSaveid = ref('')
  731. const tableFormSaveClick = async (item, index) => {
  732. if (isStatus.value !== '3') {
  733. singleSaveid.value = item.pKeyId
  734. emit('changesingSaveId', item.pKeyId)
  735. if (tabTypeKeyInfo.value === '2' && baseData.value['detectionResult'] === '') {
  736. window.$message?.warning('请选择是否合格')
  737. } else {
  738. const res = await saveExcelBussData(item, index)
  739. if (res) {
  740. if (!isaddType) {
  741. await getBussPdfInfo(item)
  742. } else {
  743. await getBussPdfInfo(item)
  744. }
  745. renewData(newaddId.value)
  746. }
  747. }
  748. } else {
  749. window?.$message?.warning('已上报的资料,不允许保存。')
  750. }
  751. }
  752. //上传图表的图片
  753. const uploadChartImgFile = async (base64) => {
  754. let fileOfBlob = base64ToFile(base64)
  755. let formData = new FormData()
  756. formData.append('file', fileOfBlob)
  757. //上传文件
  758. const { error, code, data } = await ossApi.putFile(formData, false)
  759. if (!error && code === 200) {
  760. let res = getObjValue(data)
  761. if (res?.link) {
  762. return res.link
  763. } else {
  764. return ''
  765. }
  766. } else {
  767. return ''
  768. }
  769. }
  770. const newaddId = ref('')
  771. //保存表单数据
  772. const saveExcelBussData = async (item, index, showTip = true) => {
  773. if (!getObjVal(formRegExpJson.value)) {
  774. tableFormSaveLoading.value = true
  775. const InitObj = getFormDataInit(item)
  776. if (chartKey.value) {
  777. const { ref } = await getChartRef(item.pKeyId, chartKey.value)
  778. const url = await uploadChartImgFile(ref?.getImage())
  779. const name = `${chartKey.value}_url`
  780. InitObj[name] = url
  781. }
  782. baseData.value.tableType = tabTypeKeyInfo.value
  783. if (newaddId.value.length > 0) {
  784. baseData.value.id = newaddId.value
  785. }
  786. const { error, code, data } = await dataApi.saveExcelBussData({
  787. ...baseData.value,
  788. isBatchSave: 0,
  789. dataInfo: {
  790. orderList: [{ ...formData.value[index], ...InitObj }],
  791. },
  792. })
  793. //处理数据
  794. tableFormSaveLoading.value = false
  795. if (!error && code === 200) {
  796. if (showTip) window?.$message?.success('保存成功')
  797. newaddId.value = data
  798. return true
  799. } else {
  800. return false
  801. }
  802. } else {
  803. window?.$message?.warning('请先修改完红色输入框的数据')
  804. return false
  805. }
  806. }
  807. //预览PDF
  808. const getBussPdfInfo = async ({ pKeyId }, showTip = true) => {
  809. const pkeyIds = getValString(pKeyId)
  810. if (pkeyIds) {
  811. const { id } = baseData.value
  812. const { error, code, data } = await dataApi.getBussPdf({
  813. id: id.length > 0 ? id : newaddId.value,
  814. pKeyId: pkeyIds,
  815. }, false)
  816. if (!error && code === 200) {
  817. if (data) {
  818. window.open(data, '_blank')
  819. } else if (showTip) {
  820. window?.$message?.warning('PDF错误')
  821. }
  822. } else {
  823. if (showTip) {
  824. window?.$message?.warning(data.msg || '获取PDF失败')
  825. }
  826. }
  827. } else {
  828. window?.$message?.warning('pkeyId为空')
  829. }
  830. }
  831. const delClickLoading = ref(false)
  832. //删除本表
  833. const delClick = async ({ pKeyId }) => {
  834. const pkeyIds = getValString(pKeyId)
  835. if (pkeyIds) {
  836. const { id } = baseData.value
  837. delClickLoading.value = true
  838. const { error, code } = await dataApi.removeBussTabInfo({
  839. // id: id,
  840. pKeyId: pkeyIds,
  841. })
  842. if (!error && code === 200) {
  843. window?.$message?.success('操作成功')
  844. renewData(id)
  845. delClickLoading.value = false
  846. } else {
  847. delClickLoading.value = false
  848. }
  849. } else {
  850. window?.$message?.warning('pkeyId为空')
  851. delClickLoading.value = false
  852. }
  853. }
  854. const copyClickLoading = ref(false)
  855. //复制本表
  856. const copyClick = async (item, index) => {
  857. const pkeyIds = getValString(item.pKeyId)
  858. if (pkeyIds) {
  859. if (isStatus.value !== '3') {
  860. if (item.isRenderTableForm && !item.isCancopy) {
  861. // window.$message.warning('请先保存数据再复制本表')
  862. copyClickLoading.value = true
  863. const res = await saveExcelBussData(item, index)
  864. if (res) {
  865. // renewData(newaddId.value)
  866. await copeBussTab(pkeyIds)
  867. } else {
  868. window?.$message?.warning('复制本表操作失败')
  869. }
  870. } else {
  871. if (!item.isRenderTableForm) {
  872. await copeBussTab(pkeyIds)
  873. } else if (!item.isTableForm) {
  874. window?.$message?.warning('暂无表单数据')
  875. } else if (item.isRenderTableForm) {
  876. await copeBussTab(pkeyIds)
  877. } else {
  878. window?.$message?.warning(`数据异常了, isRenderTableForm: ${item.isRenderTableForm}, isTableForm: ${item.isTableForm}, pKeyId:${pkeyIds}`)
  879. }
  880. }
  881. } else {
  882. window?.$message?.warning('已上报的资料,不允许复制')
  883. }
  884. } else {
  885. window?.$message?.warning('pkeyId为空')
  886. }
  887. }
  888. const copeBussTab = async (pkeyIds) => {
  889. const { id, contractId } = baseData.value
  890. copyClickLoading.value = true
  891. const { error, code } = await dataApi.copyBussTab({
  892. id: id || newaddId.value,
  893. pKeyId: pkeyIds,
  894. contractId: contractId,
  895. })
  896. if (!error && code === 200) {
  897. window?.$message?.success('操作成功')
  898. renewData(id)
  899. chageOrinData()
  900. }
  901. copyClickLoading.value = false
  902. }
  903. //隐藏本表
  904. const hideClick = async ({ pKeyId, isBussShow }) => {
  905. const pkeyIds = getValString(pKeyId)
  906. if (pkeyIds) {
  907. if (isStatus.value !== '3') {
  908. const { id } = baseData.value
  909. const isBussShows = isBussShow === 2 ? 1 : 2 //状态(1显示 2隐藏)
  910. const { error, code } = await dataApi.showBussTab({
  911. id: id,
  912. pKeyId: pkeyIds,
  913. status: isBussShows,
  914. })
  915. if (!error && code === 200) {
  916. window?.$message?.success('操作成功')
  917. renewData(id)
  918. changeisHide(pkeyIds, isBussShow)
  919. }
  920. } else {
  921. window?.$message?.warning('已上报的资料,不允许隐藏')
  922. }
  923. } else {
  924. window?.$message?.warning('pkeyId为空')
  925. }
  926. }
  927. //预览
  928. const previewClick = async (item) => {
  929. await getBussPdfInfo(item)
  930. }
  931. //上传变量
  932. const uploadModal = ref(false)
  933. const fileListData = ref([])
  934. const uploadData = ref({})
  935. const tableTypeValue = ref('')
  936. //上传被点击
  937. const uploadClick = (item, index) => {
  938. const pkeyIds = item.pKeyId ? item.pKeyId + '' : ''
  939. const { id } = baseData.value
  940. const tableType = item.tableType ? item.tableType : ''
  941. tableTypeValue.value = item.tableType ? item.tableType : ''
  942. const classify = authBtnTabKeyType.value
  943. const keyName = `item-${index}-${pkeyIds}`
  944. if (pkeyIds) {
  945. if (isStatus.value !== '3' && item.isTableForm) {
  946. uploadModal.value = true
  947. uploadData.value = getFormDataInit(item, pkeyIds)
  948. uploadData.value.tableType = tableType
  949. uploadData.value.classify = classify
  950. uploadData.value.id = id
  951. //获取文件列表
  952. getBussFileList(pkeyIds)
  953. } else if (!item.isRenderTableForm) {
  954. CollapseChange(keyName)
  955. window?.$message?.warning('请再次点击上传')
  956. } else if (!item.isTableForm) {
  957. window?.$message?.warning('暂无表单数据')
  958. } else {
  959. window?.$message?.warning('已上报的资料,不允许上传')
  960. }
  961. } else {
  962. window?.$message?.warning('pkeyId为空')
  963. }
  964. }
  965. //获取文件列表
  966. const getBussFileList = async (pkeyId) => {
  967. const { id } = baseData.value
  968. const { error, code, data } = await wbsApi.getBussFileList1({
  969. pkeyid: pkeyId,
  970. id: id,
  971. })
  972. if (!error && code === 200) {
  973. fileListData.value = getArrValue(data)
  974. } else {
  975. fileListData.value = []
  976. }
  977. }
  978. //上传文件
  979. const uploadChange = async ({ type }) => {
  980. const { id } = baseData.value
  981. if (type === 'success') {
  982. uploadModal.value = false
  983. renewData(id)
  984. } else if (type === 'del') {
  985. renewData(id)
  986. }
  987. }
  988. //相关变量
  989. const tableFormItemNode = ref({})
  990. //菜单数据
  991. const tableFormMenu = ref([
  992. { label: '容器参数', key: 'vessel' },
  993. { label: '引用设备仪器', key: 'device' },
  994. { label: '插入特殊字符', key: 'special' },
  995. ])
  996. //鼠标右键事件
  997. const contextMenuRef = ref(null)
  998. const onRightClick = (event, KeyName, index) => {
  999. //取光标位置
  1000. const specialDom = document.getElementById(KeyName + '')
  1001. const startPos = specialDom?.selectionStart || 0
  1002. const endPos = specialDom?.selectionEnd || 0
  1003. //存储临时信息
  1004. tableFormItemNode.value = { KeyName, index, startPos, endPos, pkeyId: formKeyIds.value }
  1005. contextMenuRef.value?.showMenu(event) //展开菜单
  1006. }
  1007. //鼠标右键菜单被点击
  1008. const handleMenuSelect = ({ key }) => {
  1009. if (key === 'vessel') {
  1010. vesselModal.value = true
  1011. getMenusData()
  1012. } else if (key === 'special') {
  1013. specialModalShow()
  1014. } else if (key === 'device') {
  1015. deviceModal.value = true
  1016. nextTick(() => {
  1017. deviceTableRef.value?.clearSelection()
  1018. })
  1019. getequipmentMenusData()
  1020. }
  1021. }
  1022. //引用容器参数
  1023. const vesselModal = ref(false)
  1024. const vesselTableRef = ref(null)
  1025. //引用容器参数菜单数据
  1026. const menuProps = {
  1027. key: 'id',
  1028. label: 'containerName',
  1029. }
  1030. //引用容器参数菜单数据
  1031. const equipmentmenuProps = {
  1032. key: 'id',
  1033. label: 'className',
  1034. }
  1035. const menus = ref([])
  1036. const getMenusData = async () => {
  1037. const { data } = await dataApi1.queryClassification({
  1038. projectId: projectId.value,
  1039. contractId: contractId.value,
  1040. })
  1041. const arr = getArrValue(data)
  1042. menus.value = arr
  1043. if (arr.length > 0) {
  1044. const item = arr[0]
  1045. menuItem.value = item
  1046. menuKey.value = item?.id
  1047. vesselTableColumn.value = []
  1048. if (item?.fieldList && item?.fieldList.length > 0) {
  1049. item?.fieldList.forEach((item1) => {
  1050. vesselTableColumn.value.push(({
  1051. key: item1?.fieldKey,
  1052. name: item1?.fieldName,
  1053. }))
  1054. })
  1055. }
  1056. getVesselTableData()
  1057. }
  1058. }
  1059. //菜单被点击
  1060. const menuKey = ref()
  1061. const menuItem = ref({})
  1062. const menuChange = (item) => {
  1063. menuItem.value = item
  1064. menuKey.value = item?.id
  1065. vesselTableColumn.value = []
  1066. item?.fieldList.forEach((item1) => {
  1067. vesselTableColumn.value.push(({
  1068. key: item1?.fieldKey,
  1069. name: item1?.fieldName,
  1070. }))
  1071. })
  1072. getVesselTableData()
  1073. }
  1074. //表格数据
  1075. const vesselTableColumn = ref([
  1076. // {key:'key_1', name: '容器编号'},
  1077. ])
  1078. const vesselTableData = ref([])
  1079. const vesselTablePage = ref({ current: 1, size: 20, total: 0 })
  1080. const vesselTablePageChange = ({ current, size }) => {
  1081. vesselTablePage.value.current = current
  1082. vesselTablePage.value.size = size
  1083. getVesselTableData()
  1084. }
  1085. //获取表格数据
  1086. const vesselTableLoading = ref(false)
  1087. const getVesselTableData = async () => {
  1088. const { fieldList } = menuItem.value
  1089. const fieldLists = getArrValue(fieldList)
  1090. if (fieldLists.length > 0) {
  1091. vesselTableLoading.value = true
  1092. const { error, code, data } = await dataApi1.queryPage({
  1093. projectId: projectId.value,
  1094. contractId: contractId.value,
  1095. containerId: menuKey.value,
  1096. fieldKey: fieldList[0].fieldKey,
  1097. size: vesselTablePage.value.size,
  1098. current: vesselTablePage.value.current,
  1099. })
  1100. //处理数据
  1101. vesselTableLoading.value = false
  1102. if (!error && code === 200) {
  1103. vesselTableData.value = getArrValue(data['records'])
  1104. vesselTablePage.value.total = data.total || 0
  1105. } else {
  1106. vesselTableData.value = []
  1107. vesselTablePage.value.total = 0
  1108. }
  1109. }
  1110. }
  1111. //多选
  1112. const vesselTableKeys = ref([])
  1113. const vesselTableSelection = (rows) => {
  1114. vesselTableKeys.value = rows
  1115. }
  1116. //确认引用
  1117. const vesselModalSave = () => {
  1118. if (vesselTableKeys.value.length > 0) {
  1119. const item = tableFormItemNode.value
  1120. const form = formData.value[item.index]
  1121. const val = []
  1122. vesselTableKeys.value.forEach((item) => {
  1123. val.push(item.key_2)
  1124. })
  1125. const newval = val.join('、')
  1126. formData.value[item.index][item.KeyName] = setPosInsert(item.startPos, item.endPos, form[item.KeyName], newval)
  1127. vesselModal.value = false
  1128. let posVal = item.startPos + newval.length
  1129. nextTick(() => {
  1130. setPosRange(item.KeyName, posVal)
  1131. })
  1132. } else {
  1133. window?.$message?.warning('请先选择引用容器参数')
  1134. }
  1135. }
  1136. //关闭
  1137. const vesselModalClose = () => {
  1138. vesselModal.value = false
  1139. }
  1140. const equipmentmenus = ref([])
  1141. const getequipmentMenusData = async () => {
  1142. const { data } = await getClassList({
  1143. projectId: projectId.value,
  1144. contractId: contractId.value,
  1145. })
  1146. const arr = getArrValue(data)
  1147. equipmentmenus.value = arr
  1148. if (arr.length > 0) {
  1149. const item = arr[0]
  1150. equipmentmenuItem.value = item
  1151. equipmentmenuKey.value = item?.id
  1152. getDeviceTableData()
  1153. }
  1154. }
  1155. //菜单被点击
  1156. const equipmentmenuKey = ref()
  1157. const equipmentmenuItem = ref({})
  1158. const equipmentmenuChange = (item) => {
  1159. equipmentmenuItem.value = item
  1160. equipmentmenuKey.value = item?.id
  1161. getDeviceTableData()
  1162. }
  1163. //引用设备仪器
  1164. const deviceModal = ref(false)
  1165. const deviceTableRef = ref(null)
  1166. //表格数据
  1167. const deviceTableColumn = ref([
  1168. { key: 'deviceNumber', name: '设备编号' },
  1169. { key: 'deviceName', name: '设备仪器名称' },
  1170. ])
  1171. const deviceTableData = ref([])
  1172. const equipmentPage = ref({ current: 1, size: 20, total: 0 })
  1173. const equipmentTablePageChange = ({ current, size }) => {
  1174. equipmentPage.value.current = current
  1175. equipmentPage.value.size = size
  1176. getDeviceTableData()
  1177. }
  1178. //数组去重
  1179. let temp = []
  1180. const getnewArr = (tempArr) => {
  1181. tempArr.forEach(function (a) {
  1182. let check = temp.every(function (b) {
  1183. return a.id !== b.id
  1184. })
  1185. check ? temp.push(a) : ''
  1186. })
  1187. return temp
  1188. }
  1189. //获取表格数据
  1190. const deviceTableLoading = ref(false)
  1191. const getDeviceTableData = async () => {
  1192. deviceTableLoading.value = true
  1193. const { error, code, data } = await dataApi2.queryPage({
  1194. projectId: projectId.value,
  1195. contractId: contractId.value,
  1196. deviceClassId: equipmentmenuKey.value,
  1197. size: equipmentPage.value.size,
  1198. current: equipmentPage.value.current,
  1199. })
  1200. //处理数据
  1201. deviceTableLoading.value = false
  1202. if (!error && code === 200) {
  1203. deviceTableData.value = getArrValue(data['records'])
  1204. equipmentPage.value.total = data.total || 0
  1205. //去重
  1206. let uniqueArray = getnewArr(checkList.value)
  1207. deviceTableKeys.value = uniqueArray
  1208. if (uniqueArray.length > 0) {
  1209. uniqueArray.forEach((item) => {
  1210. if (item.deviceClassId === equipmentmenuKey.value) {
  1211. deviceTableData.value.forEach((ele) => {
  1212. if (ele.id === item.id) {
  1213. item = ele
  1214. }
  1215. })
  1216. nextTick(() => {
  1217. deviceTableRef.value?.toggleRowSelection(item, true)
  1218. })
  1219. }
  1220. })
  1221. }
  1222. } else {
  1223. deviceTableData.value = []
  1224. equipmentPage.value.total = 0
  1225. }
  1226. }
  1227. //多选
  1228. const deviceTableKeys = ref([])
  1229. //选中的设备仪器
  1230. const checkList = ref([])
  1231. const deviceTableSelection = (rows) => {
  1232. // deviceTableKeys.value = rows
  1233. if (rows.length > 0) {
  1234. rows.forEach((item) => {
  1235. checkList.value.push(item)
  1236. })
  1237. //去重
  1238. let uniqueArray = getnewArr(checkList.value)
  1239. deviceTableKeys.value = uniqueArray
  1240. }
  1241. }
  1242. //确认引用
  1243. const deviceModalSave = () => {
  1244. if (deviceTableKeys.value.length > 0) {
  1245. const item = tableFormItemNode.value
  1246. const form = formData.value[item.index]
  1247. const val = []
  1248. const idarr = []
  1249. const listr = []
  1250. deviceTableKeys.value.forEach((item) => {
  1251. val.push(item.deviceNumber)
  1252. idarr.push(item.id)
  1253. listr.push(item.deviceNumber + '_' + item.deviceName)
  1254. })
  1255. const newval = listr.join('、')
  1256. const idval = idarr.join(',')
  1257. formData.value[item.index][item.KeyName] = setPosInsert(item.startPos, item.endPos, form[item.KeyName], newval)
  1258. vesselModal.value = false
  1259. let posVal = item.startPos + newval.length
  1260. nextTick(() => {
  1261. setPosRange(item.KeyName, posVal)
  1262. })
  1263. deviceModal.value = false
  1264. emit('updeviceUseIds', idval)
  1265. } else {
  1266. window?.$message?.warning('请先选择引用容器设备')
  1267. }
  1268. deviceTableKeys.value = []
  1269. checkList.value = []
  1270. temp = []
  1271. }
  1272. //关闭
  1273. const deviceModalClose = () => {
  1274. deviceModal.value = false
  1275. deviceTableKeys.value = []
  1276. checkList.value = []
  1277. temp = []
  1278. }
  1279. //插入特殊字符
  1280. const specialModal = ref(false)
  1281. const specialCharacters = ref([
  1282. '&#57344;', '&#57345;', '&#57346;', '&#57347;', '&#8804;', '&#8805;', '&#8451;',
  1283. '&#9312;', '&#9313;', '&#9314;', '&#9315;', '&#9316;', '&#9317;', '&#9318;', '&#9319;', '&#9320;', '&#9321;', '&#9322;', '&#9323;',
  1284. '&#9324;', '&#9325;', '&#9326;', '&#9327;', '&#9328;', '&#9329;', '&#9330;', '&#9331;',
  1285. '&#8544;', '&#8545;', '&#8546;', '&#8547;', '&#8548;', '&#8549;', '&#8550;', '&#8551;', '&#8552;', '&#8553;', '&#8554;', '&#8555;', 'K̅',
  1286. ])
  1287. //输入框验证
  1288. const specialFormRef = ref(null)
  1289. const specialFormModel = ref({ val: '' })
  1290. const specialFormRules = {
  1291. val: {
  1292. required: true,
  1293. trigger: 'blur',
  1294. message: '请选择特殊字符代码',
  1295. },
  1296. }
  1297. //显示插入特殊字符
  1298. const specialRef = ref(null)
  1299. const specialModalShow = () => {
  1300. specialFormModel.value.val = ''
  1301. specialModal.value = true
  1302. nextTick(() => {
  1303. specialRef.value?.focus()
  1304. })
  1305. }
  1306. //失去焦点
  1307. const specialPos = ref({ start: 0, end: 0 })
  1308. const specialInputBlur = (e) => {
  1309. specialPos.value = {
  1310. start: e?.target?.selectionStart || 0,
  1311. end: e?.target?.selectionEnd || 0,
  1312. }
  1313. }
  1314. //点击符号
  1315. const specialClick = (event) => {
  1316. const text = event?.target?.innerText ?? ''
  1317. const start = specialPos.value.start
  1318. const end = specialPos.value.end
  1319. const form = specialFormModel.value.val
  1320. specialFormModel.value.val = setPosInsert(start, end, form, text)
  1321. specialRef.value?.focus()
  1322. let posVal = start + text.length
  1323. nextTick(() => {
  1324. setPosRange('specialId', posVal)
  1325. })
  1326. }
  1327. //确认插入
  1328. const specialNodeClick = async () => {
  1329. const res = await formValidate(specialFormRef.value)
  1330. if (res) {
  1331. const item = tableFormItemNode.value
  1332. const form = formData.value[item.index]
  1333. const val = specialFormModel.value.val ?? ''
  1334. formData.value[item.index][item.KeyName] = setPosInsert(item.startPos, item.endPos, form[item.KeyName], val)
  1335. specialModal.value = false
  1336. specialRef.value?.focus()
  1337. let posVal = item.startPos + val.length
  1338. nextTick(() => {
  1339. setPosRange(item.KeyName, posVal)
  1340. })
  1341. }
  1342. }
  1343. //被点击
  1344. const getOffsetTop = (key = '') => {
  1345. if (key) {
  1346. const dom = document.getElementById(key)
  1347. emit('offsetTop', dom.offsetTop)
  1348. } else {
  1349. emit('offsetTop', 0)
  1350. }
  1351. }
  1352. //通知数据更新
  1353. const renewData = (newaddId) => {
  1354. emit('renew', newaddId)
  1355. ActiveKey.value = ''
  1356. }
  1357. const changeisHide = (pKeyId, isBussShow) => {
  1358. emit('changesdate', pKeyId, isBussShow)
  1359. }
  1360. const chageOrinData = () => {
  1361. emit('chageorinData')
  1362. }
  1363. //获取表单数据
  1364. const getFormData = () => {
  1365. const formArr = formData.value
  1366. return formArr.filter((item) => {
  1367. return item
  1368. })
  1369. }
  1370. const setFormChart = async () => {
  1371. const form = getFormData()
  1372. for (let i = 0; i < form.length; i++) {
  1373. const { pkeyId, formchartKeyShow } = form[i]
  1374. if (formchartKeyShow) {
  1375. const { ref } = await getChartRef(pkeyId, formchartKeyShow)
  1376. if (ref) {
  1377. const url = await uploadChartImgFile(ref?.getImage())
  1378. const name = `${formchartKeyShow}_url`
  1379. form[i][name] = url
  1380. }
  1381. }
  1382. }
  1383. return form
  1384. }
  1385. //获取表单效验数据
  1386. const getFormRegExpJson = () => {
  1387. return deepClone(formRegExpJson.value)
  1388. }
  1389. //获取当前展开项
  1390. const getActiveKey = () => {
  1391. return ActiveKey.value
  1392. }
  1393. //设置当前展开项
  1394. const setActiveKey = (key) => {
  1395. return ActiveKey.value = key
  1396. }
  1397. //打开窗口
  1398. const windowClick = (item, indexs)=>{
  1399. if (!item.isWindow) {
  1400. console.log(item, 'item')
  1401. const formSize = getTableFormSize(item?.pKeyId)
  1402. console.log(formSize, 'formSize')
  1403. const list = deepClone(DragModalTableForm.value)
  1404. let index = arrIndex(list, 'pKeyId', item.pKeyId)
  1405. const newTableForm = {
  1406. ...setInitDragModalTableForm(item, indexs),
  1407. ...formSize,
  1408. }
  1409. console.log(newTableForm, 'newTableForm')
  1410. item.isWindow = true
  1411. //弹窗表单的排序
  1412. if (index === -1) {
  1413. list.push(newTableForm)
  1414. } else if (index !== list.length - 1) {
  1415. //检查是否在最上层,不在则置顶,可以解决多次点击时,频繁更改全局状态的问题
  1416. list.splice(index, 1)
  1417. list.push(newTableForm)
  1418. }
  1419. DragModalTableForm.value = list
  1420. ActiveKey.value = ''
  1421. const { pKeyId } = item
  1422. let KeyId = `item-${indexs}-${pKeyId}`
  1423. CollapseChange(KeyId)
  1424. }
  1425. }
  1426. //获取表单的大小
  1427. const getTableFormSize = (pkeyId) => {
  1428. let formId = `table-form-${pkeyId}`
  1429. try {
  1430. const { clientWidth, clientHeight } = document.getElementById(formId).children[0]
  1431. return {
  1432. width: (clientWidth + 40) + 'px',
  1433. height: (clientHeight + 80) + 'px',
  1434. }
  1435. } catch {
  1436. return {
  1437. width: '100%',
  1438. height: '100%',
  1439. }
  1440. }
  1441. }
  1442. //初始拖动表单的内容
  1443. const setInitDragModalTableForm = (item, index) => {
  1444. console.log(item, 'item1111')
  1445. return {
  1446. projectId: projectId.value,
  1447. contractId: contractId.value,
  1448. pkeyId: item.pKeyId,
  1449. height: '100%',
  1450. width: '100%',
  1451. title: item.nodeName,
  1452. isShow: true,
  1453. index: index,
  1454. item: item,
  1455. }
  1456. }
  1457. //关闭窗口
  1458. const windowCloseClick = (item, indexs)=>{
  1459. ActiveKey.value = ''
  1460. }
  1461. const DragModalTableForm = ref([])
  1462. const DragModalHeight = ref(600)
  1463. const closeIconArr = [
  1464. { key: 'reduction', icon: 'picture-in-picture-2', name: '还原到面板内,并自动展开面板' },
  1465. ]
  1466. //关闭窗口
  1467. const TableFormClose = async ({ pkeyId, index }, indexs, type) => {
  1468. const list = deepClone(DragModalTableForm.value)
  1469. //取表单的数据
  1470. // await setChangeFormDatas(pkeyId, 'collapse')
  1471. //关闭窗口
  1472. list.splice(indexs, 1)
  1473. DragModalTableForm.value = list
  1474. listDatas.value[index].isWindow = false
  1475. if (type) {
  1476. ActiveKey.value = ''
  1477. }
  1478. }
  1479. const dragNodeMoreMenu = [
  1480. { key: 'save', icon: 'save-2', name: '保存' },
  1481. { key: 'preview', icon: 'eye', name: '预览' },
  1482. ]
  1483. //还原窗口
  1484. const closeIconTap = async (event, item, indexs) => {
  1485. item.isShow = false
  1486. item.isWindow = false
  1487. const { index, pkeyId } = item
  1488. let KeyId = `item-${index}-${pkeyId}`
  1489. await TableFormClose(item, indexs, false)
  1490. console.log(item, 'KeyId')
  1491. CollapseChange(KeyId)
  1492. item.isWindow = false
  1493. }
  1494. //菜单被点击
  1495. const dragNodeMoreMenuTap = async ({ key }, items, indexs) => {
  1496. const { item } = items
  1497. console.log(item, 'item')
  1498. console.log(items, 'items')
  1499. if (key === 'save') {
  1500. if (item?.isTableForm) {
  1501. items.tableFormSaveLoading = true
  1502. await tableFormSaveClick(item, indexs)
  1503. items.tableFormSaveLoading = false
  1504. } else {
  1505. window.$message.warning('此表单暂无数据和文件')
  1506. }
  1507. } else if (key === 'preview') {
  1508. if (item.isBussShow === 2 || item.isTabPdf === 1) {
  1509. window.$message.warning('此表单暂无可预览文件')
  1510. } else {
  1511. previewClick(item, items)
  1512. }
  1513. }
  1514. }
  1515. //清空窗口表单列表
  1516. const clearDragModalTableForm = ()=>{
  1517. DragModalTableForm.value = []
  1518. }
  1519. // 暴露出去
  1520. defineExpose({
  1521. setFormChart,
  1522. getFormData,
  1523. getFormRegExpJson,
  1524. getActiveKey,
  1525. setActiveKey,
  1526. changeSimpleInput,
  1527. changePositionInput,
  1528. clearDragModalTableForm,
  1529. })
  1530. </script>
  1531. <style lang="scss" scoped>
  1532. .data-fill-list-box {
  1533. position: relative;
  1534. //margin-bottom: 25%;
  1535. .hc-collapse-item-header {
  1536. flex: 1;
  1537. position: relative;
  1538. margin-left: 46px;
  1539. display: flex;
  1540. align-items: center;
  1541. .item-title {
  1542. flex: 1;
  1543. position: relative;
  1544. user-select: none;
  1545. color: #50545E;
  1546. font-size: 16px;
  1547. font-weight: 400;
  1548. cursor: pointer;
  1549. }
  1550. .hc-extra-text-box {
  1551. position: relative;
  1552. padding-right: 24px;
  1553. }
  1554. }
  1555. .data-fill-list-item-content {
  1556. position: relative;
  1557. display: flex;
  1558. height: calc(100vh - 428px);
  1559. .data-fill-table-form-box {
  1560. position: relative;
  1561. padding: 24px 20px;
  1562. height: 100%;
  1563. overflow: auto;
  1564. flex: 1;
  1565. &.is-window {
  1566. border: 0;
  1567. .hc-window-tip {
  1568. position: relative;
  1569. height: 100%;
  1570. display: flex;
  1571. justify-content: center;
  1572. align-items: center;
  1573. .table-form-no {
  1574. position: relative;
  1575. img {
  1576. width: 380px;
  1577. }
  1578. .desc {
  1579. text-align: center;
  1580. font-size: 20px;
  1581. color: #aaa;
  1582. }
  1583. }
  1584. }
  1585. }
  1586. .hc-no-table-form {
  1587. position: relative;
  1588. height: 100%;
  1589. display: flex;
  1590. justify-content: center;
  1591. align-items: center;
  1592. .table-form-no {
  1593. position: relative;
  1594. img {
  1595. width: 350px;
  1596. }
  1597. .desc {
  1598. text-align: center;
  1599. font-size: 20px;
  1600. color: #aaa;
  1601. }
  1602. }
  1603. }
  1604. }
  1605. .data-fill-table-tip-box {
  1606. width: 240px;
  1607. position: relative;
  1608. border-left: 1px solid #E9E9E9;
  1609. padding: 20px 15px 80px;
  1610. .tip-title {
  1611. font-size: 16px;
  1612. margin-bottom: 10px;
  1613. display: flex;
  1614. align-items: center;
  1615. }
  1616. .tip-item {
  1617. margin-bottom: 20px;
  1618. }
  1619. .table-tip-foot {
  1620. position: absolute;
  1621. bottom: 15px;
  1622. right: 0;
  1623. left: 0;
  1624. display: flex;
  1625. align-items: center;
  1626. padding: 0 15px;
  1627. .tip-left-btn {
  1628. flex: 1;
  1629. .dow-text {
  1630. cursor: pointer;
  1631. display: flex;
  1632. align-items: center;
  1633. }
  1634. }
  1635. }
  1636. }
  1637. }
  1638. }
  1639. .special-box {
  1640. position: relative;
  1641. display: flex;
  1642. justify-content: center;
  1643. align-items: center;
  1644. border: 1px solid #eee;
  1645. border-radius: 3px;
  1646. height: 52px;
  1647. width: 52px;
  1648. cursor: pointer;
  1649. user-select: none;
  1650. transition: color .3s, background-color .3s;
  1651. &:hover {
  1652. color: var(--el-color-primary);
  1653. background-color: var(--el-color-primary-light-8);
  1654. }
  1655. .font-EUDC {
  1656. font-size: 22px;
  1657. }
  1658. }
  1659. </style>
  1660. <style lang="scss">
  1661. .data-fill-list-box {
  1662. .el-collapse {
  1663. --el-collapse-header-height: 60px;
  1664. border: 0;
  1665. .el-collapse-item {
  1666. margin: 0 0 16px;
  1667. background-color: #f1f5f8;
  1668. border: 1px solid #E9E9E9;
  1669. border-radius: 4px;
  1670. }
  1671. .el-collapse-item__header {
  1672. background-color: transparent;
  1673. font-weight: 400;
  1674. border-bottom: 0;
  1675. cursor: default;
  1676. font-size: 14px;
  1677. .el-collapse-item__arrow {
  1678. position: absolute;
  1679. color: #50545E;
  1680. cursor: pointer;
  1681. left: 20px;
  1682. margin: 0;
  1683. }
  1684. }
  1685. .el-collapse-item.is-active .el-collapse-item__header.is-active {
  1686. background-color: #E7EEF4;
  1687. }
  1688. .el-collapse-item__wrap {
  1689. background-color: transparent;
  1690. border-bottom: 0;
  1691. .el-collapse-item__content {
  1692. position: relative;
  1693. padding-bottom: 0;
  1694. font-size: 14px;
  1695. color: #50545E;
  1696. line-height: initial;
  1697. }
  1698. }
  1699. }
  1700. }
  1701. //插入特殊字符弹窗的输入框
  1702. .data-fill-list-box .data-fill-table-form-box td,
  1703. .data-fill-list-box .data-fill-table-form-box td .el-input .el-input__wrapper .el-input__inner,
  1704. .el-form-item.special-form-item .el-form-item__content .el-input .el-input__wrapper .el-input__inner {
  1705. font-family: "hc-eudc", hc-sans, 宋体, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  1706. }
  1707. //引用容器参数弹窗
  1708. //关联试验数据
  1709. .adding-form-dialog-box {
  1710. position: relative;
  1711. height: 100%;
  1712. display: flex;
  1713. .dialog-tree-box {
  1714. position: relative;
  1715. border-right: 1px solid #EEEEEE;
  1716. width: 500px;
  1717. height: 100%
  1718. }
  1719. .dialog-table-box {
  1720. position: relative;
  1721. flex: 1;
  1722. height: 100%;
  1723. padding: 18px;
  1724. .dialog-search {
  1725. position: relative;
  1726. display: flex;
  1727. }
  1728. .dialog-table {
  1729. position: relative;
  1730. height: calc(100% - 68px);
  1731. padding: 18px 0;
  1732. }
  1733. .dialog-pages {
  1734. position: relative;
  1735. }
  1736. }
  1737. }
  1738. .hc-window-switch-box {
  1739. display: flex;
  1740. align-items: center;
  1741. position: absolute;
  1742. top: 14px;
  1743. right: 260px;
  1744. .icon-btn-view {
  1745. padding: 0 18px;
  1746. height: 34px;
  1747. display: flex;
  1748. align-items: center;
  1749. justify-content: center;
  1750. color: #ffffff;
  1751. cursor: pointer;
  1752. user-select: none;
  1753. border-radius: 80px;
  1754. box-shadow: 4px 4px 8px 0 rgba(54, 92, 167, 0.15), -3px -2px 8px 0 #ffffff;
  1755. background: linear-gradient(to right, var(--el-color-primary-light-5), var(--el-color-primary), var(--el-color-primary-dark-2));
  1756. background-size: 200%;
  1757. transition: background-position .5s;
  1758. .icon {
  1759. font-size: 16px;
  1760. }
  1761. &:hover {
  1762. background-position: 100% 0;
  1763. }
  1764. }
  1765. }
  1766. </style>