SendPurchaseWDLY.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. <template>
  2. <div style="width: 100%; padding: 0px 15px">
  3. <el-form
  4. :model="formData.data"
  5. :rules="rules"
  6. ref="formDom"
  7. label-position="top"
  8. :disabled="props.queryData.purchaseDetailList ? true : false"
  9. >
  10. <div class="_t">基础信息</div>
  11. <el-row :gutter="10">
  12. <el-col :span="6">
  13. <el-form-item label="采购部门" prop="deptName">
  14. <el-input v-model="formData.data.deptName" placeholder="请输入">
  15. </el-input>
  16. </el-form-item>
  17. </el-col>
  18. <el-col :span="6">
  19. <el-form-item label="采购人" prop="purchaseName">
  20. <el-input v-model="formData.data.purchaseName" placeholder="请输入">
  21. </el-input>
  22. </el-form-item>
  23. </el-col>
  24. <el-col :span="6">
  25. <el-form-item label="采购时间" prop="purchaseTime">
  26. <el-date-picker
  27. v-model="formData.data.purchaseTime"
  28. type="datetime"
  29. placeholder="请选择"
  30. />
  31. </el-form-item>
  32. </el-col>
  33. </el-row>
  34. <el-row :gutter="10">
  35. <el-col :span="6">
  36. <el-form-item label="供应商" prop="supplyId">
  37. <el-select
  38. v-model="formData.data.supplyId"
  39. placeholder="请选择"
  40. @change="handleChangeSupplier"
  41. filterable
  42. style="width: 100%"
  43. >
  44. <el-option
  45. v-for="item in supplierData"
  46. :label="item.name"
  47. :value="item.id"
  48. >
  49. </el-option>
  50. </el-select>
  51. </el-form-item>
  52. </el-col>
  53. <el-col :span="6">
  54. <el-form-item label="是否合同" prop="isAgreement">
  55. <el-select
  56. v-model="formData.data.isAgreement"
  57. placeholder="请选择"
  58. style="width: 100%"
  59. >
  60. <el-option label="是" value="1"> </el-option>
  61. <el-option label="否" value="0"> </el-option>
  62. </el-select>
  63. </el-form-item>
  64. </el-col>
  65. <el-col :span="6">
  66. <el-form-item label="付款方式" prop="paymentMethod">
  67. <el-select
  68. v-model="formData.data.paymentMethod"
  69. placeholder="请选择"
  70. filterable
  71. style="width: 100%"
  72. >
  73. <el-option
  74. v-for="item in fundsPaymentMethod"
  75. :label="item.dictValue"
  76. :value="item.dictKey"
  77. >
  78. </el-option>
  79. </el-select>
  80. </el-form-item>
  81. </el-col>
  82. <el-col :span="6">
  83. <el-form-item label="采购单号" prop="contractCode">
  84. <el-input v-model="formData.data.contractCode" placeholder="请输入">
  85. </el-input>
  86. </el-form-item>
  87. </el-col>
  88. </el-row>
  89. <el-form-item label="采购说明" prop="purchaseContent">
  90. <el-input
  91. v-model="formData.data.purchaseContent"
  92. placeholder="请输入"
  93. type="textarea"
  94. >
  95. </el-input>
  96. </el-form-item>
  97. <div class="_t">采购明细</div>
  98. <el-form-item>
  99. <el-button
  100. type="primary"
  101. @click="openProduct = true"
  102. style="margin: 10px 0"
  103. v-if="ids.length == 0"
  104. >
  105. 添加物品
  106. </el-button>
  107. <el-table :data="formData.data.purchaseDetailList">
  108. <el-table-column
  109. prop="goodType"
  110. label="物品类型"
  111. :formatter="(row) => (row.goodType == 1 ? '产品' : '物料')"
  112. />
  113. <el-table-column prop="productCode" label="物品编码" />
  114. <el-table-column prop="productName" label="物品名称" />
  115. <!-- <el-table-column prop="productSpec" label="规格型号" /> -->
  116. <el-table-column
  117. prop="productUnit"
  118. label="单位"
  119. :formatter="(row) => dictValueLabel(row.productUnit, productUnit)"
  120. />
  121. <el-table-column
  122. prop="subscribeCount"
  123. label="申购数量"
  124. v-if="ids.length > 0"
  125. />
  126. <el-table-column
  127. prop="purchaseCount"
  128. label="已采购数量"
  129. v-if="ids.length > 0"
  130. />
  131. <el-table-column prop="count" label="本次采购" min-width="150">
  132. <template #default="{ row, $index }">
  133. <el-form-item
  134. :prop="'purchaseDetailList.' + $index + '.count'"
  135. :rules="rules.count"
  136. :inline-message="true"
  137. >
  138. <el-input-number
  139. v-model="row.count"
  140. :precision="4"
  141. :controls="false"
  142. :min="0"
  143. @change="handleChangeAmount"
  144. />
  145. </el-form-item>
  146. </template>
  147. </el-table-column>
  148. <el-table-column prop="price" label="单价" min-width="150">
  149. <template #default="{ row, $index }">
  150. <el-form-item
  151. :prop="'purchaseDetailList.' + $index + '.price'"
  152. :rules="rules.price"
  153. :inline-message="true"
  154. >
  155. <el-input-number
  156. v-model="row.price"
  157. :precision="4"
  158. :controls="false"
  159. :min="0"
  160. @change="handleChangeAmount"
  161. />
  162. </el-form-item>
  163. </template>
  164. </el-table-column>
  165. <el-table-column prop="amount" label="金额" />
  166. <el-table-column prop="zip" label="操作" width="100">
  167. <template #default="{ $index }">
  168. <el-button type="primary" link @click="handleRemove($index, 20)"
  169. >删除</el-button
  170. >
  171. </template>
  172. </el-table-column>
  173. </el-table>
  174. </el-form-item>
  175. <div class="_t">其他费用</div>
  176. <el-form-item>
  177. <el-button type="primary" style="margin: 10px 0" @click="handleAdd">
  178. 添加
  179. </el-button>
  180. <el-table :data="formData.data.otherFeeList">
  181. <el-table-column prop="name" label="费用名称" min-width="150">
  182. <template #default="{ row, $index }">
  183. <el-form-item
  184. :prop="'otherFeeList.' + $index + '.name'"
  185. :rules="rulesOne.name"
  186. :inline-message="true"
  187. >
  188. <el-input v-model="row.name" placeholder="请输入" />
  189. </el-form-item>
  190. </template>
  191. </el-table-column>
  192. <el-table-column prop="price" label="金额" min-width="150">
  193. <template #default="{ row, $index }">
  194. <el-form-item
  195. :prop="'otherFeeList.' + $index + '.price'"
  196. :rules="rulesOne.price"
  197. :inline-message="true"
  198. >
  199. <el-input-number
  200. v-model="row.price"
  201. :precision="4"
  202. :controls="false"
  203. :min="0"
  204. @change="handleChangeAmount"
  205. />
  206. </el-form-item>
  207. </template>
  208. </el-table-column>
  209. <el-table-column prop="remark" label="备注" min-width="150">
  210. <template #default="{ row, $index }">
  211. <el-form-item
  212. :prop="'otherFeeList.' + $index + '.remark'"
  213. :inline-message="true"
  214. >
  215. <el-input v-model="row.remark" placeholder="请输入" />
  216. </el-form-item>
  217. </template>
  218. </el-table-column>
  219. <el-table-column prop="zip" label="操作" width="100">
  220. <template #default="{ $index }">
  221. <el-button type="primary" link @click="handleRemove($index, 10)"
  222. >删除</el-button
  223. >
  224. </template>
  225. </el-table-column>
  226. </el-table>
  227. </el-form-item>
  228. <div class="_t" style="margin-bottom: 15px">采购总金额</div>
  229. <el-row>
  230. <el-col :span="4">
  231. <el-form-item label="采购总金额" prop="amount">
  232. <el-input
  233. v-model="formData.data.amount"
  234. placeholder="请输入"
  235. disabled
  236. />
  237. </el-form-item>
  238. </el-col>
  239. </el-row>
  240. </el-form>
  241. <el-dialog
  242. v-model="openProduct"
  243. title="选择物品"
  244. width="70%"
  245. append-to-body
  246. >
  247. <SelectGoods
  248. @cancel="openProduct = false"
  249. @pushGoods="pushGoods"
  250. ></SelectGoods>
  251. </el-dialog>
  252. </div>
  253. </template>
  254. <script setup>
  255. import SelectGoods from "@/components/product/SelectGoods";
  256. import { ElMessage, ElMessageBox } from "element-plus";
  257. import useUserStore from "@/store/modules/user";
  258. import { useRouter, useRoute } from "vue-router";
  259. const { proxy } = getCurrentInstance();
  260. const route = useRoute();
  261. let formData = reactive({
  262. data: {
  263. purchaseTime: "",
  264. purchaseDetailList: [],
  265. otherFeeList: [],
  266. },
  267. });
  268. let rules = ref({
  269. deptName: [{ required: true, message: "请输入采购部门", trigger: "blur" }],
  270. purchaseName: [
  271. { required: true, message: "请输入采购人名称", trigger: "blur" },
  272. ],
  273. purchaseTime: [
  274. { required: true, message: "请选择采购时间", trigger: "change" },
  275. ],
  276. supplyId: [{ required: true, message: "请选择供应商", trigger: "change" }],
  277. count: [{ required: true, message: "请输入本次采购数量", trigger: "blur" }],
  278. price: [{ required: true, message: "请输入单价", trigger: "blur" }],
  279. remark: [{ required: true, message: "请输入备注", trigger: "blur" }],
  280. isAgreement: [
  281. { required: true, message: "请选择是否合同", trigger: "change" },
  282. ],
  283. paymentMethod: [
  284. { required: true, message: "请选择付款方式", trigger: "change" },
  285. ],
  286. contractCode: [
  287. { required: true, message: "请输入采购单号", trigger: "blur" },
  288. ],
  289. });
  290. let rulesOne = ref({
  291. name: [{ required: true, message: "请输入费用名称", trigger: "blur" }],
  292. price: [{ required: true, message: "请输入金额", trigger: "blur" }],
  293. });
  294. let openProduct = ref(false);
  295. const handleAdd = () => {
  296. formData.data.otherFeeList.push({
  297. name: "",
  298. price: 0,
  299. remark: "",
  300. });
  301. };
  302. // 物品相应逻辑
  303. const handleRemove = (index, type) => {
  304. if (type == 10) {
  305. formData.data.otherFeeList.splice(index, 1);
  306. } else if (type == 20) {
  307. formData.data.purchaseDetailList.splice(index, 1);
  308. }
  309. handleChangeAmount();
  310. return ElMessage({
  311. message: "删除成功!",
  312. type: "success",
  313. });
  314. };
  315. const pushGoods = (goods) => {
  316. const arr = goods.map((x) => ({
  317. goodType: x.goodType,
  318. productCode: x.code,
  319. productName: x.name,
  320. productSpec: x.spec,
  321. productUnit: x.unit,
  322. count: 0,
  323. price: 0,
  324. bussinessId: x.id,
  325. amount: 0,
  326. }));
  327. formData.data.purchaseDetailList =
  328. formData.data.purchaseDetailList.concat(arr);
  329. openProduct.value = false;
  330. return ElMessage({
  331. message: "添加成功!",
  332. type: "success",
  333. });
  334. };
  335. // 提交方法
  336. const formDom = ref(null);
  337. const handleSubmit = async () => {
  338. const vaild = await formDom.value.validate();
  339. if (vaild) {
  340. if (formData.data.purchaseDetailList.length > 0) {
  341. const list = formData.data.purchaseDetailList;
  342. for (let i = 0; i < list.length; i++) {
  343. const e = list[i];
  344. if (ids.value.length > 0) {
  345. if (Number(e.subscribeCount) - Number(e.purchaseCount) > 0) {
  346. if (e.count == 0) {
  347. ElMessage({
  348. message: "本次采购数量不能为0!",
  349. type: "info",
  350. });
  351. return false;
  352. }
  353. }
  354. if (e.count + Number(e.purchaseCount) > Number(e.subscribeCount)) {
  355. ElMessage({
  356. message: "本次采购数量和已采购数量和不可大于申购数量!",
  357. type: "info",
  358. });
  359. return false;
  360. }
  361. } else {
  362. if (e.count == 0) {
  363. ElMessage({
  364. message: "本次采购数量不能为0!",
  365. type: "info",
  366. });
  367. return false;
  368. }
  369. }
  370. }
  371. return true;
  372. }
  373. ElMessage({
  374. message: "请添加采购明细!",
  375. type: "info",
  376. });
  377. return false;
  378. }
  379. return false;
  380. };
  381. // 获取用户信息并赋默认值
  382. const userInfo = useUserStore().user;
  383. onMounted(() => {
  384. formData.data.purchaseTime = proxy.parseTime(new Date());
  385. formData.data.deptName = userInfo.dept.deptName;
  386. formData.data.purchaseName = userInfo.nickName;
  387. getSupplierList();
  388. if (!route.query.processType) {
  389. ids.value = props.queryData.ids.split(",") || [];
  390. getDetails();
  391. }
  392. setTimeout(() => {
  393. if (!props.queryData.purchaseDetailList) return;
  394. formData.data = props.queryData;
  395. proxy
  396. .post("/subscribeDetail/detail", {
  397. ids: props.queryData.purchaseDetailList.map((item) => {
  398. return item.subscribeDetailId;
  399. }),
  400. })
  401. .then((res) => {
  402. console.log(formData.data.purchaseDetailList);
  403. formData.data.purchaseDetailList =
  404. props.queryData.purchaseDetailList.map((x, index) => ({
  405. ...res[index],
  406. subscribeCount: x.count,
  407. count: x.count,
  408. price: x.price,
  409. amount: x.amount,
  410. }));
  411. console.log(formData.data.purchaseDetailList);
  412. });
  413. }, 2000);
  414. });
  415. // 接收父组件的传值
  416. const props = defineProps({
  417. queryData: String,
  418. });
  419. const ids = ref([]);
  420. const getDetails = () => {
  421. proxy.post("/subscribeDetail/detail", { ids: ids.value }).then((res) => {
  422. console.log(res, "123123123123123123123123");
  423. formData.data.purchaseDetailList = res.map((x) => ({
  424. ...x,
  425. subscribeCount: x.count,
  426. count: Number(x.count) - Number(x.purchaseCount),
  427. price: null,
  428. amount: null,
  429. }));
  430. });
  431. };
  432. // 获取用户信息并赋默认值
  433. // const tenantId = "@福建宏星!#¥%……&*()";
  434. const tenantId = userInfo.tenantId;
  435. // 获取供应商数据
  436. const supplierData = ref([]);
  437. const fundsPaymentMethod = ref([]);
  438. const getSupplierList = async (req) => {
  439. proxy
  440. .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
  441. .then((res) => {
  442. supplierData.value = res.rows;
  443. });
  444. proxy
  445. .post("/dictTenantData/page", {
  446. pageNum: 1,
  447. pageSize: 999,
  448. tenantId: tenantId,
  449. dictCode: "funds_payment_method",
  450. })
  451. .then((res) => {
  452. fundsPaymentMethod.value = res.rows;
  453. });
  454. };
  455. // 供应商改变逻辑
  456. const handleChangeSupplier = (val) => {
  457. const ids = formData.data.purchaseDetailList.map((x) => x.bussinessId);
  458. proxy
  459. .post("/supplierPrice/getSupplierPriceByProductIds", {
  460. supplierInfoId: val,
  461. productIdList: ids,
  462. })
  463. .then((res) => {
  464. if (Object.keys(res).length > 0) {
  465. for (let i = 0; i < formData.data.purchaseDetailList.length; i++) {
  466. const e = formData.data.purchaseDetailList[i];
  467. for (const key in res) {
  468. if (e.bussinessId === key) {
  469. e.price = Number(res[key]);
  470. } else e.price = null;
  471. }
  472. }
  473. } else {
  474. for (let i = 0; i < formData.data.purchaseDetailList.length; i++) {
  475. const e = formData.data.purchaseDetailList[i];
  476. e.price = 0;
  477. }
  478. }
  479. handleChangeAmount();
  480. });
  481. };
  482. // 计算采购总金额
  483. const handleChangeAmount = () => {
  484. let sum = 0;
  485. for (let i = 0; i < formData.data.purchaseDetailList.length; i++) {
  486. const e = formData.data.purchaseDetailList[i];
  487. e.amount = e.count * e.price;
  488. sum += e.amount;
  489. }
  490. for (let i = 0; i < formData.data.otherFeeList.length; i++) {
  491. const e = formData.data.otherFeeList[i];
  492. sum += e.price;
  493. }
  494. formData.data.amount = sum;
  495. };
  496. const productUnit = ref([]);
  497. const getDict = () => {
  498. proxy.getDictOne(["unit"]).then((res) => {
  499. productUnit.value = res["unit"].map((x) => ({
  500. label: x.dictValue,
  501. value: x.dictKey,
  502. }));
  503. });
  504. };
  505. getDict();
  506. // 向父组件暴露
  507. defineExpose({
  508. submitData: formData.data,
  509. handleSubmit,
  510. });
  511. </script>
  512. <style lang="scss" scoped>
  513. ._t {
  514. margin-bottom: 5px;
  515. font-size: 14px;
  516. }
  517. </style>