product-list.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <template>
  2. <el-dialog
  3. title="选择物品"
  4. :visible.sync="visible"
  5. :before-close="handleClose"
  6. :close-on-click-modal="false"
  7. top="5vh"
  8. :close-on-press-escape="false"
  9. append-to-body
  10. width="70%"
  11. >
  12. <el-card shadow="never">
  13. <searchProduct @search="reload"></searchProduct>
  14. <ele-split-layout
  15. width="244px"
  16. allow-collapse
  17. :right-style="{ overflow: 'hidden' }"
  18. >
  19. <div class="ele-border-lighter split-layout-right-content">
  20. <productTree
  21. @handleNodeClick="handleNodeClick"
  22. :isFirstRefreshTable="false"
  23. ref="treeList"
  24. />
  25. </div>
  26. <!-- 表格 -->
  27. <template v-slot:content>
  28. <ele-pro-table
  29. ref="table"
  30. :columns="columns"
  31. :datasource="datasource"
  32. @row-dblclick="handleDoubleClick"
  33. row-key="id"
  34. height="calc(100vh - 480px)"
  35. class="dict-table"
  36. @cell-click="cellClick"
  37. :selection.sync="selection"
  38. >
  39. <!-- 表头工具栏 -->
  40. <template v-slot:action="{ row }">
  41. <el-radio class="radio" v-model="radio" :label="row.code"
  42. ><i></i
  43. ></el-radio>
  44. </template>
  45. </ele-pro-table>
  46. </template>
  47. </ele-split-layout>
  48. </el-card>
  49. <div slot="footer">
  50. <el-button type="primary" size="small" @click="selected">选择</el-button>
  51. <el-button size="small" @click="handleClose">关闭</el-button>
  52. </div>
  53. </el-dialog>
  54. </template>
  55. <script>
  56. import { getProductList } from '@/api/bpm/components/saleManage/contact.js';
  57. import {
  58. getInventoryTotalAPI,
  59. getCategoryPackageDisposition
  60. } from '@/api/bpm/components/wms/index.js';
  61. import searchProduct from './searchProduct.vue';
  62. import productTree from '@/components/productTree/index.vue';
  63. export default {
  64. components: {
  65. productTree,
  66. searchProduct
  67. },
  68. props: {
  69. /*是否需要获取仓库产品数量*/
  70. isGetInventoryTotal: {
  71. type: Boolean,
  72. default: false
  73. },
  74. /*已选择的产品*/
  75. data: {
  76. type: Array,
  77. default: () => []
  78. },
  79. /*是否需要cBom*/
  80. isShowCBom: {
  81. type: Boolean,
  82. default: false
  83. }
  84. },
  85. data() {
  86. return {
  87. visible: false,
  88. currentIndex: null,
  89. radio: null,
  90. cBomListDialogFlag: null,
  91. dictList: {},
  92. selection: []
  93. };
  94. },
  95. watch: {},
  96. computed: {
  97. columns() {
  98. return [
  99. {
  100. action: 'action',
  101. slot: 'action',
  102. align: 'center',
  103. label: '选择',
  104. show: this.currentIndex != -1
  105. },
  106. {
  107. label: '选择',
  108. show: this.currentIndex == -1,
  109. width: 45,
  110. type: 'selection',
  111. columnKey: 'selection',
  112. align: 'center'
  113. },
  114. {
  115. columnKey: 'index',
  116. type: 'index',
  117. width: 50,
  118. align: 'center',
  119. showOverflowTooltip: true,
  120. label: '序号'
  121. },
  122. {
  123. prop: 'code',
  124. label: '编码',
  125. align: 'center',
  126. showOverflowTooltip: true,
  127. minWidth: 110
  128. },
  129. {
  130. prop: 'name',
  131. label: '名称',
  132. align: 'center',
  133. showOverflowTooltip: true,
  134. minWidth: 110
  135. },
  136. {
  137. prop: 'imgCode',
  138. align: 'center',
  139. label: '图号/件号',
  140. showOverflowTooltip: true,
  141. minWidth: 110
  142. },
  143. // {
  144. // prop: 'extField.approvalNumber',
  145. // align: 'center',
  146. // label: '批准文号',
  147. // showOverflowTooltip: true,
  148. // minWidth: 110
  149. // },
  150. {
  151. prop: 'extField.packingSpecification',
  152. align: 'center',
  153. label: '包装规格',
  154. showOverflowTooltip: true,
  155. minWidth: 110
  156. },
  157. {
  158. prop: 'brandNum',
  159. align: 'center',
  160. label: '牌号',
  161. showOverflowTooltip: true
  162. },
  163. {
  164. prop: 'modelType',
  165. label: '型号',
  166. align: 'center',
  167. showOverflowTooltip: true
  168. },
  169. {
  170. prop: 'specification',
  171. label: '规格',
  172. align: 'center',
  173. showOverflowTooltip: true
  174. },
  175. {
  176. prop: 'measuringUnit',
  177. label: '计量单位',
  178. showOverflowTooltip: true,
  179. align: 'center',
  180. minWidth: 90
  181. },
  182. {
  183. prop: 'weightUnit',
  184. label: '重量单位',
  185. showOverflowTooltip: true,
  186. align: 'center',
  187. minWidth: 90
  188. },
  189. {
  190. prop: 'roughWeight',
  191. label: '毛重',
  192. showOverflowTooltip: true,
  193. align: 'center',
  194. minWidth: 90
  195. },
  196. {
  197. prop: 'netWeight',
  198. label: '净重',
  199. showOverflowTooltip: true,
  200. align: 'center',
  201. minWidth: 90
  202. },
  203. {
  204. prop: 'packingUnit',
  205. align: 'center',
  206. label: '单位',
  207. showOverflowTooltip: true
  208. },
  209. {
  210. prop: 'categoryLevelPath',
  211. label: '分类',
  212. align: 'center',
  213. showOverflowTooltip: true
  214. },
  215. {
  216. slot: 'cz',
  217. align: 'center',
  218. minWidth: 90,
  219. fixed: 'right',
  220. label: '操作',
  221. show: this.isShowCBom
  222. }
  223. ];
  224. }
  225. },
  226. methods: {
  227. getDictV(code, val) {
  228. if (!this.dictList[code]) return '';
  229. return this.dictList[code].find((item) => item.value == val)?.label;
  230. },
  231. open(item, currentIndex) {
  232. this.currentIndex = currentIndex;
  233. this.visible = true;
  234. },
  235. /* 表格数据源 */
  236. datasource({ page, limit, where, order }) {
  237. return getProductList({
  238. pageNum: page,
  239. size: limit,
  240. ...where,
  241. isEnable: 1
  242. });
  243. },
  244. /* 刷新表格 */
  245. reload(where) {
  246. this.$refs.table.reload({ pageNum: 1, where: where, isEnable: 1 });
  247. },
  248. handleNodeClick(data, node) {
  249. this.curNodeData = data;
  250. this.reload({ categoryLevelId: data.id });
  251. },
  252. // 单击获取id
  253. cellClick(row) {
  254. if (this.currentIndex == -1) return;
  255. this.current = row;
  256. this.radio = row.id;
  257. },
  258. handleDoubleClick(row) {
  259. if (!this.isShowCBom) return;
  260. this.cBomListDialogFlag = true;
  261. this.current = row;
  262. this.$nextTick(() => {
  263. this.$refs.cBomRef.open(row);
  264. });
  265. },
  266. getSelectionCbom(rows = []) {
  267. this.$emit('getSelectionCbom', rows);
  268. this.handleClose();
  269. },
  270. handleClose() {
  271. this.visible = false;
  272. this.current = null;
  273. this.selection = [];
  274. this.$refs.table.clearSelection();
  275. this.radio = '';
  276. },
  277. async selected() {
  278. if (!this.current && !this.selection.length) {
  279. return this.$message.warning('请至少选择一条数据');
  280. }
  281. if (this.currentIndex != -1) {
  282. if (
  283. this.data
  284. .map((item) => item.productCode)
  285. .includes(this.current.code)
  286. ) {
  287. return this.$message.error('选择的产品已经存在列表了');
  288. }
  289. } else {
  290. if (
  291. this.selection.some((item) =>
  292. this.data.some((i) => i.productCode == item.code)
  293. )
  294. ) {
  295. return this.$message.error('选择的产品已经存在列表了');
  296. }
  297. }
  298. let list = this.currentIndex == -1 ? this.selection : [this.current];
  299. let codeList = list.map((item) => item.code);
  300. let idList = list.map((item) => item.id);
  301. //获取仓库库存
  302. if (this.isGetInventoryTotal) {
  303. let inventoryTotalList = await getInventoryTotalAPI(codeList);
  304. list.forEach((item) => {
  305. let find =
  306. inventoryTotalList.find((key) => key.code == item.code) || {};
  307. item.availableCountBase = find.availableCountBase;
  308. });
  309. }
  310. // 获取包装规格
  311. let packingSpecification = await getCategoryPackageDisposition({
  312. categoryIds: idList
  313. });
  314. list.forEach((item) => {
  315. item['packageDispositionList'] = packingSpecification
  316. .filter((ite) => item.id == ite.categoryId && ite.conversionUnit)
  317. .sort((a, b) => a.sort - b.sort);
  318. });
  319. this.$emit('changeParent', list, this.currentIndex);
  320. this.handleClose();
  321. }
  322. }
  323. };
  324. </script>
  325. <style lang="scss" scoped>
  326. .tree_col {
  327. border: 1px solid #eee;
  328. padding: 10px 0;
  329. box-sizing: border-box;
  330. height: 500px;
  331. overflow: auto;
  332. }
  333. .table_col {
  334. padding-left: 10px;
  335. ::v-deep .el-table th.el-table__cell {
  336. background: #f2f2f2;
  337. }
  338. }
  339. .pagination {
  340. text-align: right;
  341. padding: 10px 0;
  342. }
  343. .btns {
  344. text-align: center;
  345. padding: 10px 0;
  346. }
  347. .topsearch {
  348. margin-bottom: 15px;
  349. }
  350. </style>