index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. <template>
  2. <div class="tenant">
  3. <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
  4. :selectConfig="selectConfig" :table-events="{
  5. select: select,
  6. }" :action-list="[]" @get-list="getList" @moreSearch="() => (queryDialogVisible = false)"
  7. >
  8. <template #wareId="{ item }">
  9. <span v-if="item.exDesc=='1'">
  10. <svg-icon icon-class="jdyl" style="width: 34px;"/>
  11. </span>
  12. <span v-if="item.exDesc=='2'">
  13. <svg-icon icon-class="jdks" style="width: 34px;"/>
  14. </span>
  15. <span
  16. :style="item.productName=='' || item.productName == undefined || item.productName == 'undefined'?'color: red':''">
  17. {{item.wareId}}
  18. </span>
  19. </template>
  20. <template #wareName="{ item }">
  21. <span
  22. :style="item.productName=='' || item.productName == undefined || item.productName == 'undefined'?'color: red':''">
  23. {{item.wareName}}
  24. </span>
  25. </template>
  26. </byTable>
  27. <!--详情-->
  28. <el-dialog :z-index="1500" title="异常处理" v-if="dialogVisible" v-model="formData.data" width="500px" v-loading="loading" @close="closeHandleAction">
  29. <el-steps :active="stepsActiveindex" align-center>
  30. <el-step title="选择异常状态" ></el-step>
  31. <el-step title="处理异常明细" ></el-step>
  32. </el-steps>
  33. <el-divider></el-divider>
  34. <el-form class="stepsActive1" :model="formData.data" ref="submitform" :rules="rules" style="margin-top: 0px;height: auto"
  35. label-position="top" label-width="100px" v-if="stepsActiveindex == 1">
  36. <el-form-item label="异常状态明细" prop="abnormalStatus">
  37. <el-select v-model="formData.data.abnormalStatus" style="width: 100%;" @change="treeChange">
  38. <el-option v-for="item in abnormalHandleTypeDict" :key="item.value" :label="item.label" :value="item.value"/>
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item label="处理方案" prop="exHandle">
  42. <el-select v-model="formData.data.exHandle" style="width: 100%;" >
  43. <el-option v-for="item in abnormalHandleTypeChileDict" :key="item.value" :label="item.label" :value="item.value"/>
  44. </el-select>
  45. </el-form-item>
  46. </el-form>
  47. <el-form class="stepsActive2" :model="formData.data" style="margin-top: 20px;height: auto" ref="submitform2" :rules="rules" label-position="top" label-width="100px" v-if="stepsActiveindex == 2">
  48. <el-form-item label="出库仓库" prop="reduceWarehouseId" v-if="reduceFlag">
  49. <el-select v-model="formData.data.reduceWarehouseId" style="width: 100%;" @change="(e)=>getProductList(e,2)">
  50. <el-option v-for="item in warehouseList" :key="item.value" :label="item.label" :value="item.value"/>
  51. </el-select>
  52. </el-form-item>
  53. <el-form-item label="出库商品" prop="reduceProductId" v-if="reduceFlag">
  54. <el-select v-model="formData.data.reduceProductId" filterable style="width: 100%;">
  55. <el-option v-for="item in reduceProductList" :key="item.value" :label="item.label" :value="item.value"/>
  56. </el-select>
  57. </el-form-item>
  58. <el-form-item label="出库商品数量" prop="reduceQuantity" v-if="reduceFlag">
  59. <el-input v-model="formData.data.reduceQuantity" disabled placeholder="请输入出库商品数量" oninput="value=value.replace(/[^\d.]/g,'')"/>
  60. </el-form-item>
  61. <el-form-item label="入库仓库" prop="addWarehouseId" v-if="addFlag">
  62. <el-select v-model="formData.data.addWarehouseId" style="width: 100%;" @change="(e)=>getProductList(e,1)">
  63. <el-option v-for="item in warehouseList" :key="item.value" :label="item.label" :value="item.value"/>
  64. </el-select>
  65. </el-form-item>
  66. <el-form-item label="入库商品" prop="addProductId" v-if="addFlag">
  67. <el-select v-model="formData.data.addProductId" filterable style="width: 100%;">
  68. <el-option v-for="item in addProductList" :key="item.value" :label="item.label" :value="item.value"/>
  69. </el-select>
  70. </el-form-item>
  71. <el-form-item label="入库商品数量" prop="addQuantity" v-if="addFlag">
  72. <el-input v-model="formData.data.addQuantity" disabled placeholder="请输入出库商品数量" oninput="value=value.replace(/[^\d.]/g,'')"/>
  73. </el-form-item>
  74. <el-form-item label="快递单号" prop="expressNo" v-if="deliveryFlag">
  75. <el-input v-model="formData.data.expressNo" placeholder="请输入快递单号" oninput="value=value.replace(/[^\d.]/g,'')"/>
  76. </el-form-item>
  77. <el-form-item label="备注" prop="remark" v-if="remarkFlag">
  78. <el-input type="textarea" :rows="3" v-model="formData.data.remark" placeholder="请输入备注" oninput="value=value.replace(/[^\d.]/g,'')"/>
  79. </el-form-item>
  80. <span style="color: red" v-if="tipsFlag">*请到京东平台补单</span>
  81. </el-form>
  82. <template #footer>
  83. <el-divider></el-divider>
  84. <el-button @click="back" v-if="stepsActiveindex > 1 " size="large" :loading="submitLoading">上一步</el-button>
  85. <el-button @click="next" v-if="stepsActiveindex < 2 " size="large" :loading="submitLoading">下一步</el-button>
  86. <el-button @click="submit" v-if="stepsActiveindex ==2" size="large" :loading="submitLoading">确定</el-button>
  87. </template>
  88. </el-dialog>
  89. <!--高级搜索-->
  90. <el-dialog :title="'高级检索'" v-model="queryDialogVisible" width="500px" destroy-on-close>
  91. <el-form :model="sourceList.pagination" label-width="100px" label-position="top">
  92. <el-form-item label="采购单号">
  93. <el-input v-model="sourceList.pagination.orderId" placeholder="请输入采购单号" oninput="value=value.replace(/[^\d.]/g,'')"/>
  94. </el-form-item>
  95. <el-form-item label="京东商品编号">
  96. <el-input v-model="sourceList.pagination.wareId" placeholder="请输入京东商品编号" oninput="value=value.replace(/[^\d.]/g,'')"/>
  97. </el-form-item>
  98. </el-form>
  99. <template #footer>
  100. <el-button @click="handleReset" size="large">重置</el-button>
  101. <el-button @click="handleQuery" type="primary" size="large">搜索</el-button>
  102. </template>
  103. </el-dialog>
  104. </div>
  105. </template>
  106. <script setup>
  107. import { ElMessage, ElMessageBox } from "element-plus";
  108. import byTable from "@/components/byTable/index";
  109. import byForm from "@/components/byForm/index";
  110. import { computed, nextTick, reactive, ref } from "vue";
  111. const { proxy } = getCurrentInstance();
  112. const router = useRouter();
  113. const loading = ref(false);
  114. const deliveryCenter = ref([]);
  115. const confirmState = ref([]);
  116. const orderState = ref([]);
  117. const submitLoading = ref(false);
  118. const sourceList = ref({
  119. data: [],
  120. pagination: {
  121. total: 0,
  122. pageNum: 1,
  123. pageSize: 10,
  124. },
  125. });
  126. const warehouseList = ref([])
  127. const reduceProductList = ref([])
  128. const addProductList = ref([])
  129. const abnormalHandleTypeDict = ref([])
  130. const abnormalHandleTypeChileDict = ref([])
  131. const abnormalStatusDictAll = ref([
  132. {value: '10',label: '仓库多发',chile:[{value: '101',label: '补单(扣库存)'}]},
  133. {value: '20',label: '仓库已发',chile:[{ value: '201',label: '报损'},
  134. { value: '202',label: '补单(不扣库存)'},
  135. { value: '203',label: '索赔理赔'}]},
  136. {value: '30',label: '仓库少发',chile:[{ value: '301',label: '退回库存'}]},
  137. {value: '40',label: '仓库发错货物',chile:[{ value: '401',label: '货物退回'},
  138. { value: '402',label: '补单'},
  139. { value: '403',label: '报损'}]},
  140. {value: '50',label: '条码错误',chile:[{ value: '501',label: '货物退回'},
  141. { value: '502',label: '补单'},
  142. { value: '503',label: '报损'}]}
  143. ])
  144. const abnormalStatusDict = ref([
  145. {value: '101',label: '仓库多发-补单(扣库存)'},
  146. { value: '201',label: '仓库已发-报损'},
  147. { value: '202',label: '仓库已发-补单(不扣库存)'},
  148. { value: '203',label: '仓库已发-索赔理赔'},
  149. { value: '301',label: '仓库少发-退回库存'},
  150. { value: '401',label: '仓库发错货物-货物退回'},
  151. { value: '402',label: '仓库发错货物-补单'},
  152. { value: '403',label: '仓库发错货物-报损'},
  153. { value: '501',label: '条码错误-货物退回'},
  154. { value: '502',label: '条码错误-补单'},
  155. { value: '503',label: '条码错误-报损'}
  156. ])
  157. const treeChange = (e) => {
  158. formData.data.exHandle = ""
  159. const abnormalStatusDict = abnormalStatusDictAll.value.filter(x=> {
  160. return x.value == e
  161. });
  162. abnormalHandleTypeChileDict.value = abnormalStatusDict[0].chile
  163. }
  164. let rules = ref({
  165. abnormalStatus: [{ required: true, message: "请选择异常状态", trigger: "change" }],
  166. exHandle: [{ required: true, message: "请选择异常处理", trigger: "change" }],
  167. addWarehouseId: [{ required: true, message: "请选择入库仓库", trigger: "change" }],
  168. addProductId: [{ required: true, message: "请选择入库商品", trigger: "change" }],
  169. addQuantity: [{ required: true, message: "请填写入库数量", trigger: "blur" }],
  170. reduceWarehouseId: [{ required: true, message: "请选择出库仓库", trigger: "change" }],
  171. reduceProductId: [{ required: true, message: "请选择出库商品", trigger: "change" }],
  172. reduceQuantity: [{ required: true, message: "请填写出库数量", trigger: "blur" }],
  173. expressNo: [{ required: true, message: "请填写快递单号", trigger: "blur" }],
  174. remark: [{ required: true, message: "请填写快递单号", trigger: "blur" }],
  175. });
  176. const queryDialogVisible = ref(false);
  177. const dialogVisible = ref(false);
  178. const stepsActiveindex = ref(1);
  179. let modalType = ref("add");
  180. const selectConfig = computed(() => {
  181. return [
  182. {
  183. label: "异常状态",
  184. prop: "exDesc",
  185. data: [
  186. {
  187. label: "多货",
  188. value: "1",
  189. },
  190. {
  191. label: "少货",
  192. value: "2",
  193. },
  194. ],
  195. },
  196. {
  197. label: "处理状态",
  198. prop: "handleStatus",
  199. data: [
  200. {
  201. label: "已处理",
  202. value: "2",
  203. },
  204. {
  205. label: "未处理",
  206. value: "1",
  207. },
  208. ],
  209. },
  210. {
  211. label: "处理方案",
  212. prop: "exHandle",
  213. data: abnormalStatusDict.value,
  214. },
  215. ];
  216. });
  217. const config = computed(() => {
  218. return [
  219. {
  220. attrs: {
  221. label: "京东采购单号",
  222. prop: "orderId",
  223. align: "left",
  224. width: 120,
  225. },
  226. },
  227. {
  228. attrs: {
  229. label: "京东商品编号",
  230. slot: "wareId",
  231. align: "left",
  232. width: 175,
  233. },
  234. },
  235. {
  236. attrs: {
  237. label: "京东商品名称",
  238. slot: "wareName",
  239. align: "left",
  240. "min-width": 200,
  241. },
  242. },
  243. {
  244. attrs: {
  245. label: "产品名称",
  246. prop: "productName",
  247. align: "left",
  248. "min-width": 150,
  249. },
  250. },
  251. {
  252. attrs: {
  253. label: "配送中心名称",
  254. prop: "deliverCenterName",
  255. align: "left",
  256. width: 150,
  257. },
  258. },
  259. {
  260. attrs: {
  261. label: "采购价",
  262. prop: "purchasePrice",
  263. align: "left",
  264. width: 80,
  265. },
  266. },
  267. {
  268. attrs: {
  269. label: "原始采购数量",
  270. prop: "originalNum",
  271. align: "left",
  272. width: 110,
  273. },
  274. },
  275. {
  276. attrs: {
  277. label: "回告数量",
  278. prop: "confirmNum",
  279. align: "left",
  280. width: 80,
  281. },
  282. },
  283. {
  284. attrs: {
  285. label: "实收数量",
  286. prop: "actualNum",
  287. align: "left",
  288. width: 80,
  289. },
  290. },
  291. {
  292. attrs: {
  293. label: "不满足原因",
  294. prop: "nonDeliveryReason",
  295. align: "left",
  296. width: 100,
  297. },
  298. },
  299. {
  300. attrs: {
  301. label: "采购总金额",
  302. prop: "totalPrice",
  303. align: "left",
  304. width: 110,
  305. },
  306. },
  307. {
  308. attrs: {
  309. label: "库房名称",
  310. prop: "storeName",
  311. align: "left",
  312. width: 180,
  313. },
  314. },
  315. {
  316. attrs: {
  317. label: "EPT采购单定制相关信息",
  318. prop: "wareProperty",
  319. align: "left",
  320. width: 180,
  321. },
  322. },
  323. {
  324. attrs: {
  325. label: "操作",
  326. width: "150",
  327. align: "center",
  328. fixed: "right",
  329. },
  330. renderHTML(row) {
  331. return [
  332. row.handleStatus !== '2'
  333. ? {
  334. attrs: {
  335. label: "处理",
  336. type: "danger",
  337. text: true,
  338. },
  339. el: "button",
  340. click() {
  341. // ElMessageBox.confirm("是否确认当前采购单状态?", "提示", {
  342. // confirmButtonText: "确定",
  343. // cancelButtonText: "取消",
  344. // type: "warning",
  345. // }).then(() => {
  346. openHandleAction(row);
  347. // });
  348. },
  349. }
  350. : {},
  351. ];
  352. },
  353. },
  354. ];
  355. });
  356. let formData = reactive({
  357. data: {
  358. coverList: [],
  359. audioList: [],
  360. },
  361. });
  362. const formOption = reactive({
  363. inline: true,
  364. labelWidth: 100,
  365. itemWidth: 100,
  366. rules: [],
  367. });
  368. const byform = ref(null);
  369. const submitform = ref(null);
  370. const submitform2 = ref(null);
  371. const getDictlist = async () => {
  372. proxy.post("/warehouse/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  373. if (res.rows && res.rows.length > 0) {
  374. warehouseList.value = res.rows.map((item) => {
  375. return {
  376. label: item.name,
  377. value: item.id,
  378. };
  379. });
  380. }
  381. });
  382. };
  383. const getProductList = async (e,type) =>{
  384. proxy.post("/stock/pageByWarehouse", { pageNum: 1, pageSize: 999 ,id:e}).then((res) => {
  385. if (res.rows && res.rows.length > 0) {
  386. const product = res.rows.map((item) => {
  387. return {
  388. label: item.productName,
  389. value: item.productId,
  390. };
  391. });
  392. if (type == 1){
  393. addProductList.value = product
  394. } else {
  395. reduceProductList.value = product
  396. }
  397. }
  398. });
  399. }
  400. const getList = async (req) => {
  401. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  402. loading.value = true;
  403. proxy.post("/jdOrderEx/jdOrderDetailExList", sourceList.value.pagination).then((res) => {
  404. sourceList.value.data = res.rows;
  405. sourceList.value.pagination.total = res.total;
  406. setTimeout(() => {
  407. loading.value = false;
  408. }, 200);
  409. });
  410. };
  411. const selection = ref({
  412. data: [],
  413. });
  414. const select = (_selection, row) => {
  415. selection.value.data = _selection;
  416. };
  417. //高级搜索
  418. const handleReset = () => {
  419. sourceList.value.pagination = {
  420. pageNum: sourceList.value.pagination.pageNum,
  421. pageSize: sourceList.value.pagination.pageSize,
  422. arr: [],
  423. };
  424. handleQuery();
  425. };
  426. const handleQuery = () => {
  427. if (
  428. sourceList.value.pagination.arr &&
  429. sourceList.value.pagination.arr.length > 1
  430. ) {
  431. sourceList.value.pagination.purchaseStartTime =
  432. sourceList.value.pagination.arr[0];
  433. sourceList.value.pagination.purchaseEndTime =
  434. sourceList.value.pagination.arr[1];
  435. }
  436. queryDialogVisible.value = false;
  437. getList();
  438. };
  439. /**
  440. * 确认采购单状态
  441. * @param row
  442. */
  443. const openHandleAction = (row) => {
  444. dialogVisible.value = true;
  445. stepsActiveindex.value = 1
  446. intiFlag()
  447. let absoluteValue = Math.abs(Number(row.confirmNum) - Number(row.actualNum))
  448. formData.data = {
  449. id:row.id,
  450. reduceQuantity : absoluteValue,
  451. addQuantity : absoluteValue,
  452. }
  453. abnormalHandleTypeDict.value = abnormalStatusDictAll.value.map(x =>{
  454. return {
  455. label: x.label,
  456. value: x.value,
  457. };
  458. })
  459. };
  460. /**
  461. * 确认采购单状态
  462. * @param row
  463. */
  464. const closeHandleAction = () => {
  465. dialogVisible.value = false;
  466. stepsActiveindex.value = 1
  467. };
  468. const tipsFlag = ref(false)
  469. const reduceFlag = ref(false)
  470. const addFlag = ref(false)
  471. const remarkFlag = ref(false)
  472. const deliveryFlag = ref(false)
  473. const intiFlag = () => {
  474. tipsFlag.value = false
  475. addFlag.value = false
  476. reduceFlag.value = false
  477. remarkFlag.value = false
  478. deliveryFlag.value = false
  479. }
  480. const next = async () => {
  481. let flag = await submitform.value.validate();
  482. const type = formData.data.exHandle
  483. intiFlag()
  484. //判断 出库
  485. if (['101','402','403'].indexOf(type)>-1){
  486. reduceFlag.value = true
  487. }
  488. //判断 入库
  489. if (['301','401','402','403','501'].indexOf(type)>-1){
  490. addFlag.value = true
  491. }
  492. //判断 备注
  493. if (['201','203','403','503'].indexOf(type)>-1){
  494. remarkFlag.value = true
  495. }
  496. //判断 快递
  497. if (['401','501'].indexOf(type)>-1){
  498. deliveryFlag.value = true
  499. }
  500. //判断 提示
  501. if (['101','202','402','502'].indexOf(type)>-1){
  502. tipsFlag.value = true
  503. }
  504. stepsActiveindex.value++
  505. }
  506. const back = () => {
  507. stepsActiveindex.value--
  508. }
  509. const submit = async () => {
  510. let flag = await submitform2.value.validate();
  511. if (flag){
  512. ElMessageBox.confirm("是否确认当前处理方法?", "提示", {
  513. confirmButtonText: "确定",
  514. cancelButtonText: "取消",
  515. type: "warning",
  516. }).then(() => {
  517. submitLoading.value = true;
  518. proxy.post("/jdOrderEx/dealEx", formData.data).then(
  519. () => {
  520. ElMessage({
  521. message: "处理成功",
  522. type: "success",
  523. });
  524. dialogVisible.value = false;
  525. submitLoading.value = false;
  526. getList();
  527. },
  528. (err) => {
  529. console.log(err);
  530. submitLoading.value = false;
  531. }
  532. );
  533. });
  534. }
  535. }
  536. getDictlist();
  537. getList();
  538. </script>
  539. <style lang='scss' scoped>
  540. .tenant {
  541. padding: 20px;
  542. }
  543. :deep(.el-form-item--default) {
  544. margin-bottom: 0px;
  545. }
  546. .stepsActive1 .el-form-item{
  547. margin-bottom: 20px;
  548. }
  549. .stepsActive2 .el-form-item{
  550. margin-bottom: 10px;
  551. }
  552. </style>