creatTask.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. <template>
  2. <div>
  3. <el-row :gutter="20">
  4. <el-col :span="16">
  5. <div class="type-title">当前料箱</div>
  6. <div style="display: flex; margin-bottom: 15px">
  7. <ScanCodeInput
  8. v-model="currentBox"
  9. :clearable="true"
  10. placeholder="请扫描或输入料箱编号"
  11. style="width: 50%"
  12. @keyup.enter="enterBox"
  13. />
  14. <div class="current-box">
  15. <span class="left">{{ boxDetail?.name || "未绑定料箱" }}</span>
  16. <span class="right">{{ boxDetail?.code || "未绑定料箱" }}</span>
  17. </div>
  18. </div>
  19. <div class="type-title">请扫码物料</div>
  20. <ScanCodeInput
  21. v-model="scanCodeInput"
  22. placeholder="请扫描或输入物料编码"
  23. @keyup.enter="handleScanCodeInput"
  24. />
  25. <div
  26. v-loading="map.get('getMaterialInfoByLabel')"
  27. style="height: calc(100vh - 450px); margin-top: 15px"
  28. >
  29. <el-scrollbar>
  30. <div class="list-container">
  31. <div
  32. v-for="(item, index) in materialList"
  33. :key="index"
  34. class="list-box"
  35. >
  36. <div>
  37. <div class="name">{{ item.materialName }}</div>
  38. <div class="spec">{{ item.spec }}</div>
  39. </div>
  40. <div class="bottom">
  41. <NumberInput
  42. v-if="item.codeType === 'BATCH'"
  43. v-model="item.num"
  44. />
  45. <div v-else class="number" v-text="item.num"></div>
  46. <span class="unit">{{ item.unitDictLabel }}</span>
  47. </div>
  48. <i-ep-delete
  49. class="delete"
  50. color="#ff4d4f"
  51. size="20px"
  52. @click="deleteMaterial(index)"
  53. />
  54. </div>
  55. </div>
  56. </el-scrollbar>
  57. </div>
  58. </el-col>
  59. <el-col :span="8">
  60. <div class="type-title">流转终点</div>
  61. <div class="destination">
  62. <el-scrollbar>
  63. <div
  64. v-for="(item, index) in destinationList"
  65. :key="index"
  66. :class="{ selected: index === currentDestinationIndex }"
  67. class="end-box"
  68. @click="onEndBoxClick(index, item)"
  69. >
  70. <div class="name">{{ item.name }}</div>
  71. <!-- <div-->
  72. <!-- v-if="-->
  73. <!-- item.targetType === 'stock' && index === currentDestinationIndex-->
  74. <!-- "-->
  75. <!-- >-->
  76. <!-- <el-select-->
  77. <!-- v-model="selectStore"-->
  78. <!-- filterable-->
  79. <!-- placeholder="请选择"-->
  80. <!-- size="large"-->
  81. <!-- style="width: 200px"-->
  82. <!-- value-key="id"-->
  83. <!-- >-->
  84. <!-- <el-option-->
  85. <!-- v-for="store in storeMap.get(item.houseNo)"-->
  86. <!-- :key="store.id"-->
  87. <!-- :label="store.name"-->
  88. <!-- :value="store"-->
  89. <!-- />-->
  90. <!-- </el-select>-->
  91. <!-- </div>-->
  92. </div>
  93. </el-scrollbar>
  94. </div>
  95. <el-button class="sureBtn el-button-big" type="primary" @click="createTask"
  96. >创建任务
  97. </el-button>
  98. </el-col>
  99. </el-row>
  100. </div>
  101. </template>
  102. <script lang="ts" setup>
  103. //料箱
  104. import {
  105. addMaterialFlow,
  106. getBoxDetailByLabel,
  107. getDestinationList,
  108. getMaterialInfoByLabel,
  109. } from "@/api/process/materialFlow";
  110. import { useCommonStoreHook } from "@/store";
  111. const commonS = useCommonStoreHook();
  112. const map = commonS.loadingMap;
  113. const currentBox = ref("");
  114. const boxDetail = ref<any>({});
  115. const enterBox = () => {
  116. currentBox.value = currentBox.value.trim();
  117. getBoxDetailByLabel(currentBox.value).then((res: any) => {
  118. boxDetail.value = res.data;
  119. // materialList.value = res.data.materialList;
  120. });
  121. };
  122. // 物料
  123. const scanCodeInput = ref("");
  124. const materialList = ref<any[]>([]);
  125. const handleScanCodeInput = () => {
  126. getMaterialInfoByLabel(scanCodeInput.value).then((res: any) => {
  127. // 扫描之后要先查看数组中是否有这个物料,有的话就数量相加,没有的话就添加到数组中
  128. let hasMaterial = false;
  129. for (let i = 0; i < materialList.value.length; i++) {
  130. let currentMaterial = materialList.value[i];
  131. if (
  132. currentMaterial.batchCode === res.data.batchCode &&
  133. currentMaterial.materialCode === res.data.materialCode
  134. ) {
  135. hasMaterial = true;
  136. // SEQ/BATCH 如果是流转卡号数量只能唯1,序列号相加
  137. if (currentMaterial.codeType === "BATCH") {
  138. materialList.value[i].num += res.data.num;
  139. break;
  140. }
  141. }
  142. }
  143. !hasMaterial && materialList.value.push(res.data);
  144. scanCodeInput.value = "";
  145. });
  146. };
  147. const deleteMaterial = (index: number) => {
  148. materialList.value.splice(index, 1);
  149. };
  150. // 流转终点
  151. const destinationList = ref<any>();
  152. const currentDestination = ref<any>({});
  153. const currentDestinationIndex = ref(-1);
  154. const storeMap = new Map<string, Array<any>>();
  155. const selectStore = ref<any>({});
  156. const onEndBoxClick = (index: number, item: any) => {
  157. currentDestination.value = item;
  158. currentDestinationIndex.value = index;
  159. // 如果是仓库,会根据仓库的no获取仓储的列表,存入map, 如果已经有数据了则不需要再次请求接口 =》 后来不需要展示了 就注释了
  160. // if (item.targetType === "stock") {
  161. // if (!storeMap.has(item.houseNo)) {
  162. // getStoreListByNo(item.houseNo).then((res) => {
  163. // storeMap.set(item.houseNo, res.data || []);
  164. // });
  165. // }
  166. // }
  167. };
  168. onMounted(() => {
  169. let wm = new WeakMap();
  170. getDestinationList(1).then((res: any) => {
  171. destinationList.value = res.data;
  172. });
  173. });
  174. const createTask = () => {
  175. const params = {
  176. circulationDetail: [...materialList.value],
  177. // coordinate: "",
  178. houseNo: "",
  179. // locationNo: "",
  180. stationId: 0,
  181. targetType: "",
  182. vehicleCode: "",
  183. vehicleId: 0,
  184. vehicleName: "",
  185. };
  186. params.targetType = currentDestination.value.targetType;
  187. if (currentDestination.value.targetType === "stock") {
  188. params.houseNo = currentDestination.value.houseNo;
  189. // params.locationNo = selectStore.value.locationNo;
  190. // params.coordinate = selectStore.value.coordinate;
  191. } else {
  192. params.stationId = currentDestination.value.id;
  193. }
  194. params.vehicleId = boxDetail.value.id;
  195. params.vehicleCode = boxDetail.value.code;
  196. params.vehicleName = boxDetail.value.name;
  197. addMaterialFlow(params).then((res) => {
  198. ElMessage.success("创建成功");
  199. //1366 一体机—物料流转任务创建成功后 清空页面数据
  200. currentBox.value = "";
  201. boxDetail.value = {};
  202. scanCodeInput.value = "";
  203. materialList.value = [];
  204. });
  205. };
  206. </script>
  207. <style lang="scss" scoped>
  208. .type-title {
  209. font-weight: 500;
  210. font-size: 30px;
  211. color: rgba(0, 0, 0, 0.9);
  212. text-align: left;
  213. margin-bottom: 15px;
  214. }
  215. .current-box {
  216. background: rgba(0, 0, 0, 0.06);
  217. border-radius: 16px 16px 16px 16px;
  218. font-size: 20px;
  219. display: flex;
  220. justify-content: space-between;
  221. align-items: center;
  222. width: 50%;
  223. height: 49px;
  224. padding: 0 20px;
  225. .left {
  226. font-weight: 400;
  227. color: rgba(0, 0, 0, 0.6);
  228. text-align: left;
  229. }
  230. .right {
  231. font-weight: 500;
  232. color: rgba(0, 0, 0, 0.9);
  233. text-align: right;
  234. }
  235. }
  236. .list-container {
  237. width: 100%;
  238. display: grid;
  239. /*行间距*/
  240. grid-row-gap: 24px;
  241. /*列间距*/
  242. grid-column-gap: 24px;
  243. grid-template-columns: 1fr 1fr;
  244. .list-box {
  245. height: 210px;
  246. background: #fff;
  247. border-radius: 16px 16px 16px 16px;
  248. display: flex;
  249. flex-direction: column;
  250. justify-content: space-between;
  251. align-items: start;
  252. padding: 30px 30px;
  253. position: relative;
  254. .name {
  255. font-weight: 500;
  256. font-size: 24px;
  257. color: rgba(0, 0, 0, 0.9);
  258. text-align: left;
  259. }
  260. .spec {
  261. font-size: 20px;
  262. color: rgba(0, 0, 0, 0.6);
  263. text-align: left;
  264. }
  265. .bottom {
  266. display: flex;
  267. justify-content: start;
  268. align-items: end;
  269. }
  270. .unit {
  271. font-weight: 500;
  272. font-size: 24px;
  273. color: rgba(0, 0, 0, 0.6);
  274. text-align: left;
  275. margin-left: 5px;
  276. }
  277. .delete {
  278. position: absolute;
  279. top: 20px;
  280. right: 20px;
  281. }
  282. }
  283. }
  284. .destination {
  285. height: calc(100vh - 350px);
  286. margin-top: 15px;
  287. .end-box {
  288. height: 80px;
  289. background: #ffffff;
  290. border-radius: 40px;
  291. display: flex;
  292. justify-content: center;
  293. align-items: center;
  294. font-weight: 500;
  295. font-size: 24px;
  296. color: rgba(0, 0, 0, 0.9);
  297. display: flex;
  298. justify-content: space-evenly;
  299. align-items: center;
  300. }
  301. .end-box:not(:last-child) {
  302. margin-bottom: 15px;
  303. }
  304. .selected {
  305. border-radius: 40px;
  306. border: 2px solid rgba(10, 89, 247, 1);
  307. }
  308. .name {
  309. font-weight: 500;
  310. font-size: 24px;
  311. color: rgba(0, 0, 0, 0.9);
  312. }
  313. }
  314. .sureBtn {
  315. height: 80px;
  316. background: #0a59f7;
  317. border-radius: 76px 76px 76px 76px;
  318. width: 100%;
  319. margin-top: 10px;
  320. font-size: $f24;
  321. }
  322. .number {
  323. font-size: $f38;
  324. font-weight: bolder;
  325. }
  326. </style>