index.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170
  1. <template>
  2. <div class="pageIndexClass">
  3. <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
  4. :selectConfig="selectConfig" :action-list="[ {
  5. text: '打印任务单',
  6. action: () => openModal('add'),
  7. disabled: selectIds.length==0,
  8. }
  9. ]" :table-events="{
  10. //element talbe事件都能传
  11. select: selectRow,
  12. 'select-all':selectRow
  13. }" @get-list="getList">
  14. <template #orderCode="{ item }">
  15. <div style="width: 100%" class="el-click" @click="lookDetails(item)">
  16. {{item.orderCode}}
  17. </div>
  18. </template>
  19. <template #pic="{ item }">
  20. <div v-if="item.fileList &&item.fileList.length > 0">
  21. <img :src="item.fileList[0].fileUrl" class="pic" @click="handleClickFile(item.fileList[0])" />
  22. </div>
  23. <div v-else></div>
  24. </template>
  25. <template #picOne="{ item }">
  26. <div v-if="item.fileListOne &&item.fileListOne.length > 0">
  27. <img :src="item.fileListOne[0].fileUrl" class="pic" @click="handleClickFile(item.fileListOne[0])" />
  28. </div>
  29. <div v-else></div>
  30. </template>
  31. <template #size="{ item }">
  32. <div v-if="item.productLength && item.productWidth && item.productHeight">
  33. <span>{{ item.productLength }}</span>*
  34. <span>{{ item.productWidth }}</span>*
  35. <span>{{ item.productHeight }}</span>
  36. </div>
  37. </template>
  38. <template #isOverdue="{item}">
  39. <div style="width: 100%">
  40. <span class="red" v-if="item.isOverdue=='1'"> 逾期 </span>
  41. <span v-else> 未逾期 </span>
  42. </div>
  43. </template>
  44. <template #progress="{item}">
  45. <div style="width: 100%">
  46. <el-progress type="circle" :percentage="(Number(item.finishQuantity) / Number(item.quantity))*100" width="60"
  47. :status="(Number(item.finishQuantity) / Number(item.quantity))*100 == 100 ? 'success' : ''" />
  48. </div>
  49. </template>
  50. <template #prodTag="{ item }">
  51. <div style="width: 100%">
  52. <el-popover placement="top-start" :width="300" trigger="hover">
  53. <div>
  54. 备注:{{item.prodRemark}}
  55. </div>
  56. <template #reference>
  57. <div style="width:100%;display:inline-block">
  58. <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.prodTags" :key="index">
  59. {{ dictKeyValue(tag, contractTag) }}
  60. </el-tag>
  61. </div>
  62. </template>
  63. </el-popover>
  64. </div>
  65. </template>
  66. <template #other="{item}">
  67. <div style="width: 100%">
  68. <div>
  69. 完成:
  70. </div>
  71. <div style="border-top:1px solid #ebeef5;margin-top:3px">
  72. 结存:
  73. </div>
  74. </div>
  75. </template>
  76. <template v-for="(slotItem, index) in processesData" v-slot:[slotItem.id]="{ item }" :key="slotItem.id">
  77. <div style="width:100%">
  78. <div>
  79. <span v-if="isShowCotent(slotItem,item)" style="font-weight:700;min-width:50px;line-height:18px;display:inline-block"
  80. :class="showCotentQuantity(slotItem,item)">
  81. {{showCotent(slotItem,item,'finishQuantity')}}
  82. </span>
  83. <div v-else class="no-bk">
  84. -
  85. </div>
  86. </div>
  87. <div style="border-top:1px solid #ebeef5;margin-top:3px">
  88. <div v-if="isShowCotent(slotItem,item)">
  89. {{showCotent(slotItem,item,'balanceQuantity') || `&nbsp`}}
  90. </div>
  91. <div v-else class="no-bk">
  92. -
  93. </div>
  94. </div>
  95. </div>
  96. </template>
  97. </byTable>
  98. <el-dialog :title="'打印任务单'" v-model="dialogVisible" width="840px" destroy-on-close :before-close="beforeClose">
  99. <div style="height:calc(100vh - 280px);overflow:auto;padding: 0 10px">
  100. <div id="pdfDom" style="width:100%">
  101. <!-- <div style="font-size:20px;text-align:center">
  102. {{printData.name}}
  103. </div> -->
  104. <div v-for="item in printList" :key="item.id" style="margin-bottom:20px">
  105. <div style="font-size:32px;font-weight:700;color:#000;text-align:center">
  106. 生产任务单
  107. </div>
  108. <div style="float:right;margin: 20px 0px 5px 0;">
  109. {{printTime}}
  110. </div>
  111. <table class="table" border>
  112. <tr>
  113. <td style="width:25%">
  114. <div :ref="item.id">
  115. </div>
  116. </td>
  117. <td style="width:75%">
  118. <div style="display:flex;margin-bottom:10px">
  119. <div style="width:50%">
  120. <div class="top-title">
  121. 订单号
  122. </div>
  123. <div>
  124. {{item.orderCode}}
  125. </div>
  126. </div>
  127. <div style="width:50%">
  128. <div class="top-title">
  129. 交期
  130. </div>
  131. <div v-if="item.deliveryPeriod">
  132. {{item.deliveryPeriod.substr(0,10)}}
  133. </div>
  134. </div>
  135. </div>
  136. <div style="display:flex;margin-bottom:10px">
  137. <div style="width:50%">
  138. <div class="top-title">
  139. 产品编码
  140. </div>
  141. <div>
  142. {{item.productCode}}
  143. </div>
  144. </div>
  145. <div style="width:50%">
  146. <div class="top-title">
  147. 生产数量
  148. </div>
  149. <div>
  150. {{item.quantity}}
  151. </div>
  152. </div>
  153. </div>
  154. <div style="margin-bottom:10px">
  155. <div class="top-title">
  156. 产品名称
  157. </div>
  158. <div>
  159. {{item.productName}}
  160. </div>
  161. </div>
  162. <div style="margin-bottom:10px">
  163. <div class="top-title">
  164. 产品尺寸(cm)
  165. </div>
  166. <div>
  167. {{item.productLength}} * {{item.productWidth}} * {{item.productHeight}}
  168. </div>
  169. </div>
  170. </td>
  171. </tr>
  172. <tr>
  173. <td style="text-align:center" rowspan="4">
  174. <div>
  175. <div style="font-weight:700">产品图</div>
  176. <img v-if="item.fileList &&item.fileList.length > 0" class="bigImg" :src="item.fileList[0].fileUrl" alt="">
  177. </div>
  178. <!-- <div style="margin-top:20px">
  179. <div style="font-weight:700">设计图</div>
  180. <img v-if="item.fileListOne &&item.fileListOne.length > 0" class="bigImg" :src="item.fileListOne[0].fileUrl" alt="">
  181. </div> -->
  182. </td>
  183. <td style="height:60px;vertical-align:top">
  184. <div>
  185. <div class="top-title">
  186. 产品备注
  187. </div>
  188. <div>
  189. {{item.productRemark}}
  190. </div>
  191. </div>
  192. </td>
  193. </tr>
  194. <tr>
  195. <td style="height:60px;vertical-align:top">
  196. <div class="top-title">
  197. 生产工序
  198. </div>
  199. <div>
  200. <!-- <el-checkbox v-for="proess in item.productionTaskProgressList" :key="proess.processesId" :label="proess.progressName"
  201. size="small" /> -->
  202. <span v-for="(proess,index) in item.productionTaskProgressList" :key="proess.processesId">{{proess.progressName}} <span
  203. v-if="index<item.productionTaskProgressList.length-1"> > </span> </span>
  204. </div>
  205. </td>
  206. </tr>
  207. <tr>
  208. <td style="height:107px">
  209. <div style="margin-bottom:10px">
  210. <div class="top-title">
  211. 原材料编码
  212. </div>
  213. <div>
  214. {{item.rawMaterialCode}}
  215. </div>
  216. </div>
  217. <div>
  218. <div class="top-title">
  219. 原材料名称
  220. </div>
  221. <div>
  222. {{item.rawMaterialName}}
  223. </div>
  224. </div>
  225. </td>
  226. </tr>
  227. <tr>
  228. <td style="vertical-align:top">
  229. <div class="top-title">BOM</div>
  230. <div>
  231. <table border class="table son">
  232. <tr>
  233. <td style="width:85%">名称</td>
  234. <!-- <td style="width:15%">单价</td> -->
  235. <td style="width:15%">数量</td>
  236. </tr>
  237. <tr v-for="son in item.contractProductBomList" :key="son.id">
  238. <td>
  239. <div>
  240. {{son.productCode}}
  241. </div>
  242. <div>
  243. {{son.productName}}
  244. </div>
  245. </td>
  246. <!-- <td>{{son.price}}</td> -->
  247. <td>{{son.quantity}}</td>
  248. </tr>
  249. </table>
  250. </div>
  251. </td>
  252. </tr>
  253. </table>
  254. <div style="page-break-after: always"></div>
  255. </div>
  256. </div>
  257. </div>
  258. <template #footer>
  259. <el-button @click="dialogVisible = false" size="defualt">取 消</el-button>
  260. <el-button type="primary" v-print="printObj" size="defualt">打 印</el-button>
  261. </template>
  262. </el-dialog>
  263. <el-dialog title="备注" v-model="remarkDialog" width="500" destroy-on-close v-if="remarkDialog">
  264. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom" v-loading="submitLoading">
  265. </byForm>
  266. <template #footer>
  267. <el-button @click="remarkDialog = false" size="defualt" v-debounce>取 消</el-button>
  268. <el-button type="primary" @click="submitForm()" size="defualt" v-debounce>
  269. 确 定
  270. </el-button>
  271. </template>
  272. </el-dialog>
  273. <el-dialog title="记录查看" v-model="recordDialog" width="70%" destroy-on-close v-if="recordDialog">
  274. <el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-change="handleTabChange">
  275. <el-tab-pane label="采购记录" name="1">
  276. </el-tab-pane>
  277. <el-tab-pane label="出入库流水记录" name="2">
  278. </el-tab-pane>
  279. </el-tabs>
  280. <byForm :formConfig="recordFormConfig" :formOption="recordFormOption" v-model="formData.recordData">
  281. <template #detail1 v-if="activeName=='1'">
  282. <div style="width:100%">
  283. <el-table :data="formData.recordData.purchaseProductList">
  284. <el-table-column label="商品图片" width="80">
  285. <template #default="{ row }">
  286. <div v-if="row.fileUrl">
  287. <img :src="row.fileUrl" class="pic" @click="openImg(row.fileUrl)" />
  288. </div>
  289. </template>
  290. </el-table-column>
  291. <el-table-column prop="productCode" label="商品编码" width="160" />
  292. <el-table-column prop="productName" label="商品名称" min-width="130" />
  293. <el-table-column label="尺寸 (cm)" width="140">
  294. <template #default="{ row, $index }">
  295. <div style="width: 100%">
  296. {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
  297. </div>
  298. </template>
  299. </el-table-column>
  300. <el-table-column label="颜色" prop="productColor" width="160" />
  301. <el-table-column label="采购数量" prop="quantity" width="100" />
  302. </el-table>
  303. </div>
  304. </template>
  305. <template #detail2 v-if="activeName=='2'">
  306. <div style="width:100%">
  307. <el-table :data="formData.recordData.stockJournalDetailsList">
  308. <el-table-column label="类型" width="100" :formatter="(row) => row.opType=='1'?'入库':'出库'" />
  309. <el-table-column label="商品图片" width="80">
  310. <template #default="{ row }">
  311. <div v-if="row.fileUrl">
  312. <img :src="row.fileUrl" class="pic" @click="openImg(row.fileUrl)" />
  313. </div>
  314. </template>
  315. </el-table-column>
  316. <el-table-column prop="productCode" label="商品编码" width="160" />
  317. <el-table-column prop="productName" label="商品名称" min-width="130" />
  318. <el-table-column label="尺寸 (cm)" width="140">
  319. <template #default="{ row, $index }">
  320. <div style="width: 100%">
  321. {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
  322. </div>
  323. </template>
  324. </el-table-column>
  325. <el-table-column label="颜色" prop="productColor" width="160" />
  326. <el-table-column label="数量" prop="quantity" width="100" />
  327. </el-table>
  328. </div>
  329. </template>
  330. </byForm>
  331. <!-- <template #footer>
  332. <el-button @click="recordDialog = false" size="defualt" v-debounce>关闭</el-button>
  333. </template> -->
  334. </el-dialog>
  335. </div>
  336. </template>
  337. <script setup>
  338. import byTable from "@/components/byTable/index";
  339. import byForm from "@/components/byForm/index";
  340. import QRCode from "qrcodejs2-fix";
  341. import moment from "moment";
  342. const { proxy } = getCurrentInstance();
  343. const contractTag = computed(
  344. () => proxy.useUserStore().allDict["contract_prod_tag"]
  345. );
  346. const companyData = ref([]);
  347. const loading = ref(false);
  348. const submitLoading = ref(false);
  349. const sourceList = ref({
  350. data: [],
  351. pagination: {
  352. total: 3,
  353. pageNum: 1,
  354. pageSize: 10,
  355. keyword: "",
  356. produceStatus: "",
  357. staDeliveryPeriod: "",
  358. endDeliveryPeriod: "",
  359. beginTime: "",
  360. endTime: "",
  361. isOverdue: "",
  362. },
  363. });
  364. const treeData = ref([]);
  365. const dialogVisible = ref(false);
  366. const remarkDialog = ref(false);
  367. const modalType = ref("add");
  368. const statusData = ref([
  369. {
  370. label: "未开始",
  371. value: "0",
  372. },
  373. {
  374. label: "生产中",
  375. value: "1",
  376. },
  377. {
  378. label: "生产完成",
  379. value: "2",
  380. },
  381. {
  382. label: "出库中",
  383. value: "5",
  384. },
  385. {
  386. label: "已出库",
  387. value: "10",
  388. },
  389. ]);
  390. const isOverdueData = ref([
  391. {
  392. label: "是",
  393. value: "1",
  394. },
  395. {
  396. label: "否",
  397. value: "0",
  398. },
  399. ]);
  400. const contractTypeData = ref([
  401. {
  402. dictKey: "3",
  403. dictValue: "打样订单",
  404. },
  405. {
  406. dictKey: "2",
  407. dictValue: "内销订单",
  408. },
  409. {
  410. dictKey: "1",
  411. dictValue: "外贸订单(退税)",
  412. },
  413. {
  414. dictKey: "4",
  415. dictValue: "外贸订单(不退税)",
  416. },
  417. ]);
  418. const selectConfig = computed(() => [
  419. {
  420. label: "业务公司",
  421. prop: "contractCompanyId",
  422. data: companyData.value,
  423. isFilter: false,
  424. },
  425. {
  426. label: "工厂",
  427. prop: "companyId",
  428. data: companyData.value,
  429. },
  430. {
  431. label: "生产状态",
  432. prop: "produceStatus",
  433. data: statusData.value,
  434. },
  435. {
  436. label: "是否逾期",
  437. prop: "isOverdue",
  438. data: isOverdueData.value,
  439. },
  440. {
  441. type: "time",
  442. label: "交期",
  443. placeholder: "开始日期",
  444. prop: "staDeliveryPeriod",
  445. placeholderOne: "结束日期",
  446. propOne: "endDeliveryPeriod",
  447. },
  448. {
  449. type: "time",
  450. label: "下单日期",
  451. placeholder: "开始日期",
  452. prop: "beginTime",
  453. placeholderOne: "结束日期",
  454. propOne: "endTime",
  455. },
  456. ]);
  457. const config = ref([
  458. {
  459. type: "selection",
  460. attrs: {
  461. checkAtt: "isCheck",
  462. width: 60,
  463. },
  464. },
  465. {
  466. attrs: {
  467. label: "操作",
  468. width: "160",
  469. align: "left",
  470. // fixed: "right",
  471. },
  472. renderHTML(row) {
  473. return [
  474. {
  475. attrs: {
  476. label: "打印任务单",
  477. type: "primary",
  478. text: true,
  479. },
  480. el: "button",
  481. click() {
  482. printQrCode(row);
  483. },
  484. },
  485. {
  486. attrs: {
  487. label: "备注",
  488. type: "primary",
  489. text: true,
  490. },
  491. el: "button",
  492. click() {
  493. openRemark(row);
  494. },
  495. },
  496. ];
  497. },
  498. },
  499. {
  500. attrs: {
  501. label: "业务公司",
  502. prop: "contractCompanyName",
  503. width: 110,
  504. },
  505. },
  506. {
  507. attrs: {
  508. label: "是否逾期",
  509. slot: "isOverdue",
  510. width: 80,
  511. fixed: "left",
  512. },
  513. },
  514. {
  515. attrs: {
  516. label: "订单类型",
  517. prop: "contractType",
  518. width: 110,
  519. },
  520. render(val) {
  521. return proxy.dictKeyValue(val, contractTypeData.value);
  522. },
  523. },
  524. {
  525. attrs: {
  526. label: "工厂",
  527. prop: "companyName",
  528. width: 100,
  529. // align: "center",
  530. },
  531. },
  532. {
  533. attrs: {
  534. label: "业务员",
  535. prop: "saleUserName",
  536. width: 100,
  537. // align: "center",
  538. },
  539. },
  540. {
  541. attrs: {
  542. label: "订单号",
  543. slot: "orderCode",
  544. width: 130,
  545. },
  546. },
  547. {
  548. attrs: {
  549. label: "产品图片",
  550. slot: "pic",
  551. width: 80,
  552. },
  553. },
  554. // {
  555. // attrs: {
  556. // label: "设计图",
  557. // slot: "picOne",
  558. // width: 80,
  559. // },
  560. // },
  561. {
  562. attrs: {
  563. label: "产品编码",
  564. prop: "productCode",
  565. width: 130,
  566. },
  567. },
  568. {
  569. attrs: {
  570. label: "产品名称",
  571. prop: "productName",
  572. "min-width": 200,
  573. },
  574. },
  575. {
  576. attrs: {
  577. label: "产品尺寸 (cm)",
  578. slot: "size",
  579. width: 160,
  580. },
  581. },
  582. {
  583. attrs: {
  584. label: "产品颜色",
  585. prop: "productColor",
  586. width: 160,
  587. },
  588. },
  589. {
  590. attrs: {
  591. label: "生产件数",
  592. prop: "quantity",
  593. width: 100,
  594. },
  595. },
  596. {
  597. attrs: {
  598. label: "完成进度",
  599. slot: "progress",
  600. width: 90,
  601. },
  602. },
  603. {
  604. attrs: {
  605. label: "已完成",
  606. prop: "finishQuantity",
  607. width: 100,
  608. },
  609. },
  610. {
  611. attrs: {
  612. label: "未完成",
  613. prop: "incomplete",
  614. width: 100,
  615. },
  616. },
  617. {
  618. attrs: {
  619. label: "生产状态",
  620. prop: "produceStatus",
  621. width: 100,
  622. },
  623. render(val) {
  624. return proxy.dictValueLabel(val, statusData.value);
  625. },
  626. },
  627. {
  628. attrs: {
  629. label: "生产指示",
  630. slot: "prodTag",
  631. "min-width": 220,
  632. },
  633. },
  634. {
  635. attrs: {
  636. label: "下单时间",
  637. prop: "orderCreateTime",
  638. width: 160,
  639. },
  640. },
  641. {
  642. attrs: {
  643. label: "交期",
  644. prop: "deliveryPeriod",
  645. width: 100,
  646. },
  647. render(val) {
  648. if (val) {
  649. return val.slice(0, 10);
  650. }
  651. return "";
  652. },
  653. },
  654. // {
  655. // attrs: {
  656. // label: "投产时间",
  657. // prop: "produceTime",
  658. // width: 160,
  659. // },
  660. // },
  661. {
  662. attrs: {
  663. label: "完成时间",
  664. prop: "finishTime",
  665. width: 160,
  666. },
  667. },
  668. {
  669. attrs: {
  670. label: "生产用时",
  671. prop: "usageTime",
  672. width: 100,
  673. },
  674. },
  675. {
  676. attrs: {
  677. label: "备注",
  678. prop: "remark",
  679. "min-width": 200,
  680. },
  681. },
  682. {
  683. attrs: {
  684. label: "",
  685. slot: "other",
  686. align: "center",
  687. width: 70,
  688. fixed: "right",
  689. },
  690. },
  691. ]);
  692. const formData = reactive({
  693. data: {},
  694. recordData: {},
  695. });
  696. const formOption = reactive({
  697. inline: true,
  698. labelWidth: 100,
  699. itemWidth: 100,
  700. });
  701. const formDom = ref(null);
  702. const formConfig = computed(() => {
  703. return [
  704. {
  705. type: "input",
  706. prop: "remark",
  707. itemType: "textarea",
  708. label: "备注",
  709. itemWidth: 100,
  710. disabled: false,
  711. },
  712. ];
  713. });
  714. const rules = ref({
  715. remark: [{ required: true, message: "请输入备注", trigger: "blur" }],
  716. });
  717. const getList = async (req) => {
  718. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  719. loading.value = true;
  720. proxy
  721. .post("/produceOrderDetail/page", sourceList.value.pagination)
  722. .then((res) => {
  723. res.rows.forEach((x) => {
  724. if (x.prodTag) {
  725. x.prodTags = x.prodTag.split(",");
  726. } else {
  727. x.prodTags = [];
  728. }
  729. x.incomplete = x.quantity - x.finishQuantity;
  730. });
  731. sourceList.value.data = res.rows.map((x) => ({ ...x, isCheck: true }));
  732. sourceList.value.pagination.total = res.total;
  733. setTimeout(() => {
  734. loading.value = false;
  735. }, 200);
  736. const productIdList = res.rows.map((x) => x.productId);
  737. // 请求文件数据并回显
  738. if (productIdList.length > 0) {
  739. // proxy.getFile(productIdList, sourceList.value.data, "productId");
  740. proxy
  741. .post("/fileInfo/getList", { businessIdList: productIdList })
  742. .then((fileObj) => {
  743. for (let i = 0; i < sourceList.value.data.length; i++) {
  744. const ele = sourceList.value.data[i];
  745. for (const key in fileObj) {
  746. if (
  747. ele.productId == key &&
  748. fileObj[ele.productId] &&
  749. fileObj[ele.productId].length > 0
  750. ) {
  751. ele.fileList = fileObj[ele.productId].filter(
  752. (x) => x.businessType == "0"
  753. );
  754. }
  755. }
  756. }
  757. });
  758. }
  759. const productIdListOne = res.rows.map((x) => x.contractDetailId);
  760. // 请求文件数据并回显
  761. if (productIdListOne.length > 0) {
  762. proxy
  763. .post("/fileInfo/getList", { businessIdList: productIdListOne })
  764. .then((fileObj) => {
  765. for (let i = 0; i < sourceList.value.data.length; i++) {
  766. const ele = sourceList.value.data[i];
  767. for (const key in fileObj) {
  768. if (
  769. ele.contractDetailId == key &&
  770. fileObj[ele.contractDetailId] &&
  771. fileObj[ele.contractDetailId].length > 0
  772. ) {
  773. ele.fileListOne = fileObj[ele.contractDetailId].filter(
  774. (x) => x.businessType == "0"
  775. );
  776. }
  777. }
  778. }
  779. });
  780. // proxy.getFile(
  781. // productIdListOne,
  782. // sourceList.value.data,
  783. // "contractDetailId",
  784. // "fileListOne"
  785. // );
  786. }
  787. });
  788. };
  789. const printList = ref([]);
  790. const selectIds = ref([]);
  791. const selectRow = (data) => {
  792. selectIds.value = data.map((x) => x.id);
  793. };
  794. const printTime = ref("");
  795. const openModal = () => {
  796. proxy.msgTip("请稍后", 2);
  797. proxy
  798. .post("/produceOrderDetail/detailByIds", { taskIds: selectIds.value })
  799. .then((res) => {
  800. printList.value = res;
  801. for (let i = 0; i < printList.value.length; i++) {
  802. const iele = printList.value[i];
  803. for (let j = 0; j < sourceList.value.data.length; j++) {
  804. const jele = sourceList.value.data[j];
  805. if (iele.id == jele.id) {
  806. iele.fileList = jele.fileList;
  807. iele.fileListOne = jele.fileListOne;
  808. break;
  809. }
  810. }
  811. }
  812. printTime.value = moment().format("yyyy-MM-DD HH:mm:ss");
  813. dialogVisible.value = true;
  814. nextTick(() => {
  815. for (let i = 0; i < printList.value.length; i++) {
  816. const row = printList.value[i];
  817. proxy.$refs[row.id][0].innerHTML = ""; //清除二维码方法一
  818. new QRCode(proxy.$refs[row.id][0], {
  819. text: row.id,
  820. width: 200,
  821. height: 200,
  822. colorDark: "#000000",
  823. colorLight: "#ffffff",
  824. correctLevel: QRCode.CorrectLevel.H,
  825. });
  826. }
  827. });
  828. });
  829. };
  830. const submitForm = () => {
  831. formDom.value.handleSubmit((valid) => {
  832. submitLoading.value = true;
  833. proxy.post("/produceOrderDetail/editRemark", formData.data).then(
  834. (res) => {
  835. proxy.msgTip("操作成功", 1);
  836. remarkDialog.value = false;
  837. submitLoading.value = false;
  838. getList();
  839. },
  840. (err) => {
  841. submitLoading.value = false;
  842. }
  843. );
  844. });
  845. };
  846. const getDtl = (row) => {
  847. modalType.value = "edit";
  848. proxy.post("/shopInfo/detail", { id: row.id }).then((res) => {
  849. formData.data = res;
  850. dialogVisible.value = true;
  851. });
  852. };
  853. const processesData = ref([]);
  854. const getProcesses = () => {
  855. proxy
  856. .post("/productionProcesses/page", { pageNum: 1, pageSize: 9999 })
  857. .then((res) => {
  858. for (let i = 0; i < res.rows.length; i++) {
  859. const ele = res.rows[i];
  860. let attrs = {
  861. label: `[ ${ele.name} ]`,
  862. slot: ele.id,
  863. isNeedHeaderSlot: false,
  864. width: 70,
  865. align: "center",
  866. fixed: "right",
  867. };
  868. config.value.push({
  869. attrs,
  870. });
  871. }
  872. // config.value.push({
  873. // attrs: {
  874. // label: "操作",
  875. // width: "160",
  876. // align: "center",
  877. // fixed: "right",
  878. // },
  879. // renderHTML(row) {
  880. // return [
  881. // {
  882. // attrs: {
  883. // label: "打印任务单",
  884. // type: "primary",
  885. // text: true,
  886. // },
  887. // el: "button",
  888. // click() {
  889. // printQrCode(row);
  890. // },
  891. // },
  892. // {
  893. // attrs: {
  894. // label: "备注",
  895. // type: "primary",
  896. // text: true,
  897. // },
  898. // el: "button",
  899. // click() {
  900. // openRemark(row);
  901. // },
  902. // },
  903. // ];
  904. // },
  905. // });
  906. processesData.value = res.rows;
  907. });
  908. };
  909. getProcesses();
  910. getList();
  911. const printType = ref(false);
  912. const printQrCode = (row) => {
  913. printType.value = true;
  914. selectIds.value = [row.id];
  915. openModal();
  916. };
  917. const beforeClose = () => {
  918. if (printType.value) {
  919. selectIds.value = [];
  920. }
  921. dialogVisible.value = false;
  922. };
  923. const printObj = ref({
  924. id: "pdfDom",
  925. popTitle: "",
  926. extraCss:
  927. "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
  928. extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
  929. });
  930. const handleClickFile = (file) => {
  931. window.open(file.fileUrl, "_blank");
  932. };
  933. const isShowCotent = (slot, item) => {
  934. if (item && item.productionTaskProgressList) {
  935. return item.productionTaskProgressList.some(
  936. (x) => x.processesId == slot.id
  937. );
  938. } else {
  939. return false;
  940. }
  941. };
  942. const showCotent = (slot, item, att) => {
  943. if (item && item.productionTaskProgressList) {
  944. const current = item.productionTaskProgressList.find(
  945. (x) => x.processesId == slot.id
  946. );
  947. if (current) {
  948. return current[att];
  949. }
  950. } else {
  951. return false;
  952. }
  953. };
  954. const showCotentQuantity = (slot, item) => {
  955. if (item && item.productionTaskProgressList) {
  956. const current = item.productionTaskProgressList.find(
  957. (x) => x.processesId == slot.id
  958. );
  959. if (current && Number(current.finishQuantity) > 0) {
  960. if (Number(current.finishQuantity) >= item.quantity) {
  961. return "tag-active";
  962. } else if (Number(current.finishQuantity) < item.quantity) {
  963. return "tag-active-1";
  964. }
  965. }
  966. }
  967. };
  968. const getDict = () => {
  969. proxy
  970. .get("/tenantDept/list", {
  971. pageNum: 1,
  972. pageSize: 9999,
  973. keyword: "",
  974. tenantId: proxy.useUserStore().user.tenantId,
  975. type: 0,
  976. })
  977. .then((res) => {
  978. companyData.value = res.data.map((x) => ({
  979. ...x,
  980. label: x.deptName,
  981. value: x.deptId,
  982. }));
  983. // treeData.value = proxy.handleTree(res.data, "deptId");
  984. });
  985. };
  986. getDict();
  987. const openRemark = (row) => {
  988. formData.data = {
  989. id: row.id,
  990. remark: row.remark,
  991. };
  992. remarkDialog.value = true;
  993. };
  994. const recordDialog = ref(false);
  995. const recordFormOption = reactive({
  996. inline: true,
  997. labelWidth: 40,
  998. itemWidth: 100,
  999. });
  1000. const recordFormConfig = computed(() => {
  1001. return [
  1002. {
  1003. type: "title1",
  1004. title: "采购记录",
  1005. isShow: activeName.value == "1",
  1006. },
  1007. {
  1008. type: "slot",
  1009. slotName: "detail1",
  1010. label: " ",
  1011. isShow: activeName.value == "1",
  1012. },
  1013. {
  1014. type: "title1",
  1015. title: "出入库流水记录",
  1016. isShow: activeName.value == "2",
  1017. },
  1018. {
  1019. type: "slot",
  1020. slotName: "detail2",
  1021. label: " ",
  1022. isShow: activeName.value == "2",
  1023. },
  1024. ];
  1025. });
  1026. const activeName = ref("1");
  1027. const lookDetails = (item) => {
  1028. activeName.value = "1";
  1029. recordDialog.value = true;
  1030. proxy
  1031. .post("/produceOrder/detail", {
  1032. id: item.produceOrderId,
  1033. })
  1034. .then((res) => {
  1035. formData.recordData = res;
  1036. if (
  1037. formData.recordData.purchaseProductList &&
  1038. formData.recordData.purchaseProductList.length > 0
  1039. ) {
  1040. let productIds = formData.recordData.purchaseProductList.map(
  1041. (x) => x.productId
  1042. );
  1043. proxy.getFileData({
  1044. businessIdList: productIds,
  1045. data: formData.recordData.purchaseProductList,
  1046. att: "productId",
  1047. businessType: "0",
  1048. fileAtt: "fileList",
  1049. filePathAtt: "fileUrl",
  1050. });
  1051. }
  1052. if (
  1053. formData.recordData.stockJournalDetailsList &&
  1054. formData.recordData.stockJournalDetailsList.length > 0
  1055. ) {
  1056. let productIds = formData.recordData.stockJournalDetailsList.map(
  1057. (x) => x.productId
  1058. );
  1059. proxy.getFileData({
  1060. businessIdList: productIds,
  1061. data: formData.recordData.stockJournalDetailsList,
  1062. att: "productId",
  1063. businessType: "0",
  1064. fileAtt: "fileList",
  1065. filePathAtt: "fileUrl",
  1066. });
  1067. }
  1068. });
  1069. };
  1070. </script>
  1071. <style lang="scss" scoped>
  1072. ::v-deep(.el-progress__text) {
  1073. font-size: 14px !important;
  1074. }
  1075. .content {
  1076. padding: 20px;
  1077. }
  1078. .pic {
  1079. object-fit: contain;
  1080. width: 50px;
  1081. height: 50px;
  1082. cursor: pointer;
  1083. vertical-align: middle;
  1084. }
  1085. .table {
  1086. border-collapse: collapse;
  1087. border-spacing: 0;
  1088. width: 100%;
  1089. td {
  1090. text-align: left;
  1091. padding: 10px;
  1092. font-size: 13px;
  1093. // padding: 5px 10px;
  1094. .top-title {
  1095. font-weight: 700;
  1096. margin-bottom: 5px;
  1097. }
  1098. .bigImg {
  1099. object-fit: contain;
  1100. width: 160px;
  1101. height: 320px;
  1102. cursor: pointer;
  1103. margin-top: 10px;
  1104. vertical-align: middle;
  1105. }
  1106. }
  1107. }
  1108. .son {
  1109. td {
  1110. text-align: left;
  1111. padding: 5px !important;
  1112. }
  1113. }
  1114. .no-bk {
  1115. // background: #f3f3f3;
  1116. // height: 50px;
  1117. }
  1118. .red {
  1119. background: red;
  1120. border-radius: 2px;
  1121. padding: 4px;
  1122. color: #fff;
  1123. }
  1124. ::v-deep(.el-table-fixed-column--right) {
  1125. // vertical-align: top !important;
  1126. padding: 0px !important;
  1127. // border: 1px solid #ebeef5 !important;
  1128. .cell {
  1129. padding: 0px !important;
  1130. }
  1131. }
  1132. </style>