quick.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <template>
  2. <div>
  3. <el-card class="box-card" v-loading="loading">
  4. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
  5. <template #inOutStorageBomList>
  6. <div style="width: 100%; padding: 0 20px">
  7. <el-table :data="formData.data.inOutStorageBomList" :row-style="{ height: '35px' }" header-row-class-name="tableHeader">
  8. <el-table-column type="expand">
  9. <template #default="props">
  10. <div style="padding: 0 80px 0 50px">
  11. <el-table
  12. :data="props.row.orderList"
  13. :cell-style="{ padding: '0' }"
  14. :row-style="{ height: '35px' }"
  15. v-loading="loading"
  16. header-row-class-name="tableHeader">
  17. <el-table-column label="订单号" prop="orderCode" width="200" />
  18. <el-table-column label="万里牛单号" prop="orderWlnCode" width="140" />
  19. <el-table-column label="SKU品号" prop="skuSpecCode" width="180" />
  20. <el-table-column label="SKU品名" prop="skuSpecName" min-width="180" />
  21. <el-table-column label="出库数量" width="140">
  22. <template #default="{ row }">
  23. <span>{{ row.quantity }}</span>
  24. </template>
  25. </el-table-column>
  26. </el-table>
  27. </div>
  28. </template>
  29. </el-table-column>
  30. <el-table-column label="品号" prop="bomSpecCode" width="180" />
  31. <el-table-column label="品名" prop="bomSpecName" min-width="220" />
  32. <el-table-column label="仓库" width="160">
  33. <template #default="{ row, $index }">
  34. <el-form-item :prop="'inOutStorageBomList.' + $index + '.warehouseId'" :rules="rules.warehouseId" :inline-message="true" style="width: 100%">
  35. <el-select
  36. v-model="row.warehouseId"
  37. placeholder="请选择仓库"
  38. clearable
  39. style="width: 100%"
  40. @change="
  41. (val) => {
  42. return changeWarehouse(val, row, $index);
  43. }
  44. ">
  45. <el-option v-for="item in warehouseList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
  46. </el-select>
  47. </el-form-item>
  48. </template>
  49. </el-table-column>
  50. <el-table-column label="剩余库存" prop="surplusStock" width="120" />
  51. <el-table-column label="出库数量" width="140">
  52. <template #default="{ row }">
  53. <span :style="row.surplusStock && row.surplusStock < row.quantity ? '' : 'color: red'">{{ row.quantity }}</span>
  54. </template>
  55. </el-table-column>
  56. </el-table>
  57. </div>
  58. </template>
  59. </byForm>
  60. <div style="width: 100%; text-align: center; margin: 10px">
  61. <el-button @click="clickCancel()" size="large">取 消</el-button>
  62. <el-button type="primary" @click="submitForm()" size="large" v-preReClick>确 定</el-button>
  63. </div>
  64. </el-card>
  65. </div>
  66. </template>
  67. <script setup>
  68. import byForm from "@/components/byForm/index";
  69. import { ElMessage } from "element-plus";
  70. const { proxy } = getCurrentInstance();
  71. const departmentList = ref([{ dictKey: "0", dictValue: "胜德体育" }]);
  72. const props = defineProps({
  73. selectData: Array,
  74. });
  75. const warehouseList = ref([]);
  76. const submit = ref(null);
  77. const formOption = reactive({
  78. inline: true,
  79. labelWidth: "100px",
  80. itemWidth: 100,
  81. rules: [],
  82. labelPosition: "right",
  83. });
  84. const formData = reactive({
  85. data: {
  86. inOutStorageBomList: [],
  87. },
  88. });
  89. const formConfig = computed(() => {
  90. return [
  91. {
  92. type: "title",
  93. title: "物料信息",
  94. label: "",
  95. },
  96. {
  97. type: "slot",
  98. slotName: "inOutStorageBomList",
  99. label: "",
  100. },
  101. ];
  102. });
  103. const rules = ref({
  104. warehouseId: [{ required: true, message: "请选择仓库", trigger: "change" }],
  105. });
  106. const getDemandData = () => {
  107. proxy.post("/department/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  108. if (res.rows && res.rows.length > 0) {
  109. departmentList.value = departmentList.value.concat(
  110. res.rows.map((item) => {
  111. return {
  112. dictKey: item.id,
  113. dictValue: item.name,
  114. };
  115. })
  116. );
  117. }
  118. });
  119. };
  120. getDemandData();
  121. const emit = defineEmits(["clickCancel"]);
  122. const duplicateRemoval = (arr) => {
  123. let list = [];
  124. return arr.filter((item) => !list.includes(item) && list.push(item));
  125. };
  126. const loading = ref(false);
  127. const submitForm = () => {
  128. submit.value.handleSubmit(() => {
  129. if (formData.data.inOutStorageBomList && formData.data.inOutStorageBomList.length > 0) {
  130. for (let i = 0; i < formData.data.inOutStorageBomList.length; i++) {
  131. if (Number(formData.data.inOutStorageBomList[i].surplusStock) < Number(formData.data.inOutStorageBomList[i].quantity)) {
  132. return ElMessage("出库数量大于剩余库存数量");
  133. }
  134. }
  135. loading.value = true;
  136. let orderList = [];
  137. for (let j = 0; j < formData.data.inOutStorageBomList.length; j++) {
  138. if (formData.data.inOutStorageBomList[j].orderList && formData.data.inOutStorageBomList[j].orderList.length > 0) {
  139. orderList = orderList.concat(formData.data.inOutStorageBomList[j].orderList.map((itemOrder) => itemOrder.orderSkuId));
  140. }
  141. }
  142. proxy.post("/stockPreparation/submit", duplicateRemoval(orderList)).then(
  143. () => {
  144. ElMessage({ message: "提交完成", type: "success" });
  145. emit("clickCancel", true);
  146. },
  147. (err) => {
  148. console.log(err);
  149. loading.value = false;
  150. }
  151. );
  152. } else {
  153. return ElMessage("请添加BOM");
  154. }
  155. });
  156. };
  157. const clickCancel = () => {
  158. emit("clickCancel", false);
  159. };
  160. const delSomeObjValue = (arr, keyName, valueName) => {
  161. const idArr = []; // 相同的id放在同一数组中
  162. const resultArr = []; // 最终结果数组
  163. for (let i = 0; i < arr.length; i++) {
  164. const index = idArr.indexOf(arr[i][keyName]);
  165. if (index > -1) {
  166. resultArr[index][valueName] += Number(arr[i][valueName]); //取相同id的value累加
  167. } else {
  168. idArr.push(arr[i][keyName]);
  169. resultArr.push(arr[i]);
  170. }
  171. }
  172. return resultArr;
  173. };
  174. const getWarehouse = () => {
  175. return proxy.post("/warehouse/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  176. if (res.rows && res.rows.length > 0) {
  177. warehouseList.value = res.rows
  178. .filter((item) => ["2", "3"].includes(item.type))
  179. .map((item) => {
  180. return {
  181. dictKey: item.id,
  182. dictValue: item.name,
  183. };
  184. });
  185. }
  186. });
  187. };
  188. onMounted(() => {
  189. Promise.all([getWarehouse()]).then(async () => {
  190. if (props.selectData && props.selectData.length > 0) {
  191. formData.data.inOutStorageBomList = delSomeObjValue(
  192. props.selectData.map((item) => {
  193. let num = 0;
  194. if (item.quantity) {
  195. num = Number(item.quantity);
  196. }
  197. return {
  198. bomSpecId: item.bomSpecId,
  199. quantity: num,
  200. bomSpecName: item.bomSpecName,
  201. bomSpecCode: item.bomSpecCode,
  202. warehouseId: "",
  203. surplusStock: 0,
  204. };
  205. }),
  206. "bomSpecId",
  207. "quantity"
  208. ).map((item) => {
  209. return {
  210. ...item,
  211. orderList: props.selectData
  212. .map((item) => {
  213. let num = 0;
  214. if (item.quantity) {
  215. num = Number(item.quantity);
  216. }
  217. return {
  218. bomSpecId: item.bomSpecId,
  219. quantity: num,
  220. orderSkuId: item.orderSkuId,
  221. orderCode: item.orderCode,
  222. orderWlnCode: item.orderWlnCode,
  223. skuSpecCode: item.skuSpecCode,
  224. skuSpecName: item.skuSpecName,
  225. };
  226. })
  227. .filter((itemSelect) => itemSelect.bomSpecId === item.bomSpecId),
  228. };
  229. });
  230. let orderList = [];
  231. for (let j = 0; j < formData.data.inOutStorageBomList.length; j++) {
  232. if (formData.data.inOutStorageBomList[j].orderList && formData.data.inOutStorageBomList[j].orderList.length > 0) {
  233. orderList = orderList.concat(formData.data.inOutStorageBomList[j].orderList.map((itemOrder) => itemOrder.orderSkuId));
  234. }
  235. }
  236. const a = await proxy.post("/stockPreparation/getPackageBomList", orderList).then((res) => {
  237. if (res && res.length > 0) {
  238. formData.data.inOutStorageBomList = formData.data.inOutStorageBomList.concat(res);
  239. }
  240. });
  241. if (formData.data.inOutStorageBomList && formData.data.inOutStorageBomList.length > 0) {
  242. let bomSpecIdList = [];
  243. bomSpecIdList = formData.data.inOutStorageBomList.map((item) => item.bomSpecId);
  244. proxy
  245. .post("/inventory/getQuantity", {
  246. departmentId: "0",
  247. warehouseId: warehouseList.value[0].dictKey,
  248. bomSpecIdList: bomSpecIdList,
  249. })
  250. .then((resInventory) => {
  251. let bomSpecIdTwoList = [];
  252. for (let i = 0; i < formData.data.inOutStorageBomList.length; i++) {
  253. if (resInventory[formData.data.inOutStorageBomList[i].bomSpecId]) {
  254. formData.data.inOutStorageBomList[i].warehouseId = warehouseList.value[0].dictKey;
  255. formData.data.inOutStorageBomList[i].surplusStock = resInventory[formData.data.inOutStorageBomList[i].bomSpecId];
  256. } else {
  257. bomSpecIdTwoList.push(formData.data.inOutStorageBomList[i].bomSpecId);
  258. }
  259. }
  260. if (bomSpecIdTwoList && bomSpecIdTwoList.length > 0) {
  261. proxy
  262. .post("/inventory/getQuantity", {
  263. departmentId: "0",
  264. warehouseId: warehouseList.value[1].dictKey,
  265. bomSpecIdList: bomSpecIdTwoList,
  266. })
  267. .then((inventoryTwo) => {
  268. for (let i = 0; i < formData.data.inOutStorageBomList.length; i++) {
  269. if (inventoryTwo[formData.data.inOutStorageBomList[i].bomSpecId]) {
  270. formData.data.inOutStorageBomList[i].warehouseId = warehouseList.value[1].dictKey;
  271. formData.data.inOutStorageBomList[i].surplusStock = inventoryTwo[formData.data.inOutStorageBomList[i].bomSpecId];
  272. }
  273. }
  274. });
  275. }
  276. });
  277. }
  278. }
  279. });
  280. });
  281. const changeWarehouse = (val, item, index) => {
  282. if (val) {
  283. proxy
  284. .post("/inventory/getQuantity", {
  285. departmentId: "0",
  286. warehouseId: val,
  287. bomSpecIdList: [item.bomSpecId],
  288. })
  289. .then((res) => {
  290. if (res[item.bomSpecId]) {
  291. formData.data.inOutStorageBomList[index].surplusStock = res[item.bomSpecId];
  292. } else {
  293. formData.data.inOutStorageBomList[index].surplusStock = 0;
  294. }
  295. });
  296. } else {
  297. formData.data.inOutStorageBomList[index].surplusStock = 0;
  298. }
  299. };
  300. </script>
  301. <style lang="scss" scoped>
  302. ::v-deep(.el-input-number .el-input__inner) {
  303. text-align: left;
  304. }
  305. :deep(.el-dialog) {
  306. margin-top: 10px !important;
  307. margin-bottom: 10px !important;
  308. }
  309. </style>