index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. <template>
  2. <div class="my-container">
  3. <div class="bill-main" v-show="isShow==='home'" key="index">
  4. <module-view :propConfig="config" ref="moduleView" @pagination="getDataList" @search="getDataList"
  5. @resert="onRefresh" @detail="openEdit" @onRefresh="onRefresh">
  6. </module-view>
  7. </div>
  8. <!-- 新增/编辑弹窗 -->
  9. <div class="detail" v-show="isShow==='detail'" key="index2">
  10. <by-tool :propConfig="toolConfig" @clickHandle="insideTools" />
  11. <div class="box-shadow" style="height: 100%;">
  12. <by-table :propConfig="skuConfig" @onChangeRow="getInputValue" ref="addFormId"></by-table>
  13. </div>
  14. </div>
  15. <StoreRecord ref="StoreRecord" />
  16. </div>
  17. </template>
  18. <script lang="ts">
  19. import { Component, Prop, Vue, Watch } from "vue-property-decorator";
  20. import api from "@/api/currency";
  21. import ForTab from "@/components/ForTab/index.vue";
  22. import wmsStatus from "./components/wmsStatus.vue"
  23. import StoreRecord from "./components/storeRecord.vue";
  24. @Component({ components: { ForTab,StoreRecord } })
  25. export default class Sku extends Vue {
  26. // 右边
  27. isShow : any = 'home'
  28. timeNum = 0;
  29. calculateCount = 0;
  30. baseInfo : any = ''
  31. timer : any = null
  32. toolConfig = {
  33. tools: {
  34. return: true,
  35. save: true,
  36. },
  37. customTools: [
  38. {
  39. name: '同步WMS', icon: 'el-icon-top', audit: [''], event: {
  40. click: () => {
  41. (this as any).syncSystem2()
  42. }
  43. }
  44. }
  45. ]
  46. }
  47. skuConfig : any = {
  48. attr: {
  49. size: 'mini',
  50. align: 'left',
  51. editRules: {
  52. skuTitle: [
  53. { required: true, message: '请输入标题'}
  54. ],
  55. skuCode: [
  56. { required: true, message: '请输入物料编码'}
  57. ],
  58. barCode: [
  59. { required: true, message: '请输入69码-商品条码'}
  60. ]
  61. }
  62. },
  63. columns: [
  64. {
  65. width: '200px',
  66. title: '标题(必填项)',
  67. field: 'skuTitle',
  68. component: 'by-input',
  69. compConfig: {
  70. attr: {
  71. size: 'mini',
  72. placeholder: ' '
  73. },
  74. }
  75. },
  76. {
  77. width: '200px',
  78. title: '副标题',
  79. field: 'skuSubtitle',
  80. component: 'by-input',
  81. compConfig: {
  82. attr: {
  83. size: 'mini',
  84. placeholder: ' '
  85. },
  86. }
  87. },
  88. {
  89. width: '140px',
  90. title: '物料编码(必填项)',
  91. field: 'skuCode',
  92. component: 'by-input',
  93. compConfig: {
  94. attr: {
  95. size: 'mini',
  96. placeholder: ' '
  97. },
  98. }
  99. },
  100. {
  101. width: '110px',
  102. title: '69码-商品条码(必填项)',
  103. field: 'barCode',
  104. component: 'by-input',
  105. compConfig: {
  106. attr: {
  107. size: 'mini',
  108. placeholder: ' '
  109. },
  110. }
  111. },
  112. {
  113. width: '140px',
  114. title: '财务编号',
  115. field: 'financialCode',
  116. component: 'by-input',
  117. compConfig: {
  118. attr: {
  119. size: 'mini',
  120. placeholder: ' '
  121. },
  122. }
  123. },
  124. {
  125. width: '90px',
  126. title: '价格',
  127. field: 'price',
  128. component: 'by-input',
  129. compConfig: {
  130. attr: {
  131. size: 'mini',
  132. placeholder: ' ',
  133. type: "number",
  134. defaultValue: 0,
  135. min: 0
  136. },
  137. }
  138. },
  139. {
  140. width: '90px',
  141. title: '单位',
  142. field: 'unit',
  143. component: 'by-input',
  144. compConfig: {
  145. attr: {
  146. size: 'mini',
  147. placeholder: ' ',
  148. },
  149. }
  150. },
  151. {
  152. width: '90px',
  153. title: '单位编码',
  154. field: 'unitCode',
  155. component: 'by-input',
  156. compConfig: {
  157. attr: {
  158. size: 'mini',
  159. placeholder: ' ',
  160. },
  161. }
  162. },
  163. {
  164. width: '110px',
  165. title: '保质期(天)',
  166. field: 'shelfLife',
  167. component: 'by-input',
  168. compConfig: {
  169. attr: {
  170. size: 'mini',
  171. placeholder: ' ',
  172. type: "integer",
  173. min: 0
  174. },
  175. }
  176. },
  177. {
  178. width: '90px',
  179. title: '重量/g',
  180. field: 'weight',
  181. component: 'by-input',
  182. compConfig: {
  183. attr: {
  184. size: 'mini',
  185. placeholder: ' ',
  186. type: "number",
  187. min: 0
  188. },
  189. }
  190. },
  191. {
  192. width: '90px',
  193. title: '长/cm',
  194. field: 'length',
  195. component: 'by-input',
  196. compConfig: {
  197. attr: {
  198. size: 'mini',
  199. placeholder: ' ',
  200. type: "number",
  201. min: 0
  202. },
  203. }
  204. },
  205. {
  206. width: '90px',
  207. title: '宽/cm',
  208. field: 'width',
  209. component: 'by-input',
  210. compConfig: {
  211. attr: {
  212. size: 'mini',
  213. placeholder: ' ',
  214. type: "number",
  215. min: 0
  216. },
  217. }
  218. },
  219. {
  220. width: '90px',
  221. title: '高/cm',
  222. field: 'height',
  223. component: 'by-input',
  224. compConfig: {
  225. attr: {
  226. size: 'mini',
  227. placeholder: ' ',
  228. type: "number",
  229. min: 0
  230. },
  231. }
  232. },
  233. {
  234. // width: '90px',
  235. title: '体积/cm³',
  236. width:90,
  237. field: 'volume',
  238. },
  239. ]
  240. }
  241. config : any = {
  242. search: {
  243. attr: {
  244. size: 'mini',
  245. },
  246. columns: [
  247. [
  248. {
  249. span: 6,
  250. label: '物料编码',
  251. prop: 'skuCode',
  252. component: 'by-input',
  253. labelWidth: '70px',
  254. compConfig: {
  255. attr: {
  256. placeholder: '请输入物料编码',
  257. clearable: true
  258. }
  259. }
  260. },
  261. {
  262. span: 6,
  263. label: '69码-商品条码',
  264. prop: 'barCode',
  265. labelWidth: '130px',
  266. component: 'by-input',
  267. compConfig: {
  268. attr: {
  269. placeholder: '69码-商品条码',
  270. clearable: true
  271. }
  272. }
  273. },
  274. {
  275. span: 6,
  276. label: '财务编号',
  277. prop: 'accountingCode',
  278. component: 'by-input',
  279. compConfig: {
  280. attr: {
  281. placeholder: '请输入财务编号',
  282. clearable: true
  283. }
  284. }
  285. },
  286. {
  287. span: 6,
  288. label: '商品名称',
  289. prop: 'name',
  290. component: 'by-input',
  291. compConfig: {
  292. attr: {
  293. placeholder: '请输入商品名称',
  294. clearable: true
  295. }
  296. }
  297. }
  298. ],
  299. ]
  300. },
  301. tool: {
  302. tools: {
  303. search: true,
  304. refresh: true,
  305. },
  306. customTools: [
  307. {
  308. name: '同步WMS', icon: 'el-icon-top', audit: [''], event: {
  309. click: () => {
  310. (this as any).syncSystem()
  311. }
  312. }
  313. },
  314. {
  315. name: '商品监控', icon: 'el-icon-document', event: {
  316. click: () => {
  317. let data = (this.$refs.moduleView as any).getSelectData();
  318. if(data.length !== 1) {
  319. this.$message('请选择一条SKU商品!')
  320. return
  321. }
  322. (this.$refs.StoreRecord as any).setShow(true);
  323. (this.$refs.StoreRecord as any).setData(data[0]);
  324. }
  325. }
  326. }
  327. ]
  328. },
  329. table: {
  330. attr: {
  331. size: 'mini',
  332. align: 'left',
  333. height: '620',
  334. checkbox: true,
  335. triggerRowCheck:'row'
  336. },
  337. columns: [
  338. {
  339. width: '200px',
  340. title: '标题',
  341. field: 'skuTitle',
  342. isDetail: true,
  343. fixed: 'left'
  344. },
  345. {
  346. width: '200px',
  347. title: '副标题',
  348. field: 'skuSubtitle',
  349. },
  350. {
  351. width: '140px',
  352. title: '物料编码',
  353. field: 'skuCode',
  354. },
  355. {
  356. width: '140px',
  357. title: '69码-商品条码',
  358. field: 'barCode',
  359. },
  360. {
  361. width: '140px',
  362. title: '财务编号',
  363. field: 'financialCode',
  364. },
  365. {
  366. width: '200px',
  367. title: '商品名称',
  368. field: 'extData',
  369. },
  370. {
  371. width: '80px',
  372. title: '是否已同步WMS',
  373. field: 'isSynchronousWMS',
  374. component: wmsStatus,
  375. },
  376. {
  377. width: '80px',
  378. title: '价格',
  379. field: 'price',
  380. },
  381. {
  382. width: '80px',
  383. title: '单位',
  384. field: 'unit',
  385. },
  386. {
  387. width: '80px',
  388. title: '单位编码',
  389. field: 'unitCode',
  390. },
  391. {
  392. width: '100px',
  393. title: '保质期(天)',
  394. field: 'shelfLife',
  395. },
  396. {
  397. width: '80px',
  398. title: '重量/g',
  399. field: 'weight',
  400. },
  401. {
  402. width: '80px',
  403. title: '长/cm',
  404. field: 'length',
  405. },
  406. {
  407. width: '80px',
  408. title: '宽/cm',
  409. field: 'width',
  410. },
  411. {
  412. width: '80px',
  413. title: '高/cm',
  414. field: 'height',
  415. },
  416. {
  417. width: '90px',
  418. title: '体积/cm³',
  419. field: 'volume',
  420. },
  421. {
  422. width: 70,
  423. title: '操作',
  424. action: true,
  425. plugins: [{
  426. icon: 'el-icon-edit',
  427. name: '编辑',
  428. audit: '',
  429. event: {
  430. click: (item : any) => {
  431. (this as any).openEdit(item)
  432. }
  433. }
  434. }]
  435. },
  436. ]
  437. },
  438. }
  439. mounted() {
  440. this.timer = setInterval(() => {
  441. this.getDataList();
  442. this.initTable();
  443. }, 300)
  444. }
  445. // 计算高度
  446. initTable() {
  447. if (!this.$refs.moduleView) {
  448. this.calculateCount++;
  449. if (this.calculateCount > 5) return;
  450. setTimeout(() => {
  451. this.initTable()
  452. }, 500)
  453. return
  454. }
  455. let tableId : any = (this as any).$refs.moduleView.tableID;
  456. this.config.table.attr.height = window.innerHeight - 320;
  457. (this as any).$refs.moduleView.$refs[tableId].recalculate();
  458. }
  459. // 同步财务系统
  460. syncSystem() {
  461. let selectData = (this as any).$refs.moduleView.getSelectData();
  462. if (selectData.length > 0) {
  463. // if (selectData.length > 1) return this.$message.warning('只能同步一条数据');
  464. // if (selectData[0].financialCode) return this.$message.warning('此数据已同步WMS');
  465. this.$confirm('确定同步WMS吗', '注意', {
  466. confirmButtonText: '确定',
  467. cancelButtonText: '取消',
  468. type: 'warning',
  469. center: true
  470. }).then(() => {
  471. let ids = '';
  472. selectData.map((v : any) => {
  473. ids += v.id + ','
  474. })
  475. ids = ids.slice(0, ids.length - 1);
  476. let loading = this.$loading({ target: '.main-container' });
  477. api.WMSPushProducts({ ids: ids }).then((res : any) => {
  478. if (res.code === 200) {
  479. this.$message.success('同步WMS成功');
  480. loading.close();
  481. this.getDataList();
  482. } else loading.close();
  483. }).catch(() => loading.close());
  484. }).catch(() => this.$message.info('已取消同步WMS'));
  485. } else this.$message.warning('请选择同步数据');
  486. }
  487. syncSystem2() {
  488. this.$confirm('确定同步WMS吗', '注意', {
  489. confirmButtonText: '确定',
  490. cancelButtonText: '取消',
  491. type: 'warning',
  492. center: true
  493. }).then(() => {
  494. let loading = this.$loading({ target: '.main-container' });
  495. api.WMSPushProducts({ ids: this.baseInfo.id }).then((res : any) => {
  496. if (res.code === 200) {
  497. this.$message.success('同步WMS成功');
  498. loading.close();
  499. this.getDataList();
  500. } else loading.close();
  501. }).catch(() => loading.close());
  502. }).catch(() => this.$message.info('已取消同步WMS'));
  503. }
  504. // 保存
  505. doFormData() {
  506. let data : any = (this as any).$refs.addFormId.getValue();
  507. (this.$refs.addFormId as any).validate();
  508. if (!data[0].skuTitle) return this.$message.warning('物料标题不能为空');
  509. if (!data[0].skuCode) return this.$message.warning('物料编码不能为空');
  510. if (!data[0].barCode) return this.$message.warning('物料属性的69码-商品条码需必填');
  511. if (!/^\d{1,32}$/.test(data[0].barCode)){
  512. return this.$message.warning('69码-商品条码为数字,最大32位');
  513. }
  514. if (!/^[a-zA-Z0-9]+$/.test(data[0].skuCode)){
  515. return this.$message.warning('物料编码只能是字母和数字');
  516. }
  517. api.updateList(data[0], 'maindataMaterialSku').then((res : any) => {
  518. if (res.code === 200) {
  519. this.$message.success('编辑成功');
  520. this.isShow = 'home';
  521. this.getDataList();
  522. } else this.$message.error(res.msg);
  523. }).catch(() => {});
  524. }
  525. // 获取列表数据
  526. getDataList() {
  527. if (!this.$refs.moduleView) {
  528. if (this.timeNum > 5) {
  529. clearInterval(this.timer)
  530. }
  531. this.timeNum++;
  532. return
  533. }
  534. clearInterval(this.timer)
  535. let query = (this.$refs.moduleView as any).getQuery();
  536. // console.log('表单字段 ==> ', query);
  537. this.getPageList(query)
  538. }
  539. getPageList(query : any) {
  540. let loading = this.$loading({ target: '.main-container' });
  541. api.pageList(query, 'maindataMaterialSku').then((res : any) => {
  542. loading.close();
  543. if (res.code === 200) {
  544. res.data.records.map((v : any, i : any) => {
  545. if(v.volume&&v.weight!='0.00'&&v.weight!=0&&v.weight!='0'){
  546. v.weight = parseFloat(v.weight).toFixed(2)
  547. }
  548. if(v.volume&&v.volume!='0.00'&&v.volume!=0&&v.volume!='0'){
  549. v.volume = parseFloat(v.volume).toFixed(2)
  550. }
  551. });
  552. (this.$refs.moduleView as any).setTableValue(res.data.records);
  553. let page = {
  554. pageNo: res.data.current, //当前页
  555. pageSize: res.data.size, //每页条数
  556. total: res.data.total //总条数
  557. };
  558. (this.$refs.moduleView as any).setPage(page);
  559. } else this.$message.error(res.msg);
  560. }).catch(() => loading.close());
  561. }
  562. // 打开编辑
  563. openEdit(e : any) {
  564. let loading = this.$loading({ target: '.main-container' });
  565. api.single({ id: e.id }, 'maindataMaterialSku').then((res : any) => {
  566. if (res.code === 200) {
  567. this.baseInfo = res.data;
  568. this.isShow = 'detail';
  569. loading.close();
  570. if(res.data.volume&&res.data.volume!='0.00'&&res.data.volume!=0&&res.data.volume!='0'){
  571. res.data.volume = parseFloat(res.data.volume).toFixed(2)
  572. }
  573. setTimeout(() => { (this as any).$refs.addFormId.setValue([res.data]) }, 0);
  574. } else loading.close();
  575. }).catch(() => loading.close());
  576. }
  577. // 监听表格数据
  578. getInputValue(e : any) {
  579. // console.log('监听表格 ==> ', e);
  580. if (e.length && e.width && e.height) {
  581. e.volume = (e.length * e.width * e.height).toFixed(2);
  582. }
  583. }
  584. // 内页工具栏方法
  585. insideTools(e : any) {
  586. if (e === 'onReturn') this.isShow = 'home';
  587. if (e === 'onSave') this.doFormData();
  588. }
  589. // 刷新/重置
  590. onRefresh() {
  591. (this as any).$refs.moduleView.clearSearch();
  592. this.getDataList();
  593. }
  594. }
  595. </script>
  596. <style lang="scss" scoped>
  597. .my-container {
  598. width: 100%;
  599. box-sizing: border-box;
  600. display: flex;
  601. padding: 16px;
  602. height: 100%;
  603. .bill-left {
  604. position: relative;
  605. border-right: solid #EEE 1px;
  606. flex-shrink: 0;
  607. .bill-tab {
  608. width: 150px;
  609. height: 100%;
  610. transition: all .5s;
  611. overflow: hidden;
  612. }
  613. .tab-title {
  614. font-size: 16px;
  615. padding-bottom: 16px;
  616. width: 200px;
  617. }
  618. }
  619. .bill-main {
  620. width: 100%;
  621. box-sizing: border-box;
  622. position: relative;
  623. height: 100%;
  624. overflow-y: hidden;
  625. }
  626. .detail {
  627. width: 100%;
  628. padding: 16px;
  629. .box-shadow {
  630. box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
  631. padding: 20px;
  632. border-radius: 4px;
  633. border: 1px solid #e6ebf5;
  634. background-color: #fff;
  635. overflow: hidden;
  636. color: #303133;
  637. -webkit-transition: .3s;
  638. transition: .3s;
  639. margin-top: 20px;
  640. }
  641. }
  642. }
  643. </style>