index.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <template>
  2. <van-nav-bar :title="$t('inventoryQuery.name')" left-text="" left-arrow @click-left="onClickLeft">
  3. </van-nav-bar>
  4. <van-search v-model="req.keyword" :placeholder="$t('common.pleaseEnterKeywords')" @search="onRefresh" />
  5. <van-tabs v-model:active="active" @change="handleChangeTab">
  6. <van-tab :title="'按仓库'" name="first"></van-tab>
  7. <van-tab :title="'按产品'" name="second"></van-tab>
  8. <van-tab :title="'按SPU'" name="three"></van-tab>
  9. </van-tabs>
  10. <div style="overflow-y:auto" :style="{height:!deviceStore.isIosSysteme?'calc(100vh - 205px)':'calc(100vh - 225px)'}">
  11. <van-pull-refresh v-model="loading" @refresh="onRefresh">
  12. <div class="list">
  13. <van-list v-model:loading="loading" :finished="finished" :finished-text="$t('common.noMore')" @load="onLoad" style="margin-bottom: 60px">
  14. <commonList :data="listData" :config="listConfig" :showMore="false">
  15. <template #productUnit="{row}">
  16. <div style="width:100%">
  17. {{dictValueLabel(row.productUnit,productUnit)}}
  18. </div>
  19. </template>
  20. <template #btn="{row}">
  21. <div style="width:100%;text-align:right">
  22. <van-button type="primary" size="small" style="margin-right:10px" @click="toDtl(row,true)">良转次</van-button>
  23. <van-button type="primary" size="small" @click="toDtl(row,false)">次转良</van-button>
  24. </div>
  25. </template>
  26. </commonList>
  27. <!-- @onClick="toDtl" -->
  28. </van-list>
  29. </div>
  30. </van-pull-refresh>
  31. </div>
  32. <van-popup v-model:show="openPopup" position="bottom" :style="{ height: '370px' }" closeable>
  33. <div style="padding:10px">
  34. <van-form @submit="onSubmit" label-align="top">
  35. <TitleInfo :title="submitType?'良转次':'次转良'"></TitleInfo>
  36. <van-field v-model="formData.data.canSum" type="text" label="可转数量" readonly />
  37. <van-field v-model="formData.data.quantity" type="digit" label="数量" placeholder="请输入数量" :rules="[{ required: true, message: '请填写数量' }]" />
  38. <div style="margin: 16px">
  39. <van-button round block type="primary" native-type="submit">
  40. 提交
  41. </van-button>
  42. </div>
  43. </van-form>
  44. </div>
  45. </van-popup>
  46. </template>
  47. <script setup>
  48. import { ref, getCurrentInstance, onMounted, reactive } from "vue";
  49. import commonList from "@/components/common-list.vue";
  50. import { useRoute } from "vue-router";
  51. import { getUserInfo } from "@/utils/auth";
  52. import { showSuccessToast, showFailToast } from "vant";
  53. import TitleInfo from "@/components/TitleInfo/index.vue";
  54. import useDeviceStore from "@/store/device";
  55. const deviceStore = useDeviceStore();
  56. const loading = ref(false);
  57. const router = useRoute();
  58. const req = ref({
  59. pageNum: 1,
  60. keyword: null,
  61. });
  62. const finished = ref(false);
  63. const proxy = getCurrentInstance().proxy;
  64. const listData = ref([]);
  65. const warehouseData = ref([]);
  66. const productUnit = ref([]);
  67. const active = ref("first");
  68. let listConfigSet = [
  69. [
  70. {
  71. label: "仓库名称",
  72. prop: "warehouseName",
  73. },
  74. {
  75. label: "项目组",
  76. prop: "deptName",
  77. },
  78. {
  79. label: "所属分类",
  80. prop: "productClassifyName",
  81. },
  82. {
  83. label: "物品编码",
  84. prop: "productCustomCode",
  85. },
  86. {
  87. label: "物品名称",
  88. prop: "productName",
  89. },
  90. {
  91. label: "规格",
  92. prop: "productSpec",
  93. },
  94. {
  95. type: "slot",
  96. slotName: "productUnit",
  97. label: "单位",
  98. prop: "productUnit",
  99. },
  100. {
  101. label: "可用库存",
  102. prop: "quantity",
  103. },
  104. {
  105. label: "冻结库存",
  106. prop: "frozenQuantity",
  107. },
  108. {
  109. label: "次品库存",
  110. prop: "defectiveQuantity",
  111. },
  112. {
  113. label: "最近入库时间",
  114. prop: "updateTime",
  115. },
  116. {
  117. type: "slot",
  118. slotName: "btn",
  119. label: "",
  120. },
  121. ],
  122. [
  123. {
  124. label: "项目组",
  125. prop: "deptName",
  126. },
  127. {
  128. label: "所属分类",
  129. prop: "productClassifyName",
  130. },
  131. {
  132. label: "物品编码",
  133. prop: "productCustomCode",
  134. },
  135. {
  136. label: "物品名称",
  137. prop: "productName",
  138. },
  139. {
  140. label: "规格",
  141. prop: "productSpec",
  142. },
  143. {
  144. type: "slot",
  145. slotName: "productUnit",
  146. label: "单位",
  147. prop: "productUnit",
  148. },
  149. {
  150. label: "可用库存",
  151. prop: "quantity",
  152. },
  153. {
  154. label: "冻结库存",
  155. prop: "frozenQuantity",
  156. },
  157. {
  158. label: "次品库存",
  159. prop: "defectiveQuantity",
  160. },
  161. {
  162. label: "最近入库时间",
  163. prop: "updateTime",
  164. },
  165. {
  166. type: "slot",
  167. slotName: "btn",
  168. label: "",
  169. },
  170. ],
  171. [
  172. {
  173. label: "spu编码",
  174. prop: "productSpuCode",
  175. },
  176. {
  177. label: "spu名称",
  178. prop: "productSpuName",
  179. },
  180. {
  181. label: "关联产品数",
  182. prop: "linkProductQuantity",
  183. },
  184. {
  185. label: "库存数量",
  186. prop: "quantity",
  187. },
  188. ],
  189. ];
  190. const listConfig = ref([]);
  191. listConfig.value = listConfigSet[0];
  192. const onRefresh = () => {
  193. req.value.pageNum = 1;
  194. finished.value = false;
  195. getList("refresh");
  196. };
  197. const onLoad = () => {
  198. getList();
  199. };
  200. const onClickLeft = () => proxy.$router.push("/main/working");
  201. const onClickRight = () => {
  202. proxy.$router.push("/main/manualInboundAdd");
  203. };
  204. const formData = reactive({
  205. data: {},
  206. });
  207. const openPopup = ref(false);
  208. const submitType = ref(false);
  209. const toDtl = (row, flag) => {
  210. submitType.value = flag;
  211. // proxy.$router.push({
  212. // path: "outInList",
  213. // query: {
  214. // productId: row.productId,
  215. // warehouseId: row.warehouseId,
  216. // },
  217. // });
  218. let canSum = flag ? row.quantity : row.defectiveQuantity;
  219. formData.data = {
  220. id: row.id,
  221. canSum,
  222. quantity: null,
  223. };
  224. openPopup.value = true;
  225. };
  226. const onSubmit = () => {
  227. let url = submitType.value
  228. ? "/stock/qualifiedToDefective"
  229. : "/stock/defectiveToQualified";
  230. if (!(Number(formData.data.quantity) > 0)) {
  231. return showFailToast("数量不能为0");
  232. }
  233. if (Number(formData.data.quantity) > Number(formData.data.canSum)) {
  234. return showFailToast("数量不可大于可转数量");
  235. }
  236. proxy.post(url, formData.data).then(
  237. (res) => {
  238. onRefresh();
  239. showSuccessToast("操作成功");
  240. openPopup.value = false;
  241. },
  242. (err) => {
  243. return showFailToast(err.message);
  244. }
  245. );
  246. };
  247. const getDict = () => {
  248. let query = {
  249. pageNum: 1,
  250. pageSize: 999,
  251. tenantId: getUserInfo().tenantId,
  252. };
  253. // proxy
  254. // .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
  255. // .then((res) => {
  256. // supplierData.value = res.data.rows;
  257. // formConfig[5].data = supplierData.value;
  258. // });
  259. proxy
  260. .post("/dictTenantData/page", {
  261. ...query,
  262. dictCode: "unit",
  263. })
  264. .then((res) => {
  265. if (res.data.rows && res.data.rows.length > 0) {
  266. productUnit.value = res.data.rows.map((item) => {
  267. return {
  268. label: item.dictValue,
  269. value: item.dictKey,
  270. };
  271. });
  272. }
  273. });
  274. };
  275. getDict();
  276. const getList = (type) => {
  277. loading.value = true;
  278. proxy
  279. .post(requestUrl.value, req.value)
  280. .then((res) => {
  281. res.data.rows = res.data.rows.map((x) => ({
  282. ...x,
  283. ...JSON.parse(x.victoriatouristJson),
  284. quantity: x.quantity,
  285. }));
  286. listData.value =
  287. type === "refresh"
  288. ? res.data.rows
  289. : listData.value.concat(res.data.rows);
  290. if (req.value.pageNum * 10 >= res.data.total) {
  291. finished.value = true;
  292. }
  293. req.value.pageNum++;
  294. loading.value = false;
  295. })
  296. .catch((err) => {
  297. loading.value = false;
  298. });
  299. };
  300. const requestUrl = ref("/stock/pageByWarehouse");
  301. const handleChangeTab = (val) => {
  302. if (val == "first") {
  303. requestUrl.value = "/stock/pageByWarehouse";
  304. listConfig.value = listConfigSet[0];
  305. } else if (val == "second") {
  306. requestUrl.value = "/stock/pageByProduct";
  307. listConfig.value = listConfigSet[1];
  308. } else {
  309. requestUrl.value = "/stock/pageByProductSpu";
  310. listConfig.value = listConfigSet[2];
  311. }
  312. req.value.pageNum = 1;
  313. listData.value = [];
  314. getList();
  315. };
  316. getList();
  317. </script>
  318. <style lang="scss" scoped>
  319. .list {
  320. min-height: 100%;
  321. }
  322. </style>