SelectGoods.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. <template>
  2. <div>
  3. <byTable
  4. ref="table"
  5. :source="sourceList.data"
  6. :pagination="sourceList.pagination"
  7. :config="config"
  8. :loading="loading"
  9. highlight-current-row
  10. :selectConfig="selectConfig"
  11. :table-events="{
  12. //element talbe事件都能传
  13. select: select,
  14. }"
  15. :action-list="[]"
  16. @get-list="getList"
  17. >
  18. </byTable>
  19. <div>
  20. <div>已选择货品</div>
  21. <div style="margin: 10px 0px">
  22. <el-tag
  23. style="margin-right: 10px"
  24. type="info"
  25. closable
  26. v-for="(good, index) in goodList"
  27. :key="good.id"
  28. @close="handleRemove(index)"
  29. >{{ good.name }}</el-tag
  30. >
  31. </div>
  32. <div style="text-align: center">
  33. <el-button @click="handleCancel" size="large">取消</el-button>
  34. <el-button type="primary" @click="handleSubmit" size="large">
  35. 确 定
  36. </el-button>
  37. </div>
  38. </div>
  39. </div>
  40. </template>
  41. <script setup>
  42. /* eslint-disable vue/no-unused-components */
  43. import { ElMessage, ElMessageBox } from "element-plus";
  44. import byTable from "@/components/byTable/index";
  45. import byForm from "@/components/byForm/index";
  46. import treeList from "@/components/product/treeList";
  47. import { computed, defineComponent, ref, watch } from "vue";
  48. const loading = ref(false);
  49. const submitLoading = ref(false);
  50. const sourceList = ref({
  51. data: [],
  52. pagination: {
  53. total: 3,
  54. pageNum: 1,
  55. pageSize: 10,
  56. type: "",
  57. productClassifyId: "",
  58. keyword: "",
  59. definition: "1",
  60. },
  61. });
  62. let dialogVisible = ref(false);
  63. let openExcelDialog = ref(false);
  64. let modalType = ref("add");
  65. let rules = ref({
  66. productClassifyId: [
  67. { required: true, message: "请选择产品分类", trigger: "change" },
  68. ],
  69. type: [{ required: true, message: "请选择产品类型", trigger: "change" }],
  70. name: [{ required: true, message: "请输入产品名称", trigger: "blur" }],
  71. unit: [{ required: true, message: "请选择单位", trigger: "change" }],
  72. });
  73. const { proxy } = getCurrentInstance();
  74. const selectConfig = reactive([
  75. {
  76. label: "物品类型",
  77. prop: "definition",
  78. isShowAll: false, //不显示全部搜索
  79. data: [
  80. {
  81. label: "产品",
  82. value: "1",
  83. },
  84. {
  85. label: "物料",
  86. value: "2",
  87. },
  88. ],
  89. },
  90. {
  91. label: "所属分类",
  92. prop: "productClassifyId",
  93. data: [],
  94. },
  95. ]);
  96. const config = computed(() => {
  97. return [
  98. {
  99. attrs: {
  100. label: "货品类型",
  101. prop: "type",
  102. },
  103. render(type) {
  104. return sourceList.value.pagination.definition == 1 ? "产品" : "物料";
  105. },
  106. },
  107. {
  108. attrs: {
  109. label: "所属分类",
  110. prop: "classifyName",
  111. },
  112. },
  113. {
  114. attrs: {
  115. label: "货品编码",
  116. prop: "code",
  117. },
  118. },
  119. {
  120. attrs: {
  121. label: "货品名称",
  122. prop: "name",
  123. },
  124. },
  125. {
  126. attrs: {
  127. label: "规格",
  128. prop: "spec",
  129. },
  130. },
  131. {
  132. attrs: {
  133. label: "单位",
  134. prop: "unit",
  135. },
  136. render(unit) {
  137. return proxy.dictValueLabel(unit, productUnit.value);
  138. },
  139. },
  140. {
  141. attrs: {
  142. label: "操作",
  143. width: "60",
  144. align: "center",
  145. fixed: "right",
  146. },
  147. // 渲染 el-button,一般用在最后一列。
  148. renderHTML(row) {
  149. return [
  150. {
  151. attrs: {
  152. label: "选择",
  153. type: "primary",
  154. text: true,
  155. },
  156. el: "button",
  157. click() {
  158. handleSelect(row);
  159. },
  160. },
  161. ];
  162. },
  163. },
  164. ];
  165. });
  166. let formData = reactive({
  167. data: {},
  168. });
  169. const formOption = reactive({
  170. inline: true,
  171. labelWidth: 100,
  172. itemWidth: 100,
  173. rules: [],
  174. });
  175. const byform = ref(null);
  176. const treeListData = ref([]);
  177. const formConfig = computed(() => {
  178. return [
  179. {
  180. type: "treeSelect",
  181. prop: "productClassifyId",
  182. label: "产品分类",
  183. data: [],
  184. },
  185. {
  186. type: "select",
  187. prop: "type",
  188. label: "产品类型",
  189. required: true,
  190. data: [
  191. {
  192. label: "成品",
  193. id: "1",
  194. },
  195. {
  196. label: "半成品",
  197. id: "2",
  198. },
  199. ],
  200. },
  201. {
  202. type: "input",
  203. prop: "name",
  204. label: "产品名称",
  205. },
  206. {
  207. type: "input",
  208. prop: "spec",
  209. label: "规格",
  210. },
  211. {
  212. type: "select",
  213. prop: "unit",
  214. label: "单位",
  215. required: true,
  216. data: [
  217. {
  218. label: "个",
  219. id: "个",
  220. },
  221. {
  222. label: "双",
  223. id: "双",
  224. },
  225. ],
  226. },
  227. {
  228. type: "slot",
  229. slotName: "productPic",
  230. prop: "fileList",
  231. label: "产品图片",
  232. },
  233. {
  234. type: "input",
  235. prop: "remark",
  236. label: "备注",
  237. itemType: "textarea",
  238. },
  239. ];
  240. });
  241. const lastDefinition = ref("");
  242. const getList = async (req = {}) => {
  243. for (const key in req) {
  244. sourceList.value.pagination[key] = req[key];
  245. if (key === "definition") {
  246. if (lastDefinition.value !== req[key]) {
  247. getTreeList();
  248. lastDefinition.value = req[key];
  249. // 如果选择的物品分类不一致,则分类默认选中全部
  250. return table.value.searchItemSelct("all", selectConfig[1]);
  251. }
  252. }
  253. }
  254. sourceList.value.pagination = {
  255. ...sourceList.value.pagination,
  256. ...req,
  257. };
  258. loading.value = true;
  259. proxy
  260. .post("/productInfo/page", sourceList.value.pagination)
  261. .then((message) => {
  262. sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
  263. sourceList.value.pagination.total = message.total;
  264. setTimeout(() => {
  265. loading.value = false;
  266. }, 200);
  267. const productIdList = message.rows.map((x) => x.id);
  268. // 请求文件数据并回显
  269. if (productIdList.length > 0) {
  270. proxy
  271. .post("/fileInfo/getList", { businessIdList: productIdList })
  272. .then((fileObj) => {
  273. for (let i = 0; i < sourceList.value.data.length; i++) {
  274. const e = sourceList.value.data[i];
  275. for (const key in fileObj) {
  276. if (e.id === key) {
  277. e.fileList = fileObj[key];
  278. }
  279. }
  280. }
  281. });
  282. }
  283. });
  284. };
  285. const getTreeList = () => {
  286. proxy
  287. .post("/productClassify/tree", {
  288. parentId: "",
  289. name: "",
  290. definition: sourceList.value.pagination.definition,
  291. })
  292. .then((message) => {
  293. selectConfig[1].data = message.map((x) => ({
  294. label: x.label,
  295. value: x.id,
  296. }));
  297. });
  298. };
  299. const goodList = ref([]);
  300. const handleSelect = (row) => {
  301. const flag = goodList.value.some((x) => x.id === row.id);
  302. if (flag)
  303. return ElMessage({
  304. message: "该产品已选择",
  305. type: "info",
  306. });
  307. goodList.value.push({
  308. ...row,
  309. goodType: sourceList.value.pagination.definition,
  310. });
  311. return ElMessage({
  312. message: "选择成功",
  313. type: "success",
  314. });
  315. };
  316. const handleRemove = (index) => {
  317. goodList.value.splice(index, 1);
  318. return ElMessage({
  319. message: "删除成功",
  320. type: "success",
  321. });
  322. };
  323. const handleSubmit = () => {
  324. if (!goodList.value.length > 0)
  325. return ElMessage({
  326. message: "请添加货品",
  327. type: "info",
  328. });
  329. proxy.$emit("pushGoods", goodList.value);
  330. goodList.value = [];
  331. };
  332. const handleCancel = () => {
  333. goodList.value = [];
  334. proxy.$emit("cancel");
  335. };
  336. const table = ref(null);
  337. const searchItemSelct = () => {
  338. // 默认选中的方法
  339. table.value.searchItemSelct(selectConfig[0].data[0], selectConfig[0]);
  340. };
  341. const productUnit = ref([]);
  342. const getDict = () => {
  343. proxy.getDictOne(["unit"]).then((res) => {
  344. productUnit.value = res["unit"].map((x) => ({
  345. label: x.dictValue,
  346. value: x.dictKey,
  347. }));
  348. });
  349. };
  350. getDict();
  351. onMounted(() => {
  352. searchItemSelct();
  353. });
  354. </script>
  355. <style lang="scss" scoped>
  356. .user {
  357. padding: 20px;
  358. display: flex;
  359. justify-content: space-between;
  360. .tree {
  361. width: 300px;
  362. }
  363. .content {
  364. width: calc(100% - 320px);
  365. }
  366. }
  367. .pic {
  368. object-fit: contain;
  369. width: 50px;
  370. height: 50px;
  371. cursor: pointer;
  372. vertical-align: middle;
  373. }
  374. </style>