workOrderReport.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. <template>
  2. <ele-modal
  3. :title="title"
  4. :visible.sync="visible"
  5. :close-on-click-modal="false"
  6. @close="handleClose"
  7. resizable
  8. maxable
  9. width="80%"
  10. >
  11. <header-title title="基本信息"></header-title>
  12. <el-form
  13. ref="formRef"
  14. :model="addForm"
  15. :rules="rules"
  16. label-width="120px"
  17. v-loading="loading"
  18. :disabled="type == 'detail'"
  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 label="检查开始时间" required prop="checkStartTime">
  43. <el-date-picker
  44. v-model="addForm.checkStartTime"
  45. type="datetime"
  46. format="yyyy-MM-dd HH:mm:ss"
  47. value-format="yyyy-MM-dd HH:mm:ss"
  48. placeholder="选择日期"
  49. style="width: 100%"
  50. :picker-options="{
  51. disabledDate: (time) => time.getTime() > Date.now()
  52. }"
  53. @change="computedDuration"
  54. >
  55. </el-date-picker>
  56. </el-form-item>
  57. </el-col>
  58. <el-col :span="8">
  59. <el-form-item label="检查结束时间" required prop="checkFinishTime">
  60. <el-date-picker
  61. v-model="addForm.checkFinishTime"
  62. type="datetime"
  63. format="yyyy-MM-dd HH:mm:ss"
  64. value-format="yyyy-MM-dd HH:mm:ss"
  65. placeholder="选择日期"
  66. style="width: 100%"
  67. :picker-options="{
  68. disabledDate: (time) => time.getTime() > Date.now()
  69. }"
  70. @change="computedDuration"
  71. >
  72. </el-date-picker>
  73. </el-form-item>
  74. </el-col>
  75. <el-col :span="8">
  76. <!-- <el-form-item label="执行人" required prop="teamId">
  77. <el-select
  78. v-model="addForm.teamId"
  79. placeholder="请选择班组"
  80. filterable
  81. style="width: 120px"
  82. @change="checkTeamList(addForm.teamId)"
  83. >
  84. <el-option
  85. v-for="item in teamList"
  86. :label="item.name"
  87. :value="item.id"
  88. :key="item.id"
  89. >
  90. </el-option>
  91. </el-select>
  92. <el-select
  93. v-model="addForm.executeUsersIds"
  94. placeholder="请选择执行人"
  95. filterable
  96. multiple
  97. @change="changeId"
  98. >
  99. <div class="checkboxWrapper">
  100. <el-checkbox v-model="checked" @change="checkChange">
  101. 全选
  102. </el-checkbox>
  103. </div>
  104. <el-option
  105. v-for="item in teamUserList"
  106. :label="item.name"
  107. :value="item.id"
  108. :key="item.id"
  109. >
  110. </el-option>
  111. </el-select>
  112. </el-form-item> -->
  113. <el-form-item label="部门">
  114. <deptSelect
  115. v-model="addForm.groupId"
  116. @changeGroup="searchDeptNodeClick"
  117. />
  118. </el-form-item>
  119. </el-col>
  120. <el-col :span="8">
  121. <el-form-item label="报工人" prop="executeUsersIds">
  122. <el-select
  123. v-model="addForm.executeUsersIds"
  124. size="small"
  125. style="width: 100%"
  126. multiple
  127. filterable
  128. @change="executeIdListChange"
  129. >
  130. <el-option
  131. v-for="item in executorList"
  132. :key="item.id"
  133. :value="item.id"
  134. :label="item.name"
  135. ></el-option>
  136. </el-select>
  137. </el-form-item>
  138. </el-col>
  139. <el-col :span="8">
  140. <el-form-item label="工时" required prop="duration">
  141. <el-input
  142. placeholder="请输入"
  143. v-model="addForm.duration"
  144. type="number"
  145. min="0"
  146. step="0.1"
  147. @change="durationChagne"
  148. >
  149. <template slot="append">
  150. <div style="width: 40px; box-sizing: border-box">小时</div>
  151. </template>
  152. </el-input>
  153. </el-form-item>
  154. </el-col>
  155. <el-col :span="8">
  156. <el-form-item label="结论" required prop="conclusion">
  157. <el-radio-group v-model="addForm.conclusion">
  158. <el-radio :label="1">合格</el-radio>
  159. <el-radio :label="2">不合格</el-radio>
  160. </el-radio-group>
  161. </el-form-item>
  162. </el-col>
  163. </el-row>
  164. <header-title title="检查项目" :style="`margin-top: 20px`"></header-title>
  165. <template v-if="addForm.recordTemplateStyle == '4'">
  166. <el-tabs v-model="statisticsType" type="card">
  167. <el-tab-pane
  168. v-for="i in statisticsTypeList"
  169. :label="i.label"
  170. :name="i.value"
  171. :key="i.value"
  172. >
  173. </el-tab-pane>
  174. </el-tabs>
  175. <statistics
  176. ref="statisticsRef"
  177. :details.sync="addForm.details"
  178. :statisticsType="statisticsType"
  179. :produceTaskId="addForm.produceTaskId"
  180. :workOrderId="addForm.workOrderId"
  181. :routingId="addForm.produceRoutingId"
  182. :ruleId="addForm.ruleId"
  183. ></statistics>
  184. </template>
  185. <ele-pro-table
  186. v-if="addForm.recordTemplateStyle != '4'"
  187. v-loading="loading"
  188. ref="table"
  189. row-key="id"
  190. :columns="detailsColumns"
  191. :datasource="addForm.details"
  192. cacheKey="mes-releaseRulesDialong-2510281408"
  193. :needPage="false"
  194. >
  195. <template v-slot:toolkit>
  196. <el-button
  197. v-if="addForm.recordTemplateStyle != '3'"
  198. type="primary"
  199. @click="batchCheck"
  200. >批量检查</el-button
  201. >
  202. <el-button
  203. v-if="addForm.recordTemplateStyle != '3'"
  204. type="primary"
  205. @click="batchQualified"
  206. >批量合格</el-button
  207. >
  208. </template>
  209. <template v-slot:paramValue="{ row }">
  210. <div v-if="addForm.recordTemplateStyle == '3'">
  211. {{ row.productName }}
  212. </div>
  213. <div v-else>
  214. {{ row.paramValue }}
  215. <span v-if="row.paramValue">{{ row.paramValue }}</span>
  216. <!-- 兼容一下 模板改造功能 -->
  217. <span v-else>
  218. {{ row.productName }}
  219. </span>
  220. </div>
  221. </template>
  222. <template v-slot:toolNames="{ row }">
  223. <el-link :underline="false" style="cursor: pointer">
  224. <div class="ele-cell">
  225. <div @click="handleAdd(row)">
  226. {{ row.toolNames ? row.toolNames : '请选择' }}
  227. </div>
  228. <i
  229. v-if="!row.toolNames"
  230. class="el-icon-arrow-down"
  231. @click="handleAdd(row)"
  232. ></i>
  233. <i v-else class="el-icon-close" @click="clearTool(row)"></i>
  234. </div>
  235. </el-link>
  236. </template>
  237. <template v-slot:checkUsersIds="{ row }">
  238. <div>
  239. <el-select
  240. v-model="row.checkUsersIds"
  241. placeholder="请选择检查人"
  242. filterable
  243. multiple
  244. @change="checkUsersIdsChange(row)"
  245. >
  246. <el-option
  247. v-for="item in addForm.executeUsers"
  248. :label="item.userName"
  249. :value="item.userId"
  250. :key="item.userId"
  251. >
  252. </el-option>
  253. </el-select>
  254. </div>
  255. </template>
  256. <template v-slot:checkStatus="{ row }">
  257. <div>
  258. <el-radio-group v-model="row.checkStatus">
  259. <el-radio :label="1">已检查</el-radio>
  260. <el-radio :label="0">未检查</el-radio>
  261. </el-radio-group>
  262. </div>
  263. </template>
  264. <template v-slot:errorMsg="{ row }">
  265. <div>
  266. <el-input
  267. type="text"
  268. :rows="1"
  269. placeholder="请输入"
  270. v-model="row.errorMsg"
  271. >
  272. <template v-if="row.unitName" slot="append">
  273. <div>{{ row.unitName }}</div>
  274. </template>
  275. </el-input>
  276. </div></template
  277. >
  278. <template v-slot:checkResult="{ row }">
  279. <div>
  280. <el-radio-group v-model="row.checkResult">
  281. <el-radio :label="1">合格</el-radio>
  282. <el-radio :label="0">不合格</el-radio>
  283. </el-radio-group>
  284. </div>
  285. </template>
  286. </ele-pro-table>
  287. </el-form>
  288. <toolModal ref="toolModalRef" @chooseModal="chooseModal" />
  289. <template v-slot:footer>
  290. <el-button
  291. v-if="type == 'add'"
  292. type="primary"
  293. @click="submit"
  294. :loading="butLoading"
  295. >提 交</el-button
  296. >
  297. <el-button @click="handleClose">取 消</el-button>
  298. </template>
  299. </ele-modal>
  300. </template>
  301. <script>
  302. import dictMixins from '@/mixins/dictMixins';
  303. import { getById } from '@/api/producetaskrecordrulesrecord/index';
  304. import { getTeam } from '@/api/produce/job.js';
  305. import toolModal from '@/views/batchRecord/components/toolModal.vue';
  306. import { producetaskrulerecordSaveOrUpdateAndSubmit } from '@/api/recordRules/index.js';
  307. import deptSelect from '@/components/CommomSelect/dept-select.vue';
  308. import { getUserPage } from '@/api/system/organization';
  309. export default {
  310. mixins: [dictMixins],
  311. components: {
  312. toolModal,
  313. deptSelect
  314. },
  315. watch: {
  316. 'addForm.details': {
  317. handler(details) {
  318. // 排除 物料添加 和 生产统计 模板
  319. if (
  320. this.addForm.recordTemplateStyle == '4' ||
  321. this.addForm.recordTemplateStyle == '3'
  322. )
  323. return;
  324. const any = details.some((i) => i.checkResult === null);
  325. if (any || details.length === 0) return;
  326. const every = details.every((i) => i.checkResult == 1);
  327. this.addForm.conclusion = every ? 1 : 2;
  328. console.log('this.addForm.conclusion', this.addForm.conclusion);
  329. },
  330. deep: true
  331. }
  332. },
  333. data() {
  334. const formBaseData = {
  335. id: null,
  336. workshopArea: '',
  337. workshopAreaId: null,
  338. checkFinishTime: '',
  339. checkStartTime: '',
  340. checkValidity: null,
  341. checkValidityUnit: '',
  342. conclusion: null,
  343. isTempRecord: this.isTempRecord,
  344. details: [],
  345. deviceId: 0,
  346. deviceName: '',
  347. batchNo: '',
  348. executeMethod: 0,
  349. formingNum: 0,
  350. itemType: 0,
  351. produceRoutingId: 0,
  352. produceRoutingName: '',
  353. produceTaskConfigId: 0,
  354. produceTaskId: 0,
  355. produceTaskName: '',
  356. productCode: '',
  357. productModel: '',
  358. productName: '',
  359. recordRulesClassify: null,
  360. recordTemplateStyle: null,
  361. ruleId: 0,
  362. ruleName: '',
  363. reportWorkType: 0,
  364. specification: '',
  365. workOrderCode: '',
  366. workOrderId: 0,
  367. itemTaskName: '',
  368. brandNo: '',
  369. duration: null,
  370. // 执行人
  371. executeUsersIds: [],
  372. executeUsers: [],
  373. // 班组id
  374. teamId: '',
  375. groupId: null,
  376. // 物料字段name
  377. pickDetails: [],
  378. // 本次产出明细
  379. outputDetails: [],
  380. recordRulesExecuteMethodId: null,
  381. recordRulesExecuteMethodName: '',
  382. // 产出类型 1-原材料,2-在制品,3.BOM标准产出
  383. outputType: 1
  384. };
  385. return {
  386. visible: false,
  387. type: 'add',
  388. title: '报工',
  389. formBaseData,
  390. addForm: JSON.parse(JSON.stringify(formBaseData)),
  391. rules: {
  392. checkStartTime: [
  393. { required: true, message: '请选择检查开始时间', trigger: 'blur' },
  394. {
  395. required: true,
  396. message: '请选择检查开始时间',
  397. trigger: 'change'
  398. },
  399. {
  400. validator: (rule, value, callback) => {
  401. if (!value) return callback();
  402. const start = new Date(value).getTime();
  403. const now = Date.now();
  404. if (start > now) {
  405. callback(new Error('开始时间不能超过当前时间'));
  406. } else {
  407. callback();
  408. }
  409. },
  410. trigger: 'blur'
  411. }
  412. ],
  413. checkFinishTime: [
  414. { required: true, message: '请选择检查完成时间', trigger: 'blur' },
  415. {
  416. required: true,
  417. message: '请选择检查完成时间',
  418. trigger: 'change'
  419. },
  420. {
  421. validator: (rule, value, callback) => {
  422. if (!value) return callback();
  423. const start = new Date(this.addForm.checkStartTime).getTime();
  424. const finish = new Date(value).getTime();
  425. const now = Date.now();
  426. if (finish <= start) {
  427. callback(new Error('结束时间必须大于开始时间'));
  428. } else if (finish > now) {
  429. callback(new Error('结束时间不能超过当前时间'));
  430. } else {
  431. callback();
  432. }
  433. },
  434. trigger: 'blur'
  435. }
  436. ],
  437. conclusion: [
  438. { required: true, message: '请选择结论', trigger: 'blur' },
  439. { required: true, message: '请选择结论', trigger: 'change' }
  440. ],
  441. duration: [
  442. { required: true, message: '请输入工时', trigger: 'blur' },
  443. { required: true, message: '请输入工时', trigger: 'change' },
  444. {
  445. validator: (rule, value, callback) => {
  446. if (value === '' || value === null) {
  447. callback();
  448. } else if (Number(value) <= 0) {
  449. callback(new Error('工时必须大于0'));
  450. } else {
  451. callback();
  452. }
  453. },
  454. trigger: 'blur'
  455. }
  456. ],
  457. teamId: [
  458. { required: true, message: '请选择班组', trigger: 'blur' },
  459. { required: true, message: '请选择班组', trigger: 'change' }
  460. ]
  461. },
  462. loading: false,
  463. currentRow: null,
  464. butLoading: false,
  465. checked: false,
  466. teamUserList: [],
  467. teamList: [],
  468. teamAllList: [],
  469. workshopAreaList: [],
  470. // 1-成品统计,2-物料统计,3-工序统计"
  471. statisticsType: '1',
  472. statisticsTypeList: [
  473. { label: '成品统计', value: '1' },
  474. { label: '物料统计', value: '2' },
  475. { label: '工序统计', value: '3' }
  476. ],
  477. executorList: []
  478. };
  479. },
  480. computed: {
  481. // title() {
  482. // if (this.addForm.recordRulesClassify) {
  483. // const dictValue = this.getDictValue(
  484. // '记录规则类型',
  485. // this.addForm.recordRulesClassify
  486. // );
  487. // return dictValue + '记录表';
  488. // }
  489. // return '记录表';
  490. // },
  491. activeTeamUserList() {
  492. return this.teamUserList.filter((user) =>
  493. this.addForm.executeUsersIds.includes(user.id)
  494. );
  495. },
  496. // 规则详情表头
  497. detailsColumns() {
  498. let list = [
  499. {
  500. width: 45,
  501. type: 'index',
  502. columnKey: 'index',
  503. align: 'center'
  504. },
  505. {
  506. label: '检查内容',
  507. prop: 'paramValue',
  508. minWidth: 120,
  509. slot: 'paramValue'
  510. }
  511. ];
  512. if (this.addForm.recordTemplateStyle != '3') {
  513. list = [
  514. ...list,
  515. {
  516. label: '检查工具',
  517. prop: 'toolNames',
  518. minWidth: 120,
  519. slot: 'toolNames'
  520. },
  521. {
  522. label: '检查人',
  523. prop: 'checkUsersIds',
  524. minWidth: 120,
  525. slot: 'checkUsersIds'
  526. },
  527. {
  528. label: '检查情况',
  529. prop: 'checkStatus',
  530. minWidth: 120,
  531. slot: 'checkStatus'
  532. },
  533. {
  534. label: '描述',
  535. prop: 'errorMsg',
  536. minWidth: 120,
  537. slot: 'errorMsg'
  538. },
  539. {
  540. label: '检查结果',
  541. prop: 'checkResult',
  542. minWidth: 120,
  543. slot: 'checkResult'
  544. }
  545. ];
  546. } else {
  547. list.push({
  548. label: '描述',
  549. prop: 'errorMsg',
  550. minWidth: 120,
  551. slot: 'errorMsg'
  552. });
  553. }
  554. return list;
  555. }
  556. },
  557. created() {
  558. if (localStorage.getItem('singleUserInfo') == '1') {
  559. const data = JSON.parse(localStorage.getItem('chooseUserInfo'));
  560. this.getTeamList(data.teamId);
  561. } else {
  562. this.getTeamList(this.$store.state.user.info.teamId);
  563. }
  564. // 获取审核人列表、巡点检人员
  565. this.getUserList();
  566. },
  567. methods: {
  568. // 外部调用,打开弹窗
  569. open(type = 'add', data) {
  570. this.type = type;
  571. console.log('data', data);
  572. if (type == 'add') {
  573. this.title = '报工';
  574. } else {
  575. this.title = '详情';
  576. }
  577. this.getOrderDetials(data.id);
  578. this.visible = true;
  579. },
  580. // 获取工单详情
  581. async getOrderDetials(id) {
  582. this.loading = true;
  583. try {
  584. const data = await getById(id);
  585. console.log('data', data);
  586. data.details = data.details.map((i) => {
  587. i.toolNames = i.tools.map((j) => j.toolName).join(',');
  588. i.checkUsersIds = i.checkUsers.map((j) => j.userId);
  589. if (i.checkUsersIds.length == 0 && data.executeUsers.length > 0) {
  590. // 默认执行人作为检查人
  591. i.checkUsersIds = data.executeUsers.map((j) => j.userId);
  592. i.checkUsers = data.executeUsers.map((j) => {
  593. return {
  594. teamId: j.teamId,
  595. teamName: j.teamName,
  596. userId: j.userId,
  597. userName: j.userName
  598. };
  599. });
  600. }
  601. return i;
  602. });
  603. this.$util.assignObject(this.addForm, data);
  604. console.log('this.addForm', this.addForm);
  605. // 处理数据
  606. this.addForm.executeUsersIds = this.addForm.executeUsers.map(
  607. (i) => i.userId
  608. );
  609. this.addForm.teamId =
  610. this.addForm.executeUsers.length > 0
  611. ? this.addForm.executeUsers[0].teamId
  612. : '';
  613. if (this.addForm.executeUsers.length > 0) {
  614. this.addForm.groupId = this.addForm.executeUsers[0]?.groupId || '';
  615. this.searchDeptNodeClick(this.addForm.groupId);
  616. }
  617. if (!this.addForm.teamId && this.teamList.length > 0) {
  618. this.addForm.teamId = this.teamList[0].id;
  619. }
  620. // 工时毫秒转小时
  621. this.addForm.duration = (
  622. this.addForm.duration /
  623. (1000 * 60 * 60)
  624. ).toFixed(2);
  625. this.addForm.recordRulesClassify += '';
  626. // 加载班组人员列表
  627. if (this.addForm.teamId) {
  628. const index = this.teamList.findIndex(
  629. (item) => item.id == this.addForm.teamId
  630. );
  631. this.teamUserList = this.teamAllList[index];
  632. console.log('this.teamUserList', this.teamUserList);
  633. }
  634. this.$nextTick(() => {
  635. this.$refs.formRef.clearValidate();
  636. this.loading = false;
  637. });
  638. } catch (error) {
  639. this.loading = false;
  640. }
  641. },
  642. // 关闭时清理表单
  643. handleClose() {
  644. this.addForm = JSON.parse(JSON.stringify(this.formBaseData));
  645. this.$nextTick(() => {
  646. this.$refs.formRef.clearValidate();
  647. this.visible = false;
  648. });
  649. },
  650. // 提交
  651. submit() {
  652. this.$refs.formRef.validate(async (valid) => {
  653. if (valid) {
  654. console.log('this.addForm', this.addForm);
  655. // this.handleClose();
  656. if (this.addForm.executeUsersIds.length == 0) {
  657. this.$message.warning('请选择执行人!');
  658. return;
  659. }
  660. // 报工需要验证 缓存不验证 排除 recordTemplateStyle ==3 物料添加 == 4生产统计 模板
  661. if (
  662. this.addForm.recordTemplateStyle != '3' &&
  663. this.addForm.recordTemplateStyle != '4'
  664. ) {
  665. // 验证检查项目
  666. const detailRequired = this.addForm.details.some((i) => {
  667. return (
  668. i.checkResult == null ||
  669. !i.checkStatus ||
  670. i.checkUsers?.length == 0
  671. );
  672. });
  673. if (detailRequired) {
  674. return this.$message.warning(
  675. '请先完善 检查人、检查情况、检查结果 内容!'
  676. );
  677. }
  678. }
  679. const body = JSON.parse(JSON.stringify(this.addForm));
  680. // 工时小时转毫秒
  681. body.duration = Number(body.duration);
  682. body.duration = body.duration * 60 * 60 * 1000;
  683. this.butLoading = true;
  684. try {
  685. await producetaskrulerecordSaveOrUpdateAndSubmit(body);
  686. this.$message.success('报工成功!');
  687. this.butLoading = false;
  688. this.$emit('refresh');
  689. this.handleClose();
  690. } catch (error) {
  691. this.butLoading = false;
  692. }
  693. }
  694. });
  695. },
  696. // 选择工具
  697. handleAdd(row) {
  698. this.currentRow = row;
  699. this.$refs.toolModalRef.open(row.tools.map((i) => i.toolCode));
  700. },
  701. chooseModal(data) {
  702. console.log('data', data);
  703. this.currentRow.tools = data.map((i) => {
  704. return {
  705. toolCode: i.code,
  706. toolName: i.name
  707. };
  708. });
  709. this.currentRow.toolNames = this.currentRow.tools
  710. .map((i) => i.toolName)
  711. .join(',');
  712. },
  713. clearTool(row) {
  714. row.tools = [];
  715. row.toolNames = '';
  716. },
  717. checkTeamList(id) {
  718. const index = this.teamList.findIndex((item) => item.id == id);
  719. this.teamUserList = this.teamAllList[index];
  720. console.log('this.teamUserList', this.teamUserList);
  721. },
  722. async getTeamList(id) {
  723. if (!id) return;
  724. const ids = id.split(',');
  725. this.teamList = [];
  726. this.teamUserList = [];
  727. const list = ids.map((item) => getTeam(item));
  728. const dataList = await Promise.all(list);
  729. dataList.forEach((item) => {
  730. this.teamList.push({
  731. name: item.name,
  732. id: item.id
  733. });
  734. this.teamAllList.push(item.userVOList);
  735. });
  736. },
  737. changeId() {
  738. if (this.addForm.executeUsersIds.length == this.teamUserList.length) {
  739. this.checked = true;
  740. } else {
  741. this.checked = false;
  742. }
  743. const deleteUserIds = this.addForm.executeUsers
  744. .map((i) => i.userId)
  745. .filter((id) => !this.addForm.executeUsersIds.includes(id));
  746. const addUserIds = this.addForm.executeUsersIds.filter(
  747. (id) => !this.addForm.executeUsers.map((i) => i.userId).includes(id)
  748. );
  749. // 删除 用户
  750. if (deleteUserIds.length > 0) {
  751. this.addForm.executeUsers = this.addForm.executeUsers.filter(
  752. (item) => !deleteUserIds.includes(item.userId)
  753. );
  754. }
  755. // 添加 用户
  756. addUserIds.forEach((id) => {
  757. const user = this.teamUserList.find((item) => item.id === id);
  758. if (user) {
  759. this.addForm.executeUsers.push({
  760. teamId: this.addForm.teamId,
  761. teamName: this.teamList.find(
  762. (team) => team.id == this.addForm.teamId
  763. )?.name,
  764. userId: user.id,
  765. userName: user.name
  766. });
  767. }
  768. });
  769. console.log('this.addForm.executeUsers', this.addForm.executeUsers);
  770. this.computedDuration();
  771. // 同步详情执行人
  772. this.addForm.details.forEach((detail) => {
  773. detail.checkUsersIds = this.addForm.executeUsersIds;
  774. detail.checkUsers = this.addForm.executeUsers;
  775. });
  776. },
  777. checkChange() {
  778. this.addForm.executeUsersIds = [];
  779. if (this.checked) {
  780. this.addForm.executeUsersIds = this.teamUserList.map(
  781. (item) => item.id
  782. );
  783. } else {
  784. this.addForm.executeUsersIds = [];
  785. }
  786. },
  787. // 计算工时
  788. computedDuration() {
  789. if (
  790. this.addForm.checkStartTime &&
  791. this.addForm.checkFinishTime &&
  792. this.addForm.executeUsersIds.length > 0
  793. ) {
  794. const start = new Date(this.addForm.checkStartTime);
  795. const finish = new Date(this.addForm.checkFinishTime);
  796. const diff = finish - start; // 毫秒差值
  797. const hours = diff / (1000 * 60 * 60); // 转换为小时
  798. const totalDuration = hours * this.addForm.executeUsersIds.length;
  799. this.addForm.duration = totalDuration.toFixed(1);
  800. }
  801. },
  802. durationChagne() {
  803. // 保留小数后一位
  804. if (
  805. this.addForm.duration &&
  806. this.addForm.duration.toString().includes('.')
  807. ) {
  808. this.addForm.duration = Number(this.addForm.duration).toFixed(1);
  809. }
  810. },
  811. checkUsersIdsChange(row) {
  812. // 同步 checkUsers
  813. row.checkUsers = row.checkUsersIds.map((i) => {
  814. const user = this.addForm.executeUsers.find(
  815. (item) => item.userId === i
  816. );
  817. return user;
  818. });
  819. console.log('row', row);
  820. },
  821. // 查询车间区域
  822. async getWorkshopArea() {
  823. const data = await getFactoryarea({
  824. pageNum: 1,
  825. size: 999,
  826. type: 3
  827. });
  828. console.log('list', data.list);
  829. this.workshopAreaList = data.list;
  830. },
  831. workshopAreaIdChange(e) {
  832. const area = this.workshopAreaList.find((i) => i.id === e);
  833. if (area) {
  834. this.addForm.workshopArea = area.name;
  835. } else {
  836. this.addForm.workshopArea = '';
  837. }
  838. },
  839. // 批量检查
  840. batchCheck() {
  841. this.addForm.details = this.addForm.details.map((i) => {
  842. i.checkStatus = 1;
  843. return i;
  844. });
  845. },
  846. // 批量合格
  847. batchQualified() {
  848. this.addForm.details = this.addForm.details.map((i) => {
  849. i.checkResult = 1;
  850. return i;
  851. });
  852. },
  853. // 获取审核人列表、巡点检人员
  854. async getUserList(params) {
  855. try {
  856. let data = { pageNum: 1, size: -1 };
  857. // 如果传了参数就是获取部门人员数据
  858. if (params) {
  859. data = Object.assign(data, params);
  860. }
  861. const res = await getUserPage(data);
  862. if (params) {
  863. this.executorList = res.list;
  864. } else {
  865. this.uerList = res.list;
  866. }
  867. } catch (error) {}
  868. },
  869. //选择部门(搜索)
  870. async searchDeptNodeClick(groupId, data) {
  871. if (groupId) {
  872. // 根据部门获取人员
  873. const params = { groupId: groupId };
  874. await this.getUserList(params);
  875. } else {
  876. this.addForm.groupId = null;
  877. }
  878. },
  879. // 负责人变更 同步执行人列表
  880. executeIdListChange() {
  881. this.addForm.executeUsers = this.addForm.executeUsersIds.map(
  882. (userId) => {
  883. const user = this.executorList.find((u) => u.id === userId);
  884. return {
  885. userId: user.id,
  886. userName: user.name,
  887. groupId: user.groupId,
  888. groupName: user.groupName
  889. };
  890. }
  891. );
  892. // 同步详情执行人
  893. this.addForm.details.forEach((detail) => {
  894. detail.checkUsersIds = this.addForm.executeUsersIds;
  895. detail.checkUsers = this.addForm.executeUsers;
  896. });
  897. console.log('this.addForm.executeUsers', this.addForm.executeUsers);
  898. }
  899. }
  900. };
  901. </script>
  902. <style scoped lang="scss">
  903. :deep(.el-form) {
  904. .el-form-item:last-child {
  905. margin-bottom: 22px !important;
  906. }
  907. }
  908. ::v-deep .el-row {
  909. display: flex;
  910. flex-wrap: wrap;
  911. }
  912. .checkboxWrapper {
  913. padding: 8px 20px;
  914. border-bottom: 1px solid #ccc;
  915. }
  916. ::v-deep .el-select__tags {
  917. flex-wrap: nowrap;
  918. overflow: auto;
  919. }
  920. /* 输入框最大宽度*/
  921. ::v-deep .el-select__tags-text {
  922. max-width: 90px;
  923. }
  924. /* 底部滚动条的高度*/
  925. ::v-deep .el-select__tags::-webkit-scrollbar {
  926. height: 2px !important;
  927. }
  928. </style>