index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. <template>
  2. <el-card class="box-card">
  3. <el-tabs v-model="activeName" type="card" @tab-change="changeActiveName">
  4. <el-tab-pane label="盘点单" name="first">
  5. <byTable
  6. :source="sourceList.data"
  7. :pagination="sourceList.pagination"
  8. :config="config"
  9. :loading="loading"
  10. :searchConfig="searchConfig"
  11. highlight-current-row
  12. :action-list="[
  13. {
  14. text: '盘点登记',
  15. action: () => clickModal(),
  16. },
  17. {
  18. text: '导出Excel',
  19. action: () => clickDerive(),
  20. },
  21. ]"
  22. @get-list="getList"
  23. @clickReset="clickReset">
  24. </byTable>
  25. </el-tab-pane>
  26. <el-tab-pane label="盘点明细" name="second">
  27. <byTable
  28. :source="sourceListTwo.data"
  29. :pagination="sourceListTwo.pagination"
  30. :config="configTwo"
  31. :loading="loading"
  32. :searchConfig="searchConfigTwo"
  33. highlight-current-row
  34. :action-list="[
  35. {
  36. text: '盘点登记',
  37. action: () => clickModal(),
  38. },
  39. ]"
  40. @get-list="getListTwo"
  41. @clickReset="clickResetTwo">
  42. <template #quantity="{ item }">
  43. <div>{{ calculationNum(item) }}</div>
  44. </template>
  45. <template #money="{ item }">
  46. <div>{{ calculationMoney(item) }}</div>
  47. </template>
  48. </byTable>
  49. </el-tab-pane>
  50. </el-tabs>
  51. <el-dialog title="导出Excel文件" v-if="openDerive" v-model="openDerive" width="400">
  52. <el-form :model="formData.data" :rules="rules" ref="derive">
  53. <el-form-item label="仓库" prop="warehouseId">
  54. <el-select v-model="formData.data.warehouseId" placeholder="仓库" clearable style="width: 100%">
  55. <el-option v-for="item in warehouseList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
  56. </el-select>
  57. </el-form-item>
  58. </el-form>
  59. <template #footer>
  60. <el-button @click="openDerive = false" size="large">关 闭</el-button>
  61. <el-button type="primary" @click="clickSubmit" v-preReClick>确 认</el-button>
  62. </template>
  63. </el-dialog>
  64. </el-card>
  65. </template>
  66. <script setup>
  67. import byTable from "/src/components/byTable/index";
  68. import moment from "moment";
  69. import { ElMessage } from "element-plus";
  70. const { proxy } = getCurrentInstance();
  71. const activeName = ref("first");
  72. const departmentList = ref([{ dictKey: "0", dictValue: "胜德体育" }]);
  73. const warehouseList = ref([]);
  74. const status = ref([
  75. { dictKey: "0", dictValue: "正常" },
  76. { dictKey: "1", dictValue: "异常" },
  77. ]);
  78. const sourceList = ref({
  79. data: [],
  80. pagination: {
  81. total: 0,
  82. pageNum: 1,
  83. pageSize: 10,
  84. departmentId: "",
  85. warehouseId: "",
  86. status: "",
  87. beginTime: "",
  88. endTime: "",
  89. },
  90. });
  91. const sourceListTwo = ref({
  92. data: [],
  93. pagination: {
  94. total: 0,
  95. pageNum: 1,
  96. pageSize: 10,
  97. bomSpecCode: "",
  98. bomSpecName: "",
  99. departmentId: "",
  100. warehouseId: "",
  101. status: "",
  102. beginTime: "",
  103. endTime: "",
  104. },
  105. });
  106. const loading = ref(false);
  107. const searchConfig = computed(() => {
  108. return [
  109. {
  110. type: "select",
  111. prop: "departmentId",
  112. data: departmentList.value,
  113. label: "事业部",
  114. },
  115. {
  116. type: "select",
  117. prop: "warehouseId",
  118. data: warehouseList.value,
  119. label: "仓库",
  120. },
  121. {
  122. type: "select",
  123. prop: "status",
  124. data: status.value,
  125. label: "盘点结果",
  126. },
  127. {
  128. type: "date",
  129. propList: ["beginTime", "endTime"],
  130. label: "盘点日期",
  131. },
  132. ];
  133. });
  134. const searchConfigTwo = computed(() => {
  135. return [
  136. {
  137. type: "input",
  138. prop: "bomSpecCode",
  139. label: "品号",
  140. },
  141. {
  142. type: "input",
  143. prop: "bomSpecName",
  144. label: "品名",
  145. },
  146. {
  147. type: "select",
  148. prop: "departmentId",
  149. data: departmentList.value,
  150. label: "事业部",
  151. },
  152. {
  153. type: "select",
  154. prop: "warehouseId",
  155. data: warehouseList.value,
  156. label: "仓库",
  157. },
  158. {
  159. type: "select",
  160. prop: "status",
  161. data: status.value,
  162. label: "盘点结果",
  163. },
  164. {
  165. type: "date",
  166. propList: ["beginTime", "endTime"],
  167. label: "盘点日期",
  168. },
  169. ];
  170. });
  171. const config = computed(() => {
  172. return [
  173. {
  174. attrs: {
  175. label: "盘点时间",
  176. prop: "createTime",
  177. width: 160,
  178. align: "center",
  179. },
  180. },
  181. {
  182. attrs: {
  183. label: "盘点单号",
  184. prop: "code",
  185. width: 200,
  186. },
  187. },
  188. {
  189. attrs: {
  190. label: "归属事业部",
  191. prop: "departmentName",
  192. "min-width": 160,
  193. },
  194. },
  195. {
  196. attrs: {
  197. label: "仓库类型",
  198. prop: "warehouseType",
  199. width: 140,
  200. },
  201. render(val) {
  202. return proxy.dictKeyValue(val, proxy.useUserStore().allDict["warehouse_type"]);
  203. },
  204. },
  205. {
  206. attrs: {
  207. label: "仓库名称",
  208. prop: "warehouseName",
  209. "min-width": 200,
  210. },
  211. },
  212. {
  213. attrs: {
  214. label: "入库类型",
  215. prop: "status",
  216. width: 140,
  217. },
  218. render(val) {
  219. return proxy.dictKeyValue(val, status.value);
  220. },
  221. },
  222. {
  223. attrs: {
  224. label: "盘点人",
  225. prop: "checkTaker",
  226. width: 160,
  227. align: "center",
  228. },
  229. },
  230. ];
  231. });
  232. const configTwo = computed(() => {
  233. return [
  234. {
  235. attrs: {
  236. label: "品号",
  237. prop: "bomSpecCode",
  238. width: 150,
  239. },
  240. },
  241. {
  242. attrs: {
  243. label: "品名",
  244. prop: "bomSpecName",
  245. "min-width": 220,
  246. },
  247. },
  248. {
  249. attrs: {
  250. label: "结存单价",
  251. prop: "balanceUnitPrice",
  252. width: 120,
  253. algin: "right",
  254. },
  255. },
  256. {
  257. attrs: {
  258. label: "仓库名称",
  259. prop: "warehouseName",
  260. width: 140,
  261. },
  262. },
  263. {
  264. attrs: {
  265. label: "归属事业部",
  266. prop: "departmentName",
  267. width: 140,
  268. },
  269. },
  270. {
  271. attrs: {
  272. label: "单位",
  273. prop: "bomUnit",
  274. width: 100,
  275. },
  276. },
  277. {
  278. attrs: {
  279. label: "盘前数量",
  280. prop: "surplusStock",
  281. width: 120,
  282. },
  283. },
  284. {
  285. attrs: {
  286. label: "盘后数量",
  287. prop: "checkQuantity",
  288. width: 120,
  289. },
  290. },
  291. {
  292. attrs: {
  293. label: "盘盈/亏数量",
  294. slot: "quantity",
  295. width: 120,
  296. },
  297. },
  298. {
  299. attrs: {
  300. label: "盘盈/亏金额",
  301. slot: "money",
  302. width: 120,
  303. },
  304. },
  305. {
  306. attrs: {
  307. label: "备注",
  308. prop: "remark",
  309. width: 140,
  310. },
  311. },
  312. ];
  313. });
  314. const getList = async (req, status) => {
  315. if (status) {
  316. sourceList.value.pagination = {
  317. pageNum: sourceList.value.pagination.pageNum,
  318. pageSize: sourceList.value.pagination.pageSize,
  319. };
  320. } else {
  321. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  322. }
  323. loading.value = true;
  324. proxy.post("/check/page", sourceList.value.pagination).then((res) => {
  325. sourceList.value.data = res.rows;
  326. sourceList.value.pagination.total = res.total;
  327. setTimeout(() => {
  328. loading.value = false;
  329. }, 200);
  330. });
  331. };
  332. getList();
  333. const clickReset = () => {
  334. getList("", true);
  335. };
  336. const getListTwo = async (req, status) => {
  337. if (status) {
  338. sourceListTwo.value.pagination = {
  339. pageNum: sourceListTwo.value.pagination.pageNum,
  340. pageSize: sourceListTwo.value.pagination.pageSize,
  341. };
  342. } else {
  343. sourceListTwo.value.pagination = { ...sourceListTwo.value.pagination, ...req };
  344. }
  345. loading.value = true;
  346. proxy.post("/checkBom/page", sourceListTwo.value.pagination).then((res) => {
  347. sourceListTwo.value.data = res.rows;
  348. sourceListTwo.value.pagination.total = res.total;
  349. setTimeout(() => {
  350. loading.value = false;
  351. }, 200);
  352. });
  353. };
  354. const clickResetTwo = () => {
  355. getListTwo("", true);
  356. };
  357. const changeActiveName = (val) => {
  358. if (val === "first") {
  359. getList();
  360. } else {
  361. getListTwo();
  362. }
  363. };
  364. const getDemandData = () => {
  365. proxy.post("/department/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  366. if (res.rows && res.rows.length > 0) {
  367. departmentList.value = departmentList.value.concat(
  368. res.rows.map((item) => {
  369. return {
  370. dictKey: item.id,
  371. dictValue: item.name,
  372. };
  373. })
  374. );
  375. }
  376. });
  377. proxy.post("/warehouse/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  378. if (res.rows && res.rows.length > 0) {
  379. warehouseList.value = res.rows.map((item) => {
  380. return {
  381. dictKey: item.id,
  382. dictValue: item.name,
  383. };
  384. });
  385. }
  386. });
  387. };
  388. getDemandData();
  389. const clickModal = () => {
  390. proxy.$router.replace({
  391. path: "/check/add",
  392. query: {
  393. random: proxy.random(),
  394. },
  395. });
  396. };
  397. const calculationNum = (row) => {
  398. let num = 0;
  399. if (row.checkQuantity) {
  400. num = Number(row.checkQuantity);
  401. }
  402. if (row.surplusStock) {
  403. num = Number(num) - Number(row.surplusStock);
  404. }
  405. return num;
  406. };
  407. const calculationMoney = (row) => {
  408. let num = 0;
  409. if (row.checkQuantity) {
  410. num = Number(row.checkQuantity);
  411. }
  412. if (row.surplusStock) {
  413. num = Number(num) - Number(row.surplusStock);
  414. }
  415. if (row.balanceUnitPrice) {
  416. return Number(Math.round(num * Number(row.balanceUnitPrice) * 100) / 100);
  417. } else {
  418. return 0;
  419. }
  420. };
  421. const openDerive = ref(false);
  422. const formData = reactive({
  423. data: {
  424. warehouseId: "",
  425. },
  426. });
  427. const rules = ref({
  428. warehouseId: [{ required: true, message: "请选择仓库", trigger: "change" }],
  429. });
  430. const clickDerive = () => {
  431. formData.data.warehouseId = "";
  432. openDerive.value = true;
  433. };
  434. const clickSubmit = () => {
  435. proxy.$refs.derive.validate((valid) => {
  436. if (valid) {
  437. proxy.postFile("/check/inventoryExportExcel", { id: formData.data.warehouseId }).then((res) => {
  438. if (res.type === "application/json") {
  439. const fileReader = new FileReader();
  440. fileReader.onloadend = () => {
  441. const jsonData = JSON.parse(fileReader.result);
  442. ElMessage({ message: jsonData.msg, type: "error" });
  443. };
  444. fileReader.readAsText(res);
  445. } else {
  446. proxy.downloadFile(res, "盘点-" + moment().format("yyyy-MM-DD") + ".xlsx");
  447. }
  448. });
  449. }
  450. });
  451. };
  452. </script>
  453. <style lang="scss" scoped>
  454. ::v-deep(.el-input-number .el-input__inner) {
  455. text-align: left;
  456. }
  457. </style>