product-list.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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 { getInventoryTotalAPI } from '@/api/bpm/components/wms/index.js';
  58. import searchProduct from './searchProduct.vue';
  59. import productTree from '@/components/productTree/index.vue';
  60. export default {
  61. components: {
  62. productTree,
  63. searchProduct
  64. },
  65. props: {
  66. /*是否需要获取仓库产品数量*/
  67. isGetInventoryTotal: {
  68. type: Boolean,
  69. default: false
  70. },
  71. /*已选择的产品*/
  72. data: {
  73. type: Array,
  74. default: () => []
  75. },
  76. /*是否需要cBom*/
  77. isShowCBom: {
  78. type: Boolean,
  79. default: false
  80. }
  81. },
  82. data() {
  83. return {
  84. visible: false,
  85. currentIndex: null,
  86. radio: null,
  87. cBomListDialogFlag: null,
  88. dictList: {},
  89. selection: []
  90. };
  91. },
  92. watch: {},
  93. computed: {
  94. columns() {
  95. return [
  96. {
  97. action: 'action',
  98. slot: 'action',
  99. align: 'center',
  100. label: '选择',
  101. show: this.currentIndex != -1
  102. },
  103. {
  104. label: '选择',
  105. show: this.currentIndex == -1,
  106. width: 45,
  107. type: 'selection',
  108. columnKey: 'selection',
  109. align: 'center'
  110. },
  111. {
  112. columnKey: 'index',
  113. type: 'index',
  114. width: 50,
  115. align: 'center',
  116. showOverflowTooltip: true,
  117. label: '序号'
  118. },
  119. {
  120. prop: 'code',
  121. label: '编码',
  122. align: 'center',
  123. showOverflowTooltip: true,
  124. minWidth: 110
  125. },
  126. {
  127. prop: 'name',
  128. label: '名称',
  129. align: 'center',
  130. showOverflowTooltip: true,
  131. minWidth: 110
  132. },
  133. {
  134. prop: 'imgCode',
  135. align: 'center',
  136. label: '图号/件号',
  137. showOverflowTooltip: true,
  138. minWidth: 110
  139. },
  140. {
  141. prop: 'extField.approvalNumber',
  142. align: 'center',
  143. label: '批准文号',
  144. showOverflowTooltip: true,
  145. minWidth: 110
  146. },
  147. {
  148. prop: 'extField.packingSpecification',
  149. align: 'center',
  150. label: '包装规格',
  151. showOverflowTooltip: true,
  152. minWidth: 110
  153. },
  154. {
  155. prop: 'brandNum',
  156. align: 'center',
  157. label: '牌号',
  158. showOverflowTooltip: true
  159. },
  160. {
  161. prop: 'modelType',
  162. label: '型号',
  163. align: 'center',
  164. showOverflowTooltip: true
  165. },
  166. {
  167. prop: 'specification',
  168. label: '规格',
  169. align: 'center',
  170. showOverflowTooltip: true
  171. },
  172. {
  173. prop: 'measuringUnit',
  174. label: '计量单位',
  175. showOverflowTooltip: true,
  176. align: 'center',
  177. minWidth: 90
  178. },
  179. {
  180. prop: 'weightUnit',
  181. label: '重量单位',
  182. showOverflowTooltip: true,
  183. align: 'center',
  184. minWidth: 90
  185. },
  186. {
  187. prop: 'roughWeight',
  188. label: '毛重',
  189. showOverflowTooltip: true,
  190. align: 'center',
  191. minWidth: 90
  192. },
  193. {
  194. prop: 'netWeight',
  195. label: '净重',
  196. showOverflowTooltip: true,
  197. align: 'center',
  198. minWidth: 90
  199. },
  200. {
  201. prop: 'packingUnit',
  202. align: 'center',
  203. label: '单位',
  204. showOverflowTooltip: true
  205. },
  206. {
  207. prop: 'categoryLevelPath',
  208. label: '分类',
  209. align: 'center',
  210. showOverflowTooltip: true
  211. },
  212. {
  213. slot: 'cz',
  214. align: 'center',
  215. minWidth: 90,
  216. fixed: 'right',
  217. label: '操作',
  218. show: this.isShowCBom
  219. }
  220. ];
  221. }
  222. },
  223. methods: {
  224. getDictV(code, val) {
  225. if (!this.dictList[code]) return '';
  226. return this.dictList[code].find((item) => item.value == val)?.label;
  227. },
  228. open(item, currentIndex) {
  229. this.currentIndex = currentIndex;
  230. this.visible = true;
  231. },
  232. /* 表格数据源 */
  233. datasource({ page, limit, where, order }) {
  234. return getProductList({
  235. pageNum: page,
  236. size: limit,
  237. ...where
  238. });
  239. },
  240. /* 刷新表格 */
  241. reload(where) {
  242. this.$refs.table.reload({ pageNum: 1, where: where });
  243. },
  244. handleNodeClick(data, node) {
  245. this.curNodeData = data;
  246. this.reload({ categoryLevelId: data.id });
  247. },
  248. // 单击获取id
  249. cellClick(row) {
  250. if (this.currentIndex == -1) return;
  251. this.current = row;
  252. this.radio = row.id;
  253. },
  254. handleDoubleClick(row) {
  255. if (!this.isShowCBom) return;
  256. this.cBomListDialogFlag = true;
  257. this.current = row;
  258. this.$nextTick(() => {
  259. this.$refs.cBomRef.open(row);
  260. });
  261. },
  262. getSelectionCbom(rows = []) {
  263. this.$emit('getSelectionCbom', rows);
  264. this.handleClose();
  265. },
  266. handleClose() {
  267. this.visible = false;
  268. this.current = null;
  269. this.selection = [];
  270. this.$refs.table.clearSelection();
  271. this.radio = '';
  272. },
  273. async selected() {
  274. if (!this.current && !this.selection.length) {
  275. return this.$message.warning('请至少选择一条数据');
  276. }
  277. if (this.currentIndex != -1) {
  278. if (
  279. this.data
  280. .map((item) => item.productCode)
  281. .includes(this.current.code)
  282. ) {
  283. return this.$message.error('选择的产品已经存在列表了');
  284. }
  285. } else {
  286. if (
  287. this.selection.some((item) =>
  288. this.data.some((i) => i.productCode == item.code)
  289. )
  290. ) {
  291. return this.$message.error('选择的产品已经存在列表了');
  292. }
  293. }
  294. let codeList = [];
  295. let list = this.currentIndex == -1 ? this.selection : [this.current];
  296. //获取仓库库存
  297. if (this.isGetInventoryTotal) {
  298. codeList = list.map((item) => item.code);
  299. let inventoryTotalList = await getInventoryTotalAPI(codeList);
  300. list.forEach((item) => {
  301. let find =
  302. inventoryTotalList.find((key) => key.code == item.code) || {};
  303. item.availableCountBase = find.availableCountBase;
  304. });
  305. }
  306. this.$emit('changeParent', list, this.currentIndex);
  307. this.handleClose();
  308. }
  309. }
  310. };
  311. </script>
  312. <style lang="scss" scoped>
  313. .tree_col {
  314. border: 1px solid #eee;
  315. padding: 10px 0;
  316. box-sizing: border-box;
  317. height: 500px;
  318. overflow: auto;
  319. }
  320. .table_col {
  321. padding-left: 10px;
  322. ::v-deep .el-table th.el-table__cell {
  323. background: #f2f2f2;
  324. }
  325. }
  326. .pagination {
  327. text-align: right;
  328. padding: 10px 0;
  329. }
  330. .btns {
  331. text-align: center;
  332. padding: 10px 0;
  333. }
  334. .topsearch {
  335. margin-bottom: 15px;
  336. }
  337. </style>