index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. <template>
  2. <div class="page-container row-container">
  3. <!-- 左侧区域 -->
  4. <section class="list-part-container" style="flex: 3">
  5. <!-- 搜索区 -->
  6. <el-form
  7. class="list-search-container"
  8. :model="queryDayworkParams"
  9. ref="queryRef"
  10. :inline="true"
  11. style="margin-right: 0px"
  12. >
  13. <el-form-item class="section-title" label="生产批次" />
  14. <el-form-item label="生产计划单号:">
  15. <el-input
  16. placeholder="请输入生产计划单号/批次号"
  17. v-model.trim="queryDayworkParams.productionPlanNo"
  18. @keydown.enter.prevent
  19. clearable
  20. style="width: 200px"
  21. />
  22. </el-form-item>
  23. <el-form-item label="产品描述:">
  24. <el-input
  25. placeholder="请输入产品描述"
  26. v-model.trim="queryDayworkParams.productDescription"
  27. @keydown.enter.prevent
  28. clearable
  29. style="width: 130px"
  30. />
  31. </el-form-item>
  32. <el-form-item class="section-title" label="请选择当前工段:">
  33. <el-select-v2
  34. v-model="queryDayworkParams.deptId"
  35. :options="deptList"
  36. placeholder="请选择工段"
  37. style="width: 140px"
  38. @change="handleDeptChange"
  39. />
  40. </el-form-item>
  41. <el-form-item style="margin-left: 0">
  42. <el-button
  43. type="info"
  44. icon="Search"
  45. :disabled="deptList.length === 0"
  46. @click="handleQuery"
  47. >搜索
  48. </el-button>
  49. </el-form-item>
  50. </el-form>
  51. <div class="el-table-container">
  52. <div class="el-table-inner-container">
  53. <el-table
  54. ref="dayworkTable"
  55. :data="dayworkList"
  56. v-loading="dayworkLoading"
  57. highlight-current-row
  58. height="100%"
  59. @current-change="handleDayworkCurrentChange"
  60. >
  61. <el-table-column
  62. label="客户简称"
  63. prop="companyAlias"
  64. width="120"
  65. align="center"
  66. />
  67. <el-table-column
  68. label="生产计划单号"
  69. prop="productionPlanNo"
  70. width="100"
  71. align="center"
  72. />
  73. <el-table-column
  74. label="批次号"
  75. min-width="120"
  76. prop="lotCode"
  77. align="center"
  78. >
  79. <template #default="scope">
  80. <el-button
  81. link
  82. type="primary"
  83. v-hasPermi="['business:productionPlan:query']"
  84. @click="handleColumnClick(scope.row)"
  85. ><span>{{ scope.row.lotCode }}</span></el-button
  86. >
  87. </template>
  88. </el-table-column>
  89. <el-table-column
  90. label="产品描述"
  91. prop="productDescription"
  92. align="center"
  93. />
  94. <el-table-column
  95. label="图纸版本"
  96. prop="technologyVersion"
  97. width="60"
  98. align="center"
  99. />
  100. <el-table-column
  101. label="投产量"
  102. prop="productionQuantity"
  103. width="60"
  104. align="center"
  105. />
  106. <el-table-column
  107. label="下达日期"
  108. prop="createTime"
  109. width="100"
  110. align="center"
  111. >
  112. <template #default="scope">
  113. <span>{{
  114. proxy.moment(scope.row.createTime).format("YYYY-MM-DD")
  115. }}</span>
  116. </template>
  117. </el-table-column>
  118. <el-table-column
  119. label="报工总时长"
  120. prop="totalWorkingHours"
  121. width="150"
  122. align="center"
  123. />
  124. </el-table>
  125. </div>
  126. </div>
  127. <!-- 分页 -->
  128. <pagination
  129. v-show="total > 0"
  130. :total="total"
  131. v-model:page="queryDayworkParams.pageNum"
  132. v-model:limit="queryDayworkParams.pageSize"
  133. @pagination="getDayworks"
  134. />
  135. </section>
  136. <!-- 右侧区域 -->
  137. <section class="list-part-container" style="flex: 2">
  138. <el-form class="list-search-container" :inline="true">
  139. <el-form-item class="section-title" label="报工信息" />
  140. <el-form-item
  141. class="section-title"
  142. label="请选择工序:"
  143. prop="processId"
  144. >
  145. <el-select-v2
  146. v-model="queryItemParams.processId"
  147. clearable
  148. :options="processList"
  149. placeholder="请选择工序"
  150. style="width: 100%"
  151. @change="handleProcessChange"
  152. />
  153. </el-form-item>
  154. </el-form>
  155. <div class="el-table-container">
  156. <div class="el-table-inner-container">
  157. <el-table
  158. :data="dayworkItemList"
  159. v-loading="dayworkItemLoading"
  160. height="100%"
  161. >
  162. <el-table-column
  163. label="操作者"
  164. prop="nickName"
  165. width="60"
  166. align="center"
  167. />
  168. <el-table-column
  169. label="工序名称"
  170. prop="processAlias"
  171. align="center"
  172. />
  173. <el-table-column
  174. label="投产量"
  175. prop="prodNum"
  176. width="60"
  177. align="center"
  178. />
  179. <el-table-column
  180. label="合格数"
  181. prop="qualifiedNum"
  182. width="60"
  183. align="center"
  184. />
  185. <el-table-column
  186. label="废品数"
  187. prop="rejectNum"
  188. width="60"
  189. align="center"
  190. />
  191. <el-table-column
  192. label="开始时间"
  193. prop="startTime"
  194. width="160"
  195. align="center"
  196. />
  197. <el-table-column
  198. label="结束时间"
  199. prop="endTime"
  200. width="160"
  201. align="center"
  202. />
  203. <el-table-column
  204. label="总工时"
  205. prop="workingHours"
  206. width="160"
  207. align="center"
  208. />
  209. <el-table-column
  210. label="生产状态"
  211. prop="status"
  212. width="100"
  213. align="center"
  214. >
  215. <template #default="scope">
  216. <dict-tag :options="daywork_status" :value="scope.row.status" />
  217. </template>
  218. </el-table-column>
  219. <el-table-column
  220. fixed="right"
  221. label="操作"
  222. align="center"
  223. width="140px"
  224. >
  225. <template #default="scope">
  226. <el-button
  227. v-if="
  228. scope.row.deptProcessStatus &&
  229. (scope.row.status == 2 || scope.row.status == 3) &&
  230. scope.row.processId == latestProcessId
  231. "
  232. link
  233. type="warning"
  234. icon="Edit"
  235. @click="handleUpdateDayworkItem(scope.row)"
  236. >编辑
  237. </el-button>
  238. <el-button
  239. v-else
  240. link
  241. type="primary"
  242. icon="View"
  243. @click="handleCheckDayworkItem(scope.row)"
  244. >查看
  245. </el-button>
  246. <el-button
  247. v-hasPermi="['business:daywork:remove']"
  248. v-if="
  249. scope.row.deptProcessStatus &&
  250. (scope.row.status == 2 || scope.row.status == 3) &&
  251. scope.row.processId == latestProcessId
  252. "
  253. link
  254. type="danger"
  255. icon="Delete"
  256. @click="handleDeletedItem(scope.row.id)"
  257. >删除
  258. </el-button>
  259. </template>
  260. </el-table-column>
  261. </el-table>
  262. </div>
  263. </div>
  264. <!-- 分页 -->
  265. <pagination
  266. v-show="itemTotal > 0"
  267. :total="itemTotal"
  268. v-model:page="queryItemParams.pageNum"
  269. v-model:limit="queryItemParams.pageSize"
  270. @pagination="getDayworkItems"
  271. />
  272. </section>
  273. <!-- 报工信息表单 -->
  274. <daywork-item-form
  275. ref="dayworkItemRef"
  276. @handleSaveSuccess="handleGetDayworkItems"
  277. />
  278. </div>
  279. </template>
  280. <script setup>
  281. import {
  282. listDaywork,
  283. listDayworkItem,
  284. getProcessList,
  285. delDayworkItem
  286. } from "@/api/business/daywork.js";
  287. import { listDeptProcess } from "@/api/business/deptProcess";
  288. import { getDept } from "@/api/business/planDetailSubDetail.js";
  289. import router from "@/router";
  290. import dayworkItemForm from "./form";
  291. const { proxy } = getCurrentInstance();
  292. /** 字典 */
  293. const { daywork_status } = proxy.useDict("daywork_status");
  294. /** 生产批次 */
  295. const dayworkList = ref([]);
  296. const dayworkTable = ref(null);
  297. const currentDaywork = ref({});
  298. const dayworkLoading = ref(false);
  299. const total = ref(0);
  300. /**工段 */
  301. const deptList = ref([]);
  302. const loading = ref(false);
  303. /** 报工信息 */
  304. const dayworkItemList = ref([]);
  305. const dayworkItemLoading = ref(false);
  306. const itemTotal = ref(0);
  307. const latestProcessId = ref(null);
  308. const deptProcessList = ref([]);
  309. /**工序 */
  310. const processList = ref([]);
  311. /** 查询对象 */
  312. const queryDayworkParams = ref({
  313. productDescription: "",
  314. deptId: "",
  315. lotCode: "",
  316. pageNum: 1,
  317. pageSize: 10,
  318. });
  319. const queryItemParams = ref({
  320. dayworkId: "0",
  321. isAmend: 0,
  322. isWasteRecycling: 0,
  323. pageNum: 1,
  324. pageSize: 10,
  325. technologicalProcessDetailId: null,
  326. });
  327. /*********************** 工段相关事件 ****************************/
  328. function getList() {
  329. loading.value = true;
  330. getDept().then((response) => {
  331. deptList.value = response.data;
  332. loading.value = false;
  333. if (deptList.value.length > 0) {
  334. queryDayworkParams.value.deptId = deptList.value[0].value;
  335. getDayworks();
  336. } else {
  337. dayworkList.value = [];
  338. }
  339. });
  340. }
  341. //切换工段
  342. function handleDeptChange() {
  343. getDayworks();
  344. }
  345. /*********************** 生产批次相关事件 ****************************/
  346. /** 查询计划明细 */
  347. function getDayworks() {
  348. dayworkLoading.value = true;
  349. listDaywork(queryDayworkParams.value).then((res) => {
  350. dayworkList.value = res.rows;
  351. for (var i = 0; i < dayworkList.value.length; i++) {
  352. let timeStamp = dayworkList.value[i].totalWorkingHours;
  353. let seconds = Math.floor((timeStamp / 1000) % 60);
  354. let minutes = Math.floor((timeStamp / (1000 * 60)) % 60);
  355. let hours = Math.floor(timeStamp / (1000 * 60 * 60));
  356. let time = `${hours}小时${minutes}分钟${seconds}秒`;
  357. dayworkList.value[i].totalWorkingHours = time;
  358. }
  359. total.value = res.total;
  360. dayworkLoading.value = false;
  361. // 批次
  362. if (dayworkList.value.length > 0) {
  363. proxy.$refs.dayworkTable.setCurrentRow(dayworkList.value[0]);
  364. } else {
  365. dayworkItemList.value = [];
  366. itemTotal.value = 0;
  367. }
  368. });
  369. }
  370. /** 打开批次详情页 */
  371. function handleColumnClick(row) {
  372. router.push({ path: "/reviseBath/lotFormParticulars/" + row.lotCode });
  373. }
  374. /** 生产计划明细 current-change 事件 */
  375. function handleDayworkCurrentChange(row) {
  376. if (row) {
  377. queryItemParams.value.processId = null;
  378. currentDaywork.value = row;
  379. queryItemParams.value.dayworkId = currentDaywork.value.id;
  380. queryItemParams.value.isAmend = row.isAmend;
  381. queryItemParams.value.isWasteRecycling = row.isWasteRecycling;
  382. queryItemParams.value.technologicalProcessDetailId = null;
  383. queryItemParams.value.technologicalProcessId = row.technologicalProcessId;
  384. getDayworkItems();
  385. getProcess();
  386. } else {
  387. dayworkItemList.value = [];
  388. itemTotal.value = 0;
  389. }
  390. }
  391. /*********************** 报工信息相关事件 ****************************/
  392. //查询报工信息数据
  393. function handleGetDayworkItems() {
  394. dayworkLoading.value = true;
  395. listDaywork(queryDayworkParams.value).then((res) => {
  396. dayworkList.value = res.rows;
  397. for (var i = 0; i < dayworkList.value.length; i++) {
  398. let timeStamp = dayworkList.value[i].totalWorkingHours;
  399. let seconds = Math.floor((timeStamp / 1000) % 60);
  400. let minutes = Math.floor((timeStamp / (1000 * 60)) % 60);
  401. let hours = Math.floor(timeStamp / (1000 * 60 * 60));
  402. let time = `${hours}小时${minutes}分钟${seconds}秒`;
  403. dayworkList.value[i].totalWorkingHours = time;
  404. }
  405. total.value = res.total;
  406. dayworkLoading.value = false;
  407. if (dayworkList.value.length > 0) {
  408. for (var i = 0; i < dayworkList.value.length; i++) {
  409. if (dayworkList.value[i].id == currentDaywork.value.id) {
  410. var index = i;
  411. break;
  412. }
  413. }
  414. }
  415. proxy.$refs.dayworkTable.setCurrentRow(dayworkList.value[index]);
  416. });
  417. }
  418. //删除报工信息
  419. function handleDeletedItem(id) {
  420. proxy.$modal
  421. .confirm("是否确认删除选中的数据项?")
  422. .then(function () {
  423. delDayworkItem(id).then(res =>{
  424. if(res.code == 200) {
  425. proxy.$modal.msgSuccess("删除成功")
  426. listDaywork(queryDayworkParams.value).then((res) => {
  427. dayworkList.value = res.rows;
  428. for (var i = 0; i < dayworkList.value.length; i++) {
  429. let timeStamp = dayworkList.value[i].totalWorkingHours;
  430. let seconds = Math.floor((timeStamp / 1000) % 60);
  431. let minutes = Math.floor((timeStamp / (1000 * 60)) % 60);
  432. let hours = Math.floor(timeStamp / (1000 * 60 * 60));
  433. let time = `${hours}小时${minutes}分钟${seconds}秒`;
  434. dayworkList.value[i].totalWorkingHours = time;
  435. }
  436. total.value = res.total;
  437. // 批次
  438. proxy.$refs.dayworkTable.setCurrentRow(dayworkList.value[dayworkList.value.findIndex(daywork => daywork.id== currentDaywork.value.id)]);
  439. });
  440. }
  441. })
  442. })
  443. }
  444. //修改报工信息
  445. function handleUpdateDayworkItem(row) {
  446. //同工序下状态是否有工序已完成
  447. let processFinish = false;
  448. //除了编辑此条以外的同工序合格数
  449. let totalQuailifiedNum = 0;
  450. for (let i = 0; i < dayworkItemList.value.length; i++) {
  451. if (
  452. row.processId == dayworkItemList.value[i].processId &&
  453. (dayworkItemList.value[i].status == 2 ||
  454. dayworkItemList.value[i].status == 3) &&
  455. row.id != dayworkItemList.value[i].id
  456. ) {
  457. totalQuailifiedNum += dayworkItemList.value[i].qualifiedNum;
  458. }
  459. if (
  460. row.processId == dayworkItemList.value[i].processId &&
  461. dayworkItemList.value[i].status == 3 &&
  462. row.id != dayworkItemList.value[i].id
  463. ) {
  464. processFinish = true;
  465. }
  466. }
  467. let maxQuailifiedNum =
  468. Math.floor(row.prodNum * 1.03 - totalQuailifiedNum) > 0
  469. ? Math.floor(row.prodNum * 1.03 - totalQuailifiedNum)
  470. : 0;
  471. //该daywork合格数总数不能超过投产数的103%
  472. row.technologicalProcessId = queryItemParams.value.technologicalProcessId;
  473. row.deptId = queryDayworkParams.value.deptId;
  474. row.productionPlanDetailId = currentDaywork.value.productionPlanDetailId;
  475. row.dayworkId = currentDaywork.value.id;
  476. row.lotId = currentDaywork.value.lotId;
  477. row.isAmend = currentDaywork.value.isAmend;
  478. row.isWasteRecycling = currentDaywork.value.isWasteRecycling;
  479. row.maxQuailifiedNum = maxQuailifiedNum;
  480. row.totalQuailifiedNum = totalQuailifiedNum;
  481. //判断是否是当前工段
  482. if (row.deptId == currentDaywork.value.deptId) {
  483. row.currentDept = true;
  484. } else {
  485. row.currentDept = false;
  486. }
  487. //修改向form表单传一个状态值
  488. row.editStatus = true;
  489. //如果为true,则同工序已有工序已完成
  490. row.processFinish = processFinish;
  491. proxy.$refs.dayworkItemRef.open(row);
  492. }
  493. //查看报工信息
  494. function handleCheckDayworkItem(row) {
  495. row.technologicalProcessId = queryItemParams.value.technologicalProcessId;
  496. row.deptId = queryDayworkParams.value.deptId;
  497. row.productionPlanDetailId = currentDaywork.value.productionPlanDetailId;
  498. row.isAmend = currentDaywork.value.isAmend;
  499. row.isWasteRecycling = currentDaywork.value.isWasteRecycling;
  500. row.dayworkId = currentDaywork.value.id;
  501. row.lotId = currentDaywork.value.lotId;
  502. //判断是否是当前工段
  503. if (row.deptId == currentDaywork.value.deptId) {
  504. row.currentDept = true;
  505. } else {
  506. row.currentDept = false;
  507. }
  508. //修改向form表单传一个状态值
  509. row.editStatus = false;
  510. // row.returnFlag = false;
  511. // //如果是最新工序的已接收,则传一个状态值,给form表单一个退回按钮
  512. // if (row.processId == latestProcessId.value && row.status == 7) {
  513. // row.returnFlag = true;
  514. // }
  515. proxy.$refs.dayworkItemRef.open(row);
  516. }
  517. /**切换工序 */
  518. function handleProcessChange() {
  519. getDayworkItems();
  520. }
  521. /** 报工详情列表 */
  522. function getDayworkItems() {
  523. dayworkItemLoading.value = true;
  524. //查询该工段在工段资源分配时绑定的工序,传一个flag,如果flag有值则后端查询不分页
  525. listDeptProcess({ deptId: queryDayworkParams.value.deptId, flag: 1 }).then(
  526. (res) => {
  527. deptProcessList.value = res.rows;
  528. }
  529. );
  530. listDayworkItem(queryItemParams.value).then((res) => {
  531. console.log(currentDaywork.value);
  532. for (let i = 0; i < res.rows.length; i++) {
  533. //如果时首序,投产数是单批数
  534. if (res.rows[i].prodNum == 0) {
  535. if (currentDaywork.value.isLast == 1) {
  536. res.rows[i].prodNum = currentDaywork.value.lastLotQuantity;
  537. } else {
  538. res.rows[i].prodNum = currentDaywork.value.oneLotQuantity;
  539. }
  540. }
  541. //拿到最新一条报工信息的工序id,只能编辑当前序
  542. if (res.rows[i] == res.rows[res.rows.length - 1]) {
  543. latestProcessId.value = res.rows[i].processId;
  544. }
  545. }
  546. for (var i = 0; i < res.rows.length; i++) {
  547. let timeStamp = res.rows[i].workingHours;
  548. let seconds = Math.floor((timeStamp / 1000) % 60);
  549. let minutes = Math.floor((timeStamp / (1000 * 60)) % 60);
  550. let hours = Math.floor(timeStamp / (1000 * 60 * 60));
  551. let time = `${hours}小时${minutes}分钟${seconds}秒`;
  552. res.rows[i].workingHours = time;
  553. res.rows[i].deptProcessStatus = false;
  554. //报工记录的工序id是该工段绑定的工序时,允许编辑
  555. for (var item = 0; item < deptProcessList.value.length; item++) {
  556. if (res.rows[i].processId == deptProcessList.value[item].processId) {
  557. res.rows[i].deptProcessStatus = true;
  558. }
  559. }
  560. }
  561. dayworkItemList.value = res.rows;
  562. getProcess();
  563. itemTotal.value = res.total;
  564. dayworkItemLoading.value = false;
  565. });
  566. }
  567. //工序信息
  568. function getProcess() {
  569. //工序下拉框
  570. getProcessList({
  571. technologicalProcessId: queryItemParams.value.technologicalProcessId,
  572. isWasteRecycling: currentDaywork.value.isWasteRecycling,
  573. isAmend: currentDaywork.value.isAmend,
  574. lotId: currentDaywork.value.lotId,
  575. }).then((res) => {
  576. processList.value = res.data;
  577. });
  578. }
  579. /** 搜索按钮操作 */
  580. function handleQuery() {
  581. getDayworks();
  582. }
  583. onMounted(() => {
  584. getList();
  585. });
  586. </script>
  587. <style scoped>
  588. .el-form--inline .el-form-item {
  589. margin-right: 20px;
  590. }
  591. </style>