index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. <template>
  2. <div>
  3. <el-card class="box-card">
  4. <el-tabs v-model="activeName" type="card" @tab-change="changeActiveName">
  5. <el-tab-pane label="待备料" name="first">
  6. <byTable
  7. :hideTable="true"
  8. :hidePagination="true"
  9. :source="sourceList.data"
  10. :pagination="sourceList.pagination"
  11. :config="config"
  12. :searchConfig="searchConfig"
  13. highlight-current-row
  14. :action-list="[
  15. {
  16. text: '打印备料单',
  17. action: () => outExcel(),
  18. },
  19. {
  20. text: '快捷出库',
  21. action: () => clickQuickDelivery(),
  22. },
  23. ]"
  24. @get-list="getList"
  25. @clickReset="clickReset">
  26. </byTable>
  27. <table class="table-class" border="0" cellpadding="0" cellspacing="0" v-loading="loading">
  28. <tr>
  29. <th style="width: 200px">BOM品号</th>
  30. <th style="min-width: 320px">BOM品名</th>
  31. <th style="width: 200px">SKU品号</th>
  32. <th style="width: 120px; text-align: center">数量小计</th>
  33. <th style="width: 140px; text-align: center">数量总计</th>
  34. </tr>
  35. <tbody v-for="(item, index) in sourceList.data" :key="index">
  36. <tr v-for="(itemSKU, indexSKU) in item.skuInfoList" :key="indexSKU">
  37. <td v-if="indexSKU === 0" :rowspan="item.skuInfoList.length">{{ item.bomSpecCode }}</td>
  38. <td v-if="indexSKU === 0" :rowspan="item.skuInfoList.length">{{ item.bomSpecName }}</td>
  39. <td>{{ itemSKU.skuSpecCode }}</td>
  40. <td style="text-align: center">{{ itemSKU.quantity }}</td>
  41. <td v-if="indexSKU === 0" :rowspan="item.skuInfoList.length" style="text-align: center">{{ item.totalQuantity }}</td>
  42. </tr>
  43. </tbody>
  44. </table>
  45. </el-tab-pane>
  46. <el-tab-pane label="已备料" name="second">
  47. <byTable
  48. :source="sourceListTwo.data"
  49. :pagination="sourceListTwo.pagination"
  50. :config="configTwo"
  51. :loading="loading"
  52. :searchConfig="searchConfigTwo"
  53. highlight-current-row
  54. @get-list="getListTwo"
  55. @clickReset="clickResetTwo">
  56. <template #blueprint="{ item }">
  57. <div>
  58. <img
  59. v-if="item.blueprint"
  60. style="margin-top: 3px; width: 40px; height: 40px; cursor: pointer; object-fit: contain; vertical-align: middle"
  61. v-lazy="item.blueprint"
  62. @click="openFile(item.blueprint)" />
  63. </div>
  64. </template>
  65. <template #size="{ item }">
  66. <span>{{ `${item.length} * ${item.width} * ${item.height}` }}</span>
  67. </template>
  68. </byTable>
  69. </el-tab-pane>
  70. </el-tabs>
  71. </el-card>
  72. <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="1000px">
  73. <div style="height: calc(100vh - 174px); overflow-y: auto; overflow-x: hidden">
  74. <div class="printBomList" id="printMe">
  75. <div class="t">生产备料单</div>
  76. <div class="time" style="text-align: right">
  77. {{ printTime }}
  78. </div>
  79. <table border="1" cellspacing="0" class="table">
  80. <thead>
  81. <tr>
  82. <td style="width: 6%; text-align: center">编号</td>
  83. <td style="width: 18%">物料品号</td>
  84. <td style="width: 38%">物料品名</td>
  85. <td style="width: 18%">SKU品号</td>
  86. <td style="width: 10%; text-align: center">数量小计</td>
  87. <td style="width: 10%; text-align: center">数量总计</td>
  88. </tr>
  89. </thead>
  90. <tbody v-for="(item, index) in sourceList.data" :key="index">
  91. <tr v-for="(itemSKU, indexSKU) in item.skuInfoList" :key="indexSKU">
  92. <td :rowspan="item.skuInfoList.length" v-if="indexSKU === 0" style="text-align: center">{{ index + 1 }}</td>
  93. <td :rowspan="item.skuInfoList.length" v-if="indexSKU === 0">{{ item.bomSpecCode }}</td>
  94. <td :rowspan="item.skuInfoList.length" v-if="indexSKU === 0">{{ item.bomSpecName }}</td>
  95. <td>{{ itemSKU.skuSpecCode }}</td>
  96. <td style="text-align: center">{{ itemSKU.quantity }}</td>
  97. <td :rowspan="item.skuInfoList.length" v-if="indexSKU === 0" style="text-align: center">{{ item.totalQuantity }}</td>
  98. </tr>
  99. </tbody>
  100. </table>
  101. </div>
  102. </div>
  103. <div style="text-align: center; margin: 10px">
  104. <el-button @click="openPrint = false" size="large">取消</el-button>
  105. <el-button type="primary" v-print="printObj" size="large">打印</el-button>
  106. </div>
  107. </el-dialog>
  108. <el-dialog title="快捷出库" v-if="openQuick" v-model="openQuick" width="90%">
  109. <Quick :pagination="sourceList.pagination" @clickCancel="clickCancel"></Quick>
  110. </el-dialog>
  111. </div>
  112. </template>
  113. <script setup>
  114. import byTable from "/src/components/byTable/index";
  115. import moment from "moment";
  116. import Quick from "/src/views/production/operation/batching/quick";
  117. const { proxy } = getCurrentInstance();
  118. const activeName = ref("first");
  119. const departmentList = ref([{ dictKey: "0", dictValue: "胜德体育" }]);
  120. const sourceList = ref({
  121. data: [],
  122. pagination: {
  123. bomSpecCode: "",
  124. bomSpecName: "",
  125. skuSpecCode: "",
  126. skuSpecName: "",
  127. departmentId: "1689164627162529793",
  128. },
  129. });
  130. const sourceListTwo = ref({
  131. data: [],
  132. pagination: {
  133. total: 0,
  134. pageNum: 1,
  135. pageSize: 10,
  136. type: "1",
  137. orderCode: "",
  138. orderWlnCode: "",
  139. bomSpecCode: "",
  140. bomSpecName: "",
  141. skuSpecCode: "",
  142. skuSpecName: "",
  143. departmentId: "",
  144. width: "",
  145. },
  146. });
  147. const loading = ref(false);
  148. const searchConfig = computed(() => {
  149. return [
  150. {
  151. type: "input",
  152. prop: "bomSpecCode",
  153. label: "BOM品号",
  154. },
  155. {
  156. type: "input",
  157. prop: "bomSpecName",
  158. label: "BOM品名",
  159. },
  160. {
  161. type: "input",
  162. prop: "skuSpecCode",
  163. label: "SKU品号",
  164. },
  165. {
  166. type: "input",
  167. prop: "skuSpecName",
  168. label: "SKU品名",
  169. },
  170. {
  171. type: "select",
  172. prop: "departmentId",
  173. data: departmentList.value,
  174. label: "事业部",
  175. clearable: true,
  176. },
  177. ];
  178. });
  179. const searchConfigTwo = computed(() => {
  180. return [
  181. {
  182. type: "input",
  183. prop: "orderCode",
  184. label: "订单号",
  185. },
  186. {
  187. type: "input",
  188. prop: "orderWlnCode",
  189. label: "E10单号",
  190. },
  191. {
  192. type: "input",
  193. prop: "bomSpecCode",
  194. label: "BOM品号",
  195. },
  196. {
  197. type: "input",
  198. prop: "bomSpecName",
  199. label: "BOM品名",
  200. },
  201. {
  202. type: "input",
  203. prop: "skuSpecCode",
  204. label: "SKU品号",
  205. },
  206. {
  207. type: "input",
  208. prop: "skuSpecName",
  209. label: "SKU品名",
  210. },
  211. {
  212. type: "select",
  213. prop: "departmentId",
  214. data: departmentList.value,
  215. label: "事业部",
  216. },
  217. {
  218. type: "input",
  219. prop: "width",
  220. label: "幅宽(cm)",
  221. },
  222. ];
  223. });
  224. const config = computed(() => {
  225. return [
  226. {
  227. type: "selection",
  228. attrs: {
  229. checkAtt: "isCheck",
  230. },
  231. },
  232. {
  233. attrs: {
  234. label: "BOM品号",
  235. prop: "bomSpecCode",
  236. width: 200,
  237. },
  238. },
  239. {
  240. attrs: {
  241. label: "BOM品名",
  242. prop: "bomSpecName",
  243. "min-width": 320,
  244. },
  245. },
  246. {
  247. attrs: {
  248. label: "SKU品号",
  249. prop: "skuSpecCode",
  250. width: 180,
  251. },
  252. },
  253. {
  254. attrs: {
  255. label: "数量",
  256. prop: "quantity",
  257. width: 120,
  258. },
  259. },
  260. ];
  261. });
  262. const configTwo = computed(() => {
  263. return [
  264. {
  265. attrs: {
  266. label: "设计图",
  267. slot: "blueprint",
  268. width: 80,
  269. },
  270. },
  271. {
  272. attrs: {
  273. label: "事业部",
  274. prop: "departmentName",
  275. width: 160,
  276. },
  277. },
  278. {
  279. attrs: {
  280. label: "BOM品号",
  281. prop: "bomSpecCode",
  282. width: 160,
  283. },
  284. },
  285. {
  286. attrs: {
  287. label: "BOM品名",
  288. prop: "bomSpecName",
  289. "min-width": 240,
  290. },
  291. },
  292. {
  293. attrs: {
  294. label: "SKU品号",
  295. prop: "skuSpecCode",
  296. width: 160,
  297. },
  298. },
  299. {
  300. attrs: {
  301. label: "SKU品名",
  302. prop: "skuSpecName",
  303. "min-width": 200,
  304. },
  305. },
  306. {
  307. attrs: {
  308. label: "尺寸(长宽高,cm)",
  309. slot: "size",
  310. width: 160,
  311. },
  312. },
  313. {
  314. attrs: {
  315. label: "数量",
  316. prop: "quantity",
  317. width: 100,
  318. },
  319. },
  320. {
  321. attrs: {
  322. label: "投产时间",
  323. prop: "createTime",
  324. width: 160,
  325. align: "center",
  326. },
  327. },
  328. {
  329. attrs: {
  330. label: "订单号",
  331. prop: "orderCode",
  332. width: 160,
  333. },
  334. },
  335. {
  336. attrs: {
  337. label: "E10单号",
  338. prop: "orderWlnCode",
  339. width: 160,
  340. },
  341. },
  342. ];
  343. });
  344. const getList = async (req, status) => {
  345. if (status) {
  346. sourceList.value.pagination = {
  347. departmentId: "1689164627162529793",
  348. };
  349. } else {
  350. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  351. }
  352. loading.value = true;
  353. proxy.post("/stockPreparation/uncompletedList", sourceList.value.pagination).then((res) => {
  354. if (res && res.length > 0) {
  355. sourceList.value.data = Object.freeze(
  356. res.map((item) => {
  357. return {
  358. ...item,
  359. isCheck: false,
  360. };
  361. })
  362. );
  363. } else {
  364. sourceList.value.data = res;
  365. }
  366. setTimeout(() => {
  367. loading.value = false;
  368. }, 200);
  369. });
  370. };
  371. getList();
  372. const clickReset = () => {
  373. getList("", true);
  374. };
  375. const getListTwo = async (req, status) => {
  376. if (status) {
  377. sourceListTwo.value.pagination = {
  378. pageNum: sourceListTwo.value.pagination.pageNum,
  379. pageSize: sourceListTwo.value.pagination.pageSize,
  380. };
  381. } else {
  382. sourceListTwo.value.pagination = { ...sourceListTwo.value.pagination, ...req };
  383. }
  384. loading.value = true;
  385. proxy.post("/stockPreparation/completedPage", sourceListTwo.value.pagination).then((res) => {
  386. sourceListTwo.value.data = res.rows;
  387. sourceListTwo.value.pagination.total = res.total;
  388. setTimeout(() => {
  389. loading.value = false;
  390. }, 200);
  391. });
  392. };
  393. const clickResetTwo = () => {
  394. getListTwo("", true);
  395. };
  396. const changeActiveName = (val) => {
  397. if (val === "first") {
  398. getList();
  399. } else {
  400. getListTwo();
  401. }
  402. };
  403. const getDemandData = () => {
  404. proxy.post("/department/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  405. if (res.rows && res.rows.length > 0) {
  406. departmentList.value = departmentList.value.concat(
  407. res.rows.map((item) => {
  408. return {
  409. dictKey: item.id,
  410. dictValue: item.name,
  411. };
  412. })
  413. );
  414. }
  415. });
  416. };
  417. getDemandData();
  418. const openFile = (path) => {
  419. window.open(path);
  420. };
  421. const openPrint = ref(false);
  422. const printTime = ref("");
  423. const outExcel = () => {
  424. printTime.value = moment().format("yyyy-MM-DD HH:mm:ss");
  425. openPrint.value = true;
  426. };
  427. const printObj = ref({
  428. id: "printMe",
  429. popTitle: "",
  430. extraCss: "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",
  431. extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
  432. });
  433. const openQuick = ref(false);
  434. const clickQuickDelivery = () => {
  435. openQuick.value = true;
  436. };
  437. const clickCancel = (status) => {
  438. openQuick.value = false;
  439. if (status) {
  440. getList();
  441. }
  442. };
  443. </script>
  444. <style lang="scss" scoped>
  445. ::v-deep(.el-input-number .el-input__inner) {
  446. text-align: left;
  447. }
  448. .printBomList {
  449. width: 100%;
  450. .t {
  451. text-align: center;
  452. font-size: 26px;
  453. font-weight: 700;
  454. margin: 10px 0px;
  455. }
  456. .time {
  457. margin-bottom: 10px;
  458. }
  459. .table {
  460. width: 100%;
  461. td {
  462. padding: 10px;
  463. }
  464. }
  465. }
  466. :deep(.el-dialog) {
  467. margin-top: 10px !important;
  468. margin-bottom: 10px !important;
  469. }
  470. .table-class {
  471. width: 100%;
  472. font-size: 14px;
  473. border: 1px solid #eeeeee;
  474. }
  475. .table-class th {
  476. height: 35px;
  477. line-height: 35px;
  478. padding: 0 12px;
  479. text-align: left;
  480. background-color: #eeeeee !important;
  481. border-right: 1px solid #eeeeee;
  482. }
  483. .table-class td {
  484. height: 35px;
  485. line-height: 35px;
  486. padding: 8px 12px;
  487. text-align: left;
  488. border-bottom: 1px solid #eeeeee;
  489. border-right: 1px solid #eeeeee;
  490. }
  491. </style>