index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. <template>
  2. <div class="user">
  3. <div class="tree">
  4. <treeList title="物料分类" submitType="2" :data="treeListData" v-model="sourceList.pagination.productClassifyId" @change="treeChange"
  5. @changeTreeList="getTreeList">
  6. </treeList>
  7. </div>
  8. <div class="content">
  9. <byTable :source="sourceList.data" :tableHeight="tableHeight" :pagination="sourceList.pagination" :config="config" :loading="loading"
  10. highlight-current-row :selectConfig="selectConfig" :action-list="[
  11. {
  12. text: '添加物料',
  13. action: () => openModal('add'),
  14. disabled: false,
  15. },
  16. ]" @get-list="getList">
  17. <template #pic="{ item }">
  18. <div v-if="item.fileList.length > 0">
  19. <img :src="item.fileList[0].fileUrl" class="pic" @click="handleClickFile(item.fileList[0])" />
  20. </div>
  21. <div v-else></div>
  22. </template>
  23. <template #name="{ item }">
  24. <div>
  25. <span class="el-click">{{ item.name }}</span>
  26. </div>
  27. </template>
  28. <template #size="{ item }">
  29. <div v-if="item['length'] && item.width && item.height">
  30. <span>{{ item['length'] }}</span>*
  31. <span>{{ item.width }}</span>*
  32. <span>{{ item.height }}</span>
  33. </div>
  34. <div v-else></div>
  35. </template>
  36. <template #price="{ item }">
  37. <div v-if="item.price">
  38. <span>{{ item.currency }} {{ moneyFormat(item.price ,2)}}</span>
  39. </div>
  40. <div v-else></div>
  41. </template>
  42. <template #costPrice="{ item }">
  43. <div v-if="item.costPrice">
  44. <span>{{ item.currency }} {{ moneyFormat(item.costPrice ,2)}}</span>
  45. </div>
  46. <div v-else></div>
  47. </template>
  48. </byTable>
  49. </div>
  50. <el-dialog :title="modalType == 'add' ? '添加物料' : '编辑物料'" v-model="dialogVisible" width="80%" destroy-on-close>
  51. <div class="public_height_dialog">
  52. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom" v-loading="submitLoading">
  53. <template #size>
  54. <div style="width: 100%">
  55. <el-form-item label="尺寸" class="margin-b-0 wid100" required>
  56. <el-row>
  57. <el-col :span="8">
  58. <el-form-item prop="length" label-width="0px" class="margin-b-0 wid100">
  59. <el-input-number v-model="formData.data.length" placeholder="请输入" style="width: 100%" :precision="2" :controls="false" :min="0"
  60. onmousewheel="return false;" />
  61. </el-form-item>
  62. </el-col>
  63. <el-col :span="8">
  64. <el-form-item prop="width" label-width="0px" class="margin-b-0 wid100">
  65. <el-input-number v-model="formData.data.width" placeholder="请输入" style="width: 100%" :precision="2" :controls="false" :min="0"
  66. onmousewheel="return false;" />
  67. </el-form-item>
  68. </el-col>
  69. <el-col :span="8">
  70. <el-form-item prop="height" label-width="0px" class="margin-b-0 wid100">
  71. <el-input-number v-model="formData.data.height" placeholder="请输入" style="width: 100%" :precision="2" :controls="false" :min="0"
  72. onmousewheel="return false;" />
  73. </el-form-item>
  74. </el-col>
  75. </el-row>
  76. </el-form-item>
  77. </div>
  78. </template>
  79. </byForm>
  80. </div>
  81. <template #footer>
  82. <el-button @click="dialogVisible = false" size="defualt" v-debounce>取 消</el-button>
  83. <el-button type="primary" @click="submitForm()" size="defualt" :loading="submitLoading" v-debounce>
  84. 确 定
  85. </el-button>
  86. </template>
  87. </el-dialog>
  88. <el-dialog :title="'关联产品'" v-model="openAssociationProduct" width="70%" destroy-on-close>
  89. <div>
  90. <!-- class="public_height_dialog" -->
  91. <!-- <el-table :data="associationProductData" style="width: 100%;">
  92. <el-table-column label="产品图片" width="80">
  93. <template #default="{ row }">
  94. <div v-if="row.fileUrl">
  95. <img :src="row.fileUrl" class="pic" @click="openImg(row.fileUrl)" />
  96. </div>
  97. </template>
  98. </el-table-column>
  99. <el-table-column prop="name" label="产品名称" min-width="130" />
  100. <el-table-column prop="customCode" label="产品编码" width="180" />
  101. <el-table-column label="规格尺寸 (cm)" width="130">
  102. <template #default="{ row, $index }">
  103. <div style="width: 100%">
  104. {{row['length']}} * {{row.width}} * {{row.height}}
  105. </div>
  106. </template>
  107. </el-table-column>
  108. <el-table-column prop="color" label="颜色" width="150" />
  109. </el-table> -->
  110. <byTable :source="associationData.data" :pagination="associationData.pagination" :config="associationConfig" :loading="loading"
  111. highlight-current-row :selectConfig="[]" :action-list="[]" @get-list="getAssociationList">
  112. <template #pic="{ item }">
  113. <div v-if="item.fileUrl">
  114. <img :src="item.fileUrl" class="pic" @click="openImg(item.fileUrl)" />
  115. </div>
  116. <div v-else></div>
  117. </template>
  118. <template #size="{ item }">
  119. <div v-if="item['length'] && item.width && item.height">
  120. <span>{{ item['length'] }}</span>*
  121. <span>{{ item.width }}</span>*
  122. <span>{{ item.height }}</span>
  123. </div>
  124. <div v-else></div>
  125. </template>
  126. </byTable>
  127. </div>
  128. <!-- <template #footer>
  129. <el-button @click="openAssociationProduct = false" size="defualt" v-debounce>关 闭</el-button>
  130. </template> -->
  131. </el-dialog>
  132. </div>
  133. </template>
  134. <script setup>
  135. import byTable from "@/components/byTable/index";
  136. import byForm from "@/components/byForm/index";
  137. import treeList from "@/components/product/treeList";
  138. const { proxy } = getCurrentInstance();
  139. const currencyData = computed(
  140. () => proxy.useUserStore().allDict["account_currency"]
  141. );
  142. const materialUnitData = computed(
  143. () => proxy.useUserStore().allDict["material_unit"]
  144. );
  145. const colorLayerData = computed(
  146. () => proxy.useUserStore().allDict["color_layer"]
  147. );
  148. const backLinesData = computed(
  149. () => proxy.useUserStore().allDict["back_lines"]
  150. );
  151. const frontLinesData = computed(
  152. () => proxy.useUserStore().allDict["front_lines"]
  153. );
  154. const tableHeight = ref(0);
  155. const getTableHeight = () => {
  156. tableHeight.value = window.innerHeight - 245;
  157. };
  158. getTableHeight();
  159. window.addEventListener("resize", () => {
  160. getTableHeight();
  161. });
  162. const loading = ref(false);
  163. const submitLoading = ref(false);
  164. const sourceList = ref({
  165. data: [],
  166. pagination: {
  167. total: 3,
  168. pageNum: 1,
  169. pageSize: 10,
  170. type: "",
  171. productClassifyId: "",
  172. keyword: "",
  173. definition: "2",
  174. },
  175. });
  176. const dialogVisible = ref(false);
  177. const modalType = ref("add");
  178. const treeData = ref([]);
  179. const rules = ref({
  180. productClassifyId: [
  181. { required: true, message: "请选择物料分类", trigger: "change" },
  182. ],
  183. name: [{ required: true, message: "请输入物料名称", trigger: "blur" }],
  184. customCode: [{ required: true, message: "请输入物料编码", trigger: "blur" }],
  185. length: [{ required: true, message: "请输入长 (cm)", trigger: "blur" }],
  186. width: [{ required: true, message: "请输入宽 (cm)", trigger: "blur" }],
  187. height: [{ required: true, message: "请输入高 (cm)", trigger: "blur" }],
  188. price: [{ required: true, message: "请输入销售价", trigger: "blur" }],
  189. });
  190. const selectConfig = computed(() => []);
  191. const config = computed(() => {
  192. return [
  193. {
  194. attrs: {
  195. label: "图片",
  196. slot: "pic",
  197. align: "center",
  198. width: 80,
  199. },
  200. },
  201. {
  202. attrs: {
  203. label: "物料分类",
  204. prop: "classifyName",
  205. "min-width": 200,
  206. },
  207. },
  208. {
  209. attrs: {
  210. label: "物料编码",
  211. prop: "customCode",
  212. width: 190,
  213. },
  214. },
  215. {
  216. attrs: {
  217. label: "物料名称",
  218. slot: "name",
  219. "min-width": 300,
  220. },
  221. },
  222. {
  223. attrs: {
  224. label: "安全库存",
  225. prop: "stockThreshold",
  226. width: 100,
  227. },
  228. },
  229. // {
  230. // attrs: {
  231. // label: "物料材质",
  232. // prop: "material",
  233. // width: 120,
  234. // },
  235. // },
  236. // {
  237. // attrs: {
  238. // label: "物料型号",
  239. // prop: "spec",
  240. // width: 120,
  241. // },
  242. // },
  243. {
  244. attrs: {
  245. label: "单位",
  246. prop: "unit",
  247. width: 80,
  248. },
  249. // render(val) {
  250. // return proxy.dictKeyValue(val, materialUnitData.value);
  251. // },
  252. },
  253. {
  254. attrs: {
  255. label: "尺寸",
  256. slot: "size",
  257. width: 130,
  258. },
  259. },
  260. {
  261. attrs: {
  262. label: "净重",
  263. prop: "netWeight",
  264. width: 100,
  265. },
  266. render(val) {
  267. if (val) {
  268. return val + " kg";
  269. }
  270. },
  271. },
  272. {
  273. attrs: {
  274. label: "成本价",
  275. prop: "costPrice",
  276. width: 100,
  277. },
  278. render(val) {
  279. return proxy.moneyFormat(val, 2);
  280. },
  281. },
  282. {
  283. attrs: {
  284. label: "销售价",
  285. prop: "price",
  286. width: 100,
  287. },
  288. render(val) {
  289. return proxy.moneyFormat(val, 2);
  290. },
  291. },
  292. {
  293. attrs: {
  294. label: "操作",
  295. width: "180",
  296. align: "center",
  297. fixed: "right",
  298. },
  299. renderHTML(row) {
  300. return [
  301. {
  302. attrs: {
  303. label: "产品反查",
  304. type: "primary",
  305. text: true,
  306. },
  307. el: "button",
  308. click() {
  309. getAssociationProduct(row);
  310. },
  311. },
  312. {
  313. attrs: {
  314. label: "修改",
  315. type: "primary",
  316. text: true,
  317. },
  318. el: "button",
  319. click() {
  320. getDtl(row);
  321. },
  322. },
  323. {
  324. attrs: {
  325. label: "删除",
  326. type: "danger",
  327. text: true,
  328. },
  329. el: "button",
  330. click() {
  331. proxy
  332. .msgConfirm()
  333. .then((res) => {
  334. proxy
  335. .post("/productInfo/delete", {
  336. id: row.id,
  337. })
  338. .then((res) => {
  339. proxy.msgTip("删除成功", 1);
  340. getList();
  341. });
  342. })
  343. .catch((err) => {});
  344. },
  345. },
  346. ];
  347. },
  348. },
  349. ];
  350. });
  351. const formData = reactive({
  352. data: {},
  353. });
  354. const formOption = reactive({
  355. inline: true,
  356. labelWidth: 100,
  357. itemWidth: 100,
  358. });
  359. const formDom = ref(null);
  360. const treeListData = ref([]);
  361. function findNodeById(treeData, nodeId) {
  362. // 遍历当前层级的所有节点
  363. for (let i = 0; i < treeData.length; i++) {
  364. let node = treeData[i];
  365. // 如果当前节点的 ID 匹配目标节点的 ID,则返回当前节点
  366. if (node.id === nodeId) {
  367. return node;
  368. }
  369. // 如果当前节点有子节点,则递归调用当前函数继续查找子节点
  370. if (node.children && node.children.length > 0) {
  371. let foundNode = findNodeById(node.children, nodeId);
  372. // 如果在子节点中找到了目标节点,则返回找到的节点
  373. if (foundNode) {
  374. return foundNode;
  375. }
  376. }
  377. }
  378. // 如果遍历完所有节点仍未找到目标节点,则返回 null
  379. return null;
  380. }
  381. const isShowLabel = ref(false);
  382. const formConfig = computed(() => {
  383. return [
  384. {
  385. type: "title1",
  386. title: "基本信息",
  387. },
  388. {
  389. type: "treeSelect",
  390. prop: "productClassifyId",
  391. label: "物料分类",
  392. data: treeData.value,
  393. itemWidth: 100,
  394. disabled: false,
  395. fn: (val) => {
  396. changeProductClassifyId(val);
  397. },
  398. },
  399. {
  400. type: "input",
  401. prop: "name",
  402. label: "物料名称",
  403. itemWidth: 50,
  404. disabled: false,
  405. },
  406. {
  407. type: "input",
  408. prop: "customCode",
  409. label: "物料编码",
  410. itemWidth: 50,
  411. disabled: false,
  412. },
  413. {
  414. type: "uploadImg",
  415. // limit: 1,
  416. // listType: "picture-card",
  417. // accept: ".gif, .jpeg, .jpg, .png",
  418. imgProp: "imageUrl",
  419. prop: "fileList",
  420. label: "物料缩略图",
  421. isShow: !isSpecial.value,
  422. },
  423. {
  424. type: "title1",
  425. title: "材质特征",
  426. isShow: !isSpecial.value,
  427. },
  428. {
  429. type: "input",
  430. prop: "material",
  431. label: "材质",
  432. itemWidth: 50,
  433. isShow: !isSpecial.value,
  434. },
  435. {
  436. type: "input",
  437. prop: "spec",
  438. label: "型号",
  439. itemWidth: 50,
  440. isShow: !isSpecial.value,
  441. },
  442. {
  443. type: "select",
  444. prop: "frontalTexture",
  445. label: "正面纹路",
  446. data: frontLinesData.value,
  447. itemWidth: 50,
  448. isShow: !isSpecial.value,
  449. },
  450. {
  451. type: "select",
  452. prop: "reverseTexture",
  453. label: "背面纹路",
  454. data: backLinesData.value,
  455. itemWidth: 50,
  456. isShow: !isSpecial.value,
  457. },
  458. {
  459. type: "input",
  460. prop: "unit",
  461. label: "单位",
  462. // data: materialUnitData.value,
  463. itemWidth: 50,
  464. isShow: !isSpecial.value,
  465. },
  466. // {
  467. // type: "select",
  468. // prop: "unit",
  469. // label: "单位",
  470. // data: materialUnitData.value,
  471. // itemWidth: 50,
  472. // },
  473. {
  474. type: "select",
  475. prop: "colorLayer",
  476. label: "色层",
  477. data: colorLayerData.value,
  478. itemWidth: 50,
  479. isShow: !isSpecial.value,
  480. },
  481. // {
  482. // type: "input",
  483. // prop: "remark",
  484. // label: "备注",
  485. // itemType: "textarea",
  486. // },
  487. {
  488. type: "title1",
  489. title: "规格",
  490. isShow: !isSpecial.value,
  491. },
  492. {
  493. type: "input",
  494. prop: "color",
  495. label: "颜色",
  496. itemWidth: 50,
  497. isShow: !isSpecial.value,
  498. },
  499. {
  500. type: "number",
  501. prop: "stockThreshold",
  502. label: "安全库存",
  503. precision: 0,
  504. min: 0,
  505. controls: false,
  506. itemWidth: 50,
  507. isShow: !isSpecial.value,
  508. },
  509. {
  510. type: "number",
  511. prop: "costPrice",
  512. label: "成本价" + (isShowLabel.value ? "(cm²)" : ""),
  513. precision: 2,
  514. min: 0.01,
  515. controls: false,
  516. itemWidth: 50,
  517. isShow: !isSpecial.value,
  518. },
  519. // {
  520. // type: "selectInput",
  521. // prop: "costPrice",
  522. // selectProp: "costCurrency",
  523. // label: "成本价",
  524. // itemWidth: 50,
  525. // disabledSelect: true,
  526. // data: currencyData.value,
  527. // },
  528. {
  529. type: "number",
  530. prop: "price",
  531. label: "销售价" + (isShowLabel.value ? "(cm²)" : ""),
  532. precision: 2,
  533. min: 0.01,
  534. controls: false,
  535. itemWidth: 50,
  536. isShow: !isSpecial.value,
  537. },
  538. {
  539. type: "number",
  540. prop: "price",
  541. label: "销售价(cm²)",
  542. precision: 2,
  543. min: 0.01,
  544. controls: false,
  545. itemWidth: 50,
  546. isShow: isSpecial.value,
  547. },
  548. // {
  549. // type: "selectInput",
  550. // prop: "price",
  551. // selectProp: "currency",
  552. // label: "销售价",
  553. // itemWidth: 50,
  554. // disabledSelect: true,
  555. // data: currencyData.value,
  556. // },
  557. {
  558. type: "slot",
  559. slotName: "size",
  560. prop: "size",
  561. label: "",
  562. itemWidth: 50,
  563. disabled: false,
  564. isShow: !isSpecial.value,
  565. },
  566. {
  567. type: "number",
  568. prop: "netWeight",
  569. label: "净重(kg)",
  570. precision: 2,
  571. min: 0,
  572. controls: false,
  573. itemWidth: 50,
  574. isShow: !isSpecial.value,
  575. },
  576. ];
  577. });
  578. const getList = async (req) => {
  579. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  580. loading.value = true;
  581. proxy.post("/productInfo/page", sourceList.value.pagination).then((res) => {
  582. sourceList.value.data = res.rows.map((x) => ({ ...x, fileList: [] }));
  583. sourceList.value.pagination.total = res.total;
  584. setTimeout(() => {
  585. loading.value = false;
  586. }, 200);
  587. const productIdList = res.rows.map((x) => x.id);
  588. // 请求文件数据并回显
  589. if (productIdList.length > 0) {
  590. proxy.getFile(productIdList, sourceList.value.data, "id");
  591. }
  592. });
  593. };
  594. const treeChange = (e) => {
  595. if (e.id != undefined) {
  596. sourceList.value.pagination.productClassifyId = e.id;
  597. getList({ productClassifyId: e.id });
  598. }
  599. };
  600. const isSpecial = ref(false);
  601. const openModal = () => {
  602. isSpecial.value = false;
  603. dialogVisible.value = true;
  604. modalType.value = "add";
  605. formData.data = {
  606. definition: "2",
  607. fileList: [],
  608. };
  609. // if (currencyData.value && currencyData.value.length > 0) {
  610. // formData.data.currency = currencyData.value[0].dictKey;
  611. // formData.data.costCurrency = currencyData.value[0].dictKey;
  612. // }
  613. };
  614. const submitForm = () => {
  615. formDom.value.handleSubmit((valid) => {
  616. if (!isSpecial.value) {
  617. if (!formData.data.fileList.length > 0) {
  618. return proxy.msgTip("请上传图片", 2);
  619. }
  620. }
  621. submitLoading.value = true;
  622. proxy.post("/productInfo/" + modalType.value, formData.data).then(
  623. (res) => {
  624. proxy.msgTip("操作成功", 1);
  625. dialogVisible.value = false;
  626. submitLoading.value = false;
  627. getList();
  628. },
  629. (err) => {
  630. submitLoading.value = false;
  631. }
  632. );
  633. });
  634. };
  635. const getTreeList = () => {
  636. proxy
  637. .post("/productClassify/tree", { parentId: "", name: "", definition: "2" })
  638. .then((message) => {
  639. message = message.map((x) => ({ ...x, id: x.id + "" }));
  640. treeListData.value = [
  641. {
  642. id: "",
  643. label: "全部",
  644. parentId: "",
  645. children: message,
  646. },
  647. ];
  648. treeData.value = message;
  649. });
  650. };
  651. const changeProductClassifyId = (val) => {
  652. let current = findNodeById(treeData.value, val);
  653. if (current) {
  654. // 判断是否是无属性原材料
  655. if (current.id == 110) {
  656. isSpecial.value = true;
  657. } else {
  658. if (current.parentIdSet) {
  659. // 判断父级id是否包含无属性原材料
  660. isSpecial.value = current.parentIdSet.includes("110");
  661. } else {
  662. // 不是无属性原材料
  663. isSpecial.value = false;
  664. }
  665. }
  666. if (isSpecial.value == true) {
  667. for (const key in formData.data) {
  668. if (
  669. ["id", "name", "customCode", "price", "productClassifyId"].includes(
  670. key
  671. )
  672. ) {
  673. } else {
  674. delete formData.data[key];
  675. }
  676. }
  677. }
  678. if (current.id == 100) {
  679. isShowLabel.value = true;
  680. } else {
  681. if (current.parentIdSet) {
  682. isShowLabel.value = current.parentIdSet.includes("100");
  683. } else {
  684. isShowLabel.value = false;
  685. }
  686. }
  687. }
  688. };
  689. const getDtl = (row) => {
  690. modalType.value = "edit";
  691. proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
  692. formData.data = res;
  693. changeProductClassifyId(res.productClassifyId);
  694. formData.data.fileList = row.fileList.map((x) => ({
  695. ...x,
  696. url: x.fileUrl,
  697. name: x.fileName,
  698. }));
  699. if (formData.data.fileList.length > 0) {
  700. formData.data.imageUrl = formData.data.fileList[0].fileUrl;
  701. }
  702. dialogVisible.value = true;
  703. });
  704. };
  705. // const getDtlOne = (row) => {
  706. // modalType.value = "add";
  707. // proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
  708. // fileList.value = [];
  709. // fileListCopy.value = [];
  710. // res.type = res.type + "";
  711. // res.definition = "2";
  712. // delete res.id;
  713. // formData.data = res;
  714. // dialogVisible.value = true;
  715. // });
  716. // };
  717. const handleClickFile = (file) => {
  718. window.open(file.fileUrl, "_blank");
  719. };
  720. getTreeList();
  721. getList();
  722. const associationConfig = computed(() => {
  723. return [
  724. {
  725. attrs: {
  726. label: "产品图片",
  727. slot: "pic",
  728. align: "center",
  729. width: 80,
  730. },
  731. },
  732. {
  733. attrs: {
  734. label: "产品编码",
  735. prop: "customCode",
  736. width: 190,
  737. },
  738. },
  739. {
  740. attrs: {
  741. label: "产品名称",
  742. prop: "name",
  743. "min-width": 300,
  744. },
  745. },
  746. {
  747. attrs: {
  748. label: "尺寸",
  749. slot: "size",
  750. width: 130,
  751. },
  752. },
  753. {
  754. attrs: {
  755. label: "产品颜色",
  756. prop: "color",
  757. width: 160,
  758. },
  759. },
  760. ];
  761. });
  762. const associationData = ref({
  763. data: [],
  764. pagination: {
  765. pageNum: 1,
  766. pageSize: 10,
  767. total: 3,
  768. },
  769. });
  770. const openAssociationProduct = ref(false);
  771. const getAssociationList = (req = {}) => {
  772. associationData.value.pagination = {
  773. ...associationData.value.pagination,
  774. ...req,
  775. };
  776. proxy
  777. .post(
  778. "/productInfo/getProductByMaterialId",
  779. associationData.value.pagination
  780. )
  781. .then((res) => {
  782. associationData.value.data = res.rows;
  783. associationData.value.pagination.total = res.total;
  784. let productIds = associationData.value.data.map((x) => x.id);
  785. if (productIds && productIds.length > 0) {
  786. proxy.getFileData({
  787. businessIdList: productIds,
  788. data: associationData.value.data,
  789. att: "id",
  790. businessType: "0",
  791. fileAtt: "fileList",
  792. filePathAtt: "fileUrl",
  793. });
  794. }
  795. });
  796. };
  797. const getAssociationProduct = (row) => {
  798. openAssociationProduct.value = true;
  799. associationData.value.pagination = {
  800. pageNum: 1,
  801. pageSize: 10,
  802. total: 3,
  803. materialId: row.id,
  804. };
  805. getAssociationList();
  806. };
  807. </script>
  808. <style lang="scss" scoped>
  809. .user {
  810. padding: 10px;
  811. display: flex;
  812. justify-content: space-between;
  813. .tree {
  814. width: 300px;
  815. }
  816. .content {
  817. width: calc(100% - 310px);
  818. }
  819. }
  820. .pic {
  821. object-fit: contain;
  822. width: 50px;
  823. height: 50px;
  824. cursor: pointer;
  825. vertical-align: middle;
  826. }
  827. </style>