index.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. <template>
  2. <div class="user">
  3. <div class="content">
  4. <byTable
  5. :source="sourceList.data"
  6. :pagination="sourceList.pagination"
  7. :config="config"
  8. :loading="loading"
  9. highlight-current-row
  10. :selectConfig="selectConfig"
  11. :table-events="{
  12. //element talbe事件都能传
  13. select: select,
  14. }"
  15. :action-list="[
  16. {
  17. text: 'Excel导入',
  18. action: () => openExcel(),
  19. disabled: false,
  20. },
  21. {
  22. text: '添加物料',
  23. action: () => openModal('add'),
  24. disabled: false,
  25. },
  26. ]"
  27. @get-list="getList"
  28. >
  29. <template #pic="{ item }">
  30. <div v-if="item.fileList.length > 0">
  31. <img
  32. :src="item.fileList[0].fileUrl"
  33. class="pic"
  34. @click="handleClickFile(item.fileList[0])"
  35. />
  36. </div>
  37. <div v-else></div>
  38. </template>
  39. </byTable>
  40. </div>
  41. <el-dialog
  42. :title="modalType == 'add' ? '添加' : '编辑'"
  43. v-model="dialogVisible"
  44. width="500"
  45. v-loading="loading"
  46. >
  47. <byForm
  48. :formConfig="formConfig"
  49. :formOption="formOption"
  50. v-model="formData.data"
  51. :rules="rules"
  52. ref="byform"
  53. >
  54. <template #productPic>
  55. <div>
  56. <el-upload
  57. v-model:fileList="fileList"
  58. action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
  59. :data="uploadData"
  60. list-type="picture-card"
  61. :on-remove="handleRemove"
  62. :on-success="handleSuccess"
  63. :before-upload="handleBeforeUpload"
  64. >
  65. <el-icon><Plus /></el-icon>
  66. </el-upload>
  67. </div>
  68. </template>
  69. </byForm>
  70. <template #footer>
  71. <el-button @click="dialogVisible = false" size="large"
  72. >取 消</el-button
  73. >
  74. <el-button
  75. type="primary"
  76. @click="submitForm('byform')"
  77. size="large"
  78. :loading="submitLoading"
  79. >
  80. 确 定
  81. </el-button>
  82. </template>
  83. </el-dialog>
  84. <el-dialog
  85. title="Excel导入"
  86. v-model="openExcelDialog"
  87. width="400"
  88. v-loading="loading"
  89. >
  90. <template #footer>
  91. <el-button @click="openExcelDialog = false" size="large"
  92. >取 消</el-button
  93. >
  94. <el-button
  95. type="primary"
  96. @click="submitExcel()"
  97. size="large"
  98. :loading="submitLoading"
  99. >
  100. 确 定
  101. </el-button>
  102. </template>
  103. </el-dialog>
  104. </div>
  105. </template>
  106. <script setup>
  107. /* eslint-disable vue/no-unused-components */
  108. import { ElMessage, ElMessageBox } from 'element-plus'
  109. import byTable from '@/components/byTable/index'
  110. import byForm from '@/components/byForm/index'
  111. import { computed, defineComponent, ref } from 'vue'
  112. const loading = ref(false)
  113. const submitLoading = ref(false)
  114. const sourceList = ref({
  115. data: [],
  116. pagination: {
  117. total: 3,
  118. pageNum: 1,
  119. pageSize: 10,
  120. type: '',
  121. productClassifyId: '',
  122. keyword: '',
  123. definition: '2',
  124. },
  125. })
  126. let dialogVisible = ref(false)
  127. let openExcelDialog = ref(false)
  128. let modalType = ref('add')
  129. let rules = ref({
  130. productClassifyId: [
  131. { required: true, message: '请选择物料分类', trigger: 'change' },
  132. ],
  133. type: [{ required: true, message: '请选择物料类型', trigger: 'change' }],
  134. name: [{ required: true, message: '请输入物料名称', trigger: 'blur' }],
  135. unit: [{ required: true, message: '请选择单位', trigger: 'change' }],
  136. })
  137. const { proxy } = getCurrentInstance()
  138. const selectConfig = computed(() => {
  139. return [
  140. {
  141. label: '打款状态',
  142. prop: 'paymentStatus',
  143. data: [],
  144. },
  145. ]
  146. })
  147. const config = computed(() => {
  148. return [
  149. {
  150. attrs: {
  151. label: '归属公司',
  152. prop: 'corporationName',
  153. },
  154. },
  155. {
  156. attrs: {
  157. label: '归属部门',
  158. prop: 'deptName',
  159. },
  160. },
  161. {
  162. attrs: {
  163. label: '付款类型',
  164. prop: 'type',
  165. render(type) {
  166. return proxy.dictDataEcho(type, fundsType.value);
  167. },
  168. },
  169. },
  170. {
  171. attrs: {
  172. label: '申请人',
  173. prop: 'userName',
  174. },
  175. },
  176. {
  177. attrs: {
  178. label: '申请时间',
  179. prop: 'createTime',
  180. },
  181. },
  182. {
  183. attrs: {
  184. label: '用款时间',
  185. prop: 'paymentTime',
  186. },
  187. },
  188. {
  189. attrs: {
  190. label: '金额',
  191. prop: 'total',
  192. },
  193. },
  194. {
  195. attrs: {
  196. label: '款项说明',
  197. prop: 'paymentRemarks',
  198. },
  199. },
  200. {
  201. attrs: {
  202. label: '打款状态',
  203. prop: 'status',
  204. },
  205. },
  206. {
  207. attrs: {
  208. label: '操作',
  209. width: '200',
  210. align: 'right',
  211. },
  212. // 渲染 el-button,一般用在最后一列。
  213. renderHTML(row) {
  214. return [
  215. {
  216. attrs: {
  217. label: '查看',
  218. type: 'primary',
  219. text: true,
  220. },
  221. el: 'button',
  222. click() {
  223. getDtl(row)
  224. },
  225. },
  226. {
  227. attrs: {
  228. label: '删除',
  229. type: 'danger',
  230. text: true,
  231. },
  232. el: 'button',
  233. click() {
  234. // 弹窗提示是否删除
  235. ElMessageBox.confirm(
  236. '此操作将永久删除该数据, 是否继续?',
  237. '提示',
  238. {
  239. confirmButtonText: '确定',
  240. cancelButtonText: '取消',
  241. type: 'warning',
  242. }
  243. ).then(() => {
  244. // 删除
  245. proxy
  246. .post('/productInfo/delete', {
  247. id: row.id,
  248. })
  249. .then((res) => {
  250. ElMessage({
  251. message: '删除成功',
  252. type: 'success',
  253. })
  254. getList()
  255. })
  256. })
  257. },
  258. },
  259. ]
  260. },
  261. },
  262. ]
  263. })
  264. let formData = reactive({
  265. data: {},
  266. })
  267. const formOption = reactive({
  268. inline: true,
  269. labelWidth: 100,
  270. itemWidth: 100,
  271. rules: [],
  272. })
  273. const byform = ref(null)
  274. const treeListData = ref([])
  275. const formConfig = computed(() => {
  276. return [
  277. {
  278. type: 'treeSelect',
  279. prop: 'productClassifyId',
  280. label: '物料分类',
  281. data: [],
  282. },
  283. {
  284. type: 'select',
  285. prop: 'type',
  286. label: '物料类型',
  287. required: true,
  288. data: [
  289. {
  290. label: '原料',
  291. id: '1',
  292. },
  293. {
  294. label: '辅料',
  295. id: '2',
  296. },
  297. {
  298. label: '配件',
  299. id: '3',
  300. },
  301. {
  302. label: '包材',
  303. id: '4',
  304. },
  305. {
  306. label: '其他',
  307. id: '5',
  308. },
  309. ],
  310. },
  311. {
  312. type: 'input',
  313. prop: 'name',
  314. label: '物料名称',
  315. },
  316. {
  317. type: 'input',
  318. prop: 'spec',
  319. label: '规格型号',
  320. },
  321. {
  322. type: 'select',
  323. prop: 'unit',
  324. label: '单位',
  325. required: true,
  326. data: [
  327. {
  328. label: '个',
  329. id: '个',
  330. },
  331. {
  332. label: '双',
  333. id: '双',
  334. },
  335. ],
  336. },
  337. {
  338. type: 'slot',
  339. slotName: 'productPic',
  340. prop: 'fileList',
  341. label: '产品图片',
  342. },
  343. {
  344. type: 'input',
  345. prop: 'remark',
  346. label: '备注',
  347. itemType: 'textarea',
  348. },
  349. ]
  350. })
  351. const newPassword = () => {
  352. formData.data.password = generatePassword()
  353. }
  354. const generatePassword = () => {
  355. var length = 12,
  356. charset =
  357. 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
  358. password = ''
  359. for (var i = 0, n = charset.length; i < length; ++i) {
  360. password += charset.charAt(Math.floor(Math.random() * n))
  361. }
  362. return password
  363. }
  364. const getList = async (req) => {
  365. sourceList.value.pagination = { ...sourceList.value.pagination, ...req }
  366. loading.value = true
  367. proxy
  368. .post('/accountPayment/page', sourceList.value.pagination)
  369. .then((message) => {
  370. console.log(message)
  371. sourceList.value.data = message.rows
  372. sourceList.value.pagination.total = message.total
  373. setTimeout(() => {
  374. loading.value = false
  375. }, 200)
  376. })
  377. }
  378. const uploadData = ref({})
  379. const fileList = ref([])
  380. const fileListCopy = ref([])
  381. proxy.getDict(['payment_status','funds_type','funds_payment_method']).then((res) => {
  382. console.log(res)
  383. })
  384. const openModal = () => {
  385. dialogVisible.value = true
  386. modalType.value = 'add'
  387. formData.data = {
  388. definition: '2',
  389. fileList: [],
  390. type: '1',
  391. }
  392. fileList.value = []
  393. fileListCopy.value = []
  394. }
  395. const openExcel = () => {
  396. openExcelDialog.value = true
  397. }
  398. const submitExcel = () => {
  399. openExcelDialog.value = false
  400. }
  401. const selection = ref({
  402. data: [],
  403. })
  404. const select = (_selection, row) => {
  405. selection.value.data = _selection
  406. console.log(_selection.length)
  407. }
  408. const submitForm = () => {
  409. console.log(byform.value)
  410. byform.value.handleSubmit((valid) => {
  411. formData.data.fileList = fileListCopy.value.map((x) => ({
  412. id: x.id,
  413. fileName: x.fileName,
  414. }))
  415. submitLoading.value = true
  416. proxy.post('/productInfo/' + modalType.value, formData.data).then(
  417. (res) => {
  418. ElMessage({
  419. message: modalType.value == 'add' ? '添加成功' : '编辑成功',
  420. type: 'success',
  421. })
  422. dialogVisible.value = false
  423. submitLoading.value = false
  424. getList()
  425. },
  426. (err) => {
  427. submitLoading.value = false
  428. }
  429. )
  430. })
  431. }
  432. const getTreeList = () => {
  433. proxy
  434. .post('/productClassify/tree', {
  435. parentId: '',
  436. name: '',
  437. definition: '2',
  438. })
  439. .then((message) => {
  440. treeListData.value = message
  441. formConfig.value[0].data = message
  442. })
  443. }
  444. const getDtl = (row) => {
  445. modalType.value = 'edit'
  446. proxy.post('/accountPayment/detail', { id: row.id }).then((res) => {
  447. formData.data = res
  448. dialogVisible.value = true
  449. })
  450. }
  451. getTreeList()
  452. getList()
  453. const handleBeforeUpload = async (file) => {
  454. const res = await proxy.post('/fileInfo/getSing', { fileName: file.name })
  455. uploadData.value = res.uploadBody
  456. fileListCopy.value.push({
  457. id: res.id,
  458. fileName: res.fileName,
  459. path: res.fileUrl,
  460. url: res.fileUrl,
  461. uid: file.uid,
  462. })
  463. }
  464. const handleSuccess = (res, file, files) => {
  465. // 查当前file的index值去赋值对应的copy变量的值
  466. // let uid = file.uid;
  467. // const index = fileList.value.findIndex((x) => x.uid === uid);
  468. // fileListCopy.value[index].uid = uid;
  469. }
  470. const handleRemove = (file) => {
  471. const index = fileListCopy.value.findIndex(
  472. (x) => x.uid === file.uid || x.id === file.id
  473. )
  474. fileListCopy.value.splice(index, 1)
  475. }
  476. const handleClickFile = (file) => {
  477. window.open(file.fileUrl, '_blank')
  478. }
  479. </script>
  480. <style lang="scss" scoped>
  481. .user {
  482. padding: 20px;
  483. }
  484. .pic {
  485. object-fit: contain;
  486. width: 50px;
  487. height: 50px;
  488. cursor: pointer;
  489. vertical-align: middle;
  490. }
  491. </style>