permitAdd.vue 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390
  1. <template>
  2. <ele-modal
  3. :title="dialogTitle"
  4. :visible.sync="visible"
  5. :before-close="handleClose"
  6. :close-on-click-modal="false"
  7. :close-on-press-escape="false"
  8. width="80%"
  9. :maxable="true"
  10. append-to-body
  11. destroy-on-close
  12. >
  13. <el-form
  14. label-width="115px"
  15. :model="formData"
  16. :rules="formRules"
  17. ref="formRef"
  18. v-loading="loading"
  19. :disabled="type == 'detail'"
  20. >
  21. <el-row style="margin-bottom: 15px">
  22. <el-col :span="8">
  23. <el-form-item label="记录规则类型" prop="classify" required>
  24. <el-select
  25. style="width: 100%"
  26. v-model="formData.classify"
  27. placeholder="请选择"
  28. :disabled="type == 'processEdit'"
  29. >
  30. <el-option
  31. v-for="item in recordSheet"
  32. :key="item.value"
  33. :label="item.label"
  34. :value="item.value"
  35. >
  36. </el-option>
  37. </el-select>
  38. </el-form-item>
  39. </el-col>
  40. <el-col :span="8">
  41. <el-form-item label="记录规则编码" prop="code">
  42. <el-input
  43. v-model="formData.code"
  44. :disabled="true"
  45. placeholder="系统自动生成"
  46. ></el-input>
  47. </el-form-item>
  48. </el-col>
  49. <el-col :span="8">
  50. <el-form-item label="记录规则版本">
  51. <el-input
  52. :value="versionText"
  53. disabled
  54. placeholder="系统自动生成"
  55. ></el-input>
  56. </el-form-item>
  57. </el-col>
  58. </el-row>
  59. <el-row style="margin-bottom: 15px">
  60. <el-col :span="8">
  61. <el-form-item label="记录规则名称" prop="name">
  62. <el-input
  63. v-model="formData.name"
  64. placeholder="请输入"
  65. :disabled="type == 'processEdit'"
  66. ></el-input>
  67. </el-form-item>
  68. </el-col>
  69. <el-col :span="8">
  70. <el-form-item label="启用日期" required prop="startDate">
  71. <el-date-picker
  72. v-model="formData.startDate"
  73. type="date"
  74. placeholder="请选择启用日期"
  75. style="width: 100%"
  76. :disabled="type == 'processEdit'"
  77. ></el-date-picker>
  78. </el-form-item>
  79. </el-col>
  80. <el-col :span="8">
  81. <el-form-item label="停用日期" required prop="stopDate">
  82. <el-date-picker
  83. v-model="formData.stopDate"
  84. type="date"
  85. placeholder="请选择停用日期"
  86. style="width: 100%"
  87. :disabled="type == 'processEdit'"
  88. />
  89. </el-form-item>
  90. </el-col>
  91. </el-row>
  92. <el-row v-if="formData.classify == 3" style="margin-bottom: 15px">
  93. <el-col :span="8">
  94. <el-form-item label="关联设备" prop="deviceName" required>
  95. <el-input
  96. v-model="formData.deviceName"
  97. placeholder="请选择设备"
  98. :readonly="true"
  99. >
  100. <template #append>
  101. <el-button @click="selectDeviceId">选择设备</el-button>
  102. </template>
  103. </el-input>
  104. </el-form-item>
  105. </el-col>
  106. </el-row>
  107. <el-row style="margin-bottom: 15px">
  108. <el-col :span="8">
  109. <el-form-item label="模块分类" required prop="reportWorkType">
  110. <dict-selection
  111. v-model="formData.reportWorkType"
  112. dictName="记录规则报工类型"
  113. placeholder="请选择模块"
  114. :clearable="false"
  115. :isProhibit="type == 'processEdit'"
  116. ></dict-selection>
  117. </el-form-item>
  118. </el-col>
  119. <el-col v-if="formData.reportWorkType == 2" :span="8">
  120. <el-form-item label="关联工序">
  121. <el-input
  122. v-model="formData.produceTaskName"
  123. @click.native="openProduceTaskDialog"
  124. readonly
  125. placeholder="关联工序"
  126. clearable
  127. :disabled="type == 'processEdit'"
  128. >
  129. <i
  130. v-if="formData.produceTaskName"
  131. slot="suffix"
  132. class="el-input__icon el-icon-close"
  133. size="24"
  134. @click.stop="clearProductTask"
  135. ></i>
  136. </el-input>
  137. </el-form-item>
  138. </el-col>
  139. <el-col v-if="formData.reportWorkType == 2" :span="8">
  140. <el-form-item label="是否有执行方式" label-width="130px">
  141. <el-radio-group
  142. v-model="formData.isExecuteMethod"
  143. @change="executeMethodChange"
  144. >
  145. <el-radio :label="1">是</el-radio>
  146. <el-radio :label="0">否</el-radio>
  147. </el-radio-group>
  148. </el-form-item>
  149. </el-col>
  150. </el-row>
  151. <el-row style="margin-bottom: 15px">
  152. <el-col :span="24">
  153. <el-form-item label="周期" prop="frequencyValue" required>
  154. <rule-cycle
  155. ref="cycleMultipleRef"
  156. :formData="formData"
  157. :pageType="type"
  158. :isBindPlan="type == 'processEdit'"
  159. />
  160. </el-form-item>
  161. </el-col>
  162. </el-row>
  163. <header-title title="规则明细">
  164. <el-button
  165. v-if="formData.isExecuteMethod"
  166. type="primary"
  167. @click="addExecuteMethod"
  168. >添加执行方式</el-button
  169. >
  170. </header-title>
  171. <el-tabs
  172. v-if="formData.isExecuteMethod"
  173. v-model="formData.executeMethodTitle"
  174. type="card"
  175. closable
  176. @tab-remove="deleteExecuteMethod"
  177. >
  178. <el-tab-pane
  179. :key="item"
  180. v-for="item in formData.executeMethodList"
  181. :label="item"
  182. :name="item"
  183. >
  184. {{ item.content }}
  185. </el-tab-pane>
  186. </el-tabs>
  187. <ele-pro-table
  188. ref="table"
  189. :columns="bankColumns"
  190. :datasource="detailsList"
  191. :need-page="false"
  192. row-key="id"
  193. class="table_list"
  194. :cache-key="cacheKeyUrl"
  195. >
  196. <template v-slot:toolbar>
  197. <div style="display: flex; align-items: center; gap: 10px">
  198. <el-button
  199. type="primary"
  200. icon="el-icon-plus"
  201. class="ele-btn-icon"
  202. @click="addRow"
  203. >
  204. 新建
  205. </el-button>
  206. <el-form-item
  207. v-if="formData.isExecuteMethod"
  208. label="编辑执行方式:"
  209. label-width="110px"
  210. style="margin-bottom: 0"
  211. >
  212. <el-input type="text" v-model="executeMethodTitleComputed" />
  213. </el-form-item>
  214. </div>
  215. </template>
  216. <template v-slot:paramType="{ row }">
  217. <el-select
  218. v-model="row.paramType"
  219. placeholder="请选择参数类型"
  220. size="mini"
  221. >
  222. <el-option label="数值" :value="1" />
  223. <el-option label="选择" :value="2" />
  224. <el-option label="上下限" :value="3" />
  225. <el-option label="规格" :value="4" />
  226. <el-option label="时间" :value="5" />
  227. <el-option label="范围" :value="6" />
  228. <el-option label="文本" :value="7" />
  229. <!-- <el-option label="枚举" :value="8" /> -->
  230. </el-select>
  231. </template>
  232. <template v-slot:paramValue="{ row }">
  233. <!-- 根据参数类型渲染不同的输入组件 -->
  234. <el-link
  235. v-if="formData.classify == '4'"
  236. :underline="false"
  237. style="cursor: pointer"
  238. >
  239. <div class="ele-cell">
  240. <div @click="selectChooseModalProduct(row)">
  241. {{ row.productName ? row.productName : '请选择产品' }}
  242. </div>
  243. <i
  244. v-if="row.tools.length == 0"
  245. class="el-icon-arrow-down"
  246. @click="selectChooseModalProduct(row)"
  247. ></i>
  248. <i v-else class="el-icon-close" @click="clearProduct(row)"></i>
  249. </div>
  250. </el-link>
  251. <el-input
  252. v-else
  253. v-model="row.paramValue"
  254. placeholder="请输入参数内容"
  255. size="mini"
  256. type="textarea"
  257. rows="1"
  258. autosize
  259. ></el-input>
  260. </template>
  261. <template v-slot:defaultValue="{ row }">
  262. <el-row>
  263. <el-col :span="12">
  264. <!-- <el-select
  265. v-if="row.paramType != 7"
  266. v-model="row.symbol"
  267. placeholder="请选择"
  268. size="mini"
  269. >
  270. <el-option label=">" value=">"> </el-option>
  271. <el-option label="<" value="<"> </el-option>
  272. <el-option label="!=" value="!="> </el-option>
  273. <el-option label=">=" value=">="> </el-option>
  274. <el-option label="<=" value="<="> </el-option>
  275. <el-option label="~~" value="~~"> </el-option>
  276. <el-option label="+-" value="+-"> </el-option>
  277. <el-option label="......" value="......"> </el-option>
  278. </el-select> -->
  279. <DictSelection
  280. v-if="row.paramType != 7"
  281. clearable
  282. dictName="数学字符"
  283. v-model="row.symbol"
  284. placeholder="请选择逻辑"
  285. size="mini"
  286. ></DictSelection>
  287. </el-col>
  288. <el-col :span="row.paramType != 7 ? 12 : 24">
  289. <el-input
  290. v-model="row.defaultValue"
  291. placeholder="请输入默认值"
  292. size="mini"
  293. ></el-input>
  294. </el-col>
  295. </el-row>
  296. </template>
  297. <template v-slot:maxValue="{ row }">
  298. <el-input
  299. v-if="row.paramType == 3 || row.paramType == 6"
  300. v-model="row.maxValue"
  301. placeholder="请输入参数上限"
  302. size="mini"
  303. ></el-input>
  304. </template>
  305. <template v-slot:minValue="{ row }">
  306. <el-input
  307. v-if="row.paramType == 3 || row.paramType == 6"
  308. v-model="row.minValue"
  309. placeholder="请输入参数下限"
  310. size="mini"
  311. ></el-input>
  312. </template>
  313. <template v-slot:unitName="{ row }">
  314. <!-- <el-input
  315. v-model="row.unitName"
  316. placeholder="请输入参数单位"
  317. size="mini"
  318. ></el-input> -->
  319. <DictSelection
  320. v-if="row.paramType != 7"
  321. dictName="工艺参数单位"
  322. clearable
  323. filterable
  324. v-model="row.unitName"
  325. size="mini"
  326. >
  327. </DictSelection>
  328. </template>
  329. <template v-slot:toolName="{ row }">
  330. <el-link :underline="false" style="cursor: pointer">
  331. <div class="ele-cell">
  332. <div @click="handleAdd(row)">
  333. {{
  334. row.tools && row.tools.length > 0
  335. ? row.tools.map((i) => i.toolName).join(',')
  336. : '请选择'
  337. }}
  338. </div>
  339. <i
  340. v-if="row.tools.length == 0"
  341. class="el-icon-arrow-down"
  342. @click="handleAdd(row)"
  343. ></i>
  344. <i v-else class="el-icon-close" @click="clearTool(row)"></i>
  345. </div>
  346. </el-link>
  347. </template>
  348. <template v-slot:toolCodes="{ row }">
  349. <el-input
  350. :value="
  351. row.tools && row.tools.length > 0
  352. ? row.tools.map((i) => i.toolCode).join(',')
  353. : ''
  354. "
  355. placeholder="工具自动带出"
  356. disabled
  357. size="mini"
  358. ></el-input>
  359. </template>
  360. <template v-slot:remark="{ row }">
  361. <el-input
  362. v-model="row.remark"
  363. placeholder="请输入"
  364. size="mini"
  365. ></el-input>
  366. </template>
  367. <template v-slot:executeMethodTitle="{ row }">
  368. <!-- <el-select v-model="row.executeMethodTitle" clearable size="mini">
  369. <el-option
  370. v-for="item in formData.executeMethodList"
  371. :key="item"
  372. :label="item"
  373. :value="item"
  374. ></el-option>
  375. </el-select> -->
  376. {{ row.executeMethodTitle }}
  377. </template>
  378. <template v-slot:action="{ row }">
  379. <el-link
  380. v-if="type != 'detail'"
  381. type="danger"
  382. :underline="false"
  383. icon="el-icon-delete"
  384. @click="deleteRow(row)"
  385. >
  386. 删除
  387. </el-link>
  388. </template>
  389. </ele-pro-table>
  390. </el-form>
  391. <template v-slot:footer>
  392. <el-button
  393. v-if="type != 'detail' && type != 'processEdit'"
  394. :loading="btnLoading"
  395. type="primary"
  396. @click="saveAndPublish"
  397. >
  398. 保存并发布
  399. </el-button>
  400. <el-button
  401. v-if="type != 'detail' && type != 'processEdit'"
  402. :loading="btnLoading"
  403. type="primary"
  404. @click="confirm"
  405. >
  406. 保存
  407. </el-button>
  408. <el-button
  409. v-if="type == 'processEdit'"
  410. :loading="btnLoading"
  411. type="primary"
  412. @click="processEditSave"
  413. >
  414. 保存
  415. </el-button>
  416. <el-button :loading="btnLoading" @click="handleClose">取消</el-button>
  417. </template>
  418. <toolModal ref="toolModalRef" @chooseModal="chooseModal" />
  419. <toolModal ref="toolModalTowRef" @chooseModal="chooseModalProduct" />
  420. <MaterialAdd
  421. ref="deviceSelectDialog"
  422. selectType="single"
  423. @chooseEquipment="chooseEquipment"
  424. />
  425. <ProductModal
  426. ref="ProductModalRef"
  427. @changeProduct="changeProduct"
  428. ></ProductModal>
  429. <processModal
  430. ref="processModalRef"
  431. @chooseProcess="processChooseProcess"
  432. ></processModal>
  433. </ele-modal>
  434. </template>
  435. <script>
  436. import { getByCode } from '@/api/system/dictionary-data';
  437. // import RuleCycle from '../../matterRules/components/rule-cycle.vue';
  438. import RuleCycle from './rule-cycle.vue';
  439. import OperationGuideDialog from '@/views/rulesManagement/matterRules/components/operationGuideDialog.vue';
  440. import Details from './details.vue';
  441. import dictMixins from '@/mixins/dictMixins';
  442. import toolModal from './toolModal.vue';
  443. import MaterialAdd from '../../components/MaterialAdd.vue';
  444. import {
  445. recordrulesSave,
  446. recordrulesDetailPage,
  447. recordrulesUpdate,
  448. recordrulesPublish,
  449. recordrulesSaveAndPublish,
  450. recordrulesUpdateVersion,
  451. recordrulesCyclePage,
  452. recordrulesGetById
  453. } from '@/api/recordrules/index';
  454. import ProductModal from '@/components/selectProduct/ProductModal.vue';
  455. import { getTreeByPid } from '@/api/classifyManage';
  456. import processModal from './processModal.vue';
  457. import ProductModalCorrelation from './ProductModal.vue';
  458. import productionAPI from '@/api/technology/production/index.js';
  459. export default {
  460. components: {
  461. OperationGuideDialog,
  462. RuleCycle,
  463. Details,
  464. ProductModal,
  465. MaterialAdd,
  466. toolModal,
  467. processModal,
  468. ProductModalCorrelation
  469. },
  470. mixins: [dictMixins],
  471. computed: {
  472. bankColumns() {
  473. return [
  474. {
  475. width: 110,
  476. type: 'index',
  477. columnKey: 'index',
  478. align: 'center',
  479. label: '序号'
  480. },
  481. {
  482. prop: 'paramType',
  483. label: '参数类型',
  484. align: 'center',
  485. slot: 'paramType',
  486. minWidth: 110
  487. },
  488. {
  489. prop: 'paramValue',
  490. label: '参数内容',
  491. align: 'center',
  492. slot: 'paramValue',
  493. minWidth: 261
  494. },
  495. {
  496. prop: 'defaultValue',
  497. label: '默认值',
  498. align: 'center',
  499. slot: 'defaultValue',
  500. minWidth: 150
  501. },
  502. {
  503. prop: 'maxValue',
  504. label: '参数上限',
  505. align: 'center',
  506. slot: 'maxValue',
  507. minWidth: 110
  508. },
  509. {
  510. prop: 'minValue',
  511. label: '参数下限',
  512. align: 'center',
  513. slot: 'minValue',
  514. minWidth: 110
  515. },
  516. {
  517. prop: 'unitName',
  518. label: '参数单位',
  519. align: 'center',
  520. slot: 'unitName',
  521. minWidth: 110
  522. },
  523. {
  524. prop: 'toolName',
  525. label: '工具名称',
  526. align: 'center',
  527. slot: 'toolName',
  528. minWidth: 110
  529. },
  530. {
  531. prop: 'toolCodes',
  532. label: '工具编码',
  533. align: 'center',
  534. slot: 'toolCodes',
  535. minWidth: 110
  536. },
  537. {
  538. prop: 'remark',
  539. label: '备注',
  540. align: 'center',
  541. slot: 'remark',
  542. minWidth: 110
  543. },
  544. {
  545. prop: 'executeMethodTitle',
  546. label: '执行方式',
  547. align: 'center',
  548. slot: 'executeMethodTitle',
  549. minWidth: 110
  550. },
  551. {
  552. columnKey: 'action',
  553. label: '操作',
  554. width: 110,
  555. align: 'center',
  556. resizable: false,
  557. slot: 'action',
  558. fixed: 'right'
  559. }
  560. ];
  561. },
  562. versionText() {
  563. if (this.type == 'change') {
  564. return '系统自动生成';
  565. }
  566. return (
  567. this.formData.bigVersion +
  568. this.formData.versionMark +
  569. this.formData.smallVersion
  570. );
  571. },
  572. productColumns() {
  573. return [
  574. {
  575. columnKey: 'index',
  576. type: 'index',
  577. width: 45,
  578. align: 'center',
  579. reserveSelection: true
  580. },
  581. {
  582. prop: 'code',
  583. label: '产品编码'
  584. },
  585. {
  586. prop: 'name',
  587. label: '产品名称',
  588. showOverflowTooltip: true
  589. },
  590. {
  591. prop: 'brandNum',
  592. label: '牌号'
  593. },
  594. {
  595. prop: 'modelType',
  596. label: '型号'
  597. },
  598. {
  599. prop: 'specification',
  600. label: '规格'
  601. },
  602. {
  603. prop: 'measuringUnit',
  604. label: '计量单位'
  605. },
  606. {
  607. prop: 'packingUnit',
  608. label: '包装单位'
  609. },
  610. {
  611. columnKey: 'action',
  612. label: '操作',
  613. width: 110,
  614. align: 'center',
  615. resizable: false,
  616. slot: 'action',
  617. fixed: 'right'
  618. }
  619. ];
  620. },
  621. cacheKeyUrl() {
  622. return `main-permit-add-2510181429-reportWorkType`;
  623. },
  624. detailsList() {
  625. if (this.formData.isExecuteMethod) {
  626. return this.formData.details.filter(
  627. (i) => i.executeMethodTitle == this.formData.executeMethodTitle
  628. );
  629. } else {
  630. return this.formData.details;
  631. }
  632. },
  633. executeMethodTitleComputed: {
  634. get() {
  635. return this.formData.executeMethodTitle;
  636. },
  637. set(value) {
  638. // 更改 明细表的 executeMethodTitle
  639. this.formData.details = this.formData.details.map((i) => {
  640. if (i.executeMethodTitle == this.formData.executeMethodTitle) {
  641. return {
  642. ...i,
  643. executeMethodTitle: value
  644. };
  645. }
  646. return i;
  647. });
  648. this.formData.executeMethodList = this.formData.executeMethodList.map(
  649. (i) => {
  650. if (i == this.formData.executeMethodTitle) {
  651. return value;
  652. }
  653. return i;
  654. }
  655. );
  656. this.formData.executeMethodTitle = value;
  657. if (!value) {
  658. this.$message.warning('执行方式不能为空!');
  659. }
  660. }
  661. }
  662. },
  663. data() {
  664. const formDateBase = {
  665. id: null,
  666. classify: null,
  667. deviceId: null,
  668. deviceName: '',
  669. frequencyUnit: 2,
  670. frequencyValue: null,
  671. name: '',
  672. details: [],
  673. recordRulesCycleList: [],
  674. startDate: null,
  675. stopDate: null,
  676. version: 1,
  677. code: '',
  678. fromId: null,
  679. // 模块分类 参考字典项:record_rules_report_work_type
  680. reportWorkType: '1',
  681. // 执行方式
  682. isExecuteMethod: 0,
  683. produceTaskConfigs: [],
  684. // 执行方式列表
  685. executeMethodList: [],
  686. // 执行方式 活跃项
  687. executeMethodTitle: '',
  688. bigVersion: '',
  689. versionMark: '',
  690. smallVersion: '',
  691. produceTaskId: '',
  692. produceTaskName: ''
  693. };
  694. return {
  695. dialogTitle: '',
  696. visible: false,
  697. formDateBase,
  698. formData: JSON.parse(JSON.stringify(formDateBase)),
  699. formRules: {
  700. name: [
  701. { required: true, message: '请输入规则名称', trigger: 'blur' }
  702. ],
  703. frequencyValue: [
  704. { required: true, message: '请选择周期', trigger: 'blur' },
  705. { required: true, message: '请选择周期', trigger: 'change' }
  706. ],
  707. frequencyUnit: [
  708. { required: true, message: '请选择频率单位', trigger: 'change' }
  709. ],
  710. classify: [
  711. { required: true, message: '请选择规则类型', trigger: 'change' }
  712. ],
  713. // startDate 启用日期要大于当前时间
  714. // stopDate 停用时间要大于当前时间并且大于启用日期
  715. startDate: [
  716. { required: true, message: '请选择启用日期', trigger: 'blur' },
  717. { required: true, message: '请选择启用日期', trigger: 'change' },
  718. { validator: this.validateStartDate, trigger: 'change' }
  719. ],
  720. stopDate: [
  721. { required: true, message: '请选择停用时间', trigger: 'change' },
  722. { validator: this.validateStopDate, trigger: 'change' }
  723. ],
  724. deviceName: [
  725. { required: true, message: '请输入选择设备', trigger: 'blur' }
  726. ],
  727. reportWorkType: [
  728. { required: true, message: '请选择模块分类', trigger: 'change' },
  729. { required: true, message: '请选择模块分类', trigger: 'blur' }
  730. ]
  731. },
  732. recordSheet: [], // 记录表
  733. current: {},
  734. dataIndex: null,
  735. showEdit: false,
  736. btnLoading: false,
  737. currentRow: null,
  738. type: '',
  739. // 产品分类
  740. productCategory: [],
  741. loading: false,
  742. produceTaskCode: ''
  743. };
  744. },
  745. mounted() {
  746. this.getByCodeData();
  747. this.getProductCategory();
  748. console.log('this.formData 2233', this.formData);
  749. },
  750. methods: {
  751. open(row, type, title) {
  752. this.dialogTitle = title;
  753. this.type = type;
  754. console.log('type', type, row);
  755. if (
  756. type == 'edit' ||
  757. type == 'detail' ||
  758. type == 'change' ||
  759. type == 'clone'
  760. ) {
  761. this.getDetils(row.id);
  762. }
  763. // 过程监测临时修改
  764. if (type == 'processEdit') {
  765. this.processEditSetValue(row);
  766. }
  767. if (type == 'add') {
  768. this.formData.version = 1;
  769. // 启用日期 默认为 今天
  770. this.formData.startDate = new Date();
  771. // 停用日期 默认为 2099-12-31
  772. this.formData.stopDate = new Date('2099-12-31 00:00:00');
  773. }
  774. this.visible = true;
  775. console.log('this.formData', this.formData);
  776. },
  777. // 过程监测 修改规则详情
  778. async processEditSetValue(row) {
  779. const data = await recordrulesGetById(row.rulesId);
  780. const info = JSON.parse(JSON.stringify(row));
  781. data.executeMethodList = info.produceTaskConfigRuleDetails.map((i) => {
  782. return i.executeMethodTitle;
  783. });
  784. // 去重
  785. data.executeMethodList = [...new Set(data.executeMethodList)].filter(
  786. (i) => i
  787. );
  788. data.details = info.produceTaskConfigRuleDetails;
  789. if (data.executeMethodList.length) {
  790. data.executeMethodTitle = data.executeMethodList[0] || '';
  791. } else {
  792. data.executeMethodTitle = '';
  793. }
  794. this.$util.assignObject(this.formData, data);
  795. if (data.executeMethodList.length) {
  796. this.formData.isExecuteMethod = 1;
  797. }
  798. this.$nextTick(() => {
  799. this.$refs.cycleMultipleRef?.setRecordRulesCycleList(
  800. this.formData.recordRulesCycleList
  801. );
  802. });
  803. this.formData.startDate = new Date(info.startDate);
  804. this.formData.stopDate = new Date(info.stopDate);
  805. this.formData.classify = this.formData.classify + '';
  806. this.formData.reportWorkType = this.formData.reportWorkType + '';
  807. this.loading = false;
  808. },
  809. async getDetils(id) {
  810. this.loading = true;
  811. try {
  812. const data = await recordrulesGetById(id);
  813. if (data.isExecuteMethod) {
  814. data.executeMethodList = Object.keys(data.detailMap).map((i) => {
  815. return i;
  816. });
  817. data.details = Object.values(data.detailMap).flat();
  818. data.executeMethodTitle = data.executeMethodList[0] || '';
  819. } else {
  820. data.executeMethodList = [];
  821. data.details = data.details || [];
  822. data.executeMethodTitle = '';
  823. }
  824. this.$util.assignObject(this.formData, data);
  825. this.$nextTick(() => {
  826. this.$refs.cycleMultipleRef?.setRecordRulesCycleList(
  827. this.formData.recordRulesCycleList
  828. );
  829. });
  830. this.formData.startDate = new Date(data.startDate);
  831. this.formData.stopDate = new Date(data.stopDate);
  832. this.formData.classify = this.formData.classify + '';
  833. this.formData.reportWorkType = this.formData.reportWorkType + '';
  834. if (this.type == 'change') {
  835. this.formData.fromId = id;
  836. this.formData.id = null;
  837. }
  838. if (this.type == 'clone') {
  839. this.formData.fromId = null;
  840. this.formData.id = null;
  841. this.formData.produceTaskId = null;
  842. this.formData.produceTaskName = null;
  843. }
  844. this.loading = false;
  845. } catch (error) {
  846. this.loading = false;
  847. }
  848. },
  849. async getByCodeData() {
  850. let res = await getByCode('record_sheet');
  851. let list = res.data.map((item) => {
  852. let values = Object.keys(item);
  853. return {
  854. value: values[0],
  855. label: item[values[0]]
  856. };
  857. });
  858. this.recordSheet = list;
  859. },
  860. itemDel(index) {
  861. this.formData.details.splice(index, 1);
  862. },
  863. /* 打开操作手册编辑款 */
  864. openOperationGuideDialogDialog(row, index) {
  865. this.$refs.operationGuideDialog.open(row, index);
  866. },
  867. handleClose() {
  868. // 清空表单数据
  869. this.formData = JSON.parse(JSON.stringify(this.formDateBase));
  870. this.$refs['formRef'].resetFields();
  871. this.visible = false;
  872. },
  873. // 保存
  874. confirm() {
  875. console.log('this.formData', this.formData);
  876. // 验证表单规则
  877. this.$refs.formRef.validate(async (valid) => {
  878. if (!valid) {
  879. return false;
  880. }
  881. if (this.formData.details.length == 0) {
  882. return this.$message.warning('至少条件一条规则项');
  883. }
  884. if (this.formData.isExecuteMethod) {
  885. // 判断 formData.executeMethodList中的item 是否在details中有一条executeMethodTitle的数据
  886. if (this.formData.executeMethodList.length == 0) {
  887. return this.$message.warning(`请添加执行方式`);
  888. }
  889. for (const item of this.formData.executeMethodList) {
  890. if (!item) {
  891. return this.$message.warning(`执行方式不能为空!`);
  892. }
  893. const exists = this.formData.details.some(
  894. (detail) => detail.executeMethodTitle === item
  895. );
  896. if (!exists) {
  897. this.$message.warning(
  898. `请为执行方式 "${item}" 添加至少一条规则项`
  899. );
  900. return false;
  901. }
  902. }
  903. }
  904. try {
  905. this.btnLoading = true;
  906. const body = this.formatBody();
  907. if (this.type == 'add' || this.type == 'clone') {
  908. await recordrulesSave(body);
  909. } else if (this.type == 'change') {
  910. await recordrulesUpdateVersion(body);
  911. } else {
  912. // 编辑
  913. body.fromId = null;
  914. await recordrulesUpdate(body);
  915. }
  916. this.btnLoading = false;
  917. this.$message.success('操作成功');
  918. this.handleClose();
  919. this.$emit('reload');
  920. } catch (error) {
  921. this.btnLoading = false;
  922. }
  923. });
  924. },
  925. // 保存并发布
  926. saveAndPublish() {
  927. // 验证表单规则
  928. this.$refs.formRef.validate(async (valid) => {
  929. if (!valid) {
  930. return false;
  931. }
  932. if (this.formData.details.length == 0) {
  933. return this.$message.warning('至少条件一条规则项');
  934. }
  935. if (this.formData.isExecuteMethod) {
  936. // 判断 formData.executeMethodList中的item 是否在details中有一条executeMethodTitle的数据
  937. if (this.formData.executeMethodList.length == 0) {
  938. return this.$message.warning(`请添加执行方式`);
  939. }
  940. for (const item of this.formData.executeMethodList) {
  941. if (!item) {
  942. return this.$message.warning(`执行方式不能为空!`);
  943. }
  944. const exists = this.formData.details.some(
  945. (detail) => detail.executeMethodTitle === item
  946. );
  947. if (!exists) {
  948. this.$message.warning(
  949. `请为执行方式 "${item}" 添加至少一条规则项`
  950. );
  951. return false;
  952. }
  953. }
  954. }
  955. // 判断参数类型是否选择
  956. for (const detail of this.formData.details) {
  957. if (!detail.paramType) {
  958. return this.$message.warning('请选择规则明细中的参数类型!');
  959. }
  960. }
  961. try {
  962. this.btnLoading = true;
  963. const body = this.formatBody();
  964. if (this.type != 'saveAndPublish') {
  965. await recordrulesSaveAndPublish(body);
  966. } else {
  967. this.$emit('processSave', body);
  968. }
  969. this.btnLoading = false;
  970. this.$message.success('操作成功');
  971. this.handleClose();
  972. this.$emit('reload');
  973. } catch (error) {
  974. this.btnLoading = false;
  975. }
  976. });
  977. },
  978. // 数据格式化
  979. formatBody() {
  980. this.formData.recordRulesCycleList =
  981. this.$refs.cycleMultipleRef.recordRulesCycleList
  982. .map((i) => {
  983. // 根据月日时分排序计算权重排序
  984. let sortNum = 0;
  985. if (i.month) {
  986. sortNum += i.month * 60 * 24 * 30;
  987. }
  988. if (i.day) {
  989. sortNum += i.day * 60 * 24;
  990. }
  991. if (i.hour) {
  992. sortNum += i.hour * 60;
  993. }
  994. if (i.minute) {
  995. sortNum += i.minute * 1;
  996. }
  997. return { ...i, sortNum };
  998. })
  999. .sort((a, b) => a.sortNum - b.sortNum)
  1000. .map((i, index) => {
  1001. return { ...i, sortNum: index + 1 };
  1002. });
  1003. const body = JSON.parse(JSON.stringify(this.formData));
  1004. body.startDate = this.$util.toDateString(
  1005. body.startDate,
  1006. 'yyyy-MM-dd HH:mm:ss'
  1007. );
  1008. body.stopDate = this.$util.toDateString(
  1009. body.stopDate,
  1010. 'yyyy-MM-dd HH:mm:ss'
  1011. );
  1012. return body;
  1013. },
  1014. // startDate 启用日期要大于当前时间
  1015. validateStartDate(rule, value, callback) {
  1016. const startDate = this.formData.startDate;
  1017. if (!startDate) {
  1018. return callback(new Error('启用日期不能为空'));
  1019. }
  1020. // 启用日期大于等于今天
  1021. // const today = new Date();
  1022. // today.setHours(0, 0, 0, 0); // 设置为当天的开始时间
  1023. // if (new Date(startDate) < today) {
  1024. // return callback(new Error('启用日期必须大于等于当前日期'));
  1025. // }
  1026. callback();
  1027. },
  1028. // stopDate 停用时间要大于当前时间并且大于启用日期
  1029. validateStopDate(rule, value, callback) {
  1030. const startDate = this.formData.startDate;
  1031. const stopDate = this.formData.stopDate;
  1032. if (
  1033. stopDate &&
  1034. startDate &&
  1035. new Date(stopDate) <= new Date(startDate)
  1036. ) {
  1037. return callback(new Error('停用时间必须大于启用日期'));
  1038. }
  1039. callback();
  1040. },
  1041. // 去选择设备
  1042. selectDeviceId() {
  1043. this.$refs.deviceSelectDialog.open([]);
  1044. },
  1045. // 选择设备回调
  1046. chooseEquipment(data, index, categoryId) {
  1047. console.log('data', data, index, categoryId);
  1048. this.formData.deviceId = data[0]?.id || null;
  1049. this.formData.deviceName = data[0]?.name || '';
  1050. },
  1051. // 添加
  1052. addRow() {
  1053. this.formData.details.push({
  1054. id: new Date().getTime(),
  1055. defaultValue: '',
  1056. maxValue: null,
  1057. minValue: null,
  1058. paramType: null,
  1059. paramValue: null,
  1060. remark: '',
  1061. symbol: null,
  1062. tools: [],
  1063. unitName: null,
  1064. productName: '',
  1065. productCode: '',
  1066. executeMethodTitle: this.formData.executeMethodTitle
  1067. });
  1068. console.log('this.formData.details', this.formData.details);
  1069. },
  1070. deleteRow(row) {
  1071. const index = this.formData.details.indexOf(row);
  1072. if (index !== -1) {
  1073. this.formData.details.splice(index, 1);
  1074. }
  1075. },
  1076. handleAdd(row) {
  1077. this.currentRow = row;
  1078. this.$refs.toolModalRef.open(row.toolCodes);
  1079. },
  1080. chooseModal(data) {
  1081. console.log('data', data);
  1082. this.currentRow.tools = data.map((i) => {
  1083. return {
  1084. toolCode: i.code,
  1085. toolName: i.name
  1086. // rulesDetailId: this.currentRow.id,
  1087. // rulesId: this.formData.id
  1088. };
  1089. });
  1090. },
  1091. // 规则明细表
  1092. async recordrulesDetailPage(row) {
  1093. const { list } = await recordrulesDetailPage({
  1094. // deptId: row.deptId,
  1095. pageNum: 1,
  1096. rulesId: row.id,
  1097. size: 9999
  1098. });
  1099. console.log('list 数据', list);
  1100. this.formData.details = list;
  1101. },
  1102. // 清空工具
  1103. clearTool(row) {
  1104. row.tools = [];
  1105. },
  1106. // 查询 recordrulesCyclePage
  1107. async recordrulesCyclePage(row) {
  1108. const { list } = await recordrulesCyclePage({
  1109. pageNum: 1,
  1110. size: 9999,
  1111. recordRulesId: row.id,
  1112. orderBy: 'descending'
  1113. });
  1114. console.log('list 周期数据', list);
  1115. this.formData.recordRulesCycleList = list;
  1116. this.$nextTick(() => {
  1117. this.$refs.cycleMultipleRef.setRecordRulesCycleList(list);
  1118. });
  1119. },
  1120. // 去选择产品
  1121. selectProduct(row) {
  1122. this.currentRow = row;
  1123. this.$refs.ProductModalRef.open();
  1124. },
  1125. // 选择产品
  1126. changeProduct(current) {
  1127. console.log('current', current);
  1128. this.currentRow.productName = current.name;
  1129. this.currentRow.productCode = current.code;
  1130. },
  1131. // 选择物品 产品、物料等
  1132. selectChooseModalProduct(row) {
  1133. this.currentRow = row;
  1134. this.$refs.toolModalTowRef.open([], '选择物品');
  1135. },
  1136. chooseModalProduct(current) {
  1137. console.log('current', current);
  1138. this.currentRow.productName = current[0].name;
  1139. this.currentRow.productCode = current[0].code;
  1140. console.log('this.currentRow', this.currentRow);
  1141. },
  1142. // 清空产品
  1143. clearProduct(row) {
  1144. row.productName = '';
  1145. row.productCode = '';
  1146. },
  1147. // 获取产品分类
  1148. async getProductCategory() {
  1149. let { data } = await getTreeByPid(9);
  1150. console.log('产品分类', data);
  1151. this.productCategory = data;
  1152. },
  1153. // 选择工序
  1154. openProduceTaskDialog() {
  1155. this.$refs.processModalRef.open();
  1156. },
  1157. // 工序
  1158. processChooseProcess(process) {
  1159. console.log('选择的工序', process);
  1160. this.formData.produceTaskId = process.id;
  1161. this.formData.produceTaskName = process.name;
  1162. },
  1163. // 添加执行方式
  1164. addExecuteMethod() {
  1165. this.$prompt('', '请输入执行方式', {
  1166. confirmButtonText: '确定',
  1167. cancelButtonText: '取消',
  1168. inputValidator(value) {
  1169. if (!value) {
  1170. return '执行方式不能为空!';
  1171. }
  1172. return true;
  1173. }
  1174. })
  1175. .then(({ value }) => {
  1176. console.log('value', value);
  1177. if (!value) {
  1178. return this.$message.warning('执行方式不能为空!');
  1179. }
  1180. if (this.formData.executeMethodList.includes(value)) {
  1181. return this.$message.warning('执行方式已存在!');
  1182. }
  1183. this.formData.executeMethodList.push(value);
  1184. if (this.formData.executeMethodList.length == 1) {
  1185. // 默认高亮
  1186. this.formData.executeMethodTitle = value;
  1187. }
  1188. })
  1189. .catch((err) => {
  1190. console.log('取消输入执行方式', err);
  1191. });
  1192. },
  1193. // 删除执行方式
  1194. deleteExecuteMethod(item) {
  1195. // 如果this.formData.details总包含item 则不能删除
  1196. const exists = this.formData.details.some(
  1197. (detail) => detail.executeMethodTitle === item
  1198. );
  1199. if (exists) {
  1200. return this.$message.warning(
  1201. `执行方式 "${item}" 已被规则项使用,不能删除`
  1202. );
  1203. }
  1204. this.formData.executeMethodList =
  1205. this.formData.executeMethodList.filter((i) => i != item);
  1206. },
  1207. // 是否有执行方式改变
  1208. executeMethodChange() {
  1209. if (!this.formData.isExecuteMethod) {
  1210. this.formData.details = this.formData.details.map((i) => {
  1211. return {
  1212. ...i,
  1213. executeMethodTitle: ''
  1214. };
  1215. });
  1216. this.formData.executeMethodList = [];
  1217. } else {
  1218. if (this.formData.executeMethodList.length == 0) {
  1219. // 添加一个默认执行方式
  1220. this.formData.executeMethodList.push('无执行方式');
  1221. this.formData.details = this.formData.details.map((i) => {
  1222. return {
  1223. ...i,
  1224. executeMethodTitle: '无执行方式'
  1225. };
  1226. });
  1227. this.formData.executeMethodTitle = '无执行方式';
  1228. }
  1229. }
  1230. },
  1231. clearProductTask() {
  1232. this.formData.produceTaskId = '';
  1233. this.formData.produceTaskName = '';
  1234. },
  1235. // 过程监测修改 保存
  1236. processEditSave() {
  1237. // 只验证详情内容
  1238. if (this.formData.details.length == 0) {
  1239. return this.$message.warning('至少条件一条规则项');
  1240. }
  1241. if (this.formData.isExecuteMethod) {
  1242. // 判断 formData.executeMethodList中的item 是否在details中有一条executeMethodTitle的数据
  1243. if (this.formData.executeMethodList.length == 0) {
  1244. return this.$message.warning(`请添加执行方式`);
  1245. }
  1246. for (const item of this.formData.executeMethodList) {
  1247. if (!item) {
  1248. return this.$message.warning(`执行方式不能为空!`);
  1249. }
  1250. const exists = this.formData.details.some(
  1251. (detail) => detail.executeMethodTitle === item
  1252. );
  1253. if (!exists) {
  1254. this.$message.warning(
  1255. `请为执行方式 "${item}" 添加至少一条规则项`
  1256. );
  1257. return false;
  1258. }
  1259. }
  1260. }
  1261. // 判断参数类型是否选择
  1262. for (const detail of this.formData.details) {
  1263. if (!detail.paramType) {
  1264. return this.$message.warning('请选择规则明细中的参数类型!');
  1265. }
  1266. }
  1267. this.$emit('processSave', this.formatBody());
  1268. this.handleClose();
  1269. }
  1270. }
  1271. };
  1272. </script>
  1273. <style scoped lang="scss">
  1274. .operationGuide_box {
  1275. width: 100%;
  1276. height: 48px;
  1277. display: flex;
  1278. overflow: hidden;
  1279. cursor: pointer;
  1280. box-sizing: border-box;
  1281. padding: 5px 10px;
  1282. .left_content {
  1283. width: 50%;
  1284. padding: 10px;
  1285. box-sizing: border-box;
  1286. border: 1px solid #c0c4cc;
  1287. border-radius: 10px;
  1288. margin-right: 10px;
  1289. overflow-y: auto;
  1290. }
  1291. .right_content {
  1292. flex: 1;
  1293. padding: 10px;
  1294. box-sizing: border-box;
  1295. border: 1px solid #c0c4cc;
  1296. border-radius: 10px;
  1297. overflow-y: auto;
  1298. }
  1299. }
  1300. ::v--deep .table_list {
  1301. .el-form-item {
  1302. .el-form-item__content {
  1303. margin-left: 0;
  1304. }
  1305. }
  1306. }
  1307. </style>