release.js 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
  1. import {
  2. listByFirstTaskId,
  3. listUserByIds,
  4. listWorkCenter,
  5. listByWorkCenter,
  6. lineByCurrentUser,
  7. taskSave,
  8. taskRevoked,
  9. taskAssignment,
  10. listAssign,
  11. checkAssignConfirm,
  12. resetAssignee,
  13. listByRoutingIds,
  14. listByFactoryId,
  15. checkExists,
  16. parameterGetByCode
  17. } from '@/api/mainData/index.js';
  18. import {
  19. releaseWorkOrder,
  20. getcheckLoginUserIsTeamLeader,
  21. getUserInfo
  22. } from '@/api/workOrder/index.js';
  23. // import { }
  24. export default {
  25. data() {
  26. return {
  27. isTpye: ''
  28. };
  29. },
  30. created() {
  31. // console.log('组件传入的选项:', this.$options.mixinOptions);
  32. this.isTpye = this.$options.mixinOptions.type;
  33. },
  34. methods: {
  35. // 查询班次
  36. getClassesData() {
  37. if (!this.current.factoriesId) return;
  38. listByFactoryId(this.current.factoriesId).then((res) => {
  39. if (!res) return;
  40. this.shiftList = res;
  41. });
  42. },
  43. // 查询是否派单
  44. queryCheckExists() {
  45. let params = {
  46. workOrderId: this.current.id,
  47. workCenterId: 123,
  48. teamId: 345
  49. };
  50. checkExists(params)
  51. .then((res) => {
  52. if (!res) return;
  53. this.isDispatchRow = res;
  54. if (res.hasExists) {
  55. this.form.taskAss = 0;
  56. this.orderDis = true;
  57. this.procTaskDis = false;
  58. // 报工类型 判断
  59. this.form.singleReport = res.dispatchType;
  60. if (res.dispatchType == 1) {
  61. this.batchDis = true;
  62. this.singleDis = false;
  63. } else {
  64. this.singleDis = true;
  65. this.batchDis = false;
  66. }
  67. } else {
  68. this.batchDis = false;
  69. this.singleDis = false;
  70. this.orderDis = false;
  71. this.procTaskDis = false;
  72. }
  73. })
  74. .catch((err) => {
  75. this.$message.error(err.message);
  76. });
  77. },
  78. // 获取当前年月日
  79. getFormattedDate() {
  80. const now = new Date();
  81. const year = now.getFullYear();
  82. const month = String(now.getMonth() + 1).padStart(2, '0');
  83. const date = String(now.getDate()).padStart(2, '0');
  84. return `${year}-${month}-${date}`;
  85. },
  86. // 查询工作中心
  87. async workCenterData() {
  88. // 判断是否存在工序id 有的话就取否则取首工序id
  89. console.log(this.current, 'this.current 查询工作中心');
  90. let id = '';
  91. if (!this.current.taskId || this.current.taskId < 0) {
  92. id = this.current.firstTaskId;
  93. } else {
  94. id = this.current.taskId;
  95. }
  96. if (this.current?.factoryName) {
  97. this.form.factoryName = this.current.factoryName;
  98. }
  99. // this.current.taskId || this.current.firstTaskId;
  100. const res = await listWorkCenter(id);
  101. console.log(res, 'ressss');
  102. const userData = await getUserInfo(this.$store.state.user.info.userId);
  103. this.workCenterList = res;
  104. if (res.length > 0) {
  105. // this.form.factoryName = res[0].factoryName;
  106. this.form.workCenterId = res[0].id;
  107. if (this.isTpye == 'add') {
  108. if (userData.centerList.length == 0) {
  109. this.form.isDisable = true;
  110. return this.$message.warning(
  111. `当前登录人没有配置所属中心,请先去主数据给该登录人配置所属中心`
  112. );
  113. }
  114. if (userData.centerList.length != 0) {
  115. // centerId
  116. if (res.length != 0) {
  117. const data = userData.centerList.filter(
  118. (it) => it.centerId == res[0].id
  119. );
  120. if (data.length == 0) {
  121. this.form.isDisable = true;
  122. return this.$message.warning(`当前登录人没有权限给该工单派单`);
  123. }
  124. }
  125. }
  126. }
  127. // 查首工序
  128. await this.changeWork(res[0].id); // 选择工作中心
  129. this.getProductionData(res[0].id); // 查询产线
  130. this.FirstTaskIdFn(); // 查询工位数据
  131. } else {
  132. this.$message.warning(
  133. // `${this.current.firstTaskName}工序没有工作中心,请到主数据工序管理维护工序信息!`
  134. `当前登录人不属于首工序所属工作中心及班组,请切换首工序${this.current.firstTaskName}所在的班组成员派单`
  135. );
  136. }
  137. },
  138. // 查询工序列表数据
  139. changeDispatch(e) {
  140. this.tabsLoading = true;
  141. // listByWorkCenter(this.form.workCenterId)
  142. listByRoutingIds([this.current.produceRoutingId])
  143. .then((res) => {
  144. this.tabsLoading = false;
  145. // 如果没有首工序的数据 就不能选择工序任务派单
  146. if (!res || res.length == 0) {
  147. this.processList = [];
  148. this.form.taskAss = 1;
  149. this.procTaskDis = true;
  150. return;
  151. }
  152. this.procTaskDis = false;
  153. let list = [];
  154. let isExist = false;
  155. let firstTaskindex = '';
  156. res.forEach((item, index) => {
  157. isExist = isExist
  158. ? isExist
  159. : item.sourceTaskId === this.current.firstTaskId;
  160. // 如果有首工序id 存储它的下标
  161. if (isExist) {
  162. if (!firstTaskindex && firstTaskindex !== 0) {
  163. firstTaskindex = index;
  164. }
  165. }
  166. let obj = {
  167. id: item.sourceTaskId, //工序 id
  168. name: item.name, //工序 名称
  169. assignType: 1, // 默认的指派数据
  170. assignName: '工位', // 默认指派数据名称
  171. list: [], // 当前工序下面的指派 绑定的表格
  172. selection: [], // 当前工序下面的指派 选中的数据f
  173. code: item.code, // 工序 编码
  174. index: index, // 当前工序数据的下标
  175. radioBun: {
  176. // 指派按钮的操作状态 绑定 默认false(可操作)
  177. stationDis: false, // 工位按钮
  178. staffDis: false, // 人员按钮
  179. lineDis: false // 产线按钮
  180. },
  181. isDisable:
  182. this.form.workCenterId == item.workCenterId ? true : false,
  183. startDate: '', // 开始日期 (当前工序中最早的计划开始时间)
  184. endDate: '', // 结束日期 (当前工序中最晚的计划结束时间)
  185. workCenterId: item.workCenterId,
  186. workCenterName: item.workCenterName
  187. };
  188. list.push(obj);
  189. });
  190. this.firstTaskindex = firstTaskindex;
  191. // 存在首工序报工
  192. if (isExist) {
  193. this.processList = list;
  194. this.processId = res[0].sourceTaskId;
  195. // this.handleClick({ name: res[0].sourceTaskId });
  196. this.initializeQuery();
  197. } else {
  198. this.processList = [];
  199. this.form.taskAss = 1;
  200. this.procTaskDis = true;
  201. this.$message.warning('当前任务没有首工序报工');
  202. }
  203. })
  204. .catch((err) => {
  205. this.processList = [];
  206. this.tabsLoading = false;
  207. this.$message.error(err.message);
  208. });
  209. },
  210. // 初始化查询 查询全部工序操作过的数据
  211. async initializeQuery() {
  212. try {
  213. // 不存在 班组数据的话 就不调用这个方法
  214. if (!this.form.teamId) {
  215. return;
  216. }
  217. let params = {
  218. workOrderId: this.current.id,
  219. workCenterId: this.form.workCenterId,
  220. teamId: this.form.teamId
  221. };
  222. let processMap = {};
  223. this.processList.map((el, index) => (processMap[el.id] = index));
  224. console.log(this.processList, 'processMap');
  225. const res = await listAssign(params);
  226. let isFirstData = false; // 判断默认第一道工序是否操作过
  227. if (res && res.length > 0) {
  228. res.map((el) => {
  229. let index = processMap[el.taskId];
  230. if (index === 0 && el.assignees && el.assignees.length > 0) {
  231. isFirstData = true; // 操作过
  232. }
  233. // 这里第三个参数传空数组就好了 会自动计算的
  234. setTimeout(() => {
  235. this.operationalData(index, [el], []);
  236. });
  237. });
  238. // 没有操作过 默认获取一下表格数据
  239. if (!isFirstData) {
  240. this.handleClick({ name: this.processId });
  241. }
  242. } else {
  243. this.handleClick({ name: this.processId });
  244. }
  245. console.log(this.processList, '工序列表');
  246. } catch (err) {}
  247. },
  248. // 选择工作中心
  249. async changeWork(e) {
  250. this.form.workCenterId = e;
  251. // this.changeDispatch(); // 查询工序列表
  252. let data = this.workCenterList.find((item) => item.id == e);
  253. this.form.workCenterName = data.name;
  254. this.teamList = data.teamList || []; // 重新获取 班组数据
  255. if (this.teamList.length > 0) {
  256. this.form.teamId = this.teamList[0].id;
  257. await this.changeGroups(this.teamList[0].id); // 获取人员数据方法
  258. } else {
  259. // 如果没有 班组数据 将人员数据清空 并且判断
  260. this.crewList = [];
  261. this.form.teamId = '';
  262. let data = this.processList.find((item) => item.id == this.processId);
  263. if (data.assignType == 2) {
  264. this.$set(data, 'list', []);
  265. }
  266. }
  267. },
  268. // 选择班组 查询人员的数据
  269. async changeGroups(e) {
  270. let data = this.teamList.find((item) => item.id == e);
  271. this.form.teamName = data.name;
  272. try {
  273. const res = await listUserByIds([e]);
  274. this.crewList = res;
  275. // 查看当前的工序数据是不是 选择的人员 是的话同步更改
  276. if (!this.processId || this.processId == 0) {
  277. return;
  278. }
  279. this.handleClick({ name: this.processId });
  280. this.btnInit();
  281. } catch {
  282. this.crewList = [];
  283. }
  284. },
  285. // 工序按钮初始化
  286. btnInit() {
  287. let data = this.processList.find((item) => item.id == this.processId);
  288. this.$set(data.radioBun, 'lineDis', false);
  289. this.$set(data.radioBun, 'staffDis', false);
  290. this.$set(data.radioBun, 'stationDis', false);
  291. this.$set(data, 'assignName', '工位');
  292. this.$set(data, 'assignType', 1);
  293. },
  294. // 获取产线数据
  295. async getProductionData() {
  296. const res = await lineByCurrentUser(this.form.workCenterId);
  297. this.productionList =
  298. res &&
  299. res.map((el) => {
  300. return {
  301. name: el.name,
  302. code: el.code,
  303. id: el.id
  304. };
  305. });
  306. },
  307. // 查询工位数据
  308. async FirstTaskIdFn(taskId) {
  309. console.log(this.current, 'this.current 查询工位数据');
  310. // let id = this.current.taskId || this.current.firstTaskId;
  311. let id = '';
  312. if (!this.current.taskId || this.current.taskId < 0) {
  313. id = this.current.firstTaskId;
  314. } else {
  315. id = this.current.taskId;
  316. }
  317. console.log(id, 'id 查询工位数据');
  318. await listByFirstTaskId(taskId ? taskId : id)
  319. .then((res) => {
  320. this.stationList = res;
  321. this.stationList.forEach((item, index) => {
  322. let substance = item.workstationSubstanceList[0]?.substance;
  323. if (substance) {
  324. this.$set(this.stationList[index], 'assetName', substance.name);
  325. this.$set(this.stationList[index], 'assetCode', substance.code);
  326. this.$set(
  327. this.stationList[index],
  328. 'assetModelType',
  329. substance.category?.category?.modelType
  330. );
  331. this.$set(
  332. this.stationList[index],
  333. 'assetCategoryLevelPath',
  334. substance.category?.category?.categoryLevelPath?.split('-')[0]
  335. );
  336. }
  337. });
  338. console.log(this.stationList, '5522200');
  339. if (this.isTask) {
  340. this.changeDispatch();
  341. }
  342. })
  343. .catch((err) => {
  344. this.stationList = [];
  345. this.$message.error(err.message);
  346. });
  347. },
  348. // 重置(单个)
  349. resetData(row, item) {
  350. if (!row.changeId) {
  351. return this.$message.warning('只能对已撤回跟已保存的数据进行重置');
  352. }
  353. this.toolbarLoading = true;
  354. resetAssignee(row.changeId)
  355. .then((res) => {
  356. this.toolbarLoading = false;
  357. if (res) {
  358. this.$message.success('操作成功');
  359. // 更改当前表格数据
  360. this.setCurrentTab(item);
  361. }
  362. })
  363. .catch((err) => {
  364. this.toolbarLoading = false;
  365. this.$message.error(err.message);
  366. });
  367. },
  368. // 撤回的逻辑
  369. getWithdrawT(row, type) {
  370. if (type != 2) {
  371. return true;
  372. }
  373. let isFlag = true;
  374. row.selection.forEach((item) => {
  375. if (!item.status) {
  376. isFlag = false;
  377. return;
  378. }
  379. if (!item.status.code) {
  380. isFlag = false;
  381. }
  382. });
  383. return isFlag;
  384. },
  385. // 派单
  386. dispatch(row, type) {
  387. console.log(row, 'row 333');
  388. console.log(type, 'type');
  389. if (row.selection.length == 0) {
  390. return this.$message.warning('请最少选择一条数据');
  391. }
  392. let isWithdraw = this.getWithdrawT(row, type);
  393. if (!isWithdraw) {
  394. this.$message.warning('只有状态为派单的数据才能进行撤回');
  395. return;
  396. }
  397. let assignees = [];
  398. let changeIds = [];
  399. let flag = true; // 是否填写 校验
  400. console.log(row.selection, '选中的数据');
  401. row.selection.forEach((item) => {
  402. if (!item.quantity || !item.startTime || !item.endTime) {
  403. flag = false;
  404. return;
  405. }
  406. if (item.quantity == 0) {
  407. this.$message.warning('请检查所选数据的数量不能为0');
  408. digit = false;
  409. return;
  410. }
  411. console.log(item, '数据');
  412. let Aobj = {
  413. assigneeId: item.id,
  414. quantity: item.quantity,
  415. weight: item.weight,
  416. startTime: item.startTime,
  417. endTime: item.endTime,
  418. assigneeType: row.assignType,
  419. assigneeName: item.name,
  420. measuringUnit: this.current.measuringUnit,
  421. isNew: item.isNew ? item.isNew : '',
  422. deviceId:
  423. item.extInfo && item.extInfo.assetId ? item.extInfo.assetId : '',
  424. deviceName:
  425. item.extInfo && item.extInfo.assetName
  426. ? item.extInfo.assetName
  427. : '',
  428. workStationId: item.id,
  429. workStationName: item.name
  430. };
  431. if (item.teamTimeIds) {
  432. Aobj.teamTimeIds = item.teamTimeIds;
  433. }
  434. assignees.push(Aobj);
  435. changeIds.push(item.changeId);
  436. });
  437. // 校验没过 就不往下进行
  438. if (!flag) {
  439. this.$message.warning('请将所选数据的 数量,开始时间,完成时间 填写完毕');
  440. return;
  441. }
  442. let data = null;
  443. if (type == 2) {
  444. data = changeIds;
  445. } else {
  446. data = {
  447. taskId: this.processId,
  448. taskName: row.name,
  449. taskCode: row.code,
  450. teamName: this.form.teamName,
  451. teamId: this.form.teamId,
  452. workCenterId: this.form.workCenterId,
  453. workCenterName: this.form.workCenterName,
  454. workOrderId: this.current.id,
  455. dispatchMethod: 0,
  456. assignees
  457. };
  458. // 先判断是否派单过 有的话直接用前面派单的 类型数据 否则就是自己选择的数据
  459. if (this.isDispatchRow.hasExists) {
  460. data.dispatchType = this.isDispatchRow.dispatchType;
  461. } else {
  462. let singFlag = this.singleReportRadio();
  463. if (!singFlag) return;
  464. data.dispatchType = this.form.singleReport;
  465. }
  466. }
  467. this.toolbarLoading = true;
  468. const api =
  469. type == 1 ? taskAssignment : type == 2 ? taskRevoked : taskSave;
  470. api(data)
  471. .then((res) => {
  472. this.toolbarLoading = false;
  473. if (res) {
  474. this.$message.success('操作成功');
  475. // 更改当前表格数据
  476. this.setCurrentTab(row);
  477. // 查询是否派单
  478. this.queryCheckExists();
  479. }
  480. })
  481. .catch((err) => {
  482. this.toolbarLoading = false;
  483. this.$message.error(err.message);
  484. });
  485. },
  486. //添加工位
  487. addStation(item, index) {
  488. console.log(item, index);
  489. this.$refs.chooseStationRef.open(
  490. this.form.workCenterId,
  491. item.list,
  492. index
  493. );
  494. },
  495. chooseStationList(list, index) {
  496. const process = this.processList?.[index];
  497. if (!process) {
  498. console.warn(`processList[${index}] 不存在`);
  499. return;
  500. }
  501. const oldList = structuredClone(
  502. Array.isArray(process.list) ? process.list : []
  503. );
  504. list.forEach((item) => {
  505. item.isNew = 1;
  506. item.assetCode = item.extInfo.assetCode;
  507. item.assetId = item.extInfo.assetId;
  508. item.assetName = item.extInfo.assetName;
  509. });
  510. console.log(list, '选择的工位数据');
  511. const newList = structuredClone(Array.isArray(list) ? list : []);
  512. this.$set(this.processList[index], 'list', [...oldList, ...newList]);
  513. },
  514. cancel() {
  515. this.$emit('update:dispatchVisible', false);
  516. },
  517. // 按钮操作成功后 更改当前的表格数据
  518. setCurrentTab(row) {
  519. let arr = [];
  520. if (row.assignType == 1) {
  521. arr = this.stationList;
  522. } else if (row.assignType == 2) {
  523. arr = this.crewList;
  524. } else {
  525. arr = this.productionList;
  526. }
  527. this.getAssignData(row.index, arr);
  528. },
  529. singleReportRadio() {
  530. if (this.form.singleReport === 0 || this.form.singleReport === 1) {
  531. return true;
  532. }
  533. this.$message.warning('请先选择报工类型');
  534. return false;
  535. },
  536. // 最后提交
  537. async confirm() {
  538. let flag = this.singleReportRadio();
  539. if (!flag) return;
  540. // if (!this.form.singleReport) {
  541. // }
  542. if (!this.form.teamId) {
  543. this.$message.warning('请先选择班组');
  544. return;
  545. }
  546. let permissionRes = await parameterGetByCode({
  547. code: 'production_order_dispatch_permission'
  548. });
  549. this.processingRequired = permissionRes.value || 0; // 兜底:若接口返回空,默认设为 0
  550. console.log(this.processingRequired);
  551. if (this.processingRequired == '1') {
  552. try {
  553. const isTeamLeader = await getcheckLoginUserIsTeamLeader(
  554. this.form.teamId
  555. );
  556. if (!isTeamLeader) {
  557. this.toolbarLoading = false;
  558. this.$message.warning('当前班组不是对应组长');
  559. return; // 校验不通过,终止后续流程
  560. }
  561. } catch (err) {
  562. this.toolbarLoading = false;
  563. this.$message.error('校验组长身份失败:' + err.message);
  564. return; // 校验报错,终止后续流程
  565. }
  566. }
  567. if (this.form.taskAss == 1) {
  568. this.issue();
  569. // 按原来的逻辑
  570. return;
  571. }
  572. // 获取到首工序id 的 绑定表格数据
  573. let data = this.processList[this.firstTaskindex];
  574. // 是否进行首工序派单
  575. let isFirstDispatch = false;
  576. let dispatchArr = []; // 已派单数据
  577. data.list.map((item) => {
  578. if (!item.status) {
  579. return;
  580. }
  581. if (item.status.code == 1) {
  582. isFirstDispatch = true;
  583. dispatchArr.push(item.id);
  584. }
  585. });
  586. // 判断是否进行首工序派单
  587. if (!isFirstDispatch) {
  588. this.$message.warning(`请您先进行首工序任务(${data.name}工序)派单`);
  589. this.handleClick({ name: data.id });
  590. return;
  591. }
  592. let totalSum = 0;
  593. // 判断派单的数据 数量相加是否为 要求生产数量
  594. data.list.map((item) => {
  595. if (item.status && item.status.code == 1) {
  596. totalSum += item.quantity - 0;
  597. }
  598. });
  599. // if (totalSum != this.current.formingNum - 0) {
  600. // this.$message.warning(
  601. // `首工序已派单的数据数量相加需要等于要求生产数量${this.current.formingNum}`
  602. // );
  603. // this.handleClick({ name: data.id });
  604. // return;
  605. // }
  606. this.toolbarLoading = true;
  607. let params = {
  608. teamId: this.form.teamId,
  609. workCenterId: this.form.workCenterId,
  610. workOrderId: this.current.id
  611. };
  612. try {
  613. const res = await checkAssignConfirm(params);
  614. if (!res) {
  615. this.toolbarLoading = false;
  616. return;
  617. }
  618. let paramsD = {
  619. assignType: data.assignType,
  620. singleReport: this.form.singleReport,
  621. teamId: this.form.teamId,
  622. crewIds: data.assignType == 2 ? dispatchArr : [], // 人员 2
  623. workstationIds: data.assignType == 1 ? dispatchArr : [], // 工位 1
  624. id: this.current.id,
  625. planStartTime: this.current.planStartTime,
  626. planEndTime: this.current.planEndTime
  627. };
  628. const response = await releaseWorkOrder(paramsD);
  629. this.toolbarLoading = false;
  630. if (response) {
  631. this.$message.success('操作成功');
  632. this.cancel();
  633. this.$emit('createSuccess');
  634. }
  635. } catch (err) {
  636. this.toolbarLoading = false;
  637. // this.$message.error(err.message);
  638. }
  639. },
  640. // 下达
  641. issue() {
  642. if (this.form.assignType == 1) {
  643. if (!this.form.workstationIds || this.form.workstationIds.length == 0) {
  644. this.$message.warning('请选择工位数据');
  645. return;
  646. }
  647. }
  648. if (this.form.assignType == 3) {
  649. if (!this.form.factoryLineIds || this.form.factoryLineIds.length == 0) {
  650. this.$message.warning('请选择产线数据');
  651. return;
  652. }
  653. }
  654. let data = {
  655. assignType: this.form.assignType,
  656. singleReport: this.form.singleReport,
  657. teamId: this.form.teamId,
  658. crewIds: [],
  659. workstationIds: [],
  660. id: this.current.id,
  661. planStartTime: this.current.planStartTime,
  662. planCompleteTime: this.current.planCompleteTime,
  663. factoryLineIds: []
  664. };
  665. if (this.form.assignType == 1) {
  666. data.workstationIds = this.form.workstationIds || [];
  667. } else if (this.form.assignType == 2) {
  668. data.crewIds = this.form.crewIds || [];
  669. } else {
  670. data.factoryLineIds = this.form.factoryLineIds || [];
  671. }
  672. this.toolbarLoading = true;
  673. releaseWorkOrder(data)
  674. .then((res) => {
  675. this.toolbarLoading = false;
  676. if (res) {
  677. this.$message.success('操作成功');
  678. this.cancel();
  679. this.$emit('createSuccess');
  680. }
  681. })
  682. .catch((err) => {
  683. this.toolbarLoading = false;
  684. // this.$message.error(err.message);
  685. });
  686. },
  687. // 工序选择
  688. async handleClick(tab) {
  689. let id = tab.name;
  690. this.processId = id;
  691. this.isTask = false;
  692. await this.FirstTaskIdFn(id);
  693. let data = this.processList.find((item) => item.id == this.processId);
  694. await this.changeRadio(data.assignType, data.index);
  695. },
  696. // 指派选择
  697. async changeRadio(e, index) {
  698. let data = this.processList[index];
  699. if (e == 1) {
  700. this.dynamicName = '工位名称';
  701. data.assignName = '工位';
  702. await this.getAssignData(index, this.stationList);
  703. } else if (e == 2) {
  704. this.dynamicName = '人员名称';
  705. data.assignName = '人员';
  706. await this.getAssignData(index, this.crewList);
  707. } else {
  708. this.dynamicName = '产线名称';
  709. data.assignName = '产线';
  710. await this.getAssignData(index, this.productionList);
  711. }
  712. },
  713. // 指派数据处理
  714. async getAssignData(index, arr) {
  715. let list = JSON.parse(JSON.stringify(arr));
  716. let dataRow = this.processList[index];
  717. // 不存在 班组数据的话 就不调用这个方法
  718. if (!this.form.teamId) {
  719. return;
  720. }
  721. let params = {
  722. workOrderId: this.current.id,
  723. workCenterId: this.form.workCenterId,
  724. teamId: this.form.teamId,
  725. taskId: dataRow.id
  726. };
  727. this.tabLoading = true;
  728. try {
  729. const res = await listAssign(params);
  730. this.tabLoading = false;
  731. // 如果 res 没有数据 说明未对数据进行操作 直接赋值
  732. if (res.length == 0) {
  733. this.$set(dataRow, 'list', list);
  734. return;
  735. }
  736. // 对有操作过的数据进行赋值
  737. this.operationalData(index, res, list);
  738. } catch (err) {
  739. this.tabLoading = false;
  740. this.$message.warning(err.message);
  741. }
  742. },
  743. // 操作过的数据 赋值
  744. operationalData(index, res, list) {
  745. const dataRow = this.processList[index];
  746. // 键值对存储 当前工序 操作的数据 指派的code(键) 数据(list:值)
  747. let arrMap = {};
  748. // 要先判断有没有操作的数据 如果有的话 其它的指派操作置灰
  749. let codeT = null; // 表示有已操作的数据(对应的 code)
  750. res[0].assignees.map((el) => {
  751. let code = el.assigneeType.code;
  752. if (arrMap[code]) {
  753. arrMap[code].arr.push(el);
  754. arrMap[code].bunDis = arrMap[code].bunDis
  755. ? arrMap[code].bunDis
  756. : el.status.desc
  757. ? true
  758. : false;
  759. } else {
  760. arrMap[code] = {
  761. arr: [el],
  762. bunDis: el.status.desc ? true : false
  763. };
  764. }
  765. codeT = codeT ? codeT : el.status.desc ? code : '';
  766. });
  767. let radioBun = {
  768. lineDis: false, // 产线 3
  769. staffDis: false, // 人员 2
  770. stationDis: false // 工位 1
  771. };
  772. // 默认是传递下来的 list 数据 但是如果 codeT有值 说明 工位 人员 产线 有派单数据
  773. // 需要自动切换过去
  774. let listArr = list;
  775. if (codeT) {
  776. if (codeT == 1) {
  777. radioBun.staffDis = true;
  778. radioBun.lineDis = true;
  779. radioBun.stationDis = false;
  780. listArr = JSON.parse(JSON.stringify(this.stationList));
  781. dataRow.assignType = 1;
  782. dataRow.assignName = '工位';
  783. } else if (codeT == 2) {
  784. radioBun.stationDis = true;
  785. radioBun.lineDis = true;
  786. radioBun.staffDis = false;
  787. listArr = JSON.parse(JSON.stringify(this.crewList));
  788. dataRow.assignType = 2;
  789. dataRow.assignName = '人员';
  790. } else {
  791. radioBun.stationDis = true;
  792. radioBun.staffDis = true;
  793. radioBun.lineDis = false;
  794. listArr = JSON.parse(JSON.stringify(this.productionList));
  795. dataRow.assignType = 3;
  796. dataRow.assignName = '产线';
  797. }
  798. }
  799. // 切换完后 对 指派的数组数据进行赋值
  800. let listMap = {};
  801. listArr.map((el, index) => (listMap[el.id] = index));
  802. let arrList = codeT ? arrMap[codeT].arr : res[0].assignees;
  803. dataRow.startDate = ''; // 每次计算的时候清空之前的
  804. dataRow.endDate = '';
  805. if (listArr.length == 0) return;
  806. // listArr.forEach((it) => {
  807. // if (it.disposalStatus || it.disposalStatus == 0) {
  808. arrList.map((item) => {
  809. if (item.assigneeType.code == dataRow.assignType) {
  810. let idx = listMap[item.assigneeId];
  811. if (!idx && idx !== 0) {
  812. return;
  813. }
  814. listArr[idx].status = item.status;
  815. listArr[idx].startTime = item.startTime;
  816. listArr[idx].endTime = item.endTime;
  817. listArr[idx].quantity = item.quantity;
  818. listArr[idx].weight = item.weight;
  819. listArr[idx].changeId = item.id;
  820. listArr[idx].teamTimeIds = item.teamTimeIds;
  821. this.compareAndSetTime(listArr[idx], dataRow);
  822. this.compareEndSetTime(listArr[idx], dataRow);
  823. }
  824. });
  825. // }
  826. // });
  827. // 这里重新调用一个方法 计算出 startDate endDate
  828. this.$set(dataRow, 'list', listArr);
  829. this.$set(dataRow, 'radioBun', radioBun);
  830. this.$set(dataRow, 'selection', []);
  831. let tab = `tableRef${[dataRow.index]}`;
  832. this.$refs[tab][0].setSelectedRowKeys([]);
  833. console.log(dataRow, 'dataRow +++++');
  834. },
  835. // 时间比较与赋值方法 开始时间
  836. compareAndSetTime(data, dataRow) {
  837. // 如果startDate为空,直接赋值为startTime
  838. if (!dataRow.startDate) {
  839. dataRow.startDate = data['startTime'];
  840. return;
  841. }
  842. // 转换为Date对象进行比较
  843. const startTimeDate = new Date(data['startTime']);
  844. const startDateDate = new Date(dataRow.startDate);
  845. // 比较时间(getTime()获取时间戳)
  846. if (startTimeDate.getTime() < startDateDate.getTime()) {
  847. dataRow.startDate = data['startTime'];
  848. }
  849. },
  850. // 时间比较与赋值方法 结束时间时间
  851. compareEndSetTime(data, dataRow) {
  852. // 如果startDate为空,直接赋值为endTime
  853. if (!dataRow.endDate) {
  854. dataRow.endDate = data['endTime'];
  855. return;
  856. }
  857. // 转换为Date对象进行比较
  858. const endTimeDate = new Date(data['endTime']);
  859. const endDateDate = new Date(dataRow.endDate);
  860. // 比较时间(getTime()获取时间戳)
  861. if (endTimeDate.getTime() > endDateDate.getTime()) {
  862. dataRow.endDate = data['endTime'];
  863. }
  864. },
  865. assignRadio(e) {},
  866. // 数量正则 quantity
  867. handleQuantityInput(e, row, item) {
  868. // 过滤非数字字符(包括负号)
  869. let value = e.replace(/[^\d]/g, '');
  870. // 限制不能以 0 开头(除非是 0 本身)
  871. if (value.startsWith('0') && value.length > 1) {
  872. value = value.slice(1);
  873. }
  874. // 更新绑定值
  875. row.quantity = value;
  876. this.calculateQuantity(row, item);
  877. this.bringWeight(row.quantity, row);
  878. this.selectedListData(row, item);
  879. },
  880. // 自动算重量
  881. bringWeight(value, row) {
  882. if (!this.current.formingWeight) {
  883. this.$set(row, 'weight', 0);
  884. return;
  885. }
  886. let weight =
  887. (this.current.formingWeight / this.current.formingNum) * value;
  888. if (weight > 0) {
  889. weight = weight.toFixed(4) - 0;
  890. }
  891. this.$set(row, 'weight', weight);
  892. },
  893. calculateQuantity(row, item) {
  894. // 如果没有该字段 就不做判断
  895. if (!this.current.formingNum) {
  896. return;
  897. }
  898. let total = 0;
  899. item.list.forEach((el) => {
  900. if (el.quantity) {
  901. total = total + (el.quantity - 0);
  902. }
  903. });
  904. if (total > this.current.formingNum - 0) {
  905. this.$message.warning('列表数量相加不能大于目标要求生产数量');
  906. row.quantity = 0;
  907. }
  908. },
  909. // 计算重量
  910. calculateWeight(row, item) {
  911. // 如果没有该字段 就不做判断
  912. if (!this.current.formingWeight) {
  913. return;
  914. }
  915. let total = 0;
  916. item.list.forEach((el) => {
  917. if (el.weight) {
  918. total = total + (el.weight - 0);
  919. }
  920. });
  921. if (total > this.current.formingWeight - 0) {
  922. this.$message.warning('列表数量相加不能大于目标要求生产数量');
  923. row.weight = 0;
  924. }
  925. },
  926. // 重量正则 weight
  927. handleWeightInput(e, row, item) {
  928. // 过滤非数字和非小数点字符(包括负号)
  929. let value = e.replace(/[-+^\d.]/g, '');
  930. value = e.replace(/[^\d.]/g, '');
  931. // 限制只能有一个小数点
  932. const dotCount = (value.match(/\./g) || []).length;
  933. if (dotCount > 1) {
  934. value = value.slice(0, value.lastIndexOf('.'));
  935. }
  936. // 限制不能以小数点开头
  937. if (value.startsWith('.')) {
  938. value = '0' + value;
  939. }
  940. // 更新绑定值
  941. row.weight = value;
  942. this.calculateWeight(row, item);
  943. this.selectedListData(row, item);
  944. },
  945. // 选中班次
  946. shiftSelection(e, row, item) {
  947. // this.$refs.tableRef0[0].setSelectedRowKeys(row.id);
  948. // let data = this.shiftList.find((item) => item.id == e);
  949. // this.selectedListData(row, item);
  950. let data = this.shifTimeData(e, row);
  951. let startTime = `${this.dateValue} ${data.startTime}` + `:00`;
  952. let endTime = `${this.dateValue} ${data.endTime}` + `:00`;
  953. this.$set(row, 'startTime', startTime);
  954. this.$set(row, 'endTime', endTime);
  955. this.handleStartTimeChange(row, item);
  956. this.handleEndTimeChange(row, item);
  957. },
  958. // 默认选中当前更改数据
  959. selectedListData(row, item) {
  960. let data = item.selection.find((el) => el.id == row.id);
  961. if (!data) {
  962. let ids = item.selection.map((el) => el.id);
  963. ids.push(row.id);
  964. let tab = `tableRef${[item.index]}`;
  965. this.$refs[tab][0].setSelectedRowKeys(ids);
  966. }
  967. },
  968. // 多选班次时间数据
  969. shifTimeData(e, row) {
  970. if (!e || e.length == 0) {
  971. return {
  972. startTime: row.startTime,
  973. endTime: row.endTime
  974. };
  975. }
  976. let startTime = '';
  977. let endTime = '';
  978. e.map((el) => {
  979. let obj = this.shiftList.find((item) => item.id == el);
  980. if (!startTime) {
  981. startTime = obj.startTime;
  982. }
  983. if (!endTime) {
  984. endTime = obj.endTime;
  985. }
  986. // 获取更小的
  987. startTime =
  988. this.compareTime(startTime, obj.startTime) !== -1
  989. ? obj.startTime
  990. : startTime;
  991. // 获取更大的
  992. endTime =
  993. this.compareTime(endTime, obj.endTime) !== 1 ? obj.endTime : endTime;
  994. });
  995. return {
  996. startTime,
  997. endTime
  998. };
  999. },
  1000. // 将HH:mm:ss格式的时间转换为总秒数
  1001. timeToSeconds(timeStr) {
  1002. const [hours, minutes, seconds] = timeStr.split(':').map(Number);
  1003. return hours * 3600 + minutes * 60 + seconds;
  1004. },
  1005. // this.$refs.table.setSelectedRowKeys(ids);
  1006. // 比较两个时间的大小
  1007. compareTime(time1, time2) {
  1008. const sec1 = this.timeToSeconds(time1);
  1009. const sec2 = this.timeToSeconds(time2);
  1010. if (sec1 > sec2) {
  1011. return 1; // time1 更大
  1012. } else if (sec1 < sec2) {
  1013. return -1; // time2 更大
  1014. } else {
  1015. return 0; // 两个时间相等
  1016. }
  1017. },
  1018. // 【开始时间变化时】触发
  1019. handleStartTimeChange(row, item) {
  1020. if (!row.startTime) {
  1021. return;
  1022. }
  1023. this.selectedListData(row, item);
  1024. // 这一道工序的开始时间 不能小于前一道工序的结束时间
  1025. const startTime = new Date(row.startTime); // 开始时间
  1026. if (item.index !== 0) {
  1027. // let frontIdx = item.index - 1;
  1028. let frontIdx = this.calculateIndex(item.index).startIdx;
  1029. if (frontIdx !== 'none') {
  1030. let frontName = this.processList[frontIdx].name;
  1031. let time = this.processList[frontIdx].endDate;
  1032. const frontTime = new Date(time); // 前面工序的结束时间
  1033. if (time && startTime < frontTime) {
  1034. this.$message.closeAll();
  1035. this.$message.info(
  1036. `开始时间不能小于前面工序${frontName}的结束时间${time}`
  1037. );
  1038. // 判断是否 配置时间更改规则
  1039. if (this.time_calc_code == '1') {
  1040. row.startTime = time;
  1041. }
  1042. return;
  1043. }
  1044. }
  1045. }
  1046. // 这一道工序的开始时间更不能大于后一道工序的开始时间
  1047. if (item.index !== this.processList.length - 1) {
  1048. // let latterIdx = item.index + 1;
  1049. let latterIdx = this.calculateIndex(item.index).endIdx;
  1050. if (latterIdx !== 'none') {
  1051. let time = this.processList[latterIdx].startDate;
  1052. let latterName = this.processList[latterIdx].name;
  1053. const latterTime = new Date(time); // 下一道工序的结束时间
  1054. if (time && startTime > latterTime) {
  1055. this.$message.closeAll();
  1056. this.$message.info(
  1057. `开始时间不能大于后面工序${latterName}的开始时间${time}`
  1058. );
  1059. // 判断是否 配置时间更改规则
  1060. if (this.time_calc_code == '1') {
  1061. row.startTime = '';
  1062. }
  1063. return;
  1064. }
  1065. }
  1066. }
  1067. // 校验 是否 大于结束时间 wda
  1068. this.checkEndTimeValid(row);
  1069. },
  1070. // 当更改一个工序开始时间 结束时间的时候
  1071. // 开始时间 不能小于之前工序的结束时间 ( 要先去上一道工序找 是否存在结束时间 不存在就再往前找 直到 第一道工序 )
  1072. // 结束时间 不能大于后面工序的开始时间 ( 要先去后一道工序找 是否存在开始时间 不存在就再往后找 直到 最后一道工序 )
  1073. // 计算出当前下标数据 的前后 有 开始时间 结束时间的数据下标
  1074. calculateIndex(index) {
  1075. let startIdx = 'none';
  1076. let endIdx = 'none';
  1077. // 前面工序下标
  1078. for (let i = index - 1; i >= 0; i--) {
  1079. let row = this.processList[i];
  1080. if (row && row.endDate) {
  1081. startIdx = i;
  1082. break;
  1083. }
  1084. }
  1085. // 后面工序的下标
  1086. for (let i = index + 1; i <= this.processList.length; i++) {
  1087. let row = this.processList[i];
  1088. if (row && row.startDate) {
  1089. endIdx = i;
  1090. break;
  1091. }
  1092. }
  1093. return {
  1094. startIdx,
  1095. endIdx
  1096. };
  1097. },
  1098. // 【结束时间变化时】触发
  1099. handleEndTimeChange(row, item) {
  1100. if (!row.endTime) {
  1101. return;
  1102. }
  1103. this.selectedListData(row, item);
  1104. const endTime = new Date(row.endTime); // 结束时间
  1105. // 当前工序的结束时间 不能大于后一道工序的开始时间
  1106. if (item.index !== this.processList.length - 1) {
  1107. let latterIdx = this.calculateIndex(item.index).endIdx;
  1108. if (latterIdx !== 'none') {
  1109. let latterName = this.processList[latterIdx].name;
  1110. let time = this.processList[latterIdx].startDate;
  1111. const latterTime = new Date(time); // 后面工序的开始时间
  1112. if (time && endTime > latterTime) {
  1113. this.$message.closeAll();
  1114. this.$message.info(
  1115. `结束时间不能大于后面工序${latterName}的开始时间${time}`
  1116. );
  1117. // 判断是否 配置时间更改规则
  1118. if (this.time_calc_code == '1') {
  1119. row.endTime = time;
  1120. }
  1121. return;
  1122. }
  1123. }
  1124. }
  1125. // 这一道工序的开始时间更不能小于于前一道工序的结束时间
  1126. if (item.index !== 0) {
  1127. let frontIdx = this.calculateIndex(item.index).startIdx;
  1128. if (frontIdx !== 'none') {
  1129. let frontName = this.processList[frontIdx].name;
  1130. let time = this.processList[frontIdx].endDate;
  1131. const frontTime = new Date(time); // 上一道工序的结束时间
  1132. if (time && endTime < frontTime) {
  1133. this.$message.closeAll();
  1134. this.$message.info(
  1135. `结束时间不能小于前面工序${frontName}的结束时间${time}`
  1136. );
  1137. // 判断是否 配置时间更改规则
  1138. if (this.time_calc_code == '1') {
  1139. row.endTime = '';
  1140. }
  1141. return;
  1142. }
  1143. }
  1144. }
  1145. this.checkEndTimeValid(row, item);
  1146. },
  1147. // 时间校验
  1148. checkEndTimeValid(row) {
  1149. const { startTime: start, endTime: end } = row;
  1150. // if (!start || !end) return; // 开始/结束时间未填,跳过
  1151. const startTime = new Date(start); // 开始时间
  1152. const endTime = new Date(end); // 结束时间
  1153. if (endTime < startTime) {
  1154. row.endTime = new Date(startTime); // 修正为开始时间
  1155. this.$message.info('结束时间不能早于开始时间,已自动设为开始时间');
  1156. }
  1157. }
  1158. }
  1159. };