index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. <template>
  2. <div class="tenant">
  3. <byTable
  4. :source="sourceList.data"
  5. :pagination="sourceList.pagination"
  6. :config="config"
  7. :loading="loading"
  8. :selectConfig="selectConfig"
  9. highlight-current-row
  10. :action-list="[
  11. {
  12. text: '新建样品单',
  13. action: () => newSample(),
  14. },
  15. ]"
  16. @get-list="getList">
  17. <template #amount="{ item }">
  18. <div>
  19. <span style="padding-right: 4px">{{ item.currency }}</span>
  20. <span>{{ moneyFormat(item.amount, 2) }}</span>
  21. </div>
  22. </template>
  23. <template #advanceRatio="{ item }">
  24. <div>
  25. <span>{{ item.advanceRatio }}%</span>
  26. </div>
  27. </template>
  28. </byTable>
  29. <el-dialog title="交接单" v-if="openHandoverSlip" v-model="openHandoverSlip" width="600">
  30. <byForm :formConfig="formConfig" :formOption="formOption" v-model="handoverSlipForm">
  31. <template #file>
  32. <div style="width: 100%">
  33. <el-upload
  34. v-model:fileList="handoverSlipForm.fileList"
  35. action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
  36. :data="uploadData"
  37. multiple
  38. :before-upload="uploadFile"
  39. :on-success="handleSuccess"
  40. :on-preview="onPreviewFile">
  41. <el-button type="primary" plain>选择</el-button>
  42. </el-upload>
  43. </div>
  44. </template>
  45. <template #indication>
  46. <div style="width: 100%">
  47. <el-upload
  48. v-model:fileList="handoverSlipForm.packageFileList"
  49. action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
  50. :data="indicationUploadData"
  51. multiple
  52. :before-upload="indicationUploadFile"
  53. :on-success="handleSuccess"
  54. :on-preview="onPreviewFile">
  55. <el-button type="primary" plain>选择</el-button>
  56. </el-upload>
  57. </div>
  58. </template>
  59. </byForm>
  60. <template #footer>
  61. <el-button @click="openHandoverSlip = false" size="large">关 闭</el-button>
  62. <el-button type="primary" @click="submitHandoverSlip()" size="large">确 定</el-button>
  63. </template>
  64. </el-dialog>
  65. </div>
  66. </template>
  67. <script setup>
  68. import { computed, ref } from "vue";
  69. import byTable from "@/components/byTable/index";
  70. import byForm from "@/components/byForm/index";
  71. import useUserStore from "@/store/modules/user";
  72. import { ElMessage, ElMessageBox } from "element-plus";
  73. const { proxy } = getCurrentInstance();
  74. const accountCurrency = ref([]);
  75. const tradeMethods = ref([]);
  76. const corporationList = ref([]);
  77. const customerList = ref([]);
  78. const userList = ref([]);
  79. const shippingMethod = ref([]);
  80. const status = ref([
  81. {
  82. label: "草稿",
  83. value: 0,
  84. },
  85. {
  86. label: "审批中",
  87. value: 10,
  88. },
  89. {
  90. label: "驳回",
  91. value: 20,
  92. },
  93. {
  94. label: "审批通过",
  95. value: 30,
  96. },
  97. {
  98. label: "终止",
  99. value: 99,
  100. },
  101. ]);
  102. const sourceList = ref({
  103. data: [],
  104. pagination: {
  105. total: 0,
  106. pageNum: 1,
  107. pageSize: 10,
  108. keyword: "",
  109. status: "",
  110. sellCorporationId: "",
  111. },
  112. });
  113. const loading = ref(false);
  114. const selectConfig = computed(() => {
  115. return [
  116. {
  117. label: "审批状态",
  118. prop: "status",
  119. data: status.value,
  120. },
  121. {
  122. label: "归属公司",
  123. prop: "sellCorporationId",
  124. data: corporationList.value,
  125. },
  126. ];
  127. });
  128. const config = computed(() => {
  129. return [
  130. {
  131. attrs: {
  132. label: "样品单编号",
  133. prop: "code",
  134. width: 180,
  135. },
  136. },
  137. {
  138. attrs: {
  139. label: "归属公司",
  140. prop: "sellCorporationId",
  141. "min-width": 220,
  142. },
  143. render(type) {
  144. return proxy.dictValueLabel(type, corporationList.value);
  145. },
  146. },
  147. {
  148. attrs: {
  149. label: "业务员",
  150. prop: "createUser",
  151. width: 140,
  152. },
  153. render(type) {
  154. return proxy.dictValueLabel(type, userList.value);
  155. },
  156. },
  157. {
  158. attrs: {
  159. label: "下单时间",
  160. prop: "createTime",
  161. width: 160,
  162. },
  163. },
  164. {
  165. attrs: {
  166. label: "客户名称",
  167. prop: "buyCorporationId",
  168. "min-width": 220,
  169. },
  170. render(type) {
  171. return proxy.dictValueLabel(type, customerList.value);
  172. },
  173. },
  174. {
  175. attrs: {
  176. label: "合同金额",
  177. slot: "amount",
  178. width: 140,
  179. },
  180. },
  181. {
  182. attrs: {
  183. label: "预付比例",
  184. slot: "advanceRatio",
  185. width: 140,
  186. },
  187. },
  188. {
  189. attrs: {
  190. label: "审批状态",
  191. prop: "status",
  192. width: 140,
  193. },
  194. render(type) {
  195. return proxy.dictValueLabel(type, status.value);
  196. },
  197. },
  198. {
  199. attrs: {
  200. label: "操作",
  201. width: 140,
  202. align: "center",
  203. fixed: "right",
  204. },
  205. renderHTML(row) {
  206. return [
  207. {
  208. attrs: {
  209. label: "交接单",
  210. type: "primary",
  211. text: true,
  212. },
  213. el: "button",
  214. click() {
  215. clickHandoverSlip(row);
  216. },
  217. },
  218. {
  219. attrs: {
  220. label: "作废",
  221. type: "primary",
  222. text: true,
  223. },
  224. el: "button",
  225. click() {
  226. ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
  227. confirmButtonText: "确定",
  228. cancelButtonText: "取消",
  229. type: "warning",
  230. }).then(() => {
  231. proxy
  232. .post("/sample/edit", {
  233. id: row.id,
  234. status: 88,
  235. })
  236. .then(() => {
  237. ElMessage({
  238. message: "作废成功",
  239. type: "success",
  240. });
  241. getList();
  242. });
  243. });
  244. },
  245. },
  246. ];
  247. },
  248. },
  249. ];
  250. });
  251. const getDict = () => {
  252. proxy.getDictOne(["trade_methods", "account_currency", "shipping_method"]).then((res) => {
  253. tradeMethods.value = res["trade_methods"].map((x) => ({
  254. label: x.dictValue,
  255. value: x.dictKey,
  256. }));
  257. accountCurrency.value = res["account_currency"].map((x) => ({
  258. label: x.dictValue,
  259. value: x.dictKey,
  260. }));
  261. shippingMethod.value = res["shipping_method"].map((x) => ({
  262. label: x.dictValue,
  263. value: x.dictKey,
  264. }));
  265. });
  266. proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  267. corporationList.value = res.rows.map((item) => {
  268. return {
  269. ...item,
  270. label: item.name,
  271. value: item.id,
  272. };
  273. });
  274. });
  275. proxy.post("/customer/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  276. customerList.value = res.rows.map((item) => {
  277. return {
  278. ...item,
  279. label: item.name,
  280. value: item.id,
  281. };
  282. });
  283. });
  284. proxy
  285. .get("/tenantUser/list", {
  286. pageNum: 1,
  287. pageSize: 10000,
  288. tenantId: useUserStore().user.tenantId,
  289. })
  290. .then((res) => {
  291. userList.value = res.rows.map((item) => {
  292. return {
  293. label: item.nickName,
  294. value: item.userId,
  295. };
  296. });
  297. });
  298. };
  299. const getList = async (req) => {
  300. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  301. loading.value = true;
  302. proxy.post("/sample/page", sourceList.value.pagination).then((res) => {
  303. sourceList.value.data = res.rows;
  304. sourceList.value.pagination.total = res.total;
  305. setTimeout(() => {
  306. loading.value = false;
  307. }, 200);
  308. });
  309. };
  310. getDict();
  311. getList();
  312. const newSample = () => {
  313. proxy.$router.replace({
  314. path: "/platform_manage/process/processApproval",
  315. query: {
  316. flowKey: "sample_flow",
  317. flowName: "样品单审批流程",
  318. random: proxy.random(),
  319. tenantType: "EHSD",
  320. },
  321. });
  322. };
  323. const openHandoverSlip = ref(false);
  324. const handoverSlipForm = ref({
  325. id: "",
  326. code: "",
  327. buyCorporationName: "",
  328. fileList: [],
  329. packageFileList: [],
  330. });
  331. const formOption = reactive({
  332. inline: true,
  333. labelWidth: 100,
  334. itemWidth: 100,
  335. rules: [],
  336. });
  337. const formConfig = computed(() => {
  338. return [
  339. {
  340. type: "input",
  341. prop: "code",
  342. label: "样品单编号",
  343. itemType: "text",
  344. disabled: true,
  345. },
  346. {
  347. type: "input",
  348. prop: "buyCorporationName",
  349. label: "客户名称",
  350. itemType: "text",
  351. disabled: true,
  352. },
  353. {
  354. type: "slot",
  355. slotName: "file",
  356. label: "交接单",
  357. },
  358. {
  359. type: "slot",
  360. slotName: "indication",
  361. label: "包装指示",
  362. },
  363. ];
  364. });
  365. const uploadData = ref({});
  366. const indicationUploadData = ref({});
  367. const clickHandoverSlip = (item) => {
  368. handoverSlipForm.value.id = item.id;
  369. handoverSlipForm.value.code = item.code;
  370. handoverSlipForm.value.buyCorporationName = item.buyCorporationName;
  371. if (item.fileInfoVos && item.fileInfoVos.length > 0) {
  372. handoverSlipForm.value.fileList = item.fileInfoVos.map((item) => {
  373. return {
  374. raw: item,
  375. name: item.fileName,
  376. url: item.fileUrl,
  377. };
  378. });
  379. } else {
  380. handoverSlipForm.value.fileList = [];
  381. }
  382. if (item.packageFileInfoVOList && item.packageFileInfoVOList.length > 0) {
  383. handoverSlipForm.value.packageFileList = item.packageFileInfoVOList.map((item) => {
  384. return {
  385. raw: item,
  386. name: item.fileName,
  387. url: item.fileUrl,
  388. };
  389. });
  390. } else {
  391. handoverSlipForm.value.packageFileList = [];
  392. }
  393. openHandoverSlip.value = true;
  394. };
  395. const uploadFile = async (file) => {
  396. const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
  397. uploadData.value = res.uploadBody;
  398. file.id = res.id;
  399. file.fileName = res.fileName;
  400. file.fileUrl = res.fileUrl;
  401. file.uploadState = true;
  402. return true;
  403. };
  404. const indicationUploadFile = async (file) => {
  405. const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
  406. indicationUploadData.value = res.uploadBody;
  407. file.id = res.id;
  408. file.fileName = res.fileName;
  409. file.fileUrl = res.fileUrl;
  410. file.uploadState = true;
  411. return true;
  412. };
  413. const handleSuccess = (any, UploadFile) => {
  414. UploadFile.raw.uploadState = false;
  415. };
  416. const onPreviewFile = (file) => {
  417. window.open(file.raw.fileUrl, "_blank");
  418. };
  419. const submitHandoverSlip = () => {
  420. if (handoverSlipForm.value.fileList && handoverSlipForm.value.fileList.length > 0) {
  421. for (let i = 0; i < handoverSlipForm.value.fileList.length; i++) {
  422. if (handoverSlipForm.value.fileList[i].raw.uploadState) {
  423. return ElMessage("文件上传中,请稍后提交");
  424. }
  425. }
  426. }
  427. if (handoverSlipForm.value.packageFileList && handoverSlipForm.value.packageFileList.length > 0) {
  428. for (let i = 0; i < handoverSlipForm.value.packageFileList.length; i++) {
  429. if (handoverSlipForm.value.packageFileList[i].raw.uploadState) {
  430. return ElMessage("文件上传中,请稍后提交");
  431. }
  432. }
  433. }
  434. let data = proxy.deepClone(handoverSlipForm.value);
  435. if (data.fileList && data.fileList.length > 0) {
  436. data.fileList = data.fileList.map((item) => {
  437. return {
  438. id: item.raw.id,
  439. fileName: item.raw.fileName,
  440. fileUrl: item.raw.fileUrl,
  441. };
  442. });
  443. } else {
  444. data.fileList = [];
  445. }
  446. if (data.packageFileList && data.packageFileList.length > 0) {
  447. data.packageFileList = data.packageFileList.map((item) => {
  448. return {
  449. id: item.raw.id,
  450. fileName: item.raw.fileName,
  451. fileUrl: item.raw.fileUrl,
  452. };
  453. });
  454. } else {
  455. data.packageFileList = [];
  456. }
  457. proxy.post("/sample/sampleHandover", data).then(() => {
  458. ElMessage({
  459. message: "操作成功!",
  460. type: "success",
  461. });
  462. openHandoverSlip.value = false;
  463. getList();
  464. });
  465. };
  466. </script>
  467. <style lang="scss" scoped>
  468. .tenant {
  469. padding: 20px;
  470. }
  471. ::v-deep(.el-input-number .el-input__inner) {
  472. text-align: left;
  473. }
  474. .baseRow {
  475. min-height: 24px;
  476. border-top: 1px solid black;
  477. border-left: 1px solid black;
  478. }
  479. .contentRow {
  480. border-right: 1px solid black;
  481. line-height: 24px;
  482. padding-left: 4px;
  483. }
  484. </style>