add.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <template>
  2. <div class="form">
  3. <van-nav-bar
  4. title="销售合同"
  5. left-text="返回"
  6. left-arrow
  7. @click-left="onClickLeft"
  8. >
  9. </van-nav-bar>
  10. <testForm
  11. v-model="formData.data"
  12. :formOption="formOption"
  13. :formConfig="formConfig"
  14. :rules="rules"
  15. @onSubmit="onSubmit"
  16. ref="formDom"
  17. ></testForm>
  18. </div>
  19. </template>
  20. <script setup>
  21. import { ref, reactive, getCurrentInstance, onMounted } from "vue";
  22. import { showSuccessToast, showFailToast } from "vant";
  23. import { useRoute } from "vue-router";
  24. import testForm from "@/components/testForm/index.vue";
  25. const proxy = getCurrentInstance().proxy;
  26. const route = useRoute();
  27. const formDom = ref(null);
  28. const formData = reactive({
  29. data: {
  30. salesContractDetailsList: [],
  31. },
  32. });
  33. const rules = {
  34. customerId: [{ required: true, message: "请选择客户名称" }],
  35. deliveryDate: [{ required: true, message: "请选择交货期限" }],
  36. payMethod: [{ required: true, message: "请选择付款方式" }],
  37. freightPayer: [{ required: true, message: "请选择运费支付方" }],
  38. productId: [{ required: true, message: "请选择产品名称" }],
  39. isCustomized: [{ required: true, message: "请选择是否定制" }],
  40. unitPrice: [{ required: true, message: "请输入单价" }],
  41. quantity: [{ required: true, message: "请输入数量" }],
  42. };
  43. const formOption = reactive({
  44. readonly: false, //用于控制整个表单是否只读
  45. disabled: false,
  46. labelAlign: "top",
  47. scroll: true,
  48. labelWidth: "62pk",
  49. hiddenSubmitBtn: false,
  50. btnConfig: {
  51. isNeed: true,
  52. prop: "salesContractDetailsList",
  53. plain: true,
  54. listTitle: "合同明细",
  55. listConfig: [
  56. {
  57. type: "picker",
  58. label: "产品名称",
  59. prop: "productId",
  60. itemType: "onePicker",
  61. showPicker: false,
  62. readonly: false,
  63. fieldNames: {
  64. text: "label",
  65. value: "value",
  66. },
  67. data: [],
  68. },
  69. {
  70. type: "picker",
  71. label: "是否定制",
  72. prop: "isCustomized",
  73. itemType: "onePicker",
  74. showPicker: false,
  75. readonly: false,
  76. fieldNames: {
  77. text: "label",
  78. value: "value",
  79. },
  80. data: [
  81. {
  82. label: "是",
  83. value: "1",
  84. },
  85. {
  86. label: "否",
  87. value: "0",
  88. },
  89. ],
  90. },
  91. {
  92. type: "input",
  93. itemType: "number",
  94. label: "单价",
  95. prop: "unitPrice",
  96. clearable: true,
  97. changeFn: (index, val) => {
  98. changeAmount(index);
  99. },
  100. },
  101. {
  102. type: "input",
  103. itemType: "number",
  104. label: "数量",
  105. prop: "quantity",
  106. clearable: true,
  107. changeFn: (index, val) => {
  108. changeAmount(index);
  109. },
  110. },
  111. {
  112. type: "input",
  113. itemType: "number",
  114. label: "金额小计",
  115. prop: "total",
  116. placeholder: "根据单价、数量自动计算",
  117. readonly: true,
  118. },
  119. ],
  120. clickFn: () => {
  121. if (
  122. formData.data.salesContractDetailsList &&
  123. formData.data.salesContractDetailsList.length > 0
  124. ) {
  125. formData.data.salesContractDetailsList.push({
  126. productId: "",
  127. quantity: "",
  128. });
  129. } else {
  130. formData.data.salesContractDetailsList = [
  131. {
  132. productId: "",
  133. quantity: "",
  134. },
  135. ];
  136. }
  137. },
  138. },
  139. });
  140. const formConfig = reactive([
  141. {
  142. type: "picker",
  143. label: "客户名称",
  144. prop: "customerId",
  145. itemType: "onePicker",
  146. showPicker: false,
  147. fieldNames: {
  148. text: "label",
  149. value: "value",
  150. },
  151. data: [],
  152. },
  153. {
  154. type: "picker",
  155. label: "交货期限",
  156. prop: "deliveryDate",
  157. itemType: "datePicker",
  158. showPicker: false,
  159. split: "-",
  160. columnsType: ["year", "month", "day"],
  161. },
  162. {
  163. type: "picker",
  164. label: "付款方式",
  165. prop: "payMethod",
  166. itemType: "onePicker",
  167. showPicker: false,
  168. fieldNames: {
  169. text: "label",
  170. value: "value",
  171. },
  172. data: [],
  173. },
  174. {
  175. type: "picker",
  176. label: "运费支付方",
  177. prop: "freightPayer",
  178. itemType: "onePicker",
  179. showPicker: false,
  180. fieldNames: {
  181. text: "label",
  182. value: "value",
  183. },
  184. data: [
  185. {
  186. label: "甲方",
  187. value: "0",
  188. },
  189. {
  190. label: "乙方",
  191. value: "1",
  192. },
  193. ],
  194. },
  195. {
  196. type: "input",
  197. itemType: "textarea",
  198. label: "备注",
  199. prop: "remark",
  200. },
  201. {
  202. type: "input",
  203. itemType: "number",
  204. label: "合同总金额",
  205. prop: "total",
  206. readonly: true,
  207. },
  208. ]);
  209. const onClickLeft = () => history.back();
  210. const fundsPaymentMethod = ref([]);
  211. const customerData = ref([]);
  212. const productData = ref([]);
  213. const getDict = () => {
  214. proxy.getDictOne(["funds_payment_method"]).then((res) => {
  215. fundsPaymentMethod.value = res["funds_payment_method"].data.map((x) => ({
  216. label: x.dictValue,
  217. value: x.dictKey,
  218. }));
  219. formConfig[2].data = fundsPaymentMethod.value;
  220. });
  221. proxy.post("/customer/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
  222. customerData.value = res.data.rows.map((x) => ({
  223. label: x.name,
  224. value: x.id,
  225. }));
  226. formConfig[0].data = customerData.value;
  227. });
  228. proxy
  229. .post("/productInfo/page", { pageNum: 1, pageSize: 9999, definition: "1" })
  230. .then((res) => {
  231. productData.value = res.data.rows.map((x) => ({
  232. label: x.name,
  233. value: x.id,
  234. }));
  235. formOption.btnConfig.listConfig[0].data = productData.value;
  236. });
  237. };
  238. const getDetails = (id) => {
  239. proxy.post("/salesContract/detail", { id }).then((res) => {
  240. if (res.data && res.data.contractDetailsList.length > 0) {
  241. res.data.salesContractDetailsList = res.data.contractDetailsList;
  242. } else {
  243. res.data.salesContractDetailsList = [];
  244. }
  245. formData.data = res.data;
  246. changeAmount();
  247. });
  248. };
  249. onMounted(() => {
  250. getDict();
  251. if (route.query.id) {
  252. getDetails(route.query.id);
  253. formOption.readonly = true; //全部只读
  254. formOption.hiddenSubmitBtn = true; //隐藏提交按钮
  255. formOption.btnConfig.isNeed = false;
  256. }
  257. });
  258. const onSubmit = () => {
  259. if (formData.data.salesContractDetailsList.length > 0) {
  260. proxy
  261. .post("/flowProcess/initiate", {
  262. flowKey: "jxst_sales_contract_flow",
  263. data: formData.data,
  264. })
  265. .then(
  266. () => {
  267. showSuccessToast("操作成功");
  268. setTimeout(() => {
  269. onClickLeft();
  270. }, 500);
  271. },
  272. (err) => {
  273. return showFailToast(err.message);
  274. }
  275. );
  276. } else {
  277. return showFailToast("请添加合同明细!");
  278. }
  279. };
  280. const changeAmount = (index) => {
  281. let total = 0;
  282. for (let i = 0; i < formData.data.salesContractDetailsList.length; i++) {
  283. const element = formData.data.salesContractDetailsList[i];
  284. if (element.unitPrice && element.quantity) {
  285. element.total = parseFloat(element.unitPrice * element.quantity).toFixed(
  286. 2
  287. );
  288. total += Number(element.total);
  289. }
  290. }
  291. if (total) {
  292. formData.data.total = total.toFixed(2);
  293. }
  294. };
  295. </script>
  296. <style lang="scss" scoped>
  297. .form {
  298. margin-bottom: 60px;
  299. }
  300. </style>