releaseRulesDialog.vue 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  1. <template>
  2. <ele-modal
  3. width="80%"
  4. :visible="visible"
  5. append-to-body
  6. custom-class="ele-dialog-form"
  7. :title="title"
  8. :close-on-click-modal="false"
  9. :before-close="handleBeforeClose"
  10. maxable
  11. >
  12. <header-title title="基本信息"></header-title>
  13. <el-form
  14. :model="addForm"
  15. :rules="formRules"
  16. ref="ruleFormRef"
  17. label-width="150px"
  18. v-loading="loading"
  19. >
  20. <el-row>
  21. <el-col :span="8">
  22. <el-form-item label="记录规则名称" required>
  23. <el-input
  24. v-model="addForm.ruleName"
  25. placeholder="自动带出"
  26. disabled
  27. ></el-input>
  28. </el-form-item>
  29. </el-col>
  30. <el-col :span="8">
  31. <el-form-item label="记录规则分类" required>
  32. <DictSelection
  33. dictName="记录规则类型"
  34. clearable
  35. v-model="addForm.recordRulesClassify"
  36. disabled
  37. >
  38. </DictSelection>
  39. </el-form-item>
  40. </el-col>
  41. <el-col :span="8">
  42. <el-form-item
  43. v-if="ruleInfo && ruleInfo.classify == 3"
  44. label="关联设备"
  45. >
  46. <el-input
  47. v-model="addForm.deviceName"
  48. placeholder="自动带出"
  49. disabled
  50. ></el-input>
  51. </el-form-item>
  52. <el-form-item v-else label="车间区域">
  53. <el-select
  54. v-model="addForm.workshopAreaId"
  55. placeholder="请选择车间区域"
  56. filterable
  57. clearable
  58. style="width: 100%"
  59. @change="workshopAreaIdChange"
  60. >
  61. <el-option
  62. v-for="item in workshopAreaList"
  63. :key="item.id"
  64. :label="item.name"
  65. :value="item.id"
  66. />
  67. </el-select>
  68. </el-form-item>
  69. </el-col>
  70. </el-row>
  71. <el-row>
  72. <el-col :span="8">
  73. <el-form-item label="当前工序">
  74. <el-input
  75. v-model="addForm.produceTaskName"
  76. placeholder="当前工序"
  77. disabled
  78. ></el-input>
  79. </el-form-item>
  80. </el-col>
  81. <el-col :span="8">
  82. <el-form-item label="检查开始时间" required prop="checkStartTime">
  83. <el-date-picker
  84. v-model="addForm.checkStartTime"
  85. type="datetime"
  86. format="yyyy-MM-dd HH:mm:ss"
  87. value-format="yyyy-MM-dd HH:mm:ss"
  88. placeholder="选择日期"
  89. style="width: 100%"
  90. @change="computedDuration"
  91. >
  92. </el-date-picker>
  93. </el-form-item>
  94. </el-col>
  95. <el-col :span="8">
  96. <el-form-item label="检查结束时间" required prop="checkFinishTime">
  97. <el-date-picker
  98. v-model="addForm.checkFinishTime"
  99. type="datetime"
  100. format="yyyy-MM-dd HH:mm:ss"
  101. value-format="yyyy-MM-dd HH:mm:ss"
  102. placeholder="选择日期"
  103. style="width: 100%"
  104. @change="computedDuration"
  105. >
  106. </el-date-picker>
  107. </el-form-item>
  108. </el-col>
  109. </el-row>
  110. <el-row>
  111. <el-col :span="8">
  112. <el-form-item label="执行人" required prop="teamId">
  113. <el-select
  114. v-model="addForm.teamId"
  115. placeholder="请选择班组"
  116. filterable
  117. style="width: 120px"
  118. @change="checkTeamList(addForm.teamId)"
  119. >
  120. <el-option
  121. v-for="item in teamList"
  122. :label="item.name"
  123. :value="item.id"
  124. :key="item.id"
  125. >
  126. </el-option>
  127. </el-select>
  128. <el-select
  129. v-model="addForm.executeUsersIds"
  130. placeholder="请选择执行人"
  131. filterable
  132. multiple
  133. @change="changeId"
  134. >
  135. <div class="checkboxWrapper">
  136. <el-checkbox v-model="checked" @change="checkChange">
  137. 全选
  138. </el-checkbox>
  139. </div>
  140. <el-option
  141. v-for="item in teamUserList"
  142. :label="item.name"
  143. :value="item.id"
  144. :key="item.id"
  145. >
  146. </el-option>
  147. </el-select>
  148. </el-form-item>
  149. </el-col>
  150. <el-col :span="8">
  151. <el-form-item label="工时" required prop="duration">
  152. <el-input
  153. placeholder="请输入"
  154. v-model="addForm.duration"
  155. type="number"
  156. min="0"
  157. step="0.1"
  158. @change="durationChagne"
  159. >
  160. <template slot="append">
  161. <div style="width: 40px; box-sizing: border-box">小时</div>
  162. </template>
  163. </el-input>
  164. </el-form-item>
  165. </el-col>
  166. <el-col :span="8">
  167. <el-form-item label="检查有效期">
  168. <el-input
  169. placeholder="请输入"
  170. v-model="addForm.checkValidity"
  171. type="text"
  172. >
  173. <template slot="append">
  174. <div style="width: 40px; box-sizing: border-box">
  175. <el-form-item>
  176. <DictSelection
  177. dictName="检查有效期单位"
  178. clearable
  179. v-model="addForm.checkValidityUnit"
  180. placeholder="单位"
  181. style="width: auto"
  182. >
  183. </DictSelection>
  184. </el-form-item>
  185. </div>
  186. </template>
  187. </el-input>
  188. </el-form-item>
  189. </el-col>
  190. </el-row>
  191. <el-row>
  192. <el-col v-if="addForm.recordRulesExecuteMethodName" :span="8">
  193. <el-form-item label="执行方式" required>
  194. <el-input
  195. v-model="addForm.recordRulesExecuteMethodName"
  196. placeholder="自动带出"
  197. disabled
  198. ></el-input>
  199. </el-form-item>
  200. </el-col>
  201. <el-col :span="8">
  202. <el-form-item
  203. v-if="addForm.produceTaskId && addForm.reportWorkType == 2"
  204. label="产出物"
  205. >
  206. <el-select
  207. v-model="addForm.outputType"
  208. placeholder="请选择产出物类型"
  209. filterable
  210. style="width: 100%"
  211. >
  212. <el-option
  213. v-for="item in outputTypeList"
  214. :key="item.value"
  215. :label="item.label"
  216. :value="item.value"
  217. />
  218. </el-select>
  219. </el-form-item>
  220. </el-col>
  221. <el-col :span="8">
  222. <el-form-item label="结论" required prop="conclusion">
  223. <el-radio-group v-model="addForm.conclusion">
  224. <el-radio :label="1">合格</el-radio>
  225. <el-radio :label="2">不合格</el-radio>
  226. </el-radio-group>
  227. </el-form-item>
  228. </el-col>
  229. </el-row>
  230. </el-form>
  231. <material
  232. v-if="addForm.produceTaskId && addForm.reportWorkType == 2"
  233. ref="materialRef"
  234. :pickDetails.sync="addForm.pickDetails"
  235. :outputDetails.sync="addForm.outputDetails"
  236. :preOutputDetails="preOutputDetails"
  237. :workOrderId="addForm.workOrderId"
  238. :ruleId="addForm.ruleId"
  239. :produceTaskId="addForm.produceTaskId"
  240. :produceTaskName="addForm.produceTaskName"
  241. :produceTaskInstanceId="workOrderInfo.taskId"
  242. :bomCategoryId="workOrderInfo.bomCategoryId"
  243. :outputType="addForm.outputType"
  244. :categoryId="workOrderInfo.categoryId"
  245. @refresh="getListByWorkOrderId"
  246. ></material>
  247. <header-title title="检查项目" :style="`margin-top: 20px`"></header-title>
  248. <template v-if="addForm.recordRulesClassify == 10">
  249. <el-tabs v-model="statisticsType" type="card">
  250. <el-tab-pane
  251. v-for="i in statisticsTypeList"
  252. :label="i.label"
  253. :name="i.value"
  254. :key="i.value"
  255. >
  256. </el-tab-pane>
  257. </el-tabs>
  258. <statistics
  259. ref="statisticsRef"
  260. :details.sync="addForm.details"
  261. :statisticsType="statisticsType"
  262. :produceTaskId="addForm.produceTaskId"
  263. :workOrderId="addForm.workOrderId"
  264. :routingId="addForm.produceRoutingId"
  265. :ruleId="addForm.ruleId"
  266. ></statistics>
  267. </template>
  268. <ele-pro-table
  269. v-if="addForm.recordRulesClassify && addForm.recordRulesClassify != 10"
  270. v-loading="loading"
  271. ref="table"
  272. row-key="id"
  273. :columns="detailsColumns"
  274. :datasource="addForm.details"
  275. cacheKey="mes-releaseRulesDialong-2510281408"
  276. :needPage="false"
  277. >
  278. <template v-slot:toolkit>
  279. <el-button
  280. v-if="addForm.recordRulesClassify != 4"
  281. type="primary"
  282. @click="batchCheck"
  283. >批量检查</el-button
  284. >
  285. <el-button
  286. v-if="addForm.recordRulesClassify != 4"
  287. type="primary"
  288. @click="batchQualified"
  289. >批量合格</el-button
  290. >
  291. </template>
  292. <template v-slot:paramValue="{ row }">
  293. <div v-if="addForm.recordRulesClassify == 4">
  294. {{ row.productName || row.name }}
  295. </div>
  296. <div v-else>
  297. {{ row.paramValue }}
  298. </div>
  299. </template>
  300. <template v-slot:toolNames="{ row }">
  301. <el-link :underline="false" style="cursor: pointer">
  302. <div class="ele-cell">
  303. <div @click="handleAdd(row)">
  304. {{ row.toolNames ? row.toolNames : '请选择' }}
  305. </div>
  306. <i
  307. v-if="!row.toolNames"
  308. class="el-icon-arrow-down"
  309. @click="handleAdd(row)"
  310. ></i>
  311. <i v-else class="el-icon-close" @click="clearTool(row)"></i>
  312. </div>
  313. </el-link>
  314. </template>
  315. <template v-slot:checkUsersIds="{ row }">
  316. <div>
  317. <el-select
  318. v-model="row.checkUsersIds"
  319. placeholder="请选择检查人"
  320. filterable
  321. multiple
  322. @change="checkUsersIdsChange(row)"
  323. >
  324. <el-option
  325. v-for="item in activeTeamUserList"
  326. :label="item.name"
  327. :value="item.id"
  328. :key="item.id"
  329. >
  330. </el-option>
  331. </el-select>
  332. </div>
  333. </template>
  334. <template v-slot:checkStatus="{ row }">
  335. <div>
  336. <el-radio-group v-model="row.checkStatus">
  337. <el-radio :label="1">已检查</el-radio>
  338. <el-radio :label="0">未检查</el-radio>
  339. </el-radio-group>
  340. </div>
  341. </template>
  342. <template v-slot:errorMsg="{ row }">
  343. <div>
  344. <el-input
  345. type="text"
  346. :rows="1"
  347. placeholder="请输入"
  348. v-model="row.errorMsg"
  349. >
  350. <template v-if="row.unitName" slot="append">
  351. <div>{{ row.unitName }}</div>
  352. </template>
  353. </el-input>
  354. </div></template
  355. >
  356. <template v-slot:checkResult="{ row }">
  357. <div>
  358. <el-radio-group v-model="row.checkResult">
  359. <el-radio :label="1">合格</el-radio>
  360. <el-radio :label="0">不合格</el-radio>
  361. </el-radio-group>
  362. </div>
  363. </template>
  364. </ele-pro-table>
  365. <!-- 底部按钮 -->
  366. <template #footer>
  367. <div class="modal-footer">
  368. <el-button
  369. v-if="
  370. $hasPermission('mes:producetaskrecordrulesrecord:res') &&
  371. productionInfo &&
  372. productionInfo.executeStatus == 2
  373. "
  374. :loading="butLoading"
  375. type="primary"
  376. @click="submit('submit-reset')"
  377. >
  378. 重新一键报工
  379. </el-button>
  380. <el-button
  381. v-if="$hasPermission('mes:producetaskrecordrulesrecord:sus')"
  382. :loading="butLoading"
  383. type="primary"
  384. @click="submit('submit')"
  385. :disabled="productionInfo && productionInfo.executeStatus == 2"
  386. >
  387. 一键报工
  388. </el-button>
  389. <template
  390. v-if="$hasPermission('mes:producetaskrecordrulesrecord:logicdelete')"
  391. >
  392. <el-popconfirm
  393. v-if="
  394. productionInfo &&
  395. productionInfo.recordId != null &&
  396. productionInfo.executeStatus == 1
  397. "
  398. title="您确定要清空缓存吗?"
  399. @confirm="clearCache"
  400. >
  401. <el-button slot="reference" :loading="butLoading" type="primary">
  402. 清空缓存
  403. </el-button>
  404. </el-popconfirm>
  405. </template>
  406. <el-button
  407. v-if="$hasPermission('mes:producetaskrecordrulesrecord:saveorupdate')"
  408. :loading="butLoading"
  409. type="primary"
  410. @click="submit('cache')"
  411. :disabled="productionInfo && productionInfo.executeStatus == 2"
  412. >
  413. 缓存
  414. </el-button>
  415. <el-button
  416. v-if="productionInfo && productionInfo.executeStatus == 2"
  417. @click="handleBeforeClose"
  418. >
  419. 关闭
  420. </el-button>
  421. </div>
  422. </template>
  423. <toolModal ref="toolModalRef" @chooseModal="chooseModal" />
  424. </ele-modal>
  425. </template>
  426. <script>
  427. import {
  428. recordRulesDetailPage,
  429. getRecordRulesDetail
  430. } from '@/api/recordRules/index.js';
  431. import DictSelection from '@/components/Dict/DictSelection.vue';
  432. import SelectUser from '@/components/select/SelectUser/index.vue';
  433. import {
  434. saveOrUpdateAndSubmit,
  435. saveOrUpdate,
  436. logicDelete,
  437. getById,
  438. queryListByWorkOrderId,
  439. resetSubmit
  440. } from '@/api/producetaskrecordrulesrecord/index';
  441. import toolModal from '@/views/batchRecord/components/toolModal.vue';
  442. import { getTeam } from '@/api/produce/job.js';
  443. import { getFactoryarea } from '@/api/aps/index';
  444. import dictMixins from '@/mixins/dictMixins';
  445. import tableColumnsMixin from '@/mixins/tableColumnsMixin';
  446. import material from './material.vue';
  447. import statistics from './statistics.vue';
  448. export default {
  449. components: { SelectUser, toolModal, material, statistics },
  450. mixins: [dictMixins, tableColumnsMixin],
  451. emits: ['reload'],
  452. props: {
  453. isTempRecord: {
  454. type: Number,
  455. default: 0
  456. }
  457. },
  458. watch: {
  459. 'addForm.details': {
  460. handler(details) {
  461. // 排除 物料添加 和 生产统计 的情况
  462. if (
  463. this.addForm.recordRulesClassify == '10' ||
  464. this.addForm.recordRulesClassify == '4'
  465. )
  466. return;
  467. const any = details.some((i) => i.checkResult === null);
  468. if (any || details.length === 0) return;
  469. const every = details.every((i) => i.checkResult == 1);
  470. this.addForm.conclusion = every ? 1 : 2;
  471. console.log('this.addForm.conclusion', this.addForm.conclusion);
  472. },
  473. deep: true
  474. }
  475. },
  476. data() {
  477. const formDate = {
  478. id: null,
  479. workshopArea: '',
  480. workshopAreaId: null,
  481. checkFinishTime: '',
  482. checkStartTime: '',
  483. checkValidity: null,
  484. checkValidityUnit: '',
  485. conclusion: null,
  486. isTempRecord: this.isTempRecord,
  487. details: [],
  488. deviceId: 0,
  489. deviceName: '',
  490. batchNo: '',
  491. executeMethod: 0,
  492. formingNum: 0,
  493. itemType: 0,
  494. produceRoutingId: 0,
  495. produceRoutingName: '',
  496. produceTaskConfigId: 0,
  497. produceTaskId: 0,
  498. produceTaskName: '',
  499. productCode: '',
  500. productModel: '',
  501. productName: '',
  502. recordRulesClassify: null,
  503. ruleId: 0,
  504. ruleName: '',
  505. reportWorkType: 0,
  506. specification: '',
  507. workOrderCode: '',
  508. workOrderId: 0,
  509. itemTaskName: '',
  510. brandNo: '',
  511. duration: null,
  512. // 执行人
  513. executeUsersIds: [],
  514. executeUsers: [
  515. // {
  516. // teamId: 0,
  517. // teamName: '',
  518. // userId: 0,
  519. // userName: ''
  520. // }
  521. ],
  522. // 班组id
  523. teamId: '',
  524. // 物料字段name
  525. pickDetails: [],
  526. // 本次产出明细
  527. outputDetails: [],
  528. recordRulesExecuteMethodId: null,
  529. recordRulesExecuteMethodName: '',
  530. // 产出类型 1-原材料,2-在制品,3.BOM标准产出
  531. outputType: 1
  532. };
  533. return {
  534. visible: false,
  535. formDate,
  536. addForm: JSON.parse(JSON.stringify(formDate)),
  537. formRules: {
  538. checkStartTime: [
  539. { required: true, message: '请选择检查开始时间', trigger: 'blur' },
  540. {
  541. required: true,
  542. message: '请选择检查开始时间',
  543. trigger: 'change'
  544. },
  545. {
  546. validator: (rule, value, callback) => {
  547. if (!value) return callback();
  548. const now = new Date();
  549. const start = new Date(value);
  550. callback();
  551. },
  552. trigger: 'blur'
  553. }
  554. ],
  555. checkFinishTime: [
  556. { required: true, message: '请选择检查完成时间', trigger: 'blur' },
  557. {
  558. required: true,
  559. message: '请选择检查完成时间',
  560. trigger: 'change'
  561. },
  562. {
  563. validator: (rule, value, callback) => {
  564. if (!value) return callback();
  565. const start = new Date(this.addForm.checkStartTime);
  566. const finish = new Date(value);
  567. if (finish <= start) {
  568. callback(new Error('结束时间必须大于开始时间'));
  569. } else {
  570. callback();
  571. }
  572. },
  573. trigger: 'blur'
  574. }
  575. ],
  576. conclusion: [
  577. { required: true, message: '请选择结论', trigger: 'blur' },
  578. { required: true, message: '请选择结论', trigger: 'change' }
  579. ],
  580. duration: [
  581. { required: true, message: '请输入工时', trigger: 'blur' },
  582. { required: true, message: '请输入工时', trigger: 'change' },
  583. {
  584. validator: (rule, value, callback) => {
  585. if (value === '' || value === null) {
  586. callback();
  587. } else if (Number(value) <= 0) {
  588. callback(new Error('工时必须大于0'));
  589. } else {
  590. callback();
  591. }
  592. },
  593. trigger: 'blur'
  594. }
  595. ],
  596. teamId: [
  597. { required: true, message: '请选择班组', trigger: 'blur' },
  598. { required: true, message: '请选择班组', trigger: 'change' }
  599. ]
  600. },
  601. productionInfo: null,
  602. list: [],
  603. ruleInfo: null,
  604. showSelectUser: false,
  605. currentRow: null,
  606. butLoading: false,
  607. // 工艺路线
  608. workOrderInfo: null,
  609. // 加载中 loading
  610. loading: false,
  611. checked: false,
  612. teamUserList: [],
  613. teamList: [],
  614. teamAllList: [],
  615. workshopAreaList: [],
  616. // 上到工序的 产出明细
  617. preOutputDetails: [],
  618. outputTypeList: [
  619. { label: '原材料', value: 1 },
  620. { label: '在制品', value: 2 },
  621. { label: 'BOM标准产出', value: 3 }
  622. ],
  623. // 1-成品统计,2-物料统计,3-工序统计"
  624. statisticsType: '1',
  625. statisticsTypeList: [
  626. { label: '成品统计', value: '1' },
  627. { label: '物料统计', value: '2' },
  628. { label: '工序统计', value: '3' }
  629. ]
  630. };
  631. },
  632. computed: {
  633. title() {
  634. if (this.addForm.recordRulesClassify) {
  635. const dictValue = this.getDictValue(
  636. '记录规则类型',
  637. this.addForm.recordRulesClassify
  638. );
  639. return dictValue + '记录表';
  640. }
  641. return '记录表';
  642. },
  643. activeTeamUserList() {
  644. return this.teamUserList.filter((user) =>
  645. this.addForm.executeUsersIds.includes(user.id)
  646. );
  647. },
  648. // 规则详情表头
  649. detailsColumns() {
  650. let list = [
  651. {
  652. width: 45,
  653. type: 'index',
  654. columnKey: 'index',
  655. align: 'center'
  656. },
  657. {
  658. label: '检查内容',
  659. prop: 'paramValue',
  660. minWidth: 120,
  661. slot: 'paramValue'
  662. }
  663. ];
  664. if (this.addForm.recordRulesClassify != '4') {
  665. list = [
  666. ...list,
  667. {
  668. label: '检查工具',
  669. prop: 'toolNames',
  670. minWidth: 120,
  671. slot: 'toolNames'
  672. },
  673. {
  674. label: '检查人',
  675. prop: 'checkUsersIds',
  676. minWidth: 120,
  677. slot: 'checkUsersIds'
  678. },
  679. {
  680. label: '检查情况',
  681. prop: 'checkStatus',
  682. minWidth: 120,
  683. slot: 'checkStatus'
  684. },
  685. {
  686. label: '描述',
  687. prop: 'errorMsg',
  688. minWidth: 120,
  689. slot: 'errorMsg'
  690. },
  691. {
  692. label: '检查结果',
  693. prop: 'checkResult',
  694. minWidth: 120,
  695. slot: 'checkResult'
  696. }
  697. ];
  698. } else {
  699. list.push({
  700. label: '描述',
  701. prop: 'errorMsg',
  702. minWidth: 120,
  703. slot: 'errorMsg'
  704. });
  705. }
  706. return list;
  707. }
  708. },
  709. mounted() {
  710. if (localStorage.getItem('singleUserInfo') == '1') {
  711. const data = JSON.parse(localStorage.getItem('chooseUserInfo'));
  712. this.getTeamList(data.teamId);
  713. } else {
  714. this.getTeamList(this.$store.state.user.info.teamId);
  715. }
  716. this.getWorkshopArea();
  717. },
  718. methods: {
  719. open(productionInfo, workOrderInfo) {
  720. console.log(
  721. 'productionInfo, workOrderInfo',
  722. productionInfo,
  723. workOrderInfo
  724. );
  725. this.visible = true;
  726. this.productionInfo = productionInfo;
  727. this.workOrderInfo = workOrderInfo;
  728. // 存在缓存记录
  729. if (this.productionInfo.recordId != null) {
  730. // 查询详情
  731. this.getCacheInfo();
  732. } else {
  733. this.addForm.batchNo = workOrderInfo.batchNo;
  734. this.addForm.executeMethod = productionInfo.executeMethod;
  735. this.addForm.formingNum = workOrderInfo.formingNum;
  736. this.addForm.itemType = productionInfo.itemType;
  737. this.addForm.produceRoutingId = workOrderInfo.produceRoutingId;
  738. this.addForm.produceRoutingName = workOrderInfo.produceRoutingName;
  739. this.addForm.produceTaskConfigId = productionInfo.produceTaskConfigId;
  740. this.addForm.produceTaskId = productionInfo.produceTaskId;
  741. this.addForm.produceTaskName =
  742. productionInfo.produceTaskName || workOrderInfo.taskName;
  743. this.addForm.productCode = workOrderInfo.productCode;
  744. this.addForm.productModel = workOrderInfo.model;
  745. this.addForm.productName = workOrderInfo.productName;
  746. this.addForm.reportWorkType = productionInfo.reportWorkType;
  747. this.addForm.specification = workOrderInfo.specification;
  748. this.addForm.workOrderCode = workOrderInfo.code;
  749. this.addForm.workOrderId = workOrderInfo.id;
  750. this.addForm.brandNo = productionInfo.brandNo;
  751. this.addForm.recordRulesExecuteMethodId =
  752. productionInfo.recordRulesExecuteMethodId;
  753. this.addForm.recordRulesExecuteMethodName =
  754. productionInfo.recordRulesExecuteMethodName;
  755. // 临时添加存在规则详情
  756. if (
  757. this.productionInfo.details &&
  758. this.productionInfo.details.length > 0
  759. ) {
  760. this.addForm.details = this.productionInfo.details.map((i) => {
  761. i.toolNames = i.tools.map((j) => j.toolName).join(',');
  762. return i;
  763. });
  764. } else {
  765. this.getRuleList();
  766. }
  767. }
  768. console.log('this.productionInfo', this.productionInfo);
  769. console.log('this.addForm', this.addForm);
  770. this.getRuleInfo();
  771. },
  772. // 获取详情
  773. async getCacheInfo() {
  774. this.loading = true;
  775. try {
  776. const data = await getById(this.productionInfo.recordId);
  777. console.log('dat 缓存', data);
  778. data.details = data.details.map((i) => {
  779. i.toolNames = i.tools.map((j) => j.toolName).join(',');
  780. i.checkUsersIds = i.checkUsers.map((j) => j.userId);
  781. return i;
  782. });
  783. this.$util.assignObject(this.addForm, data);
  784. // 工时毫秒转小时
  785. this.addForm.duration = (
  786. this.addForm.duration /
  787. (1000 * 60 * 60)
  788. ).toFixed(2);
  789. this.addForm.recordRulesClassify += '';
  790. if (this.addForm.details?.length == 0) {
  791. this.getRuleList();
  792. }
  793. this.addForm.executeUsersIds = this.addForm.executeUsers.map(
  794. (i) => i.userId
  795. );
  796. this.addForm.teamId =
  797. this.addForm.executeUsers.length > 0
  798. ? this.addForm.executeUsers[0].teamId
  799. : '';
  800. // 加载班组人员列表
  801. if (this.addForm.teamId) {
  802. const index = this.teamList.findIndex(
  803. (item) => item.id == this.addForm.teamId
  804. );
  805. this.teamUserList = this.teamAllList[index];
  806. }
  807. if (this.addForm.outputType == null) {
  808. this.addForm.outputType = 1;
  809. }
  810. this.getListByWorkOrderId();
  811. this.loading = false;
  812. } catch (error) {
  813. this.loading = false;
  814. }
  815. },
  816. // 物料信息查询
  817. async getListByWorkOrderId(type = '') {
  818. console.log('type 物料信息', type);
  819. if (
  820. !this.productionInfo.produceTaskId ||
  821. this.addForm.reportWorkType != 2
  822. )
  823. return;
  824. // 查询物料信息
  825. const materialObject = await queryListByWorkOrderId({
  826. workOrderId: this.addForm.workOrderId,
  827. recordId: this.productionInfo.recordId,
  828. produceTaskId: this.productionInfo.produceTaskId,
  829. ruleId: this.addForm.ruleId
  830. });
  831. console.log('materialList 物料信息', materialObject);
  832. if (type == '') {
  833. this.addForm.outputDetails = materialObject.outputDetails;
  834. this.addForm.pickDetails = materialObject.pickDetails.map((i) => {
  835. // 物料清单中如果存在则 selected 设置为 true
  836. const any = this.addForm.outputDetails.find(
  837. (j) => j.categoryId === i.categoryId
  838. );
  839. if (any) {
  840. i.selected = true;
  841. } else {
  842. i.selected = false;
  843. }
  844. return i;
  845. });
  846. this.preOutputDetails = materialObject.preOutputDetails;
  847. }
  848. if (type == 'output') {
  849. this.addForm.outputDetails = materialObject.outputDetails;
  850. this.addForm.pickDetails = this.addForm.pickDetails.map((i) => {
  851. // 物料清单中如果存在则 selected 设置为 true
  852. const any = this.addForm.outputDetails.find(
  853. (j) => j.categoryId === i.categoryId
  854. );
  855. if (any) {
  856. i.selected = true;
  857. } else {
  858. i.selected = false;
  859. }
  860. return i;
  861. });
  862. }
  863. },
  864. // 规则信息
  865. async getRuleInfo() {
  866. const data = await getRecordRulesDetail(this.productionInfo.ruleId);
  867. this.ruleInfo = data;
  868. console.log('this.ruleInfo', this.ruleInfo);
  869. if (this.productionInfo.recordId == null) {
  870. // 赋值表单信息
  871. this.addForm.recordRulesClassify = this.ruleInfo.classify + '';
  872. this.addForm.ruleId = this.ruleInfo.id;
  873. this.addForm.ruleName = this.ruleInfo.name;
  874. this.addForm.deviceId = this.ruleInfo.deviceId;
  875. this.addForm.deviceName = this.ruleInfo.deviceName;
  876. }
  877. },
  878. // 查询记录规则 事项列表
  879. async getRuleList() {
  880. const { list } = await recordRulesDetailPage({
  881. rulesId: this.productionInfo.ruleId,
  882. pageNum: 1,
  883. size: 9999
  884. });
  885. // 添加必要参数
  886. this.addForm.details = list.map((i) => {
  887. return {
  888. ...i,
  889. id: null,
  890. checkResult: null,
  891. checkStatus: null,
  892. checkStatusDesc: i.defaultValue || '',
  893. errorMsg: '',
  894. checkUsers: [],
  895. checkUsersIds: [],
  896. paramValue: i.paramValue,
  897. toolNames: i.tools.map((i) => i.toolName).join(',')
  898. };
  899. });
  900. console.log('this.addForm 添加规则', this.addForm, list);
  901. },
  902. handleBeforeClose() {
  903. this.addForm = JSON.parse(JSON.stringify(this.formDate));
  904. this.statisticsType = '1';
  905. console.log('this.$refs.ruleFormRef', this.addForm);
  906. this.$nextTick(() => {
  907. this.$refs.ruleFormRef.clearValidate();
  908. this.visible = false;
  909. });
  910. },
  911. // 提交
  912. submit(type) {
  913. console.log('this.addForm', this.addForm);
  914. if (type == 'submit') {
  915. if (this.$refs.materialRef) {
  916. // 验证产出物数量
  917. const valid = this.$refs.materialRef.validateOutputQuantities();
  918. if (!valid) {
  919. return;
  920. }
  921. }
  922. }
  923. // 验证表单
  924. this.$refs.ruleFormRef.validate(async (valid) => {
  925. if (!valid) {
  926. return;
  927. }
  928. if (this.addForm.executeUsersIds.length == 0) {
  929. this.$message.warning('请选择执行人!');
  930. return;
  931. }
  932. if (this.addForm.duration <= 0) {
  933. this.$message.warning('工时必须大于0!');
  934. return;
  935. }
  936. // 报工需要验证 缓存不验证 排除 recordRulesClassify ==4 物料添加 == 10生产统计 的情况
  937. if (
  938. type.includes('submit') &&
  939. this.addForm.recordRulesClassify != '4' &&
  940. this.addForm.recordRulesClassify != '10'
  941. ) {
  942. // 验证检查项目
  943. const detailRequired = this.addForm.details.some((i) => {
  944. return (
  945. i.checkResult == null ||
  946. !i.checkStatus ||
  947. i.checkUsers?.length == 0
  948. );
  949. });
  950. if (detailRequired) {
  951. return this.$message.warning(
  952. '请先完善 检查人、检查情况、检查结果 内容!'
  953. );
  954. }
  955. }
  956. const body = JSON.parse(JSON.stringify(this.addForm));
  957. // 工时小时转毫秒
  958. body.duration = Number(body.duration);
  959. body.duration = body.duration * 60 * 60 * 1000;
  960. if (this.$refs.materialRef) {
  961. // 验证产出物数量
  962. const materialValid =
  963. await this.$refs.materialRef.validateOutputQuantities();
  964. if (!materialValid) {
  965. return;
  966. }
  967. }
  968. if (this.$refs.statisticsRef && type != 'cache') {
  969. // 验证统计项目
  970. const valid = this.$refs.statisticsRef.validateStatisticsFilled();
  971. if (!valid) {
  972. return;
  973. }
  974. }
  975. // 提交
  976. this.butLoading = true;
  977. try {
  978. if (type == 'submit') {
  979. await saveOrUpdateAndSubmit(body);
  980. this.$message.success('报工成功!');
  981. } else if (type == 'submit-reset') {
  982. await resetSubmit(body);
  983. this.$message.success('重新报工成功!');
  984. } else {
  985. const id = await saveOrUpdate(body);
  986. this.addForm.id = id;
  987. this.$message.success('缓存成功!');
  988. }
  989. this.butLoading = false;
  990. // 返回
  991. this.$emit('reload');
  992. this.handleBeforeClose();
  993. } catch (error) {
  994. this.butLoading = false;
  995. }
  996. });
  997. },
  998. async clearCache() {
  999. if (!this.productionInfo || !this.productionInfo.recordId) {
  1000. this.$message.warning('无缓存记录!');
  1001. return;
  1002. }
  1003. try {
  1004. this.butLoading = true;
  1005. await logicDelete(this.productionInfo.recordId);
  1006. this.butLoading = false;
  1007. this.productionInfo.recordId = null;
  1008. this.addForm.workshopArea = '';
  1009. this.addForm.workshopAreaId = null;
  1010. this.addForm.checkFinishTime = null;
  1011. this.addForm.checkStartTime = null;
  1012. this.addForm.checkValidity = null;
  1013. this.addForm.checkValidityUnit = '';
  1014. this.addForm.conclusion = null;
  1015. this.addForm.id = null;
  1016. this.addForm.duration = 0;
  1017. this.addForm.executeUsers = [];
  1018. this.addForm.executeUsersIds = [];
  1019. this.addForm.pickDetails = [];
  1020. this.addForm.outputDetails = [];
  1021. this.getRuleList();
  1022. this.$message.success('缓存清空成功!');
  1023. this.productionInfo.executeStatus = 0;
  1024. if (this.addForm.isTempRecord) {
  1025. this.handleBeforeClose();
  1026. } else {
  1027. this.$nextTick(() => {
  1028. this.$refs.ruleFormRef.clearValidate();
  1029. });
  1030. }
  1031. this.$emit('reload');
  1032. } catch (error) {
  1033. this.butLoading = false;
  1034. }
  1035. },
  1036. // 选择工具
  1037. handleAdd(row) {
  1038. this.currentRow = row;
  1039. this.$refs.toolModalRef.open(row.tools.map((i) => i.toolCode));
  1040. },
  1041. chooseModal(data) {
  1042. console.log('data', data);
  1043. this.currentRow.tools = data.map((i) => {
  1044. return {
  1045. toolCode: i.code,
  1046. toolName: i.name
  1047. };
  1048. });
  1049. this.currentRow.toolNames = this.currentRow.tools
  1050. .map((i) => i.toolName)
  1051. .join(',');
  1052. },
  1053. clearTool(row) {
  1054. row.tools = [];
  1055. row.toolNames = '';
  1056. },
  1057. checkTeamList(id) {
  1058. this.addForm.executeUsersIds = [];
  1059. const index = this.teamList.findIndex((item) => item.id == id);
  1060. this.teamUserList = this.teamAllList[index];
  1061. console.log('this.teamUserList', this.teamUserList);
  1062. },
  1063. async getTeamList(id) {
  1064. const ids = id.split(',');
  1065. this.teamList = [];
  1066. this.teamUserList = [];
  1067. const list = ids.map((item) => getTeam(item));
  1068. const dataList = await Promise.all(list);
  1069. dataList.forEach((item) => {
  1070. this.teamList.push({
  1071. name: item.name,
  1072. id: item.id
  1073. });
  1074. this.teamAllList.push(item.userVOList);
  1075. });
  1076. },
  1077. changeId() {
  1078. if (this.addForm.executeUsersIds.length == this.teamUserList.length) {
  1079. this.checked = true;
  1080. } else {
  1081. this.checked = false;
  1082. }
  1083. // 同步 executeUsers
  1084. this.addForm.executeUsers = this.addForm.executeUsersIds
  1085. .map((id) => {
  1086. const user = this.teamUserList.find((item) => item.id === id);
  1087. console.log('user', user);
  1088. if (user) {
  1089. return {
  1090. teamId: this.addForm.teamId,
  1091. teamName: this.teamList.find(
  1092. (team) => team.id == this.addForm.teamId
  1093. )?.name,
  1094. userId: user.id,
  1095. userName: user.name
  1096. };
  1097. } else {
  1098. return null;
  1099. }
  1100. })
  1101. .filter((item) => item !== null);
  1102. console.log('this.addForm.executeUsers', this.addForm.executeUsers);
  1103. this.computedDuration();
  1104. // 同步详情执行人
  1105. this.addForm.details.forEach((detail) => {
  1106. detail.checkUsersIds = this.addForm.executeUsersIds;
  1107. detail.checkUsers = this.addForm.executeUsers;
  1108. });
  1109. },
  1110. checkChange() {
  1111. this.addForm.executeUsersIds = [];
  1112. if (this.checked) {
  1113. this.addForm.executeUsersIds = this.teamUserList.map(
  1114. (item) => item.id
  1115. );
  1116. } else {
  1117. this.addForm.executeUsersIds = [];
  1118. }
  1119. },
  1120. // 计算工时
  1121. computedDuration() {
  1122. if (
  1123. this.addForm.checkStartTime &&
  1124. this.addForm.checkFinishTime &&
  1125. this.addForm.executeUsersIds.length > 0
  1126. ) {
  1127. const start = new Date(this.addForm.checkStartTime);
  1128. const finish = new Date(this.addForm.checkFinishTime);
  1129. const diff = finish - start; // 毫秒差值
  1130. const hours = diff / (1000 * 60 * 60); // 转换为小时
  1131. const totalDuration = hours * this.addForm.executeUsersIds.length;
  1132. this.addForm.duration = totalDuration.toFixed(1);
  1133. }
  1134. },
  1135. durationChagne() {
  1136. // 保留小数后一位
  1137. if (
  1138. this.addForm.duration &&
  1139. this.addForm.duration.toString().includes('.')
  1140. ) {
  1141. this.addForm.duration = Number(this.addForm.duration).toFixed(1);
  1142. }
  1143. },
  1144. checkUsersIdsChange(row) {
  1145. // 同步 checkUsers
  1146. row.checkUsers = row.checkUsersIds.map((i) => {
  1147. const user = this.activeTeamUserList.find((item) => item.id === i);
  1148. return {
  1149. teamId: this.addForm.teamId,
  1150. teamName: this.teamList.find(
  1151. (team) => team.id == this.addForm.teamId
  1152. )?.name,
  1153. userId: user.id,
  1154. userName: user.name
  1155. };
  1156. });
  1157. console.log('row', row);
  1158. },
  1159. // 查询车间区域
  1160. async getWorkshopArea() {
  1161. const data = await getFactoryarea({
  1162. pageNum: 1,
  1163. size: 999,
  1164. type: 3
  1165. });
  1166. console.log('list', data.list);
  1167. this.workshopAreaList = data.list;
  1168. },
  1169. workshopAreaIdChange(e) {
  1170. const area = this.workshopAreaList.find((i) => i.id === e);
  1171. if (area) {
  1172. this.addForm.workshopArea = area.name;
  1173. } else {
  1174. this.addForm.workshopArea = '';
  1175. }
  1176. },
  1177. // 批量检查
  1178. batchCheck() {
  1179. this.addForm.details = this.addForm.details.map((i) => {
  1180. i.checkStatus = 1;
  1181. return i;
  1182. });
  1183. },
  1184. // 批量合格
  1185. batchQualified() {
  1186. this.addForm.details = this.addForm.details.map((i) => {
  1187. i.checkResult = 1;
  1188. return i;
  1189. });
  1190. }
  1191. }
  1192. };
  1193. </script>
  1194. <style scoped lang="scss">
  1195. .modal-body {
  1196. padding: 16px;
  1197. min-height: 100px;
  1198. }
  1199. .modal-footer {
  1200. display: flex;
  1201. align-items: center;
  1202. gap: 10px;
  1203. justify-content: flex-end;
  1204. }
  1205. .el-form-item .el-form-item {
  1206. margin-bottom: -5px;
  1207. }
  1208. .checkboxWrapper {
  1209. padding: 8px 20px;
  1210. border-bottom: 1px solid #ccc;
  1211. }
  1212. ::v-deep .el-select__tags {
  1213. flex-wrap: nowrap;
  1214. overflow: auto;
  1215. }
  1216. /* 输入框最大宽度*/
  1217. ::v-deep .el-select__tags-text {
  1218. max-width: 90px;
  1219. }
  1220. /* 底部滚动条的高度*/
  1221. ::v-deep .el-select__tags::-webkit-scrollbar {
  1222. height: 2px !important;
  1223. }
  1224. </style>