ListItem.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  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 :name="`item-${index}-${item?.pkeyId}`" :disabled="item['isBussShow'] === 2" :id="`item-${index}-${item?.pkeyId}`">
  6. <template #title>
  7. <div class="hc-collapse-item-header">
  8. <div class="text-lg truncate item-title">{{item.nodeName}}</div>
  9. <div class="hc-extra-text-box">
  10. <HcTooltip keys="wbs_del_table" v-if="item['isCopeTab'] === 2">
  11. <el-button type="danger" plain :disabled="item['isBussShow'] === 2" @click.stop="delClick(item,index)">删除本表</el-button>
  12. </HcTooltip>
  13. <HcTooltip keys="wbs_copy_table">
  14. <el-button type="primary" plain :disabled="item['isBussShow'] === 2" @click.stop="copyClick(item,index)">复制本表</el-button>
  15. </HcTooltip>
  16. <HcTooltip keys="wbs_hide_table">
  17. <el-button type="primary" plain @click.stop="hideClick(item,index)">
  18. <template v-if="item['isBussShow'] === 1">隐藏本表</template>
  19. <template v-else>显示本表</template>
  20. </el-button>
  21. </HcTooltip>
  22. <HcTooltip keys="wbs_preview_table">
  23. <el-button type="info" plain disabled v-if="item['isBussShow'] === 2 || item['isTabPdf'] === 1">预览</el-button>
  24. <el-button type="primary" plain @click.stop="previewClick(item,index)" v-else>预览</el-button>
  25. </HcTooltip>
  26. <HcTooltip keys="wbs_upload_table">
  27. <el-button :type="item['tabFileType'] === 2?'success':'primary'" plain :disabled="item['isBussShow'] === 2" @click.stop="uploadClick(item,index)">
  28. <template v-if="item['tabFileType'] === 2">已上传</template>
  29. <template v-else>上传</template>
  30. </el-button>
  31. </HcTooltip>
  32. </div>
  33. </div>
  34. </template>
  35. <div class="data-fill-list-item-content">
  36. <div class="data-fill-table-form-box">
  37. <div class="hc-excel-table-form-view" :id="`table-form-${item?.pkeyId}`"/>
  38. <div class="hc-no-table-form" v-if="item?.isTableForm === false">
  39. <div class="table-form-no">
  40. <img :src="notableform" alt=""/>
  41. <div class="desc">暂无表单数据</div>
  42. </div>
  43. </div>
  44. </div>
  45. <div class="data-fill-table-tip-box">
  46. <div class="text-orange tip-title">
  47. <HcIcon name="error" fill ui="text-2xl"/>
  48. <span class="ml-1">提示</span>
  49. </div>
  50. <div class="text-gray-400 tip-item">1、灰色框代表可通过系统识别计算,公式自动引用,可通过公式计算少量数据,(表头数据及简单),也可只填写白色框数据</div>
  51. <div class="text-gray-400 tip-item">2、系统支持键盘中,shift + tab键向上一个填报框切换,tab向下一个填报框切换。暂不支持上下按键切换输入框</div>
  52. <div class="table-tip-foot">
  53. <div class="tip-left-btn">
  54. <HcTooltip keys="wbs_import_table">
  55. <div class="text-gray-400 dow-text">
  56. <HcIcon name="publish" ui="text-lg"/>
  57. <span class="ml-1">导入列表数据</span>
  58. </div>
  59. </HcTooltip>
  60. <HcTooltip keys="wbs_download_table">
  61. <div class="text-main dow-text">
  62. <HcIcon name="file_download" ui="text-lg"/>
  63. <span class="ml-1">下载导入模板</span>
  64. </div>
  65. </HcTooltip>
  66. </div>
  67. <div class="tip-right-btn">
  68. <HcTooltip keys="wbs_save_table">
  69. <el-button type="primary" hc-btn :disabled="item?.isTableForm === false" :loading="tableFormSaveLoading" @click="tableFormSaveClick(item,index)">
  70. <HcIcon name="save"/>
  71. <span>保存</span>
  72. </el-button>
  73. </HcTooltip>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. </el-collapse-item>
  79. </template>
  80. </el-collapse>
  81. </div>
  82. <!--右键菜单-->
  83. <HcContextMenu ref="contextMenuRef" :datas="tableFormMenu" @item-click="handleMenuSelect"/>
  84. <!--上传文件-->
  85. <HcDialog :show="uploadModal" title="上传文件" widths="38rem" :footer="false" @close="uploadModal = false">
  86. <HcUpload :fileList="fileListData" :datas="uploadData" @change='uploadChange'/>
  87. </HcDialog>
  88. <!--插入设计值/频率-->
  89. <HcDialog :show="IDVFModal" title="插入设计值/频率" widths="600px" saveText="确认插入" @close="IDVFModal = false" @save="IDVFModalSaveClick">
  90. <el-alert title="填写完设计值和频率,系统自动计算实测值" type="warning" :closable="false"/>
  91. <el-form ref="formIDVFRef" :model="formIDVFModel" :rules="formIDVFRules" label-width="auto" size="large">
  92. <el-form-item label="设计值">
  93. <el-input v-model="formIDVFModel.design" placeholder="请输入设计值"/>
  94. </el-form-item>
  95. <el-form-item label="频率">
  96. <el-input v-model="formIDVFModel.size" placeholder="请输入频率"/>
  97. </el-form-item>
  98. </el-form>
  99. </HcDialog>
  100. <!--插入特殊字符-->
  101. <HcDialog :show="specialModal" title="插入特殊字符" widths="600px" saveText="确认插入" @close="specialModal = false" @save="specialNodeClick">
  102. <el-form ref="specialFormRef" :model="specialFormModel" :rules="specialFormRules" label-width="0px" size="large" class="mb-6">
  103. <el-form-item prop="val" class="special-form-item">
  104. <el-input v-model="specialFormModel.val" ref="specialRef" id="specialId" placeholder="请选择特殊字符代码" clearable @blur="specialInputBlur"/>
  105. </el-form-item>
  106. </el-form>
  107. <el-row :gutter="20" style="margin: -10px;">
  108. <el-col :span="3" style="padding: 10px;" v-for="item in specialCharacters">
  109. <div class="special-box" @click="specialClick">
  110. <span class="font-EUDC" :title="`字符代码(C):${item !== 'K̅'?item.slice(2,7):'K̅'}`" v-html="item"/>
  111. </div>
  112. </el-col>
  113. </el-row>
  114. </HcDialog>
  115. <!--关联试验数据-->
  116. <HcDialog :show="CTDModal" title="关联试验数据" widths="850px" saveText="确认关联" @close="CTDModal = false" @save="CTDModal = false">
  117. 开发中...
  118. </HcDialog>
  119. </template>
  120. <script setup>
  121. import {ref,watch,nextTick} from "vue";
  122. import notableform from '~src/assets/view/notableform.svg';
  123. import HTableForm from "~src/plugins/HTableForm"
  124. import wbsApi from "~api/data-fill/wbs"
  125. import HcUpload from "./HcUpload.vue"
  126. import {utilsText, isType, formValidate, deepClone} from "vue-utils-plus"
  127. //初始
  128. const props = defineProps({
  129. datas: {
  130. type: Array,
  131. default: () => ([])
  132. },
  133. classify: {
  134. type: [String,Number],
  135. default: ''
  136. },
  137. status: {
  138. type: [String,Number],
  139. default: ''
  140. },
  141. primaryKeyId: {
  142. type: [String,Number],
  143. default: ''
  144. },
  145. contractId: {
  146. type: [String,Number],
  147. default: ''
  148. },
  149. })
  150. const {isString, getObjNullValue, getArrValue} = isType()
  151. const {setPosInsert, setPosRange} = utilsText()
  152. const listDatas = ref(props.datas)
  153. const classify = ref(props.classify)
  154. const isStatus = ref(props.status)
  155. const isPrimaryKeyId = ref(props.primaryKeyId)
  156. const contractId = ref(props.contractId)
  157. //监听
  158. watch(() => [
  159. props.datas,
  160. props.classify,
  161. props.primaryKeyId,
  162. props.contractId,
  163. ], ([datas, classifyVal, primaryKeyId, cid]) => {
  164. listDatas.value = datas
  165. classify.value = classifyVal
  166. isPrimaryKeyId.value = primaryKeyId
  167. contractId.value = cid
  168. setFormDataNum(datas)
  169. })
  170. //监听
  171. watch(() => [
  172. props.status
  173. ], ([val]) => {
  174. //1 未填报,2待上报,3已上报
  175. isStatus.value = val
  176. })
  177. //渲染完成
  178. nextTick(() => {
  179. setFormDataNum(props.datas)
  180. })
  181. //获取表单初始数据
  182. const getFormDataInit = (item, pkeyId) => {
  183. return {
  184. projectId: item?.projectId,
  185. contractId: item?.contractId,
  186. classify: classify.value,
  187. pkeyId: pkeyId ? pkeyId + '' : '',
  188. nodeId: isPrimaryKeyId.value
  189. }
  190. }
  191. //设置表单对象的数量
  192. const formData = ref([])
  193. const setFormDataNum = (datas) => {
  194. ActiveKey.value = ''
  195. let newArr = [];
  196. for (let i = 0; i < datas.length; i++) {
  197. newArr.push({
  198. ...getFormDataInit(datas[i], datas[i].pkeyId),
  199. isCollapseLoad: false,
  200. })
  201. }
  202. formData.value = newArr
  203. }
  204. //展开事件
  205. const ActiveKey = ref('')
  206. const formKeyIds = ref('')
  207. const CollapseChange = async (name) => {
  208. ActiveKey.value = name
  209. const names = name ? name.split('-') : []
  210. if (names.length > 0) {
  211. getOffsetTop(name)
  212. const index = names[1]
  213. const item = listDatas.value[index]
  214. formKeyIds.value = item.pkeyId ? item.pkeyId + '' : ''
  215. if (!item.isTableFormRender) {
  216. //获取已填写的数据
  217. await getBussDataInfo(item,item.pkeyId, index)
  218. //渲染表单
  219. await getExcelHtml(item,index)
  220. }
  221. } else {
  222. getOffsetTop()
  223. formKeyIds.value = ''
  224. }
  225. }
  226. //获取模板标签数据
  227. const formRegExpJson = ref({})
  228. const getExcelHtml = async (item,index) => {
  229. const pkeyIds = item.pkeyId ? item.pkeyId + '' : ''
  230. if (pkeyIds) {
  231. const {error, code, data} = await wbsApi.getExcelHtml({pkeyId: pkeyIds}, false)
  232. const resData = isString(data) ? data || '' : ''
  233. if (!error && code === 200 && resData) {
  234. item.isTableForm = true
  235. //渲染表单
  236. HTableForm.createForm({
  237. template: resData,
  238. tableForm: formData.value[index],
  239. appId: `#table-form-${pkeyIds}`,
  240. onRight: (event, KeyName) => {
  241. onRightClick(event, KeyName, index)
  242. },
  243. //表单正则效验
  244. onBlur: (event, key, reg, val, msg) => {
  245. setTableFormBlurReg(pkeyIds, event, key, reg, val, msg, item, index)
  246. }
  247. })
  248. item.isTableFormRender = true
  249. item.isRenderTableForm = true
  250. } else {
  251. item.isTableForm = false
  252. item.isRenderTableForm = true
  253. window?.$message?.warning('暂无表单')
  254. }
  255. } else {
  256. item.isTableForm = false
  257. item.isRenderTableForm = false
  258. window?.$message?.warning('pkeyId为空')
  259. }
  260. }
  261. //正则效验
  262. const setTableFormBlurReg = (pkeyId, event, key, reg, val, msg, item, index) => {
  263. const dom = document.getElementById(key)?.parentElement ?? ''
  264. if (dom) {
  265. if (val && reg) {
  266. let regx = new RegExp(reg);
  267. let state = regx.test(val);
  268. if (state) {
  269. delete formRegExpJson.value[pkeyId]
  270. dom.style = ''
  271. } else {
  272. formRegExpJson.value[pkeyId] = {key, reg, val, msg, state, nodeName: item.nodeName, itemId: `item-${index}-${item?.pkeyId}`}
  273. dom.style = '--el-input-border-color: #fe0000'
  274. window?.$message?.warning(msg)
  275. }
  276. } else {
  277. delete formRegExpJson.value[pkeyId]
  278. dom.style = ''
  279. }
  280. }
  281. }
  282. //获取已填写的数据
  283. const getBussDataInfo = async (item, pkeyId, index) => {
  284. const pkeyIds = pkeyId ? pkeyId + '' : ''
  285. if (pkeyIds) {
  286. const {error, code, data} = await wbsApi.getBussDataInfo({
  287. pkeyId: pkeyIds
  288. }, false)
  289. const resData = getObjNullValue(data)
  290. if (!error && code === 200 && resData) {
  291. HTableForm.setPickerKey(resData)
  292. const InitObj = getFormDataInit(item, pkeyId) //有数据,关联数据
  293. formData.value[index] = {...resData, ...InitObj, isCollapseLoad: true}
  294. } else {
  295. formData.value[index] = {...getFormDataInit(item, pkeyId), isCollapseLoad: true}
  296. }
  297. } else {
  298. window?.$message?.warning('pkeyId为空')
  299. }
  300. }
  301. //单个保存
  302. const tableFormSaveLoading = ref(false)
  303. const tableFormSaveClick = async (item,index) => {
  304. if (isStatus.value !== '3') {
  305. const res = await saveExcelBussData(item,index)
  306. if (res) {
  307. await getBussPdfInfo(item)
  308. renewData()
  309. }
  310. } else {
  311. window?.$message?.warning('已上报的资料,不允许保存。')
  312. }
  313. }
  314. //保存表单数据
  315. const saveExcelBussData = async (item, index, showTip = true) => {
  316. if (!getObjNullValue(formRegExpJson.value)) {
  317. tableFormSaveLoading.value = true
  318. const InitObj = getFormDataInit(item, item.pkeyId)
  319. const {error, code, data} = await wbsApi.saveExcelBussData({
  320. ...formData.value[index],
  321. ...InitObj
  322. })
  323. //处理数据
  324. tableFormSaveLoading.value = false
  325. if (!error && code === 200) {
  326. if(showTip) window?.$message?.success('保存成功')
  327. return true
  328. } else {
  329. return false
  330. }
  331. } else {
  332. window?.$message?.warning('请先修改完红色输入框的数据')
  333. return false
  334. }
  335. }
  336. //预览PDF
  337. const getBussPdfInfo = async (item, showTip = true) => {
  338. const pkeyIds = item.pkeyId ? item.pkeyId + '' : ''
  339. if (pkeyIds) {
  340. const {error, code, data} = await wbsApi.getBussPdfInfo({
  341. pkeyId: pkeyIds
  342. },false)
  343. if (!error && code === 200) {
  344. if (data) {
  345. window.open(data, '_blank')
  346. } else if(showTip) {
  347. window?.$message?.warning('PDF错误')
  348. }
  349. } else {
  350. if(showTip) {
  351. window?.$message?.warning(data.msg || '获取PDF失败')
  352. }
  353. }
  354. } else {
  355. window?.$message?.warning('pkeyId为空')
  356. }
  357. }
  358. //删除本表
  359. const delClick = async (item) => {
  360. const pkeyIds = item.pkeyId ? item.pkeyId + '' : ''
  361. if (pkeyIds) {
  362. if (isStatus.value !== '3') {
  363. const {error, code} = await wbsApi.removeBussTabInfo({
  364. pkeyid: pkeyIds,
  365. classify: classify.value,
  366. })
  367. if (!error && code === 200) {
  368. window?.$message?.success('操作成功')
  369. renewData()
  370. }
  371. } else {
  372. window?.$message?.warning('已上报的资料,不允许删除')
  373. }
  374. } else {
  375. window?.$message?.warning('pkeyId为空')
  376. }
  377. }
  378. //复制本表
  379. const copyClick = async (item,index) => {
  380. const pkeyIds = item.pkeyId ? item.pkeyId + '' : ''
  381. if (pkeyIds) {
  382. if (isStatus.value !== '3') {
  383. if (!item.isRenderTableForm) {
  384. await copeBussTab(pkeyIds)
  385. } else if (!item.isTableForm) {
  386. window?.$message?.warning('暂无表单数据')
  387. } else if (item.isRenderTableForm) {
  388. const res = await saveExcelBussData(item,index,false)
  389. if (res) {
  390. await copeBussTab(pkeyIds)
  391. } else {
  392. window?.$message?.warning('复制本表操作失败')
  393. }
  394. } else {
  395. window?.$message?.warning(`数据异常了, isRenderTableForm: ${item.isRenderTableForm}, isTableForm: ${item.isTableForm}, pkeyIds:${pkeyIds}`)
  396. }
  397. } else {
  398. window?.$message?.warning('已上报的资料,不允许复制')
  399. }
  400. } else {
  401. window?.$message?.warning('pkeyId为空')
  402. }
  403. }
  404. const copeBussTab = async (pkeyIds) => {
  405. const {error, code} = await wbsApi.copeBussTab({
  406. pkeyId: pkeyIds
  407. })
  408. if (!error && code === 200) {
  409. window?.$message?.success('操作成功')
  410. renewData()
  411. }
  412. }
  413. //隐藏本表
  414. const hideClick = async (item) => {
  415. const pkeyIds = item.pkeyId ? item.pkeyId + '' : ''
  416. if (pkeyIds) {
  417. if (isStatus.value !== '3') {
  418. const isBussShow = item['isBussShow'] === 2 ? 1 : 2 //状态(1显示 2隐藏)
  419. const {error, code} = await wbsApi.showBussTab({
  420. pkeyId: pkeyIds,
  421. status: isBussShow
  422. })
  423. if (!error && code === 200) {
  424. window?.$message?.success('操作成功')
  425. renewData()
  426. }
  427. } else {
  428. window?.$message?.warning('已上报的资料,不允许隐藏')
  429. }
  430. } else {
  431. window?.$message?.warning('pkeyId为空')
  432. }
  433. }
  434. //预览
  435. const previewClick = async (item,index) => {
  436. await getBussPdfInfo(item)
  437. }
  438. //上传变量
  439. const uploadModal = ref(false)
  440. const fileListData = ref([]);
  441. const uploadData = ref({})
  442. //上传被点击
  443. const uploadClick = (item,index) => {
  444. const pkeyIds = item.pkeyId ? item.pkeyId + '' : ''
  445. const keyName = `item-${index}-${pkeyIds}`
  446. if (pkeyIds) {
  447. if (isStatus.value !== '3' && item.isTableForm) {
  448. uploadModal.value = true
  449. uploadData.value = getFormDataInit(item,pkeyIds)
  450. //获取文件列表
  451. getBussFileList(pkeyIds)
  452. } else if (!item.isRenderTableForm) {
  453. CollapseChange(keyName)
  454. window?.$message?.warning('请再次点击上传')
  455. } else if (!item.isTableForm) {
  456. window?.$message?.warning('暂无表单数据')
  457. } else {
  458. window?.$message?.warning('已上报的资料,不允许上传')
  459. }
  460. } else {
  461. window?.$message?.warning('pkeyId为空')
  462. }
  463. }
  464. //获取文件列表
  465. const getBussFileList = async (pkeyId) => {
  466. const {error, code, data} = await wbsApi.getBussFileList({
  467. pkeyid: pkeyId
  468. })
  469. if (!error && code === 200) {
  470. fileListData.value = getArrValue(data)
  471. } else {
  472. fileListData.value = []
  473. }
  474. }
  475. //上传文件
  476. const uploadChange = async ({type}) => {
  477. if(type === 'success') {
  478. uploadModal.value = false
  479. renewData()
  480. } else if (type === 'del') {
  481. renewData()
  482. }
  483. }
  484. //相关变量
  485. const tableFormItemNode = ref({})
  486. //菜单数据
  487. const tableFormMenu = ref([
  488. {label: '插入设计值/频率', key: "IDVF"},
  489. {label: '插入特殊字符', key: "special"},
  490. {label: '关联试验数据', key: "CTD"},
  491. ])
  492. //鼠标右键事件
  493. const contextMenuRef = ref(null)
  494. const onRightClick = (event, KeyName, index) => {
  495. //取光标位置
  496. const specialDom = document.getElementById(KeyName + "")
  497. const startPos = specialDom?.selectionStart || 0
  498. const endPos = specialDom?.selectionEnd || 0
  499. //存储临时信息
  500. tableFormItemNode.value = {KeyName, index, startPos, endPos, pkeyId: formKeyIds.value}
  501. contextMenuRef.value?.showMenu(event) //展开菜单
  502. }
  503. //鼠标右键菜单被点击
  504. const handleMenuSelect = ({key}) => {
  505. if (key === 'IDVF') {
  506. IDVFModal.value = true
  507. } else if (key === 'special') {
  508. specialModalShow()
  509. } else if (key === 'CTD') {
  510. CTDModal.value = true
  511. }
  512. }
  513. //插入设计值
  514. const IDVFModal = ref(false)
  515. const formIDVFRef = ref(null)
  516. const formIDVFModel = ref({design: '', size: '', dev: '', key: '', pkId: ''})
  517. const formIDVFRules = {
  518. design: {
  519. required: true,
  520. trigger: "blur",
  521. message: "请输入设计值"
  522. },
  523. size: {
  524. required: true,
  525. trigger: "blur",
  526. message: "请输入频率"
  527. }
  528. }
  529. //插入特殊字符
  530. const specialModal = ref(false)
  531. const specialCharacters = ref([
  532. '&#57344;', "&#57345;", "&#57346;", "&#57347;", '&#8804;', '&#8805;', '&#8451;',
  533. '&#9312;', '&#9313;', '&#9314;', '&#9315;', '&#9316;', '&#9317;', '&#9318;', '&#9319;', '&#9320;', '&#9321;', '&#9322;', '&#9323;',
  534. '&#9324;', '&#9325;', '&#9326;', '&#9327;', '&#9328;', '&#9329;', '&#9330;', '&#9331;',
  535. "&#8544;", "&#8545;", "&#8546;", "&#8547;", "&#8548;", "&#8549;", "&#8550;", "&#8551;", "&#8552;", "&#8553;", "&#8554;", "&#8555;","K̅"
  536. ])
  537. //输入框验证
  538. const specialFormRef = ref(null)
  539. const specialFormModel = ref({val: ''})
  540. const specialFormRules = {
  541. val: {
  542. required: true,
  543. trigger: "blur",
  544. message: "请选择特殊字符代码"
  545. }
  546. }
  547. //显示插入特殊字符
  548. const specialRef = ref(null)
  549. const specialModalShow = () => {
  550. specialFormModel.value.val = ''
  551. specialModal.value = true
  552. nextTick(() => {
  553. specialRef.value?.focus();
  554. })
  555. }
  556. //失去焦点
  557. const specialPos = ref({start: 0, end: 0})
  558. const specialInputBlur = (e) => {
  559. specialPos.value = {
  560. start: e?.target?.selectionStart || 0,
  561. end: e?.target?.selectionEnd || 0
  562. }
  563. }
  564. //点击符号
  565. const specialClick = (event) => {
  566. const text = event?.target?.innerText ?? ''
  567. const start = specialPos.value.start
  568. const end = specialPos.value.end
  569. const form = specialFormModel.value.val
  570. specialFormModel.value.val = setPosInsert(start, end, form, text)
  571. specialRef.value?.focus();
  572. let posVal = start + text.length;
  573. nextTick(() => {
  574. setPosRange('specialId', posVal)
  575. })
  576. }
  577. //确认插入
  578. const specialNodeClick = async () => {
  579. const res = await formValidate(specialFormRef.value)
  580. if (res) {
  581. const item = tableFormItemNode.value
  582. const form = formData.value[item.index]
  583. const val = specialFormModel.value.val ?? ''
  584. formData.value[item.index][item.KeyName] = setPosInsert(item.startPos, item.endPos, form[item.KeyName], val)
  585. specialModal.value = false
  586. specialRef.value?.focus();
  587. let posVal = item.startPos + val.length;
  588. nextTick(() => {
  589. setPosRange(item.KeyName, posVal)
  590. })
  591. }
  592. }
  593. //关联试验数据
  594. const CTDModal = ref(false)
  595. //设计值频率计算
  596. const IDVFModalSaveClick = async () => {
  597. const {pkeyId, KeyName, index} = tableFormItemNode.value
  598. if (pkeyId) {
  599. const { design, size } = formIDVFModel.value
  600. const { error, code, data } = await wbsApi.queryFormulaRange({
  601. ...formIDVFModel.value,
  602. dev: (!design && !size) ? '±5': '',
  603. key: KeyName,
  604. pkId: pkeyId
  605. })
  606. //处理数据
  607. const res = getObjNullValue(data)
  608. if (!error && code === 200 && res) {
  609. Object.keys(data).forEach(key => {
  610. formData.value[index][key] = data[key]
  611. })
  612. IDVFModal.value = false
  613. }
  614. } else {
  615. window?.$message?.warning('pkeyId为空')
  616. }
  617. }
  618. //事件
  619. const emit = defineEmits(['renew','offsetTop'])
  620. //被点击
  621. const getOffsetTop = (key = '') => {
  622. if (key) {
  623. const dom = document.getElementById(key)
  624. emit('offsetTop', dom.offsetTop)
  625. } else {
  626. emit('offsetTop', 0)
  627. }
  628. }
  629. //通知数据更新
  630. const renewData = () => {
  631. emit('renew')
  632. ActiveKey.value = ''
  633. }
  634. //获取表单数据
  635. const getFormData = () => {
  636. const formArr = deepClone(formData.value);
  637. return formArr.filter((item) => {
  638. return (item.pkeyId??'') !== '' && item.isCollapseLoad;
  639. })
  640. }
  641. //获取表单效验数据
  642. const getFormRegExpJson = () => {
  643. return deepClone(formRegExpJson.value);
  644. }
  645. //获取当前展开项
  646. const getActiveKey = () => {
  647. return ActiveKey.value;
  648. }
  649. //设置当前展开项
  650. const setActiveKey = (key) => {
  651. return ActiveKey.value = key;
  652. }
  653. // 暴露出去
  654. defineExpose({
  655. getFormData,
  656. getFormRegExpJson,
  657. getActiveKey,
  658. setActiveKey
  659. })
  660. </script>
  661. <style lang="scss" scoped>
  662. .data-fill-list-box {
  663. position: relative;
  664. //margin-bottom: 25%;
  665. .hc-collapse-item-header {
  666. flex: 1;
  667. position: relative;
  668. margin-left: 46px;
  669. display: flex;
  670. align-items: center;
  671. .item-title {
  672. flex: 1;
  673. position: relative;
  674. user-select: none;
  675. color: #50545E;
  676. font-size: 16px;
  677. font-weight: 400;
  678. cursor: pointer;
  679. }
  680. .hc-extra-text-box {
  681. position: relative;
  682. padding-right: 24px;
  683. }
  684. }
  685. .data-fill-list-item-content {
  686. position: relative;
  687. display: flex;
  688. height: calc(100vh - 386px);
  689. .data-fill-table-form-box {
  690. position: relative;
  691. padding: 24px 20px;
  692. height: 100%;
  693. overflow: auto;
  694. flex: 1;
  695. .hc-no-table-form {
  696. position: relative;
  697. height: 100%;
  698. display: flex;
  699. justify-content: center;
  700. align-items: center;
  701. .table-form-no {
  702. position: relative;
  703. img {
  704. width: 350px;
  705. }
  706. .desc {
  707. text-align: center;
  708. font-size: 20px;
  709. color: #aaa;
  710. }
  711. }
  712. }
  713. }
  714. .data-fill-table-tip-box {
  715. width: 240px;
  716. position: relative;
  717. border-left: 1px solid #E9E9E9;
  718. padding: 20px 15px 80px;
  719. .tip-title {
  720. font-size: 16px;
  721. margin-bottom: 10px;
  722. display: flex;
  723. align-items: center;
  724. }
  725. .tip-item {
  726. margin-bottom: 20px;
  727. }
  728. .table-tip-foot {
  729. position: absolute;
  730. bottom: 15px;
  731. right: 0;
  732. left: 0;
  733. display: flex;
  734. align-items: center;
  735. padding: 0 15px;
  736. .tip-left-btn {
  737. flex: 1;
  738. .dow-text {
  739. cursor: pointer;
  740. display: flex;
  741. align-items: center;
  742. }
  743. }
  744. }
  745. }
  746. }
  747. }
  748. .special-box {
  749. position: relative;
  750. display: flex;
  751. justify-content: center;
  752. align-items: center;
  753. border: 1px solid #eee;
  754. border-radius: 3px;
  755. height: 52px;
  756. width: 52px;
  757. cursor: pointer;
  758. user-select: none;
  759. transition: color .3s, background-color .3s;
  760. &:hover {
  761. color: var(--el-color-primary);
  762. background-color: var(--el-color-primary-light-8);
  763. }
  764. .font-EUDC {
  765. font-size: 22px;
  766. }
  767. }
  768. </style>
  769. <style lang="scss">
  770. .data-fill-list-box {
  771. .el-collapse {
  772. --el-collapse-header-height: 60px;
  773. border: 0;
  774. .el-collapse-item {
  775. margin: 0 0 16px;
  776. background-color: #f1f5f8;
  777. border: 1px solid #E9E9E9;
  778. border-radius: 4px;
  779. }
  780. .el-collapse-item__header {
  781. background-color: transparent;
  782. font-weight: 400;
  783. border-bottom: 0;
  784. cursor: default;
  785. font-size: 14px;
  786. .el-collapse-item__arrow {
  787. position: absolute;
  788. color: #50545E;
  789. cursor: pointer;
  790. left: 20px;
  791. margin: 0;
  792. }
  793. }
  794. .el-collapse-item.is-active .el-collapse-item__header.is-active {
  795. background-color: #E7EEF4;
  796. }
  797. .el-collapse-item__wrap {
  798. background-color: transparent;
  799. border-bottom: 0;
  800. .el-collapse-item__content {
  801. position: relative;
  802. padding-bottom: 0;
  803. font-size: 14px;
  804. color: #50545E;
  805. line-height: initial;
  806. }
  807. }
  808. }
  809. }
  810. //插入特殊字符弹窗的输入框
  811. .data-fill-list-box .data-fill-table-form-box td,
  812. .data-fill-list-box .data-fill-table-form-box td .el-input .el-input__wrapper .el-input__inner,
  813. .el-form-item.special-form-item .el-form-item__content .el-input .el-input__wrapper .el-input__inner {
  814. font-family: "EUDC", 宋体, v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  815. }
  816. </style>