index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. <template>
  2. <div class="tenant">
  3. <!-- <Banner /> -->
  4. <div class="content">
  5. <byTable
  6. :source="sourceList.data"
  7. :pagination="sourceList.pagination"
  8. :config="config"
  9. :loading="loading"
  10. highlight-current-row
  11. :selectConfig="selectConfig"
  12. :table-events="{
  13. //element talbe事件都能传
  14. select: select,
  15. }"
  16. :action-list="[
  17. {
  18. text: '添加供应价格',
  19. action: () => openModal('add'),
  20. },
  21. ]"
  22. @get-list="getList"
  23. >
  24. <template #fileSlot="{ item }">
  25. <div
  26. style="cursor: pointer; color: #409eff"
  27. @click="handleClickFile(item)"
  28. >
  29. {{ item.fileName }}
  30. </div>
  31. </template>
  32. </byTable>
  33. </div>
  34. <el-dialog
  35. :title="modalType == 'add' ? '添加供应价格' : '编辑供应价格'"
  36. v-model="dialogVisible"
  37. width="800"
  38. v-loading="loading"
  39. >
  40. <byForm
  41. :formConfig="formConfig"
  42. :formOption="formOption"
  43. v-model="formData.data"
  44. :rules="rules"
  45. ref="byform"
  46. >
  47. <template #details>
  48. <div style="width: 100%">
  49. <el-button type="primary" @click="openProduct = true">
  50. 添加货品
  51. </el-button>
  52. <el-form
  53. ref="tableForm"
  54. :model="formData.data"
  55. :rules="rules"
  56. label-width="0px"
  57. style="margin-top: 15px"
  58. >
  59. <el-table :data="formData.data.supplierPriceList">
  60. <el-table-column prop="code" label="货品编码" />
  61. <el-table-column prop="name" label="货品名称" min-width="150" />
  62. <el-table-column prop="spec" label="规格型号" />
  63. <el-table-column prop="unit" label="单位" />
  64. <el-table-column prop="price" label="供应单价" min-width="150">
  65. <template #default="{ row, $index }">
  66. <el-form-item
  67. :prop="'supplierPriceList.' + $index + '.price'"
  68. :rules="rules.price"
  69. :inline-message="true"
  70. >
  71. <el-input-number
  72. v-model="row.price"
  73. :precision="4"
  74. :controls="false"
  75. :min="1"
  76. />
  77. </el-form-item>
  78. </template>
  79. </el-table-column>
  80. <el-table-column prop="zip" label="操作" width="100">
  81. <template #default="{ $index }">
  82. <el-button type="primary" link @click="handleRemove($index)"
  83. >删除</el-button
  84. >
  85. </template>
  86. </el-table-column>
  87. </el-table>
  88. </el-form>
  89. </div>
  90. </template>
  91. </byForm>
  92. <template #footer>
  93. <el-button @click="dialogVisible = false" size="large">取 消</el-button>
  94. <el-button
  95. type="primary"
  96. @click="submitForm('byform')"
  97. size="large"
  98. :loading="submitLoading"
  99. >
  100. 确 定
  101. </el-button>
  102. </template>
  103. </el-dialog>
  104. <el-dialog
  105. v-model="openProduct"
  106. title="选择货品"
  107. width="70%"
  108. append-to-body
  109. >
  110. <SelectGoods
  111. @cancel="openProduct = false"
  112. @pushGoods="pushGoods"
  113. ></SelectGoods>
  114. </el-dialog>
  115. </div>
  116. </template>
  117. <script setup>
  118. /* eslint-disable vue/no-unused-components */
  119. import { ElMessage, ElMessageBox } from "element-plus";
  120. import byTable from "@/components/byTable/index";
  121. import byForm from "@/components/byForm/index";
  122. import FileUpload from "@/components/FileUpload/index";
  123. import { computed, defineComponent, ref } from "vue";
  124. import { getToken } from "@/utils/auth";
  125. import SelectGoods from "@/components/product/SelectGoods";
  126. const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
  127. const headers = ref({ Authorization: "Bearer " + getToken() });
  128. const uploadData = ref({});
  129. const loading = ref(false);
  130. const submitLoading = ref(false);
  131. const sourceList = ref({
  132. data: [],
  133. pagination: {
  134. total: 3,
  135. pageNum: 1,
  136. pageSize: 10,
  137. },
  138. });
  139. let dialogVisible = ref(false);
  140. let openProduct = ref(false);
  141. let modalType = ref("add");
  142. let fileList = ref([]);
  143. let rules = ref({
  144. supplierInfoId: [
  145. { required: true, message: "请选择供应商", trigger: "change" },
  146. ],
  147. price: [{ required: true, message: "请输入供应单价", trigger: "blur" }],
  148. });
  149. const { proxy } = getCurrentInstance();
  150. const selectConfig = reactive([
  151. {
  152. label: "供应商类型",
  153. prop: "supplierType",
  154. data: [
  155. {
  156. label: "贸易商",
  157. value: "1",
  158. },
  159. {
  160. label: "工厂",
  161. value: "2",
  162. },
  163. ],
  164. },
  165. {
  166. label: "货品类型",
  167. prop: "definition",
  168. data: [
  169. {
  170. label: "产品",
  171. value: "1",
  172. },
  173. {
  174. label: "物料",
  175. value: "2",
  176. },
  177. ],
  178. },
  179. ]);
  180. const config = computed(() => {
  181. return [
  182. {
  183. attrs: {
  184. label: "货品类型",
  185. prop: "definition",
  186. },
  187. render(definition) {
  188. return definition === 1 ? "产品" : definition === 2 ? "物料" : "";
  189. },
  190. },
  191. {
  192. attrs: {
  193. label: "所属分类",
  194. prop: "productClassifyName",
  195. },
  196. },
  197. {
  198. attrs: {
  199. label: "货品编码",
  200. prop: "productCode",
  201. },
  202. },
  203. {
  204. attrs: {
  205. label: "货品名称",
  206. prop: "productName",
  207. },
  208. },
  209. {
  210. attrs: {
  211. label: "规格型号",
  212. prop: "productSpec",
  213. },
  214. },
  215. {
  216. attrs: {
  217. label: "单位",
  218. prop: "productUnit",
  219. },
  220. },
  221. {
  222. attrs: {
  223. label: "供应商类型",
  224. prop: "supplierType",
  225. },
  226. render(supplierType) {
  227. return supplierType === 1 ? "贸易商" : supplierType === 2 ? "工厂" : "";
  228. },
  229. },
  230. {
  231. attrs: {
  232. label: "供应商名称",
  233. prop: "supplierName",
  234. },
  235. },
  236. {
  237. attrs: {
  238. label: "供应单价",
  239. prop: "price",
  240. },
  241. },
  242. {
  243. attrs: {
  244. label: "操作",
  245. width: "200",
  246. align: "right",
  247. },
  248. // 渲染 el-button,一般用在最后一列。
  249. renderHTML(row) {
  250. return [
  251. {
  252. attrs: {
  253. label: "修改",
  254. type: "primary",
  255. text: true,
  256. },
  257. el: "button",
  258. click() {
  259. getDtl(row);
  260. },
  261. },
  262. {
  263. attrs: {
  264. label: "删除",
  265. type: "danger",
  266. text: true,
  267. },
  268. el: "button",
  269. click() {
  270. // 弹窗提示是否删除
  271. ElMessageBox.confirm(
  272. "此操作将永久删除该数据, 是否继续?",
  273. "提示",
  274. {
  275. confirmButtonText: "确定",
  276. cancelButtonText: "取消",
  277. type: "warning",
  278. }
  279. ).then(() => {
  280. // 删除
  281. proxy
  282. .post("/supplierPrice/delete", {
  283. id: row.id,
  284. })
  285. .then((res) => {
  286. ElMessage({
  287. message: "删除成功",
  288. type: "success",
  289. });
  290. getList();
  291. });
  292. });
  293. },
  294. },
  295. ];
  296. },
  297. },
  298. ];
  299. });
  300. let formData = reactive({
  301. data: {
  302. supplierPriceList: [],
  303. },
  304. });
  305. const formOption = reactive({
  306. inline: true,
  307. labelWidth: 100,
  308. itemWidth: 100,
  309. rules: [],
  310. });
  311. const byform = ref(null);
  312. const formConfig = reactive([
  313. {
  314. type: "select",
  315. prop: "supplierInfoId",
  316. label: "供应商",
  317. required: true,
  318. disabled: false,
  319. isLoad: {
  320. url: "/supplierInfo/page",
  321. req: {
  322. pageNum: 1,
  323. pageSize: 9999,
  324. },
  325. labelKey: "name",
  326. labelVal: "id",
  327. method: "post",
  328. resUrl: "rows",
  329. },
  330. },
  331. {
  332. type: "slot",
  333. slotName: "details",
  334. prop: "supplierPriceList",
  335. label: "供应明细",
  336. required: true,
  337. },
  338. ]);
  339. const getList = async (req) => {
  340. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  341. loading.value = true;
  342. proxy
  343. .post("/supplierPrice/page", sourceList.value.pagination)
  344. .then((message) => {
  345. console.log(message);
  346. sourceList.value.data = message.rows;
  347. sourceList.value.pagination.total = message.total;
  348. setTimeout(() => {
  349. loading.value = false;
  350. }, 200);
  351. });
  352. };
  353. const openModal = () => {
  354. dialogVisible.value = true;
  355. modalType.value = "add";
  356. formConfig[0].disabled = false;
  357. formData.data = {
  358. supplierPriceList: [],
  359. renewWhileItExists: false,
  360. };
  361. };
  362. const submitForm = () => {
  363. byform.value.handleSubmit((valid) => {
  364. if (formData.data.supplierPriceList.length > 0) {
  365. proxy.$refs.tableForm.validate((vaild) => {
  366. if (vaild) {
  367. if (!formData.data.id) {
  368. const submitData = {
  369. ...formData.data,
  370. supplierPriceList: formData.data.supplierPriceList.map((x) => ({
  371. productInfoId: x.productInfoId,
  372. price: x.price,
  373. })),
  374. };
  375. submitLoading.value = true;
  376. proxy.post("/supplierPrice/" + modalType.value, submitData).then(
  377. (res) => {
  378. if (res.addSuccess) {
  379. ElMessage({
  380. message: modalType.value == "add" ? "添加成功" : "编辑成功",
  381. type: "success",
  382. });
  383. getList();
  384. dialogVisible.value = false;
  385. submitLoading.value = false;
  386. } else {
  387. ElMessage({
  388. message: `已存在供应价格,价格为${res.existSupplierPriceList[0].price}`,
  389. type: "info",
  390. });
  391. ElMessageBox.confirm(
  392. "继续提交将修改已存在的单价数据, 是否继续?",
  393. "提示",
  394. {
  395. confirmButtonText: "确定",
  396. cancelButtonText: "取消",
  397. type: "warning",
  398. }
  399. )
  400. .then(() => {
  401. const arr = [];
  402. for (
  403. let i = 0;
  404. i < formData.data.supplierPriceList.length;
  405. i++
  406. ) {
  407. const iele = formData.data.supplierPriceList[i];
  408. for (
  409. let j = 0;
  410. j < res.existSupplierPriceList.length;
  411. j++
  412. ) {
  413. const jele = res.existSupplierPriceList[j];
  414. if (iele.productInfoId === jele.productInfoId) {
  415. jele.price = iele.price;
  416. arr.push(jele);
  417. }
  418. }
  419. }
  420. formData.data.supplierPriceList = arr.map((x) => ({
  421. productInfoId: x.productInfoId,
  422. price: x.price,
  423. }));
  424. formData.data.renewWhileItExists = true;
  425. proxy
  426. .post(
  427. "/supplierPrice/" + modalType.value,
  428. formData.data
  429. )
  430. .then((res) => {
  431. if (res.addSuccess) {
  432. ElMessage({
  433. message: "修改成功",
  434. type: "success",
  435. });
  436. getList();
  437. dialogVisible.value = false;
  438. submitLoading.value = false;
  439. }
  440. });
  441. })
  442. .catch(() => {});
  443. }
  444. },
  445. (err) => {
  446. submitLoading.value = false;
  447. }
  448. );
  449. } else {
  450. formData.data.supplierInfoId = formData.data.supplierInfoIdCopy;
  451. formData.data.productInfoId =
  452. formData.data.supplierPriceList[0].productInfoId;
  453. formData.data.price = formData.data.supplierPriceList[0].price;
  454. delete formData.data.supplierPriceList;
  455. delete formData.data.supplierInfoIdCopy;
  456. proxy
  457. .post("/supplierPrice/" + modalType.value, formData.data)
  458. .then((res) => {
  459. ElMessage({
  460. message: "修改成功",
  461. type: "success",
  462. });
  463. getList();
  464. dialogVisible.value = false;
  465. submitLoading.value = false;
  466. });
  467. }
  468. }
  469. });
  470. } else {
  471. return ElMessage({
  472. message: "请添加供应明细!",
  473. type: "info",
  474. });
  475. }
  476. });
  477. };
  478. const getDtl = (row) => {
  479. modalType.value = "edit";
  480. formConfig[0].disabled = true;
  481. dialogVisible.value = true;
  482. formData.data = {
  483. id: row.id,
  484. supplierInfoIdCopy: row.supplierInfoId,
  485. supplierInfoId: row.supplierName,
  486. supplierPriceList: [
  487. {
  488. productInfoId: row.productInfoId,
  489. name: row.productName,
  490. code: row.productCode,
  491. unit: row.productUnit,
  492. spec: row.productSpec,
  493. price: row.price,
  494. },
  495. ],
  496. };
  497. };
  498. // const handleClickFile = (row) => {
  499. // ElMessage({
  500. // message: "数据请求中,请稍后!",
  501. // type: "success",
  502. // });
  503. // let id = row.id;
  504. // proxy.post("/fileInfo/getList", { businessIdList: [id] }).then((res) => {
  505. // const file = res[id][0];
  506. // window.open(file.fileUrl, "_blank");
  507. // });
  508. // };
  509. const handleRemove = (index) => {
  510. formData.data.supplierPriceList.splice(index, 1);
  511. return ElMessage({
  512. message: "删除成功!",
  513. type: "success",
  514. });
  515. };
  516. const pushGoods = (goods) => {
  517. const arr = goods.map((x) => ({ ...x, productInfoId: x.id, price: "" }));
  518. formData.data.supplierPriceList = formData.data.supplierPriceList.concat(arr);
  519. return ElMessage({
  520. message: "添加成功!",
  521. type: "success",
  522. });
  523. };
  524. getList();
  525. </script>
  526. <style lang="scss" scoped>
  527. .tenant {
  528. padding: 20px;
  529. }
  530. </style>