qrd-modal.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. <script setup lang="ts">
  2. import { ref, computed, nextTick } from "vue";
  3. import { ElForm, ElMessage } from "element-plus";
  4. import { ModalTypes } from "/@/modules/modal";
  5. import { useAsync } from "/@/hooks/core/useAsync";
  6. import { useCompany } from "/@/hooks/core/useCompany";
  7. import Company from "./components/company.vue";
  8. import Customer from "./components/customer.vue";
  9. import Supplier from "./components/supplier.vue";
  10. import Category from "./components/category.vue";
  11. import SaleUser from "./components/sale-user.vue";
  12. import User from "./components/user.vue";
  13. import {
  14. httpRatelist,
  15. httpCreate,
  16. httpUpdate,
  17. httpDetail
  18. } from "/@/api/netOrderEnter/netOrderEntry";
  19. import {
  20. formRules,
  21. saleDepartOptions,
  22. purchaseDepartOptions,
  23. defaultData
  24. } from "./config/_options";
  25. const emit = defineEmits(["reload"]);
  26. const visible = ref(false);
  27. const loading = ref(false);
  28. const modalType = ref<ModalTypes>(ModalTypes.create);
  29. const customerRef = ref<InstanceType<typeof Customer> | null>(null);
  30. const supplierRef = ref<InstanceType<typeof Supplier> | null>(null);
  31. const companyRef = ref<InstanceType<typeof Company> | null>(null);
  32. const saleUserRef = ref<InstanceType<typeof User> | null>(null);
  33. const buyerUserRef = ref<InstanceType<typeof User> | null>(null);
  34. const categoryRef = ref<InstanceType<typeof Category> | null>(null);
  35. const disabledDate = (time: Date) => time.getTime() > new Date().valueOf();
  36. const formRef = ref<InstanceType<typeof ElForm> | null>(null);
  37. const formData = ref<Record<string, any>>({ ...defaultData });
  38. const { currentCompany } = useCompany();
  39. function onSuccess() {
  40. visible.value = false;
  41. emit("reload");
  42. }
  43. function onRequsetDetailSuccess(data: Record<string, string>) {
  44. const keys = Object.keys(data);
  45. const numberField = ["goodNum", "goodPrice", "cgd_tax"];
  46. keys.forEach(key => {
  47. let value = numberField.includes(key) ? Number(data[key]) : data[key];
  48. formData.value[key] = value;
  49. });
  50. const { companyNo, supplierNo, khNo, cat, sale_name, buyer } = formData.value;
  51. const _cat = cat ? cat[cat.length - 1].id : "";
  52. formData.value.cat = _cat;
  53. requsetRatelist();
  54. //回显数据
  55. companyRef.value.initalData({ companyNo });
  56. supplierRef.value.initalData({ companyNo: supplierNo });
  57. customerRef.value.initalData({ companyNo: khNo });
  58. categoryRef.value.initalData({ cat: _cat });
  59. buyerUserRef.value.initalData({ nickname: buyer, companyNo });
  60. saleUserRef.value.initalData({ nickname: sale_name, companyNo });
  61. }
  62. function onRequsetRateSuccess(data: Array<Record<string, string>>) {
  63. const { tax } = formData.value;
  64. if (!data || !tax) return null;
  65. formData.value.tax = data.find(({ rate }) => rate === tax)?.id;
  66. }
  67. const {
  68. data: ratelist,
  69. run: runRatelist,
  70. loading: rateLoading
  71. } = useAsync<Array<Record<string, any>>>({
  72. isList: false,
  73. initalData: [],
  74. success: data => onRequsetRateSuccess(data)
  75. });
  76. const { run: runCreate, loading: createLoading } = useAsync({
  77. success: () => onSuccess()
  78. });
  79. const { run: runUpdate, loading: updateLoading } = useAsync({
  80. success: () => onSuccess()
  81. });
  82. const { run: runDetail, loading: detailLoading } = useAsync({
  83. initalData: {},
  84. success: data => onRequsetDetailSuccess(data)
  85. });
  86. const title = computed(() => {
  87. const baseTitle = "确认单";
  88. const isPreview = modalType.value === ModalTypes.preview;
  89. const isCreate = modalType.value === ModalTypes.create;
  90. if (isPreview) return `${baseTitle}详情`;
  91. return `${isCreate ? "创建" : "修改"}${baseTitle}`;
  92. });
  93. function handleUserChange(
  94. data: Record<string, string>,
  95. key: "sale_name" | "buyer"
  96. ) {
  97. if (!data) return null;
  98. const { nickname } = data;
  99. formData.value[key] = nickname;
  100. }
  101. const dialogloading = computed(() => rateLoading.value || detailLoading.value);
  102. const actionLoading = computed(
  103. () => createLoading.value || updateLoading.value
  104. );
  105. const total = computed(() => {
  106. const { goodNum, goodPrice } = formData.value;
  107. return (Number(goodNum) * Number(goodPrice)).toFixed(2);
  108. });
  109. const requsetRatelist = () => runRatelist(httpRatelist());
  110. const requsetCreateQrd = data => runCreate(httpCreate(data));
  111. const requsetUpdateQrd = data => runUpdate(httpUpdate(data));
  112. const requsetQrdDetail = data => runDetail(httpDetail(data));
  113. function handleConfirm() {
  114. const { sale_id, buyerid, companyNo, supplierNo } = formData.value;
  115. if (sale_id === buyerid && sale_id && buyerid) {
  116. ElMessage.warning("采购员和销售员不能相同");
  117. return;
  118. }
  119. if (companyNo === supplierNo) {
  120. ElMessage.warning("销售方公司和供应商公司不能相同");
  121. return;
  122. }
  123. formRef.value.validate(isValid => {
  124. if (!isValid) return null;
  125. const isUpdate = modalType.value === ModalTypes.update;
  126. const requsetFunc = isUpdate ? requsetUpdateQrd : requsetCreateQrd;
  127. requsetFunc(formData.value);
  128. });
  129. }
  130. function onDisplay(_modalType: ModalTypes, id?: string) {
  131. const isUpdateOrPriview =
  132. _modalType === ModalTypes.update || _modalType === ModalTypes.preview;
  133. modalType.value = _modalType;
  134. visible.value = true;
  135. if (!isUpdateOrPriview && !currentCompany.value.companyNo) {
  136. ElMessage.warning("请在右上角选择一家公司");
  137. return;
  138. }
  139. if (isUpdateOrPriview) {
  140. requsetQrdDetail({ id });
  141. return;
  142. }
  143. requsetRatelist();
  144. formData.value.companyNo = currentCompany.value.companyNo;
  145. nextTick(() =>
  146. companyRef.value.initalData({ companyNo: currentCompany.value.companyNo })
  147. );
  148. }
  149. defineExpose({ onDisplay });
  150. </script>
  151. <template>
  152. <ElDialog
  153. v-model="visible"
  154. :title="title"
  155. destroy-on-close
  156. width="1040px"
  157. top="10vh"
  158. center
  159. @close="() => (formData = { ...defaultData })"
  160. :close-on-click-modal="false"
  161. >
  162. <ElForm
  163. v-loading="dialogloading"
  164. ref="formRef"
  165. :model="formData"
  166. :rules="formRules"
  167. label-width="93px"
  168. :disabled="modalType === ModalTypes.preview"
  169. >
  170. <ElRow :gutter="10">
  171. <ElCol :span="24" style="padding: 0 0 10px 0; margin-top: -5px">
  172. <ElDivider><ElTag>确认单信息</ElTag></ElDivider>
  173. </ElCol>
  174. <ElCol :span="8">
  175. <ElFormItem label="销售员" prop="sale_id">
  176. <SaleUser
  177. ref="saleUserRef"
  178. v-model="formData.sale_id"
  179. @item-change="handleUserChange($event, 'sale_name')"
  180. />
  181. </ElFormItem>
  182. </ElCol>
  183. <ElCol :span="8">
  184. <ElFormItem label="销售员部门" prop="sale_depart">
  185. <ElSelect style="width: 100%" v-model="formData.sale_depart">
  186. <ElOption
  187. v-for="(deparment, index) in saleDepartOptions"
  188. :label="deparment.value"
  189. :value="deparment.value"
  190. :disabled="deparment.status !== '1'"
  191. :key="index"
  192. />
  193. </ElSelect>
  194. </ElFormItem>
  195. </ElCol>
  196. <ElCol :span="8">
  197. <ElFormItem label="采购毛利率" prop="cgd_tax">
  198. <ElInputNumber
  199. v-model="formData.cgd_tax"
  200. style="width: 100%"
  201. controls-position="right"
  202. placeholder="采购毛利率"
  203. step-strictly
  204. :min="0"
  205. :precision="2"
  206. :step="0.01"
  207. :max="100"
  208. />
  209. </ElFormItem>
  210. </ElCol>
  211. <ElCol :span="8">
  212. <ElFormItem label="采购员" prop="buyerid">
  213. <User
  214. ref="buyerUserRef"
  215. v-model="formData.buyerid"
  216. @item-change="handleUserChange($event, 'buyer')"
  217. />
  218. </ElFormItem>
  219. </ElCol>
  220. <ElCol :span="8">
  221. <ElFormItem label="采购员部门" prop="cgd_depart">
  222. <ElSelect style="width: 100%" v-model="formData.cgd_depart">
  223. <ElOption
  224. v-for="(deparment, index) in purchaseDepartOptions"
  225. :label="deparment.value"
  226. :value="deparment.value"
  227. :disabled="deparment.status !== '1'"
  228. :key="index"
  229. />
  230. </ElSelect>
  231. </ElFormItem>
  232. </ElCol>
  233. <ElCol :span="12">
  234. <ElFormItem label="单据号" prop="workCode">
  235. <ElInput
  236. v-model="formData.workCode"
  237. placeholder="单据号"
  238. maxlength="200"
  239. />
  240. </ElFormItem>
  241. </ElCol>
  242. <ElCol :span="12">
  243. <ElFormItem label="PO编号" prop="poCode">
  244. <ElInput
  245. v-model="formData.poCode"
  246. placeholder="PO编号"
  247. maxlength="200"
  248. />
  249. </ElFormItem>
  250. </ElCol>
  251. <ElCol :span="12">
  252. <ElFormItem label="购买方公司" prop="khNo">
  253. <Customer ref="customerRef" v-model="formData.khNo" />
  254. </ElFormItem>
  255. </ElCol>
  256. <ElCol :span="12">
  257. <ElFormItem label="销售方公司" prop="companyNo">
  258. <Company ref="companyRef" v-model="formData.companyNo" />
  259. </ElFormItem>
  260. </ElCol>
  261. <ElCol :span="24" style="padding: 0 0 10px 0; margin-top: -5px">
  262. <ElDivider><ElTag>收货信息</ElTag></ElDivider>
  263. </ElCol>
  264. <ElCol :span="12">
  265. <ElFormItem label="收货人" prop="contactor">
  266. <ElInput
  267. v-model="formData.contactor"
  268. placeholder="收货人"
  269. maxlength="200"
  270. />
  271. </ElFormItem>
  272. </ElCol>
  273. <ElCol :span="12">
  274. <ElFormItem label="联系电话" prop="mobile">
  275. <ElInput
  276. v-model="formData.mobile"
  277. placeholder="联系电话"
  278. maxlength="11"
  279. />
  280. </ElFormItem>
  281. </ElCol>
  282. <ElCol :span="12">
  283. <ElFormItem label="联系地址" prop="addr">
  284. <ElInput
  285. v-model="formData.addr"
  286. placeholder="联系地址"
  287. maxlength="200"
  288. />
  289. </ElFormItem>
  290. </ElCol>
  291. <ElCol :span="12">
  292. <ElFormItem label="发货时间" prop="sendtime">
  293. <ElDatePicker
  294. v-model="formData.sendtime"
  295. :disabled-date="disabledDate"
  296. :editable="false"
  297. :clearable="true"
  298. placeholder="发货时间"
  299. style="width: 100%; margin: 0"
  300. type="datetime"
  301. value-format="YYYY-MM-DD HH:mm:ss"
  302. />
  303. </ElFormItem>
  304. </ElCol>
  305. <ElCol :span="24" style="padding: 0 0 10px 0; margin-top: -5px">
  306. <ElDivider><ElTag>商品信息</ElTag></ElDivider>
  307. </ElCol>
  308. <ElCol :span="12">
  309. <ElFormItem label="供应商公司" prop="supplierNo">
  310. <Supplier ref="supplierRef" v-model="formData.supplierNo" />
  311. </ElFormItem>
  312. </ElCol>
  313. <ElCol :span="12">
  314. <ElFormItem label="商品分类" prop="cat">
  315. <Category v-model="formData.cat" ref="categoryRef" />
  316. </ElFormItem>
  317. </ElCol>
  318. <ElCol :span="12">
  319. <ElFormItem label="商品名称" prop="goodName">
  320. <ElInput
  321. v-model="formData.goodName"
  322. placeholder="商品名称"
  323. maxlength="200"
  324. />
  325. </ElFormItem>
  326. </ElCol>
  327. <ElCol :span="6">
  328. <ElFormItem label="数量" prop="goodNum">
  329. <ElInputNumber
  330. v-model="formData.goodNum"
  331. style="width: 100%"
  332. controls-position="right"
  333. placeholder="数量"
  334. :min="0"
  335. :precision="0"
  336. step-strictly
  337. :step="1"
  338. :max="9999999"
  339. />
  340. </ElFormItem>
  341. </ElCol>
  342. <ElCol :span="6">
  343. <ElFormItem label="单价" label-width="55px" prop="goodPrice">
  344. <ElInputNumber
  345. v-model="formData.goodPrice"
  346. controls-position="right"
  347. placeholder="单价"
  348. style="width: 100%"
  349. :min="0"
  350. :precision="2"
  351. step-strictly
  352. :step="0.01"
  353. :max="9999999"
  354. />
  355. </ElFormItem>
  356. </ElCol>
  357. <ElCol :span="6">
  358. <ElFormItem label="货款总额">
  359. <ElInput :value="total" placeholder="货款总额" disabled>
  360. <template #append>元</template>
  361. </ElInput>
  362. </ElFormItem>
  363. </ElCol>
  364. <ElCol :span="6">
  365. <ElFormItem label="税率" prop="tax">
  366. <ElSelect style="width: 100%" v-model="formData.tax">
  367. <ElOption
  368. v-for="rate in ratelist"
  369. :key="rate.id"
  370. :label="rate.rate + '%'"
  371. :value="rate.id"
  372. />
  373. </ElSelect>
  374. </ElFormItem>
  375. </ElCol>
  376. <ElCol :span="12" style="text-align: right; padding: 5px 0 0 0">
  377. <ElButton
  378. type="primary"
  379. @click="handleConfirm"
  380. :loading="actionLoading || loading"
  381. >保存</ElButton
  382. >
  383. <ElButton @click="() => (visible = false)">关闭</ElButton>
  384. </ElCol>
  385. </ElRow>
  386. </ElForm>
  387. </ElDialog>
  388. </template>