773 Commits
xqhz ... clay

Author SHA1 Message Date
clay
e576000267 feat : 科创部直接跳过审批节点 2024-07-19 14:51:07 +08:00
clay
ae6da83a1a feat : 科创部直接跳过审批节点 2024-07-19 14:23:00 +08:00
clay
bd01e4c94b feat : 科创部直接跳过审批节点 2024-07-19 14:22:17 +08:00
lilinyuan
9783ca8506 feat: 表单组件添加回车事件 2024-07-19 11:10:51 +08:00
clay
264f6283dc feat : 部门副职用户选择框无法弹出 2024-07-19 10:07:39 +08:00
acf261b58b Merge pull request 'feat : 台账导入' (#602) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/602
2024-07-18 17:54:19 +00:00
fde9ba3781 feat : 台账导入 2024-07-19 01:53:51 +08:00
04a65c6932 Merge pull request 'dd' (#600) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/600
2024-07-18 16:43:39 +00:00
e9333f7859 feat : 台账导入 2024-07-19 00:43:11 +08:00
0a2004e3ce feat : 台账导入 2024-07-19 00:41:15 +08:00
b69a147c61 Merge pull request 'feat : 台账导入' (#598) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/598
2024-07-18 14:56:21 +00:00
5deae5d846 feat : 台账导入 2024-07-18 22:56:08 +08:00
c2c60d01af Merge pull request 'fix : 修复页面bug' (#596) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/596
2024-07-18 14:06:59 +00:00
9d5c393ebe fix : 修复页面bug 2024-07-18 22:06:23 +08:00
3ec7a9c78e Merge pull request 'dd' (#594) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/594
2024-07-18 09:49:11 +00:00
5dc25d1480 fix : 项目实施台账刷新 2024-07-18 17:48:56 +08:00
ad3e7479f4 fix : 项目实施台账时间搜索 2024-07-18 17:33:54 +08:00
c082ffc884 Merge pull request 'fix : 项目实施台账时间搜索' (#592) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/592
2024-07-18 08:56:59 +00:00
618cc8cb87 fix : 项目实施台账时间搜索 2024-07-18 16:56:38 +08:00
8e91feb616 fix : 附件上传修复 2024-07-18 16:15:11 +08:00
203b53936f fix : 附件上传修复 2024-07-18 15:21:41 +08:00
f154e2789b Merge remote-tracking branch 'origin/master' 2024-07-18 14:52:23 +08:00
b4cfb8a5c6 fix : 附件上传修复 2024-07-18 14:52:06 +08:00
6c874cac48 Merge pull request 'fix : 修复项目立项校验' (#587) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/587
2024-07-18 04:27:39 +00:00
63eba1d0dc Merge remote-tracking branch 'origin/master' 2024-07-18 12:22:45 +08:00
094474b680 fix : 修复项目立项校验 2024-07-18 12:19:43 +08:00
0cfe4a8698 Merge pull request 'fix : 修复项目立项校验' (#586) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/586
2024-07-18 03:45:59 +00:00
60d9b958bc fix : 修复项目立项校验 2024-07-18 11:45:30 +08:00
1591e5d057 Merge pull request 'feat : 刷新缓存' (#584) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/584
2024-07-17 15:11:41 +00:00
0c3580768b feat : 刷新缓存 2024-07-17 23:11:26 +08:00
2793a62628 Merge pull request 'feat : 刷新缓存' (#582) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/582
2024-07-17 14:47:52 +00:00
cccd370671 feat : 刷新缓存 2024-07-17 22:47:38 +08:00
ec86d11537 Merge pull request 'fix : 修复年度计划创建及状态' (#580) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/580
2024-07-17 13:21:00 +00:00
2dea264c51 fix : 修复年度计划创建及状态 2024-07-17 21:20:48 +08:00
7dbaf5ca48 Merge pull request 'fix : 还原需求征集详情按钮显示' (#578) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/578
2024-07-17 09:29:38 +00:00
fb469d5139 fix : 还原需求征集详情按钮显示 2024-07-17 17:29:24 +08:00
fbccc01bbc Merge pull request 'feat : 需求征集详情审核通过后加上需求上报按钮' (#576) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/576
2024-07-17 09:21:31 +00:00
92de396d12 feat : 需求征集详情审核通过后加上需求上报按钮 2024-07-17 17:20:45 +08:00
a1dbcf8dce Merge remote-tracking branch 'origin/master' 2024-07-16 21:56:48 +08:00
ad4f2f5ba9 fix : 人员组件和组织结构组件改为懒加载模式 2024-07-16 21:56:39 +08:00
da10fca727 Merge pull request 'fix : 修复人员选择框' (#573) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/573
2024-07-16 13:11:20 +00:00
a934176986 fix : 修复人员选择框 2024-07-16 21:10:55 +08:00
c60245fb79 Merge pull request 'fix : 修复组织机构左侧高亮' (#571) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/571
2024-07-16 13:07:21 +00:00
280137b7e2 fix : 修复组织机构左侧高亮 2024-07-16 21:07:10 +08:00
36440928ae Merge pull request 'feat : 项目管理表单缓存,文件回显,个人中心icon排版' (#569) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/569
2024-07-16 12:36:23 +00:00
b77253b0cb feat : 项目管理表单缓存,文件回显,个人中心icon排版 2024-07-16 20:36:06 +08:00
clay
d4ba4bc7c2 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/layout/navbar/index.vue
2024-07-15 22:23:54 +08:00
clay
80116c77f6 feat : 账号切换刷新修改 2024-07-15 22:23:09 +08:00
d923330b77 Merge pull request 'feat : 用户个人中心密码校验及专项资金关联项目是否展示' (#566) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/566
2024-07-15 14:07:05 +00:00
4f41c43d37 feat : 用户个人中心密码校验及专项资金关联项目是否展示 2024-07-15 22:02:43 +08:00
45fccc9d57 Merge pull request 'feat : 用户个人中心展示及密码设置' (#564) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/564
2024-07-15 13:47:02 +00:00
8f993d0644 feat : 用户个人中心展示及密码设置 2024-07-15 21:46:40 +08:00
587c3c6477 Merge pull request 'dd' (#562) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/562
2024-07-15 12:45:24 +00:00
1f631ea65d fix : 注释log输出 2024-07-15 20:45:09 +08:00
4d9007c87e fix : 修复年度计划细节,表格高度 2024-07-15 20:44:48 +08:00
f4cf15656e Merge pull request 'fix : 修复阶段变更附件显示' (#560) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/560
2024-07-15 11:47:01 +00:00
55f12a2fb8 fix : 修复阶段变更附件显示 2024-07-15 19:46:34 +08:00
2616b916db Merge pull request 'fix : 修复项目详情排版,组织机构管理排版' (#558) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/558
2024-07-15 11:13:06 +00:00
6ac1dba2b5 fix : 修复项目详情排版,组织机构管理排版 2024-07-15 19:12:30 +08:00
lilinyuan
f6dcb6b71b fix: 页面缓存 2024-07-15 09:47:02 +08:00
7e1f5ca820 Merge pull request 'feat : 组织机构管理公司详情' (#555) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/555
2024-07-14 16:03:17 +00:00
5342a4d891 feat : 组织机构管理公司详情 2024-07-15 00:02:58 +08:00
602e69007c Merge pull request 'fix : 修复需求上报排版' (#553) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/553
2024-07-14 14:51:12 +00:00
04bbedf025 fix : 修复需求上报排版 2024-07-14 22:50:58 +08:00
6ab2b5f947 Merge pull request 'fix : 修改需求征集状态权限' (#551) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/551
2024-07-14 14:36:52 +00:00
a64e6827c1 fix : 修改需求征集状态权限 2024-07-14 22:36:40 +08:00
8173bfb6fb Merge pull request 'fix : 修改首页排版' (#550) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/550
2024-07-14 14:35:39 +00:00
599fe5febb fix : 修改首页排版 2024-07-14 22:35:12 +08:00
8313be513b Merge pull request 'fix : 修复项目立项回车搜索' (#549) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/549
2024-07-14 11:21:03 +00:00
cef1d50833 fix : 修复项目立项回车搜索 2024-07-14 19:08:49 +08:00
54db74b033 Merge pull request 'fix : 修复项目立项校验' (#548) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/548
2024-07-14 11:07:44 +00:00
cdb7811133 fix : 修复项目立项校验 2024-07-14 19:07:30 +08:00
wenhua
4c91a6a336 Merge branch 'master' of http://git.feashow.cn/clay/mosr-web 2024-07-14 18:18:36 +08:00
wenhua
c6222e0528 fix: 增加tag组件兼容性; 调整steps样式 2024-07-14 18:18:32 +08:00
a7d8bf63ca Merge pull request 'fix : 修复项目立项校验' (#547) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/547
2024-07-14 09:50:02 +00:00
29180cfb9f fix : 修复项目立项校验 2024-07-14 17:48:26 +08:00
02bf07f4da Merge pull request 'dd' (#546) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/546
2024-07-14 08:43:41 +00:00
8791d220e6 fix : 组织机构样式修改 2024-07-14 16:43:14 +08:00
88ab0d3526 fix : 修改项目立项校验 2024-07-14 15:57:56 +08:00
04cc61047a fix : 文件表格高度, 组织机构管理 2024-07-14 15:55:55 +08:00
925a8045f4 fix : 台账更新权限 2024-07-13 17:41:37 +08:00
3c12bafa59 fix : 所有下拉框, 加上搜索删除 2024-07-13 17:10:41 +08:00
f1237de72a Merge pull request 'fix : 上传文件表格滚动时, 表头固定' (#544) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/544
2024-07-13 06:19:07 +00:00
b1309fae57 fix : 上传文件表格滚动时, 表头固定 2024-07-13 14:18:47 +08:00
e45c71ccd0 Merge pull request 'fix : 上传文件表格滚动时, 表头固定' (#542) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/542
2024-07-13 05:23:53 +00:00
3e1db9c1a4 fix : 上传文件表格滚动时, 表头固定 2024-07-13 13:23:28 +08:00
6c55b66dde Merge pull request 'fix : 征集公司居中' (#540) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/540
2024-07-13 05:00:23 +00:00
e4ecd22c2e fix : 征集公司居中 2024-07-13 13:00:04 +08:00
clay
22d1c6fc46 Merge remote-tracking branch 'origin/master' 2024-07-12 15:04:02 +08:00
clay
1c095d3fcc feat : 调整布局 2024-07-12 15:03:54 +08:00
d49b771101 Merge pull request 'fix : 前置流程全选' (#538) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/538
2024-07-12 06:06:27 +00:00
8ac168023b fix : 前置流程全选 2024-07-12 14:06:15 +08:00
e7090f7cd8 Merge pull request 'fix : 前置流程enter的bug' (#536) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/536
2024-07-12 04:10:43 +00:00
7f581ef763 fix : 前置流程enter的bug 2024-07-12 12:10:18 +08:00
clay
fa05c22efc feat : 调整简答布局 2024-07-12 11:52:20 +08:00
clay
2856fa4785 feat : 流程渲染与有任务跳转到首页 2024-07-12 10:06:43 +08:00
0a40d4d068 Merge pull request 'fix : 表格更新负责人回显' (#532) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/532
2024-07-11 15:59:51 +00:00
649445f784 fix : 表格更新负责人回显 2024-07-11 23:59:39 +08:00
bdc23982ce Merge pull request 'fix : 项目立项页面细节优化' (#530) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/530
2024-07-11 15:49:34 +00:00
45220348d3 fix : 项目立项页面细节优化 2024-07-11 23:49:15 +08:00
dfe422345e Merge pull request 'fix : 项目立项页面细节优化' (#528) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/528
2024-07-11 15:32:44 +00:00
80cd6363ab fix : 项目立项页面细节优化 2024-07-11 23:31:59 +08:00
0b6e825bbd Merge pull request 'fix : 项目立项页面细节优化' (#526) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/526
2024-07-11 15:00:36 +00:00
5dacc784ea fix : 项目立项页面细节优化 2024-07-11 23:00:18 +08:00
68938c7ff0 Merge pull request 'fix : 项目立项页面细节优化' (#524) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/524
2024-07-11 14:48:17 +00:00
2722c9915b fix : 项目立项页面细节优化 2024-07-11 22:47:53 +08:00
97a81b6670 Merge pull request 'fix : 项目立项页面细节优化' (#522) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/522
2024-07-11 14:28:59 +00:00
61e7e096a4 fix : 项目立项页面细节优化 2024-07-11 22:28:43 +08:00
clay
3401c8a5e3 feat : 年度计划删除操作 2024-07-11 22:22:20 +08:00
480d419a6c Merge pull request 'fix : 项目立项页面细节优化' (#520) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/520
2024-07-11 13:09:26 +00:00
37755d62b1 fix : 项目立项页面细节优化 2024-07-11 21:09:10 +08:00
06e175cd8c Merge pull request 'dd' (#518) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/518
2024-07-11 08:40:31 +00:00
ddcbc02025 fix : 项目立项页面细节优化 2024-07-11 16:40:11 +08:00
7c63c5e791 Merge remote-tracking branch 'origin/master' 2024-07-11 14:48:27 +08:00
clay
7bf6336a46 fix : 年度计划删除 2024-07-10 23:19:41 +08:00
wenhua
50a4e21a99 Merge branch 'master' of http://git.feashow.cn/clay/mosr-web 2024-07-10 22:18:43 +08:00
wenhua
e8d3148937 fix: 调整样式 2024-07-10 22:18:40 +08:00
zhangkaihuai
dfdeaec16c Merge remote-tracking branch 'origin/master' 2024-07-10 18:09:02 +08:00
zhangkaihuai
42fd8d9740 feat:增加项目负责人和成员选择功能
在项目申请详情中,新增了项目负责人和成员的选择功能,使用user-picker组件实现。
同时,对前置流程的展示进行了调整,并完善了审批记录和流程图的相关逻辑。
2024-07-10 18:08:51 +08:00
17994928bf Merge pull request 'fix : 细节优化' (#516) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/516
2024-07-10 08:57:20 +00:00
5efa1b8764 Merge remote-tracking branch 'origin/master' 2024-07-10 16:57:08 +08:00
71b9065f29 fix : 细节优化 2024-07-10 16:56:28 +08:00
zhangkaihuai
b1616b716c Merge remote-tracking branch 'origin/master' 2024-07-10 16:53:48 +08:00
wenhua
7836450a10 fix: bug修复 2024-07-09 23:31:10 +08:00
cbc97891b8 Merge pull request 'fix : 修复年度计划详情展示' (#513) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/513
2024-07-09 11:35:25 +00:00
7a38c34da9 fix : 修复年度计划详情展示 2024-07-09 19:35:04 +08:00
9f06ecbc62 Merge pull request 'fix : 修复专项资金权限, 费用台账时间搜索' (#511) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/511
2024-07-07 15:36:36 +00:00
23975e056a fix : 修复专项资金权限, 费用台账时间搜索 2024-07-07 23:36:20 +08:00
ac409710d8 Merge pull request 'fix : 修复归档-附件搜索传参问题' (#509) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/509
2024-07-06 20:13:29 +00:00
2c8de29fcd fix : 修复归档-附件搜索传参问题 2024-07-07 04:12:06 +08:00
c5a3bc9b58 Merge pull request 'fix : 修复征集公司选择' (#507) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/507
2024-07-06 19:31:33 +00:00
09d95babd0 fix : 修复征集公司选择 2024-07-07 03:31:18 +08:00
584adb63d4 Merge pull request 'dd' (#505) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/505
2024-07-06 18:43:56 +00:00
06090fc00b fix : 修复费用台账时间搜索 2024-07-07 02:43:40 +08:00
fce1bfdb6f fix : 修复年度计划编辑功能 2024-07-07 02:36:40 +08:00
c10f7b2398 Merge pull request 'fix : 修复台账基础信息展示及年度计划通过后跳转' (#503) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/503
2024-07-06 18:22:36 +00:00
b21719aaa0 fix : 修复台账基础信息展示及年度计划通过后跳转 2024-07-07 02:22:17 +08:00
wenhua
9b19de0ff9 feat: 添加需求汇总详情 2024-07-07 00:56:20 +08:00
10e5db2cd6 Merge pull request 'fix : 修复需求上报预期成果形式回显' (#501) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/501
2024-07-06 16:46:43 +00:00
2a25942cdf fix : 修复需求上报预期成果形式回显 2024-07-07 00:46:19 +08:00
wenhua
a5864a32ce feat: 添加详情静态路由 2024-07-07 00:45:16 +08:00
5d661e1276 Merge pull request 'fix : 修复需求上报预期成果形式回显' (#499) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/499
2024-07-06 16:05:57 +00:00
8feef06c11 fix : 修复需求上报预期成果形式回显 2024-07-07 00:05:47 +08:00
dd5fb4f44a Merge pull request 'fix : 修复征集公司回显' (#497) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/497
2024-07-06 15:29:45 +00:00
57776764f8 fix : 修复征集公司回显 2024-07-06 23:29:33 +08:00
ce5297145b Merge pull request 'fix : 修复文件删除功能' (#495) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/495
2024-07-06 15:10:57 +00:00
3c564b600b fix : 修复文件删除功能 2024-07-06 23:10:45 +08:00
e7ee3fbc9d Merge pull request 'fix : 修复文件删除功能' (#494) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/494
2024-07-06 15:09:04 +00:00
edec70ebbb fix : 修复文件删除功能 2024-07-06 23:08:36 +08:00
13cbd1c7cd Merge pull request 'fix : 年度计划权限按钮' (#492) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/492
2024-07-06 14:38:49 +00:00
06524178c7 fix : 年度计划权限按钮 2024-07-06 22:38:31 +08:00
564084cb02 Merge pull request 'fix : 年度计划权限按钮' (#491) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/491
2024-07-06 14:38:05 +00:00
e5777b55bc fix : 年度计划权限按钮 2024-07-06 22:37:51 +08:00
41134a6266 Merge pull request 'fix : 台账表格更新输入框对齐' (#489) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/489
2024-07-06 13:39:51 +00:00
7e07010f0d fix : 台账表格更新输入框对齐 2024-07-06 21:39:37 +08:00
zhangkaihuai
ac28c3235e Merge remote-tracking branch 'origin/master' 2024-07-06 17:40:24 +08:00
2a5443dc4e Merge pull request 'fix : 流程管理中人员回显,表格更新负责人按钮更换位置,需求汇总选择框过滤' (#487) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/487
2024-07-06 09:36:54 +00:00
12f6f27b1a fix : 流程管理中人员回显,表格更新负责人按钮更换位置,需求汇总选择框过滤 2024-07-06 17:36:39 +08:00
9eebacc47a Merge pull request 'fix : 修复审批记录主次账号显示, 年度计划详情显示' (#485) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/485
2024-07-06 07:46:35 +00:00
ddc3b70ddf fix : 修复审批记录主次账号显示, 年度计划详情显示 2024-07-06 15:46:22 +08:00
clay
bd57a54931 fix : 矩阵审批选择自己时可以跳过自己审批 2024-07-06 15:05:19 +08:00
8f3d97ec1c Merge pull request 'feat : 年度计划生成功能及分摊汇总导出功能' (#483) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/483
2024-07-05 18:21:44 +00:00
8180c248ac feat : 年度计划生成功能及分摊汇总导出功能 2024-07-06 02:21:26 +08:00
zhangkaihuai
a7c1c3a483 Merge remote-tracking branch 'origin/master' 2024-07-05 09:29:40 +08:00
lilinyuan
fce1708f5c Merge branch 'master' of http://git.feashow.cn/clay/mosr-web 2024-07-04 17:18:41 +08:00
lilinyuan
dd80659044 fix: 样式调整 2024-07-04 17:18:38 +08:00
d7de238c38 Merge pull request 'fix : 分摊研发人员回显' (#480) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/480
2024-07-04 06:13:40 +00:00
08bc318875 fix : 分摊研发人员回显 2024-07-04 14:13:26 +08:00
888f97125b Merge pull request 'fix : 统一按钮颜色' (#478) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/478
2024-07-04 05:58:46 +00:00
c065008da0 fix : 统一按钮颜色 2024-07-04 13:58:26 +08:00
b2fdfc6227 Merge pull request 'fix : 流程图/人员与按钮间距' (#476) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/476
2024-07-04 05:08:33 +00:00
05585bb980 fix : 流程图/人员与按钮间距 2024-07-04 13:08:00 +08:00
f2863557f9 Merge pull request 'fix : 修复分摊编辑传参' (#474) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/474
2024-07-04 04:30:52 +00:00
70ffe5c1eb fix : 修复分摊编辑传参 2024-07-04 12:30:38 +08:00
a17ab96395 Merge pull request 'fix : 修改所属公司->征集公司' (#472) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/472
2024-07-04 03:31:06 +00:00
2466e15659 fix : 修改所属公司->征集公司 2024-07-04 11:30:03 +08:00
lilinyuan
5c889e41c2 Merge branch 'master' of http://git.feashow.cn/clay/mosr-web 2024-07-04 10:04:31 +08:00
lilinyuan
8ae817ffb3 fix: 分页 2024-07-04 10:04:28 +08:00
df09fbbd38 Merge pull request 'fix : 人员选择框,主次账号回显' (#469) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/469
2024-07-03 14:58:20 +00:00
842fa7b782 fix : 人员选择框,主次账号回显 2024-07-03 22:58:01 +08:00
a8afb48cf7 Merge pull request 'fix : 修复更新表格' (#467) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/467
2024-07-03 13:52:55 +00:00
bbc883a116 fix : 修复更新表格 2024-07-03 21:52:33 +08:00
216b0d273e Merge pull request 'fix : 修复台账表格最小高度' (#465) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/465
2024-07-03 13:40:13 +00:00
361510242c fix : 修复台账表格最小高度 2024-07-03 21:38:51 +08:00
94913d558d Merge pull request 'dd' (#464) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/464
2024-07-03 13:31:21 +00:00
9a789db8a7 fix : 修复分摊编辑传参问题 2024-07-03 21:31:05 +08:00
0f0fa0f4e0 fix : 修复研究人员每行的回显 2024-07-03 20:47:47 +08:00
212cbbcb78 Merge pull request 'fix : 修复征集公司回显,所属公司改为征集公司' (#462) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/462
2024-07-03 11:40:08 +00:00
9edf5d484f fix : 修复征集公司回显,所属公司改为征集公司 2024-07-03 19:39:53 +08:00
3bae1d1cc0 Merge pull request 'feat : 优化指定用户时该用户的矩阵状态检查' (#460) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/460
2024-07-03 06:10:26 +00:00
f26a29338a feat : 优化指定用户时该用户的矩阵状态检查 2024-07-03 14:10:10 +08:00
509b216e4c Merge pull request 'feat : 优化指定用户时该用户的矩阵状态检查' (#458) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/458
2024-07-03 05:30:20 +00:00
bffa726cbf feat : 优化指定用户时该用户的矩阵状态检查 2024-07-03 13:30:01 +08:00
a7fb633b89 feat : 优化指定用户时该用户的矩阵状态检查 2024-07-03 01:46:13 +08:00
b1ac328d9d Revert "feat : 优化指定用户时该用户的矩阵状态检查"
This reverts commit d2ddf378bf.
2024-07-03 01:45:10 +08:00
faaeb7be2b Merge remote-tracking branch 'origin/master' 2024-07-03 01:44:38 +08:00
d2ddf378bf feat : 优化指定用户时该用户的矩阵状态检查 2024-07-03 01:44:28 +08:00
c97798696a Merge pull request 'fix : 修复提交校验' (#455) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/455
2024-07-02 16:38:36 +00:00
0d7c303397 fix : 修复提交校验 2024-07-03 00:38:21 +08:00
zhangkaihuai
3d9db30ba3 Merge remote-tracking branch 'origin/master' 2024-07-02 23:58:49 +08:00
66be60d011 Merge pull request 'fix : 调整头部icon,删除没用的代码' (#453) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/453
2024-07-01 12:53:12 +00:00
928f41112c fix : 调整头部icon,删除没用的代码 2024-07-01 20:53:03 +08:00
9d55358d73 Merge pull request 'fix : 调整头部icon,删除没用的代码' (#451) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/451
2024-07-01 10:56:40 +00:00
2fd2d1d25b fix : 调整头部icon,删除没用的代码 2024-07-01 18:56:16 +08:00
daa76ada6e Merge pull request 'fix : 调整部门管理演示,优化移动端详情' (#449) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/449
2024-06-30 14:49:59 +00:00
09e2bfc605 fix : 调整部门管理演示,优化移动端详情 2024-06-30 22:49:37 +08:00
cae3746a7b Merge pull request 'fix : 新增分摊/上传费用输入框显示问题' (#447) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/447
2024-06-30 13:28:56 +00:00
47a5cd3338 fix : 新增分摊/上传费用输入框显示问题 2024-06-30 21:28:46 +08:00
51d2e8357b Merge pull request 'fix : "科研管理平台" 标题放开' (#445) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/445
2024-06-30 13:09:24 +00:00
d87027423e fix : "科研管理平台" 标题放开 2024-06-30 21:08:56 +08:00
592bba132e Merge pull request 'fix : 调整费用分摊,表格更新人员回显' (#443) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/443
2024-06-30 12:50:39 +00:00
a7b898fe48 fix : 调整费用分摊,表格更新人员回显 2024-06-30 20:43:08 +08:00
3c494d038e Merge pull request 'fix : 调整台账显示信息' (#441) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/441
2024-06-30 12:10:05 +00:00
c226715097 fix : 调整台账显示信息 2024-06-30 20:09:53 +08:00
3ba97bca2d Merge pull request 'fix : 调整台账显示信息' (#439) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/439
2024-06-30 12:04:04 +00:00
7daa4b676d fix : 调整台账显示信息 2024-06-30 20:03:31 +08:00
zhangkaihuai
88198a62b2 Merge remote-tracking branch 'origin/master' 2024-06-30 19:33:03 +08:00
a07bc1cc1c Merge remote-tracking branch 'origin/master' 2024-06-30 19:18:04 +08:00
fd3231db4d fix : 添加征集详情 2024-06-30 19:17:56 +08:00
d011dc4008 Merge pull request 'fix : 优化分摊汇总项目阶段显示' (#437) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/437
2024-06-30 09:21:10 +00:00
e43213d9a7 fix : 优化分摊汇总项目阶段显示 2024-06-30 17:21:00 +08:00
zhangkaihuai
9fbfa918e9 Merge remote-tracking branch 'origin/master' 2024-06-30 17:16:34 +08:00
04fa4bc334 Merge pull request 'fix : 优化阶段变更详情/项目编辑界面' (#435) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/435
2024-06-30 08:43:36 +00:00
c89f4db529 fix : 优化阶段变更详情/项目编辑界面 2024-06-30 16:43:21 +08:00
zhangkaihuai
7a49a23128 Merge remote-tracking branch 'origin/master' 2024-06-30 15:54:18 +08:00
7b18a92a26 Merge pull request 'fix : 优化移动端详情界面' (#433) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/433
2024-06-29 17:22:58 +00:00
6434605c7a fix : 优化移动端详情界面 2024-06-30 01:22:29 +08:00
c8eea20196 Merge pull request 'dd' (#431) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/431
2024-06-29 16:10:56 +00:00
87613e8113 fix : 优化移动端详情界面 2024-06-30 00:10:42 +08:00
80aef38e7a fix : 优化移动端详情界面 2024-06-30 00:00:16 +08:00
14ce31262d Merge pull request 'fix : 优化页面细节' (#430) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/430
2024-06-29 15:18:01 +00:00
2e9adb3248 fix : 优化页面细节 2024-06-29 23:17:47 +08:00
68b954a21e Merge pull request 'fix : 修复项目详情单个文件回显' (#428) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/428
2024-06-29 14:46:50 +00:00
1e4397b5ea fix : 修复项目详情单个文件回显 2024-06-29 22:46:37 +08:00
zhangkaihuai
eac76ca3bf Merge remote-tracking branch 'origin/master' 2024-06-29 22:32:21 +08:00
215b17f066 Merge pull request 'fix : 修复需求汇总文件回显' (#427) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/427
2024-06-29 14:31:46 +00:00
zhangkaihuai
719012f075 Merge remote-tracking branch 'origin/master' 2024-06-29 22:30:31 +08:00
40d3d423c7 fix : 修复需求汇总文件回显 2024-06-29 22:30:21 +08:00
02ac44f389 Merge pull request 'fix : 修复需求上报成果展示,需求新增专项资金校验' (#426) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/426
2024-06-29 14:27:35 +00:00
3b884c0b78 fix : 修复需求上报成果展示,需求新增专项资金校验 2024-06-29 22:27:22 +08:00
870ee5a6d0 Merge pull request 'fix : 修复项目详情前置流程更改回显' (#425) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/425
2024-06-29 13:44:08 +00:00
a446dfcaa6 fix : 修复项目详情前置流程更改回显 2024-06-29 21:43:57 +08:00
zhangkaihuai
167bff642e Merge remote-tracking branch 'origin/master' 2024-06-29 19:57:55 +08:00
630e35b078 Merge pull request 'fix : 修复需求上报成果多选' (#424) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/424
2024-06-29 10:57:13 +00:00
bd6fef9f7e fix : 修复需求上报成果多选 2024-06-29 18:56:05 +08:00
zhangkaihuai
da885d4965 Merge remote-tracking branch 'origin/master' 2024-06-29 18:27:19 +08:00
5394e45ab8 Merge pull request 'dd' (#422) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/422
2024-06-29 09:13:54 +00:00
d25c285ad6 fix : 完善信息提示框 2024-06-29 17:13:42 +08:00
zhangkaihuai
0273e19156 Merge remote-tracking branch 'origin/master' 2024-06-29 16:47:45 +08:00
e075eeb0d5 fix : 时间选择框为月份 2024-06-29 16:39:30 +08:00
54e50de6b1 fix : 修复阶段变更编辑回显 2024-06-29 15:51:03 +08:00
58d6a8f567 Merge pull request 'fix : 修复表格更新数据回显,新增征集提示框' (#420) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/420
2024-06-29 07:40:05 +00:00
38e9c1d1e5 fix : 修复表格更新数据回显,新增征集提示框 2024-06-29 15:39:42 +08:00
080b588723 Merge pull request 'dd' (#418) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/418
2024-06-29 05:43:24 +00:00
3efcc1d039 fix : 还原vite.config.js 2024-06-29 13:42:40 +08:00
0ad12c361d fix : 优化需求征集新增 2024-06-29 13:40:05 +08:00
0bfa18eac8 fix : 修复所属公司选择框细节 2024-06-29 13:02:12 +08:00
12db4164d0 fix : 单文件和多文件上传样式调整 2024-06-29 12:05:10 +08:00
5d9331c23f Merge remote-tracking branch 'origin/master' 2024-06-29 11:22:14 +08:00
c247659c6c Merge pull request 'fix : 需求上报-预期成果形式多选及展示' (#416) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/416
2024-06-29 03:22:13 +00:00
ed08c6a796 fix : 需求上报-预期成果形式多选及展示 2024-06-29 11:21:50 +08:00
a769d114bb Merge pull request 'fix : 优化流程图样式及位置,需求上报排版展示' (#414) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/414
2024-06-28 19:30:39 +00:00
e44b41bf14 fix : 优化流程图样式及位置,需求上报排版展示 2024-06-29 03:30:26 +08:00
6fe8626acb Merge pull request 'fix : 优化流程图样式及位置' (#413) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/413
2024-06-28 18:12:34 +00:00
0a6c37019a fix : 优化流程图样式及位置 2024-06-29 02:12:04 +08:00
657b43f739 Merge pull request 'fix : 修复需求汇总' (#411) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/411
2024-06-28 16:09:54 +00:00
13c0e3a7f0 fix : 修复需求汇总 2024-06-29 00:09:42 +08:00
72d5448e90 Merge pull request 'dd' (#409) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/409
2024-06-28 16:07:58 +00:00
72171fb573 fix : 需求征集新增/详情样式优化,需求汇总详情优化 2024-06-29 00:07:43 +08:00
wenhua
bd2d12551a fix: 修改步骤条样式, 增强tag组件兼容性 2024-06-28 23:53:43 +08:00
942fc219e2 fix : 修复需求上报排版、费用分摊传参、需求汇总查询字段 2024-06-28 22:37:30 +08:00
zhangkaihuai
5a6d16afc6 Merge remote-tracking branch 'origin/master' 2024-06-28 22:03:09 +08:00
clay
16c4e07a86 Merge remote-tracking branch 'origin/master' 2024-06-28 21:54:34 +08:00
clay
58d5efb655 fix : 费用分摊选择用户会被批量修改 2024-06-28 21:54:16 +08:00
c199ecb9fb Merge pull request 'fix : 修复项目归档-附件上传后跳转展示页面, 专项资金加"名称"二字' (#407) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/407
2024-06-28 13:50:23 +00:00
aa9001edd7 fix : 修复项目归档-附件上传后跳转展示页面, 专项资金加"名称"二字 2024-06-28 21:50:05 +08:00
clay
377509b62a feat : 分摊汇总小计保留两位小数 2024-06-28 21:41:24 +08:00
zhangkaihuai
c83a3b2ca3 Merge remote-tracking branch 'origin/master' 2024-06-28 21:13:44 +08:00
clay
fc034cc653 feat : 需求征集字段调整 2024-06-28 20:22:23 +08:00
fe72d0706a Merge pull request 'dd' (#406) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/406
2024-06-28 12:16:35 +00:00
84fb6838fb fix : 优化所属公司选择框 2024-06-28 20:16:24 +08:00
efd06e0da7 fix : 修改需求上报展示 2024-06-28 20:15:58 +08:00
291708e71a fix : 修改新增需求征集"专项资金名称" 2024-06-28 20:05:23 +08:00
9db5ad0052 Merge pull request 'dd' (#404) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/404
2024-06-28 08:39:06 +00:00
b7946d44c8 fix : 修改用户管理展示 2024-06-28 16:38:35 +08:00
daac1812bf fix : 优化审批记录、用户账号切换点击位置、所属公司选择框 2024-06-28 16:25:21 +08:00
wenhua
114c9116b1 feat: 阶段变更详情 2024-06-28 00:08:24 +08:00
wenhua
c5d5066ee1 Merge branch 'master' of http://git.feashow.cn/clay/mosr-web 2024-06-27 23:35:07 +08:00
wenhua
a943687afe feat: 新增移动端适配详情 2024-06-27 23:35:05 +08:00
clay
c61e584dea Merge remote-tracking branch 'origin/master' 2024-06-27 22:53:50 +08:00
clay
9bdad91b7e feat : 首页任务字段调整 2024-06-27 22:53:43 +08:00
8684132fc7 Merge pull request 'fix : 公司选择框' (#400) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/400
2024-06-26 15:04:46 +00:00
7bcd75e6fb fix : 公司选择框 2024-06-26 23:04:30 +08:00
c10f40f668 Merge pull request 'dd' (#398) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/398
2024-06-25 10:47:01 +00:00
bbb8705cee feat : 用户管理主账号-新增绑定账号功能 2024-06-25 18:13:43 +08:00
65b8af3e3e fix : 修复新增分摊复制/添加一行功能 2024-06-25 16:21:40 +08:00
afa0a52898 fix : 修复新增分摊复制/添加一行功能 2024-06-25 16:21:03 +08:00
zhangkaihuai
1032340cc2 Merge remote-tracking branch 'origin/master' 2024-06-25 11:59:55 +08:00
0e633c40a1 Merge pull request 'fix : 修复分摊编辑传参和台账导出' (#396) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/396
2024-06-25 03:56:00 +00:00
9d0490a253 fix : 修复分摊编辑传参和台账导出 2024-06-25 11:55:48 +08:00
zhangkaihuai
2eaa8337f6 Merge remote-tracking branch 'origin/master' 2024-06-24 18:35:22 +08:00
87768bfdf4 Merge pull request 'fix : 修复分摊/资金详情页面移动端适配' (#394) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/394
2024-06-24 05:39:45 +00:00
36c5b04dbc fix : 修复分摊/资金详情页面移动端适配 2024-06-24 13:39:30 +08:00
9945cc1c86 Merge pull request 'fix : 修复详情页面移动端适配' (#392) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/392
2024-06-24 05:25:50 +00:00
6f320a47bb fix : 修复详情页面移动端适配 2024-06-24 13:25:34 +08:00
zhangkaihuai
0551379a65 Merge remote-tracking branch 'origin/master' 2024-06-24 01:06:15 +08:00
clay
f66a570f00 feat : 台账导出 2024-06-23 18:55:42 +08:00
clay
5edf97338e Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/views/expense-management/share/add.vue
2024-06-23 18:15:07 +08:00
0b9712962d Merge pull request 'dd' (#389) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/389
2024-06-23 04:08:23 +00:00
d03f352169 fix : 注释npm install 2024-06-23 12:08:02 +08:00
dc20a6e33d Merge remote-tracking branch 'origin/master' 2024-06-23 12:06:53 +08:00
1efe8c4aaf fix : 修复项目实施-台账基础信息展示及表格更新功能 2024-06-23 12:04:22 +08:00
wenhua
27b4f41749 Merge branch 'master' of http://git.feashow.cn/clay/mosr-web 2024-06-23 01:36:20 +08:00
wenhua
30bd9da52f feat: 新增移动端详情 2024-06-23 01:36:17 +08:00
74e1938d3c fix : 修改分摊汇总金额展示 2024-06-23 01:02:27 +08:00
5757846e7c Merge pull request 'fix : 修复费用分摊详情合计bug' (#387) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/387
2024-06-22 16:59:07 +00:00
058421bdd7 fix : 修复费用分摊详情合计bug 2024-06-23 00:58:56 +08:00
da9bf2304b Merge pull request 'feat : 项目实施-台账新增表格更新功能' (#385) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/385
2024-06-22 16:39:16 +00:00
1a3d2bcf1a feat : 项目实施-台账新增表格更新功能 2024-06-23 00:37:07 +08:00
e0ba874746 Merge pull request 'fix : 修复用户切换报错提示、税后余额数字输入框、新增分摊时研发人员传参' (#384) from dd into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/384
2024-06-22 15:55:21 +00:00
7e524039bd fix : 修复用户切换报错提示、税后余额数字输入框、新增分摊时研发人员传参 2024-06-22 23:54:54 +08:00
2d9bba98a7 fix : 分摊详情小计与导出 2024-06-22 18:49:14 +08:00
e849c6cde6 Merge remote-tracking branch 'origin/master' 2024-06-22 18:45:50 +08:00
5c60bf91e4 fix : 分摊详情小计与导出 2024-06-22 18:45:40 +08:00
clay
dc189aa726 fix : 修复新增分摊细节 2024-06-22 18:44:49 +08:00
82634ddf97 Merge pull request 'fix : 审批记录优化' (#379) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/379
2024-06-21 10:40:00 +00:00
3f32683d69 fix : 审批记录优化 2024-06-21 18:39:45 +08:00
5fbef17b86 Merge pull request 'dj' (#377) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/377
2024-06-21 10:35:54 +00:00
1cdd2cb02b fix : 主次账号消息框展示、审批记录优化、头像框组件优化 2024-06-21 18:35:30 +08:00
2a80c8df21 fix : 修复项目归档开启/关闭上传文件二次确认 2024-06-21 17:17:35 +08:00
4bee8bf9e4 fix : 修复项目实施/归档上传附件显示, 2024-06-21 17:15:01 +08:00
efe1be3929 Merge pull request 'dj' (#375) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/375
2024-06-21 07:31:37 +00:00
bce9b2d8d2 fix : 修复导出表格宽度 2024-06-21 15:31:06 +08:00
b73b9aad4b fix : 分摊汇总表格及小计导出 2024-06-21 15:22:22 +08:00
8a9fffb3d0 Merge pull request 'fix : 移除输出log' (#373) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/373
2024-06-21 05:03:07 +00:00
9b758d41d0 fix : 移除输出log 2024-06-21 13:02:55 +08:00
9a3bfc784e Merge pull request 'fix : 审批记录优化' (#371) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/371
2024-06-21 04:41:58 +00:00
ddc305297f fix : 审批记录优化 2024-06-21 12:41:43 +08:00
853be5f9de Merge pull request 'dj' (#369) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/369
2024-06-21 04:33:31 +00:00
5977f13b91 fix : 修复人员选择框 2024-06-21 12:33:18 +08:00
3f26324747 fix : 修复研发人员选择框 2024-06-21 12:32:46 +08:00
141e965f95 fix : 修复研发人员选择框 2024-06-21 12:31:27 +08:00
e12dd9e5d7 Merge pull request 'dj' (#367) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/367
2024-06-21 04:30:50 +00:00
d97ea2f19e Merge remote-tracking branch 'origin/master' 2024-06-21 12:30:31 +08:00
e3664314d0 fix : 修复所属公司选择框细节 2024-06-21 12:30:19 +08:00
bfc38d035f Merge pull request 'dj' (#365) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/365
2024-06-21 04:23:54 +00:00
cef8530a5b fix : 固定所属公司选择条数为14则隐藏 2024-06-21 12:23:25 +08:00
a6476c359d fix : 审批记录样式优化, 上传费用,新增分摊输入框宽度固定 2024-06-20 16:55:15 +08:00
57f27c2b84 fix : 修复专项资金/费用分摊,编辑,审批记录展示 2024-06-20 15:08:12 +08:00
4c8959e3c4 fix : 修复专项资金/费用分摊,编辑,审批记录展示 2024-06-20 14:39:24 +08:00
clay
a1064f6111 Merge pull request 'fix : 修复分摊明细/汇总导出' (#363) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/363
2024-06-19 19:25:23 +00:00
255dbe67e0 fix : 修复分摊明细/汇总导出 2024-06-20 03:24:58 +08:00
994e474532 feat: 分摊明细异构表格数据对接 + 分摊明细异构表格excel导出 2024-06-20 02:27:42 +08:00
f3e8e12a5a fix : 右上角用户展示样式优化 2024-06-19 11:53:50 +08:00
4289ab2709 fix : 右上角用户展示样式优化 2024-06-19 11:52:07 +08:00
a9dfa26b0d fix : 修改首页待办数量 2024-06-19 11:44:30 +08:00
lilinyuan
c0bfbbfe65 fix: user 暂存 2024-06-19 11:26:01 +08:00
lilinyuan
f812b4af4d feat: 新增table获取数据总量方法 2024-06-19 11:25:50 +08:00
94bb4ce943 Merge pull request 'dj' (#360) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/360
2024-06-18 19:07:21 +00:00
7ad99048f4 fix : 修改右上角用户样式 2024-06-19 03:07:06 +08:00
0eba2c45f5 fix : 修改右上角用户样式 2024-06-19 03:03:29 +08:00
6f33aa1114 fix : 修改用户切换样式 2024-06-19 02:56:00 +08:00
clay
4f8a27e518 Merge remote-tracking branch 'origin/master' 2024-06-19 01:26:31 +08:00
clay
59014f6367 feat : 用户账号切换 2024-06-19 01:26:24 +08:00
20825fee23 Merge pull request 'fix : 修改人员选择框细节' (#359) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/359
2024-06-18 16:08:18 +00:00
bd1393d41c fix : 修改人员选择框细节 2024-06-19 00:08:09 +08:00
a3ac29b28b Merge pull request 'fix : 前置流程回显' (#358) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/358
2024-06-18 16:03:27 +00:00
da49b51b3d fix : 前置流程回显 2024-06-19 00:02:38 +08:00
fbd6c3695d Merge pull request 'dj' (#357) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/357
2024-06-18 15:55:54 +00:00
aa15e9b8d0 fix : 前置流程多选 2024-06-18 23:55:40 +08:00
91f21409f6 fix : 前置流程多选 2024-06-18 23:46:24 +08:00
820349877c fix : 修复需求征集编辑时所属公司回显,项目阶段改成研发阶段,人员选择器主子账号颜色区分 2024-06-18 23:11:27 +08:00
clay
5410b6d248 feat : 菜单与公司选择组件修改 2024-06-18 22:24:50 +08:00
369647f64f Merge pull request 'fix : 修复需求征集/汇总/费用台账页面搜索细节' (#356) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/356
2024-06-18 14:19:02 +00:00
3745c9cb28 fix : 修复需求征集/汇总/费用台账页面搜索细节 2024-06-18 22:18:35 +08:00
45a6b6733f Merge pull request 'fix : 修复列表左侧选择框,及正确json格式' (#355) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/355
2024-06-18 13:27:22 +00:00
6ab1dc806e fix : 修复列表左侧选择框,及正确json格式 2024-06-18 21:27:03 +08:00
a678420f4f Merge pull request 'fix : 修改征集类型为字典、直接上报时详情专项资金回显、项目归档-需求征集文件回显、重大项目前置流程必填' (#353) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/353
2024-06-18 12:43:17 +00:00
5100281c1f fix : 修改征集类型为字典、直接上报时详情专项资金回显、项目归档-需求征集文件回显、重大项目前置流程必填 2024-06-18 20:43:02 +08:00
3a79c85033 Merge pull request 'fix : 修复所属公司选择框右侧的删除功能' (#352) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/352
2024-06-18 08:45:40 +00:00
df513a91fe fix : 修复所属公司选择框右侧的删除功能 2024-06-18 16:45:19 +08:00
lilinyuan
506c794c5d fix: 多标签页bug 2024-06-18 16:09:21 +08:00
1c908017bb Merge pull request 'fix : 修复上传费用输入框垂直居中、台账时间搜索' (#349) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/349
2024-06-17 03:40:03 +00:00
9cbe89007d fix : 修复上传费用输入框垂直居中、台账时间搜索 2024-06-17 11:39:34 +08:00
132ab60d0f Merge pull request 'fix : 修复新增费用分摊输入框垂直居中' (#347) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/347
2024-06-16 13:41:33 +00:00
0c36801e83 fix : 修复新增费用分摊输入框垂直居中 2024-06-16 21:41:20 +08:00
f187e7c5b1 Merge pull request 'fix : 修复费用分摊时间搜索' (#346) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/346
2024-06-16 13:08:13 +00:00
b162bb8977 fix : 修复费用分摊时间搜索 2024-06-16 21:08:04 +08:00
75664822e4 Merge pull request 'fix : 修复项目费用显示bug' (#344) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/344
2024-06-16 12:35:12 +00:00
009d73ce86 fix : 修复项目费用显示bug 2024-06-16 20:34:46 +08:00
33a90e59f6 Merge pull request 'fix : 修改所属公司选择框bug' (#342) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/342
2024-06-16 11:50:30 +00:00
63107ece02 fix : 修改所属公司选择框bug 2024-06-16 19:50:17 +08:00
a75c2dd0fa Merge pull request 'fix : 流程图位置更换' (#341) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/341
2024-06-16 11:36:30 +00:00
d1a8077eea fix : 流程图位置更换 2024-06-16 19:34:08 +08:00
zhangkaihuai
a72a09008f Merge remote-tracking branch 'origin/master' 2024-06-16 18:07:39 +08:00
46e67f30a0 Merge pull request 'dj' (#339) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/339
2024-06-16 10:07:18 +00:00
7ffb689927 fix : 修复所属公司选择框 2024-06-16 18:06:53 +08:00
zhangkaihuai
13e0b6401c Merge remote-tracking branch 'origin/master' 2024-06-16 17:31:15 +08:00
79171758f5 fix : 修复需求汇总重新提交专项资金参数回传 2024-06-16 15:41:38 +08:00
61a999758e fix : 修复默认矩阵审批 2024-06-15 18:02:32 +08:00
f624b4d290 Merge pull request 'fix : 修复公司选择框全选功能' (#337) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/337
2024-06-14 16:47:29 +00:00
9153c20902 fix : 修复公司选择框全选功能 2024-06-15 00:47:17 +08:00
5fdcf42336 Merge pull request 'fix : 修复阶段变更中抄送人员回显' (#335) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/335
2024-06-14 15:26:51 +00:00
73313a1532 fix : 修复阶段变更中抄送人员回显 2024-06-14 23:26:38 +08:00
21cfe73a13 Merge pull request 'fix : 修复新增需求征集所属公司选择弹框' (#333) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/333
2024-06-14 15:18:10 +00:00
532ef440ce fix : 修复新增需求征集所属公司选择弹框 2024-06-14 23:17:32 +08:00
2ff0dbd2a4 Merge pull request 'fix : 修复项目实施台账字典问题' (#331) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/331
2024-06-14 06:01:59 +00:00
58cbceb747 fix : 修复项目实施台账字典问题 2024-06-14 14:01:41 +08:00
49b64c177f Merge pull request 'fix : 修复费用分摊复制功能、数字框默认值为null、项目归档显示是哪个流程的上传附件' (#329) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/329
2024-06-14 05:04:56 +00:00
f240016e44 fix : 修复费用分摊复制功能、数字框默认值为null、项目归档显示是哪个流程的上传附件 2024-06-14 13:04:37 +08:00
zhangkaihuai
d3133a8860 Merge remote-tracking branch 'origin/master' 2024-06-11 21:19:00 +08:00
6d56c4702b Merge pull request 'fix : 修复细节' (#327) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/327
2024-06-11 13:14:24 +00:00
3db0f3bd5b fix : 修复细节 2024-06-11 21:14:09 +08:00
363e2b983e Merge pull request 'fix : 修复新增需求细节' (#325) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/325
2024-06-11 13:05:46 +00:00
90a26f2e1e fix : 修复新增需求细节 2024-06-11 21:05:31 +08:00
f931c65b57 Merge pull request 'fix : 修复新增需求细节' (#323) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/323
2024-06-11 12:59:11 +00:00
e64b7fe0ae fix : 修复新增需求细节 2024-06-11 20:58:47 +08:00
48e97ed275 Merge pull request 'dj' (#321) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/321
2024-06-11 12:56:37 +00:00
a2977d0702 fix : 屏蔽导出修复角色权限 2024-06-11 20:56:22 +08:00
78ab1ddc45 fix : 屏蔽导出 2024-06-11 20:32:20 +08:00
7f73afa6b5 Merge pull request 'fix : 修复流程图切换功能和屏蔽导出' (#320) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/320
2024-06-11 12:15:02 +00:00
208584c34b fix : 修复流程图切换功能和屏蔽导出 2024-06-11 20:14:49 +08:00
40d2bef0ba Merge pull request 'dj' (#318) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/318
2024-06-11 11:16:58 +00:00
b425e709aa fix : 修复流程图切换功能及修改"研发阶段"文字为项目阶段 2024-06-11 19:16:35 +08:00
3f7de153da fix : 修复项目立项/验收前置流程展示及系统部分页面分页bug 2024-06-11 18:47:35 +08:00
99224392a3 Merge pull request 'dj' (#316) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/316
2024-06-11 07:42:16 +00:00
ab83724056 fix : 修复详情页切换流程图渲染bug 2024-06-11 15:42:01 +08:00
e33a6d5c58 Merge pull request 'fix : 二级页面上加基础信息' (#314) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/314
2024-06-11 04:19:21 +00:00
5e2f9df706 Merge remote-tracking branch 'origin/master' 2024-06-11 12:18:43 +08:00
1009cb7345 fix : 二级页面上加基础信息 2024-06-10 23:28:34 +08:00
e5f80ed017 Merge pull request 'dj' (#313) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/313
2024-06-10 15:01:42 +00:00
050c5cf57a fix : 列表按钮加权限 2024-06-10 23:01:28 +08:00
3e6c82dd19 fix : 修复列表页按钮固定右侧 2024-06-10 22:38:26 +08:00
15a2dda0fa fix : 修复需求征集/汇总权限按钮 2024-06-10 22:36:03 +08:00
9c812af394 fix : 修复详情提交/重新提交功能 2024-06-10 22:34:51 +08:00
3379d851c6 Merge remote-tracking branch 'origin/master' 2024-06-10 22:34:27 +08:00
535d3f680b fix : 优化直接上报时项目归档附件tab展示 2024-06-10 16:19:09 +08:00
2f2dabb82d Merge pull request 'fix : 优化需求汇总详情页面' (#312) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/312
2024-06-10 07:52:38 +00:00
b05d0ff42f fix : 优化需求汇总详情页面 2024-06-10 15:50:26 +08:00
4a749fc220 Merge pull request 'fix : 修复详情基本信息显示位置、项目验收、结项操作放在详情页面' (#310) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/310
2024-06-10 07:26:03 +00:00
07c089ed29 fix : 修复详情基本信息显示位置、项目验收、结项操作放在详情页面 2024-06-10 15:25:28 +08:00
3483a32d55 Merge pull request 'fix : 修改阶段变更抄送人样式' (#309) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/309
2024-06-09 16:44:41 +00:00
cb224ab437 fix : 修改阶段变更抄送人样式 2024-06-10 00:44:20 +08:00
d8b8c65dfb Merge pull request 'fix : 修复提交按钮旁边的返回页面细节' (#308) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/308
2024-06-09 16:25:25 +00:00
d3fe46f0bc fix : 修复提交按钮旁边的返回页面细节 2024-06-10 00:25:00 +08:00
zhangkaihuai
1bfb34305f Merge remote-tracking branch 'origin/master' 2024-06-09 23:50:14 +08:00
bf0cb73946 Merge remote-tracking branch 'origin/master' 2024-06-09 23:48:50 +08:00
992eb2b890 fix : 修复分摊金额显示bug 2024-06-09 23:48:42 +08:00
zhangkaihuai
eb8e772e66 Merge remote-tracking branch 'origin/master' 2024-06-09 22:37:31 +08:00
fb52f8b04e Merge pull request 'fix : 修复需求上报接口' (#307) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/307
2024-06-09 14:11:06 +00:00
53e461bc4d fix : 修复需求上报接口 2024-06-09 22:10:52 +08:00
f251c08982 Merge pull request 'fix : 修复项目实施上传费用,查看分摊功能细节' (#306) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/306
2024-06-09 14:03:31 +00:00
83ba497d73 fix : 修复项目实施上传费用,查看分摊功能细节 2024-06-09 22:02:37 +08:00
zhangkaihuai
c20fbcc356 Merge remote-tracking branch 'origin/master' 2024-06-09 21:33:49 +08:00
bb771b2f6d Merge pull request 'dj' (#305) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/305
2024-06-09 13:29:06 +00:00
zhangkaihuai
7fbd067e11 Merge remote-tracking branch 'origin/dj' 2024-06-09 20:59:19 +08:00
zhangkaihuai
008c474b76 Merge remote-tracking branch 'origin/master' 2024-06-09 20:58:09 +08:00
a88ae09628 fix : 修复项目实施阶段变更功能 2024-06-09 20:03:26 +08:00
b0eabd9c39 fix : 修复项目立项切换bug 2024-06-09 19:33:03 +08:00
adbd98f035 fix : 修复项目立项切换bug 2024-06-09 19:30:45 +08:00
f61adaf18b Merge remote-tracking branch 'origin/master' 2024-06-09 19:19:15 +08:00
clay
d1c6b23aa4 feat : 需求变更详情修改 2024-06-09 19:19:02 +08:00
c3e006bba8 fix : 修复项目立项重新提交等操作替换到详情页面 2024-06-09 19:12:37 +08:00
812298acce fix : 修复需求上报是否专项资金流程图显示 2024-06-09 19:00:43 +08:00
fd61fcc485 Merge pull request 'fix : 修复费用分摊详情研究人员显示' (#304) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/304
2024-06-09 10:09:41 +00:00
60b7133939 fix : 修复费用分摊详情研究人员显示 2024-06-09 18:09:13 +08:00
8e46c27af8 Merge pull request 'dj' (#303) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/303
2024-06-09 09:51:15 +00:00
4ed64339fa fix : 金额格式化 2024-06-09 17:50:49 +08:00
zhangkaihuai
d6a9ecd944 Merge remote-tracking branch 'origin/dj' 2024-06-09 17:09:05 +08:00
cafb0ef5bf Merge remote-tracking branch 'origin/master' 2024-06-09 15:06:29 +08:00
29b8bad394 fix : 格式化金额显示 2024-06-08 23:20:44 +08:00
9a862f8cce feat : 修复需求汇总页面细节 2024-06-08 11:43:39 +08:00
91b2ead3d4 Merge pull request 'dj' (#302) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/302
2024-06-07 16:05:41 +00:00
521e40cf3d feat : 项目详情中立项/编辑页面demo 2024-06-08 00:05:28 +08:00
86ff3c2e94 fix : 修复附件校验问题 2024-06-08 00:04:33 +08:00
617a867965 fix : 修复查看分摊功能 2024-06-07 21:34:18 +08:00
b2e0983cf0 Merge pull request 'fix : 修改提交/重新提交功能文件传参问题' (#301) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/301
2024-06-07 12:37:11 +00:00
27bc6ea89f fix : 修改提交/重新提交功能文件传参问题 2024-06-07 20:36:54 +08:00
c2413fe8b2 Merge pull request 'fix : 修改专项资金新增的介绍输入框' (#300) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/300
2024-06-07 11:47:55 +00:00
ee81e1bb23 fix : 修改专项资金新增的介绍输入框 2024-06-07 18:40:54 +08:00
a6a124d61a Merge pull request 'fix : 修复需求上报bug' (#299) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/299
2024-06-07 10:28:22 +00:00
1bc8f26724 fix : 修复需求上报bug 2024-06-07 18:28:10 +08:00
1c56ccae40 Merge pull request 'fix : 修复需求上报文件上传/删除问题' (#298) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/298
2024-06-07 08:46:59 +00:00
42fea1853d fix : 修复需求上报文件上传/删除问题 2024-06-07 16:46:44 +08:00
0eb0bcb0ef Merge pull request 'fix : 修复专项资金显示情况' (#297) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/297
2024-06-07 05:26:04 +00:00
9655c41492 fix : 修复专项资金显示情况 2024-06-07 13:24:17 +08:00
ec7cf224d3 Merge pull request 'fix : 修改需求上报页面细节' (#296) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/296
2024-06-06 15:14:04 +00:00
35ecec13ad fix : 修改需求上报页面细节 2024-06-06 23:13:10 +08:00
0adb104c46 Merge pull request 'fix : 修改专项资金' (#295) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/295
2024-06-06 14:59:03 +00:00
54e7b81f1e fix : 修改专项资金 2024-06-06 22:58:50 +08:00
d9d3a7f02a Merge pull request 'dj' (#293) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/293
2024-06-06 14:21:30 +00:00
e1a7b46b35 fix : 修改分摊汇总bug 2024-06-06 22:13:14 +08:00
4ddd53cec7 fix : 修改需求征集征集说明输入框 2024-06-06 21:52:33 +08:00
a8921a0683 fix : 修复需求上报数字输入框和人员选择器优化 2024-06-06 21:44:43 +08:00
6a0c3570f6 fix : 修复需求上报的专项资金显示问题 2024-06-06 19:50:46 +08:00
781b4cfb96 Merge pull request 'fix : 修复分摊汇总及编辑功能' (#291) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/291
2024-06-06 05:36:20 +00:00
53ecadf315 fix : 修复分摊汇总及编辑功能 2024-06-06 13:36:07 +08:00
18806f13e4 Merge pull request 'dj' (#289) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/289
2024-06-05 18:01:52 +00:00
031a08e65c fix : 修复分摊汇总及编辑功能 2024-06-06 02:01:36 +08:00
ec4c61d758 fix : 修复费用分摊详情渲染数据问题 2024-06-06 01:15:12 +08:00
aa9d7d9028 Merge pull request 'fix : 修复细节' (#287) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/287
2024-06-05 14:57:14 +00:00
1c204b39df fix : 修复细节 2024-06-05 22:57:04 +08:00
0685143b3a Merge pull request 'dj' (#285) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/285
2024-06-05 14:10:46 +00:00
2e86683f41 fix : 修复新增分摊表格数据校验及矩阵审批加箭头 2024-06-05 22:03:49 +08:00
ca64562059 fix : 修复项目归档中附件上传问题 2024-06-05 11:40:31 +08:00
d676868cf7 fix : 修复首页点击阶段变更的查看跳转问题 2024-06-05 11:05:47 +08:00
80d84c4a85 fix : 修复首页点击费用分摊的查看跳转问题 2024-06-05 11:01:41 +08:00
71b2b372b1 Merge pull request 'fix : 修复审核意见位置' (#284) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/284
2024-06-04 16:51:52 +00:00
a7d91a8f32 fix : 修复审核意见位置 2024-06-05 00:51:27 +08:00
e513af4983 Merge pull request 'fix : 修复阶段变更详情页面细节' (#282) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/282
2024-06-04 10:43:23 +00:00
df6f49caeb fix : 修复阶段变更详情页面细节 2024-06-04 18:43:01 +08:00
3e2249431b Merge pull request 'dj' (#280) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/280
2024-06-04 10:23:55 +00:00
b9d33bd6e4 fix : 修复阶段变更/详情/编辑功能 2024-06-04 18:23:42 +08:00
8f1cc442ac fix : 修复项目立项上传文件bug 2024-06-04 17:10:32 +08:00
cc2babcd32 Merge pull request 'dj' (#279) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/279
2024-06-04 08:43:00 +00:00
8b5868fde6 fix : 优化需求征集详情页面 2024-06-04 16:42:00 +08:00
1d66c44edb fix : 优化需求征集详情页面 2024-06-04 16:41:28 +08:00
6597506435 Merge remote-tracking branch 'origin/master' 2024-06-04 10:36:31 +08:00
00a2b7a3af fix : 修复项目验收其他文件上传bug 2024-06-03 21:56:20 +08:00
63a6f9b85e fix : 修复新增台账功能 2024-06-03 16:48:00 +08:00
abd060b530 fix : 修复项目实施查看分摊功能 2024-06-03 15:53:21 +08:00
d1eb5c3327 Merge pull request 'fix : 修复项目实施附件查询及上传功能、代码文件优化' (#278) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/278
2024-06-03 07:39:38 +00:00
abe80eafdc fix : 修复项目实施附件查询及上传功能、代码文件优化 2024-06-03 15:39:22 +08:00
1ee92f698e Merge pull request 'fix : 项目归档附件查询功能优化' (#276) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/276
2024-06-02 15:17:16 +00:00
747b40f9ba fix : 项目归档附件查询功能优化 2024-06-02 23:17:06 +08:00
clay
83fd1b37e2 Merge remote-tracking branch 'origin/master' 2024-06-02 22:36:09 +08:00
clay
f6ada88026 feat : 附件处理 2024-06-02 22:36:02 +08:00
2a0e193374 Merge pull request 'fix : 文件权限处理' (#275) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/275
2024-06-02 14:23:39 +00:00
e0b5487951 fix : 文件权限处理 2024-06-02 22:23:19 +08:00
f20318843e Merge pull request 'fix : 修复直接上报的详情组件渲染' (#274) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/274
2024-06-02 14:22:15 +00:00
456f2284e9 fix : 修复直接上报的详情组件渲染 2024-06-02 22:22:06 +08:00
fb64361c64 Merge pull request 'fix : 修复细节' (#273) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/273
2024-06-02 11:42:44 +00:00
6bb97b4a1d fix : 修复细节 2024-06-02 19:42:33 +08:00
clay
9ad29c3a13 feat : 文件组件抽象封装 2024-06-02 19:37:20 +08:00
clay
20fbd0e2d4 feat : 需求上报详情删除 2024-06-02 18:23:32 +08:00
clay
eebb3003c7 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/views/project-demand/requirement/detail.vue
2024-06-02 17:39:20 +08:00
clay
3ed5068dee feat : 需求上报fileLie 权限控制 2024-06-02 17:37:53 +08:00
918a02b201 Merge pull request 'fix : 修复获取流程接口的提示框' (#272) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/272
2024-06-02 08:54:58 +00:00
e0ffef25bd fix : 修复获取流程接口的提示框 2024-06-02 16:54:46 +08:00
419397fc00 Merge pull request 'fix : 修复文件列表表格高度' (#271) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/271
2024-06-02 08:31:53 +00:00
9b45135a18 fix : 修复文件列表表格高度 2024-06-02 16:31:37 +08:00
f0eb28ab84 Merge pull request 'fix : 修复文件下载、专项资金新增、删除功能、流程新增细节优化' (#270) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/270
2024-06-02 08:12:55 +00:00
c416424253 fix : 修复文件下载、专项资金新增、删除功能、流程新增细节优化 2024-06-02 16:12:40 +08:00
e9592920e7 Merge pull request 'fix : 修复首页查看跳转问题及简化代码' (#269) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/269
2024-06-02 03:54:31 +00:00
c05322a2bf fix : 修复首页查看跳转问题及简化代码 2024-06-02 11:54:19 +08:00
9be3d7096a Merge pull request 'fix : 修复菜单图标、金额单位为元、项目实施台账上传费用功能、' (#268) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/268
2024-06-02 03:05:08 +00:00
cd715fbf98 fix : 修复菜单图标、金额单位为元、项目实施台账上传费用功能、 2024-06-02 11:04:54 +08:00
lilinyuan
a796e7622f Merge branch 'master' of http://git.feashow.cn/clay/mosr-web 2024-06-01 23:15:39 +08:00
lilinyuan
e2d6722ec6 fix: 修复bug 2024-06-01 23:15:37 +08:00
13386303e8 Merge pull request 'fix : 修复细节' (#265) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/265
2024-06-01 14:54:37 +00:00
c4db5d6719 fix : 修复细节 2024-06-01 22:54:23 +08:00
clay
495e39c802 feat : 表单权限处理 2024-06-01 22:18:57 +08:00
dd5d24768b Merge pull request 'fix : 修复附件上传' (#263) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/263
2024-06-01 14:18:22 +00:00
3746a19063 fix : 修复附件上传 2024-06-01 22:17:46 +08:00
lilinyuan
9acd05a2cc fix: 修复角色页面跳转bug 2024-06-01 20:49:27 +08:00
d7a4eef7db Merge pull request 'fix : 修复申请文件校验' (#262) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/262
2024-06-01 12:34:25 +00:00
346ad4c4df fix : 修复申请文件校验 2024-06-01 20:33:28 +08:00
5d570f3108 Merge pull request 'dj' (#261) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/261
2024-06-01 11:25:22 +00:00
4a0b3db4e4 fix : 修复新增流程数据重置 2024-06-01 19:25:04 +08:00
bc27a83848 fix : 修复项目归档五个附件上传功能 2024-06-01 19:05:11 +08:00
dd046f645f fix : 修复项目归档五个附件上传功能、提示框、文件多选上传、详情驳回/同意路由跳转问题 2024-06-01 18:30:11 +08:00
04a7ba8802 Merge remote-tracking branch 'origin/master' 2024-06-01 17:33:22 +08:00
lilinyuan
b0199c8fd9 fix: 部分权限标识, 修复部门编辑bug 2024-06-01 17:03:43 +08:00
lilinyuan
d2f9bfcb33 fix: 项目管理详情查询为空的时候关闭loading 2024-06-01 16:24:40 +08:00
lilinyuan
6391ab458b feat: 退出时多标签页全部清空 2024-06-01 16:07:57 +08:00
e1f6652672 Merge remote-tracking branch 'origin/master' 2024-06-01 15:57:32 +08:00
lilinyuan
4d1ba82696 Merge branch 'master' of http://git.feashow.cn/clay/mosr-web 2024-06-01 15:57:11 +08:00
lilinyuan
de2475f39a feat: 部门详情, 编辑 2024-06-01 15:57:07 +08:00
80ecad0864 fix : 修复需求征集界面样式及提示 2024-06-01 14:36:03 +08:00
fa94f9e78d Merge pull request 'fix : 修复项目实施附件查询功能及上传附件页面初始' (#260) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/260
2024-06-01 05:34:32 +00:00
7501c37379 fix : 修复项目实施附件查询功能及上传附件页面初始 2024-06-01 13:34:12 +08:00
f776f994ab Merge pull request 'dj' (#259) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/259
2024-05-31 16:46:19 +00:00
daf5ffe2c9 fix : 修复项目实施附件查询及上传功能 2024-06-01 00:46:00 +08:00
f4ad871831 fix : 修改详情页数据回显问题及简化代码 2024-06-01 00:45:13 +08:00
lilinyuan
5be806104f fix: 修复退出登录再次登录菜单不刷新问题 2024-05-31 21:49:43 +08:00
7ec6cba0f0 Merge pull request 'fix : 修复页面细节' (#258) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/258
2024-05-31 13:05:09 +00:00
14abf64e5d fix : 修复页面细节 2024-05-31 21:04:54 +08:00
661bc2e397 Merge pull request 'dj' (#257) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/257
2024-05-31 12:57:30 +00:00
2246fcb621 fix : 修复页面细节 2024-05-31 20:57:17 +08:00
5ae8e4be78 fix : 修复页面细节 2024-05-31 20:56:58 +08:00
clay
5a1e1848cb fix : 字典为空死循环bug 2024-05-31 11:23:34 +08:00
3f9b7f9011 Merge pull request 'fix : 修复页面细节' (#254) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/254
2024-05-30 14:53:44 +00:00
f47180dfbe fix : 修复页面细节 2024-05-30 22:53:33 +08:00
2e7e55464d Merge pull request 'fix : 修复页面细节' (#252) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/252
2024-05-30 14:51:22 +00:00
7791648837 fix : 修复页面细节 2024-05-30 22:51:06 +08:00
clay
92e935622a Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/views/project-demand/requirement/add.vue
2024-05-30 22:32:41 +08:00
clay
ee890c0e80 feat : 表单权限处理 2024-05-30 22:31:47 +08:00
e39d953385 Merge pull request 'fix : 修复页面细节' (#249) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/249
2024-05-30 12:06:55 +00:00
8c6da666d5 fix : 修复页面细节 2024-05-30 20:04:57 +08:00
29a019b32a Merge pull request 'fix : 修复页面细节' (#247) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/247
2024-05-30 09:48:57 +00:00
8bc9a27ccf fix : 修复页面细节 2024-05-30 17:48:36 +08:00
ed988b99b3 Merge pull request 'fix : 修复上传费用校验问题' (#246) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/246
2024-05-30 09:29:20 +00:00
c799c97643 fix : 修复上传费用校验问题 2024-05-30 17:29:05 +08:00
f9064ddeb4 Merge pull request 'dj' (#245) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/245
2024-05-30 08:49:38 +00:00
0c1e566578 fix : 修复项目附件页面细节 2024-05-30 16:46:51 +08:00
94528cfa06 fix : 修复页面细节 2024-05-30 16:05:09 +08:00
2ab4eb1a7e Merge remote-tracking branch 'origin/master' 2024-05-29 22:10:13 +08:00
04c1175cf8 fix : 修复提交/重新提交按钮显示 2024-05-29 21:34:37 +08:00
7a5fbd501e Merge pull request 'fix : 修复费用分摊详情数据' (#244) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/244
2024-05-29 12:53:39 +00:00
dd3f793ac2 fix : 修复费用分摊详情数据 2024-05-29 20:53:26 +08:00
dc153e459e Merge pull request 'dj' (#243) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/243
2024-05-28 15:56:48 +00:00
00ad1c3098 Merge remote-tracking branch 'origin/master' 2024-05-28 23:55:22 +08:00
6ac425f7de fix : 修复需求上报下拉框数据 2024-05-28 23:54:05 +08:00
80ae6bdf7e Merge pull request 'feat : 项目实施的阶段变更界面初始化' (#242) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/242
2024-05-28 15:18:49 +00:00
9198837d65 feat : 项目实施的阶段变更界面初始化 2024-05-28 23:17:34 +08:00
4acba8bedc Merge pull request 'fix : 修复费用管理功能细节' (#241) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/241
2024-05-28 15:05:30 +00:00
7f40296f3b fix : 修复费用管理功能细节 2024-05-28 23:05:10 +08:00
0ae84ba12e Merge pull request 'fix : 修复项目实施附件接口' (#240) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/240
2024-05-28 10:00:57 +00:00
be367ead6e fix : 修复项目实施附件接口 2024-05-28 18:00:42 +08:00
335d8c1e72 Merge pull request 'dj' (#239) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/239
2024-05-28 08:42:16 +00:00
dd406e4ba6 fix : 修复专项资金页面搜索功能 2024-05-28 16:42:05 +08:00
beb07edc73 fix : 修复专项资金页面搜索功能 2024-05-28 16:39:37 +08:00
0eb036e8a5 Merge pull request 'fix : 修复专项资金页面功能细节' (#238) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/238
2024-05-28 08:36:15 +00:00
ba86f54369 fix : 修复专项资金页面功能细节 2024-05-28 16:36:03 +08:00
11544acbad Merge pull request 'dj' (#237) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/237
2024-05-28 04:05:49 +00:00
63e94af451 fix : 修复项目实施中功能细节 2024-05-28 12:05:31 +08:00
554c7d2be7 fix : 修复首页查看跳转 2024-05-27 23:10:34 +08:00
e3222e906d Merge remote-tracking branch 'origin/master' 2024-05-27 22:45:42 +08:00
30a8ceb424 fix : 修复首页查看跳转 2024-05-27 22:38:15 +08:00
wenhua
304effe93c fix: up detail, router, display for dont have role 2024-05-27 22:33:24 +08:00
26931f4200 Merge pull request 'fix : 修复路由跳转' (#234) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/234
2024-05-27 13:16:30 +00:00
e71c142ea9 fix : 修复路由跳转 2024-05-27 21:16:14 +08:00
7ebd897d57 Merge pull request 'fix : 修复步骤条样式' (#233) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/233
2024-05-27 03:38:17 +00:00
0ec14cfd9b fix : 修复步骤条样式 2024-05-27 11:37:59 +08:00
bef0c2d792 Merge pull request 'fix : 修复路由跳转' (#232) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/232
2024-05-24 08:34:47 +00:00
08f66803a2 fix : 修复路由跳转 2024-05-24 16:34:17 +08:00
lilinyuan
6af7bf9d2f fix: 修复问题 2024-05-24 16:10:15 +08:00
lilinyuan
9013d54add fix: 去掉log 2024-05-24 14:26:29 +08:00
lilinyuan
fd722b5c82 Merge branch 'master' of http://git.feashow.cn/clay/mosr-web 2024-05-24 14:24:39 +08:00
lilinyuan
a8e56fe985 fix: 修改新增编辑等单页面路由层级 2024-05-24 14:24:36 +08:00
clay
4953e96415 feat : 需求征集表单权限测试 2024-05-24 10:44:24 +08:00
5b85abd219 Merge pull request 'fix : 修复详情渲染细节' (#228) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/228
2024-05-23 16:16:00 +00:00
7156e34fde fix : 修复详情渲染细节 2024-05-24 00:12:53 +08:00
e903dd2994 Merge pull request 'fix : 修复权限按钮细节' (#227) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/227
2024-05-23 15:43:22 +00:00
549e307b3e fix : 修复权限按钮细节 2024-05-23 23:42:09 +08:00
390474ea24 Merge pull request 'fix : 修复页面细节' (#226) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/226
2024-05-23 12:48:45 +00:00
43c9cb03d3 fix : 修复页面细节 2024-05-23 20:48:09 +08:00
clay
5eb7e34571 fix : 用户nickname查询 2024-05-23 20:29:24 +08:00
clay
d12fb8a12b fix : 用户nickname查询 2024-05-23 20:28:46 +08:00
1991d7eada Merge pull request 'fix : 修复页面细节' (#225) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/225
2024-05-23 09:53:04 +00:00
31a12e566a fix : 修复页面细节 2024-05-23 17:52:48 +08:00
5c8679d5f9 Merge pull request 'fix : 修复页面细节' (#224) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/224
2024-05-23 09:39:12 +00:00
7e70c9271f fix : 修复页面细节 2024-05-23 17:38:58 +08:00
6748685712 Merge pull request 'fix : 修复页面细节' (#223) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/223
2024-05-23 08:44:19 +00:00
cd7f94e8f2 fix : 修复页面细节 2024-05-23 16:44:04 +08:00
clay
db8a96a664 feat : 需求征集index.vue 2024-05-23 15:53:33 +08:00
clay
17207b2c87 feat : 按钮全新啊demo 2024-05-23 15:48:31 +08:00
d6de4d5854 Merge pull request 'fix : 修复页面细节' (#222) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/222
2024-05-23 07:37:20 +00:00
bcdafbc7cd fix : 修复页面细节 2024-05-23 15:36:57 +08:00
clay
e9e5a0c785 feat : 修改菜单状态 2024-05-23 14:49:56 +08:00
clay
21f90e438c fix : 修复细节 2024-05-23 10:00:21 +08:00
e1b9f3f220 Merge pull request 'fix : 修复人员选择框' (#221) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/221
2024-05-22 15:53:21 +00:00
96d46e6480 fix : 修复人员选择框 2024-05-22 23:52:51 +08:00
6ab0c206c4 Merge pull request 'fix : 修复细节' (#219) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/219
2024-05-20 16:22:29 +00:00
a4255c3157 fix : 修复细节 2024-05-21 00:21:24 +08:00
39b1690c0a Merge pull request 'fix : 修复流程图渲染问题' (#218) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/218
2024-05-20 16:15:50 +00:00
9f4fe95e4d fix : 修复流程图渲染问题 2024-05-21 00:14:53 +08:00
1635482e09 Merge pull request 'fix : 重新提交全流程初步完成' (#217) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/217
2024-05-20 15:02:07 +00:00
3270aeef06 fix : 重新提交全流程初步完成 2024-05-20 23:01:53 +08:00
lilinyuan
6c80652416 feat: agree and reject 2024-05-20 22:18:17 +08:00
lilinyuan
c97091db4f feat: 主流程详情组件基本完成 2024-05-20 22:03:53 +08:00
1c57cb277b Merge pull request 'fix : 重新提交页面初始化' (#216) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/216
2024-05-20 09:56:49 +00:00
e648faba69 fix : 重新提交页面初始化 2024-05-20 17:56:38 +08:00
a663b84fab Merge pull request 'fix : 修复需求上报/详情下流程渲染' (#215) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/215
2024-05-20 03:47:24 +00:00
f83ae8df51 fix : 修复所属公司及详情loading 2024-05-20 11:45:53 +08:00
1d772e1414 fix : 修复需求上报/详情下流程渲染 2024-05-20 11:05:29 +08:00
92e9468cb9 Merge pull request 'fix : 修复页面细节' (#214) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/214
2024-05-19 16:59:19 +00:00
5c93eae4ce fix : 修复页面细节 2024-05-20 00:58:48 +08:00
5d7b6bc59f Merge pull request 'dj' (#213) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/213
2024-05-19 16:45:20 +00:00
1825b6c871 fix : 修复页面细节 2024-05-20 00:44:37 +08:00
dee7fdacf2 Merge pull request 'dj' (#212) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/212
2024-05-19 16:31:02 +00:00
dc7d90c349 Merge remote-tracking branch 'origin/master' 2024-05-20 00:29:46 +08:00
9661cdbb2b fix : 修复页面细节功能及附件上传组件 2024-05-20 00:29:31 +08:00
wenhua
3a4f9927c9 feat: up detail 2024-05-19 23:07:32 +08:00
1f4389eb5e fix : 修复项目申请/验收/结项功能 2024-05-19 20:39:54 +08:00
wenhua
4a90f4bc1e 合并冲突 2024-05-19 20:19:50 +08:00
wenhua
8155a4d160 feat: 需求上报详情 2024-05-19 20:17:55 +08:00
771a844552 Merge pull request 'fix : 修复页面' (#211) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/211
2024-05-19 10:01:01 +00:00
08a609e2a8 fix : 修复页面 2024-05-19 18:00:48 +08:00
d16045a1b2 Merge pull request 'fix : 修复项目立项页面' (#210) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/210
2024-05-19 08:40:20 +00:00
1fc0ae6ac0 fix : 修复项目立项页面 2024-05-19 16:40:05 +08:00
08f20bb171 Merge pull request 'fix : 修改细节' (#209) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/209
2024-05-19 08:20:12 +00:00
5421145583 fix : 修改细节 2024-05-19 16:19:53 +08:00
b7a0dc2545 Merge pull request 'fix : 修改审批记录样式' (#208) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/208
2024-05-19 07:27:32 +00:00
3bd6df74cc fix : 修改审批记录样式 2024-05-19 15:27:22 +08:00
wenhua
190a1d6477 Merge branches 'master' and 'master' of http://git.feashow.cn/clay/mosr-web 2024-05-19 14:04:30 +08:00
wenhua
cb7f6e9919 feat: 详情组件, 实例文件 2024-05-19 14:04:28 +08:00
5ea20654cc Merge pull request 'fix : 修复需求汇总详情功能' (#207) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/207
2024-05-19 05:23:23 +00:00
670c8a5653 fix : 修复需求汇总详情功能 2024-05-19 13:23:10 +08:00
206a024f4b Merge pull request 'fix : 修复需求汇总详情功能' (#206) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/206
2024-05-19 05:18:22 +00:00
89d5c86d8b fix : 修复需求汇总详情功能 2024-05-19 13:18:03 +08:00
397d5f0182 Merge pull request 'fix : 修复需求上报功能' (#205) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/205
2024-05-19 04:31:09 +00:00
10bc019866 fix : 修复需求上报功能 2024-05-19 12:29:59 +08:00
62620b1dc5 Merge pull request 'fix : 修复页面细节' (#204) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/204
2024-05-19 03:40:46 +00:00
ff68ce96af fix : 修复页面细节 2024-05-19 11:40:37 +08:00
65d933c027 Merge pull request 'fix : 修复页面细节' (#203) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/203
2024-05-19 03:26:53 +00:00
726c746a87 fix : 修复页面细节 2024-05-19 11:26:32 +08:00
c498a3de62 Merge pull request 'fix : 修复页面细节' (#202) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/202
2024-05-19 03:14:26 +00:00
d432e54bc8 fix : 修复页面细节 2024-05-19 11:09:51 +08:00
5b68ee6846 Merge pull request 'feat : 需求上报界面初始化' (#201) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/201
2024-05-18 18:04:09 +00:00
96e7ca1a67 feat : 需求上报界面初始化 2024-05-19 02:03:52 +08:00
9368ea24ab Merge pull request 'dj' (#200) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/200
2024-05-18 16:17:14 +00:00
c96cbf8415 fix : 修复细节 2024-05-19 00:16:40 +08:00
bab0421b6d Merge pull request 'fix : 修复tooltip细节' (#199) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/199
2024-05-18 15:05:04 +00:00
fccce985b6 Merge remote-tracking branch 'origin/master' 2024-05-18 23:05:01 +08:00
c675b1ec48 fix : 修复tooltip细节 2024-05-18 23:04:51 +08:00
02bda3c71f Merge pull request 'fix : 修复附件上传组件bug' (#198) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/198
2024-05-18 14:10:06 +00:00
b7ebd66729 fix : 修复附件上传组件bug 2024-05-18 22:08:08 +08:00
76c759c088 Merge pull request 'fix : 修复需求征集详情组件下载bug' (#197) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/197
2024-05-18 12:59:52 +00:00
e4e7444aff fix : 修复需求征集详情组件下载bug 2024-05-18 20:59:35 +08:00
a8f5f84b20 Merge pull request 'dj' (#196) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/196
2024-05-18 12:52:32 +00:00
716d18122f feat : 封装带有附件及其他文件上传的组件 2024-05-18 20:52:14 +08:00
2f19bb7bdc Merge remote-tracking branch 'origin/master' 2024-05-18 19:56:54 +08:00
8f8d954bb6 Merge pull request 'feat : 文件下载组件删除功能' (#195) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/195
2024-05-18 11:56:52 +00:00
0732acf8c7 feat : 文件下载组件删除功能 2024-05-18 19:54:58 +08:00
6540ac8991 Merge pull request 'fix : 替换文件下载方式' (#194) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/194
2024-05-18 09:33:33 +00:00
6009885c09 fix : 替换文件下载方式 2024-05-18 17:32:58 +08:00
83a8fac0fb Merge pull request 'dj' (#193) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/193
2024-05-18 09:13:26 +00:00
0c070154e1 fix : 修复需求征集详情组件引用细节 2024-05-18 17:12:51 +08:00
32a3ab3001 Merge remote-tracking branch 'origin/master' 2024-05-18 16:56:28 +08:00
d0fe340f9d Merge pull request 'feat : 新增需求征集组件' (#192) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/192
2024-05-17 15:25:09 +00:00
92d2278dfd Merge remote-tracking branch 'origin/master' 2024-05-17 23:24:52 +08:00
f5c6680c66 feat : 新增需求征集组件 2024-05-17 23:24:38 +08:00
b5e5a3f12a Merge pull request 'feat : 项目归档页面初始化' (#191) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/191
2024-05-17 13:27:15 +00:00
7869ff4e6a feat : 项目归档页面初始化 2024-05-17 21:26:15 +08:00
95f4610714 Merge pull request 'dj' (#189) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/189
2024-05-17 12:55:39 +00:00
9754b62038 feat : 新增需求征集删除功能和文件下载功能 2024-05-17 20:53:49 +08:00
573fff84e4 Merge remote-tracking branch 'origin/master' 2024-05-17 19:35:49 +08:00
lilinyuan
1f1ff3a466 fix: 调整权限按钮判断 2024-05-16 10:04:31 +08:00
79f2032fde feat : 项目归档和分摊页面初始化 2024-05-15 23:39:21 +08:00
lilinyuan
f820c25892 fix: 修改table显示bug 2024-05-15 16:35:36 +08:00
lilinyuan
a4cb59ff9a fix: 修改权限按钮逻辑判断 2024-05-15 16:00:24 +08:00
a7b6b44a42 Merge pull request 'feat : 项目实施分页面初始化' (#185) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/185
2024-05-15 06:20:09 +00:00
1f126592e1 feat : 项目实施分页面初始化 2024-05-15 14:19:36 +08:00
0f914237bf Merge pull request 'fix : 修复细节' (#183) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/183
2024-05-15 05:29:07 +00:00
9a0f5b0e12 fix : 修复细节 2024-05-15 13:28:53 +08:00
9f7e3778ad Merge pull request 'fix : 修复细节' (#181) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/181
2024-05-15 05:25:16 +00:00
01540a3144 fix : 修复细节 2024-05-15 13:24:44 +08:00
5e4e8d6389 Merge pull request 'fix : 修复需求征集新增功能' (#179) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/179
2024-05-15 01:49:01 +00:00
08579c8aad fix : 修复需求征集新增功能 2024-05-15 09:48:38 +08:00
5ae971e0ac Merge pull request 'dj' (#178) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/178
2024-05-14 16:27:50 +00:00
9ae0b7547c feat : 项目立项详情页面初始化 2024-05-15 00:18:40 +08:00
b2369d1702 feat : 项目实施页面初始化 2024-05-15 00:17:18 +08:00
8b6c9a7d1e Merge remote-tracking branch 'origin/master' 2024-05-14 23:53:02 +08:00
6097e74a9b Merge pull request 'feat : 项目立项申请页面初始化' (#177) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/177
2024-05-14 14:16:45 +00:00
11b794bf96 Merge remote-tracking branch 'origin/master' 2024-05-14 22:16:31 +08:00
2a72de08a4 feat : 项目立项申请页面初始化 2024-05-14 22:16:22 +08:00
77fcdc240b Merge pull request 'fix : 修复功能细节' (#175) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/175
2024-05-14 13:32:27 +00:00
6d8dbaa8c4 fix : 修复功能细节 2024-05-14 21:32:10 +08:00
d7b004ae80 Merge pull request 'fix : 修复细节' (#174) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/174
2024-05-14 13:07:27 +00:00
1f9a3603d8 fix : 修复细节 2024-05-14 21:07:17 +08:00
b8b165c205 Merge pull request 'fix : 修复路由规范问题' (#172) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/172
2024-05-14 12:56:36 +00:00
de2f566bd0 fix : 修复路由规范问题 2024-05-14 20:55:49 +08:00
38182da467 Merge pull request 'fix : 修复路由规范问题' (#171) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/171
2024-05-14 12:50:05 +00:00
de0e0be953 fix : 修复路由规范问题 2024-05-14 20:49:46 +08:00
ef1acd65b7 Merge pull request 'fix : 修复路由规范问题' (#170) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/170
2024-05-14 12:26:50 +00:00
27dcca6617 fix : 修复路由规范问题 2024-05-14 20:26:33 +08:00
2ad94511d0 Merge pull request 'dj' (#169) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/169
2024-05-14 09:56:48 +00:00
bfdf2cf4a2 feat : 项目立项页面初始化 2024-05-14 17:56:36 +08:00
4f4ef2cfde fix : 修复细节 2024-05-14 17:56:10 +08:00
222ab1bec7 Merge pull request 'fix : 修复细节' (#167) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/167
2024-05-14 09:14:30 +00:00
bead5edc86 fix : 修复细节 2024-05-14 17:11:59 +08:00
18caa0ee58 Merge pull request 'dj' (#165) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/165
2024-05-13 16:11:21 +00:00
96d8f1e48a Merge remote-tracking branch 'origin/master' 2024-05-14 00:09:46 +08:00
3bc24219ed fix : 修复首页tag报错 2024-05-14 00:09:36 +08:00
07d5380818 Merge pull request 'dj' (#163) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/163
2024-05-13 16:03:34 +00:00
cd91dd3cad fix : 修复首页卡死问题 2024-05-14 00:03:08 +08:00
edb235ff0d Merge remote-tracking branch 'origin/master' 2024-05-13 23:30:20 +08:00
9ade24768e fix : 优化样式 2024-05-13 23:30:07 +08:00
e753c27455 Merge pull request 'dj' (#162) from dj into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/162
2024-05-13 15:04:01 +00:00
1684e49662 Merge remote-tracking branch 'origin/master' 2024-05-13 23:03:15 +08:00
42ea1dde8b fix : 修复功能 2024-05-13 23:03:05 +08:00
wenhua
bb2a0ce177 Merge pull request 'xqhz' (#160) from xqhz into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/160
2024-05-13 14:36:20 +00:00
270 changed files with 19801 additions and 26478 deletions

View File

@@ -25,9 +25,9 @@ steps:
- npm -v
- mkdir -p ./node_modules
- export NODE_MODULES_PATH=`pwd`/node_modules
# - npm config set registry https://registry.npmmirror.com
#- set NODE_OPTIONS=--openssl-legacy-provider
# - npm install
# - npm config set registry https://registry.npmmirror.com
# - set NODE_OPTIONS=--openssl-legacy-provider
# - npm install
- npm run build
- ls /app/build/$DRONE_REPO_NAME/
- echo $NODE_MODULES_PATH

11348
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,7 @@
"d3": "^7.8.5",
"echarts": "^5.4.2",
"element-plus": "^2.6.0",
"file-saver": "^2.0.5",
"highlight.js": "9.18.5",
"jquery": "^3.6.0",
"js-cookie": "^3.0.5",
@@ -30,7 +31,9 @@
"vue-codemirror": "^6.1.1",
"vue-json-viewer": "^3.0.4",
"vue-router": "^4.1.6",
"vuedraggable": "^4.1.0"
"vuedraggable": "^4.1.0",
"xlsx": "^0.18.5",
"xlsx-style-vite": "^0.0.2"
},
"devDependencies": {
"@codemirror/lang-java": "^6.0.1",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -8,5 +8,6 @@ window.addEventListener('beforeunload', e=>beforeunload(e))
const beforeunload = (()=>{
const permisstionStore = usePermisstionStroe()
permisstionStore.setIsLoadRoutes(true)
permisstionStore.setIsSuccessReq()
})
</script>

View File

@@ -1,9 +1,16 @@
import request from "@/utils/request.js";
export const modifyUser=(data)=>{
export const initPassword=(data)=>{
return request({
url:'/admin/user',
method:'put',
url:'/admin/mosr/user/init/password',
method:'post',
data
})
}
}
export const editPassword=(data)=>{
return request({
url:'/admin/mosr/user/update/password',
method:'post',
data
})
}

View File

@@ -1,61 +0,0 @@
import request from '@/utils/request.js'
// 请求数据源适配器list
export const getDataAdapterList = (params) => {
return request({
url: '/custom/query/query/adapter',
method: 'get',
params
})
}
//获取到option列表
export const getDataAdapterOpt = () => {
return request({
url: '/custom/query/query/adapter/option',
method: 'get',
})
}
// 获取数据源适配器详情
export const getDataAdapterDetails = (dataAdapterId) => {
return request({
url: '/custom/query/query/adapter/' + dataAdapterId,
method: 'get'
})
}
// 新增数据源适配器
export const addDataAdapter = (data) => {
return request({
url: '/custom/query/query/adapter',
method: 'post',
data
})
}
//模拟执行适配器函数
export const executeAdapterMockData = (data) => {
return request({
url: '/custom/query/query/adapter/mock/execute',
method: 'post',
data
})
}
// 修改数据源适配器
export const editDataAdapter = (data) => {
return request({
url: '/custom/query/query/adapter',
method: 'put',
data
})
}
// 删除数据源适配器
export const delDataAdapter =(dataAdapterId) => {
return request({
url: '/custom/query/query/adapter/' + dataAdapterId,
method: 'delete'
})
}

View File

@@ -1,66 +0,0 @@
import request from '@/utils/request.js'
// 请求数据源管理list
export const getDataSourceManageList = (params) => {
return request({
url: '/custom/query/datasource',
method: 'get',
params
})
}
//获取到option列表
export const getDataSourceManageOpt = () => {
return request({
url: '/custom/query/datasource/option',
method: 'get',
})
}
// 获取数据源管理详情
export const getDataSourceManageDetails = (queryDataSourceId) => {
return request({
url: '/custom/query/datasource/' + queryDataSourceId,
method: 'get'
})
}
// 获取数据源管理详情
export const getDataSourceType = () => {
return request({
url: '/custom/query/datasource/option/type',
method: 'get'
})
}
// 获取校验规则option
export const getDataSourceOption = () => {
return request({
url: '/custom/query/datasource/option',
method: 'get'
})
}
// 新增数据源管理
export const addDataSourceManage = (data) => {
return request({
url: '/custom/query/datasource',
method: 'post',
data
})
}
// 修改数据源管理
export const editDataSourceManage = (data) => {
return request({
url: '/custom/query/datasource',
method: 'put',
data
})
}
// 删除数据源管理
export const delDataSourceManage =(queryDataSourceId) => {
return request({
url: '/custom/query/datasource/' + queryDataSourceId,
method: 'delete'
})
}

View File

@@ -1,36 +0,0 @@
import request from '@/utils/request.js'
export const getEchartsList = (params) => {
return request({
url: '/custom/query/echarts',
method: 'get',
params
})
}
export const getEchartsDetails = (echartsId) => {
return request({
url: '/custom/query/echarts/' + echartsId,
method: 'get'
})
}
export const addEcharts = (data) => {
return request({
url: '/custom/query/echarts',
method: 'post',
data
})
}
export const editEcharts = (data) => {
return request({
url: '/custom/query/echarts',
method: 'put',
data
})
}
export const delEcharts=(echartsIdList) => {
return request({
url: '/custom/query/echarts/' + echartsIdList,
method: 'delete'
})
}

View File

@@ -1,22 +0,0 @@
import request from '@/utils/request.js'
// 获取查询页面信息
export const getPageInfo = (queryId, params) => {
return request({
url: '/custom/query/page/' + queryId,
method: 'get',
params: params
})
}
// 获取到页面数据
export const getPageData = (params, data) => {
return request({
url: '/custom/query/page/data',
method: 'post',
params: params,
data: data
})
}

View File

@@ -1,37 +0,0 @@
import request from '@/utils/request.js'
export const getSqlInfo = (queryId) => {
return request({
url: '/custom/query/sql/search/' + queryId,
method: 'get'
})
}
export const previewSql= (data,pageInfo) => {
return request({
url:'/custom/query/sql/search/preview' ,
method: 'put',
data,
params:pageInfo
})
}
export const saveSqlQueryParams = (data) => {
return request({
url: '/custom/query/sql/search',
method: 'post',
data
})
}
export const sqlToLine = (data) => {
return request({
url: '/custom/query/sql/search/publish',
method: 'post',
data
})
}
export const sqlDownLine = (queryId) => {
return request({
url: '/custom/query/sql/search/cancel/'+queryId,
method: 'put'
})
}

View File

@@ -1,42 +0,0 @@
import request from '@/utils/request.js'
// 获取Sql List
export const getSqlList = (params) => {
return request({
url: '/custom/query/sql/uni',
method: 'get',
params
})
}
// 获取Sql详情
export const getSqlDetails = (sqlId) => {
return request({
url: '/custom/query/sql/uni/' + sqlId,
method: 'get'
})
}
// 新增Sql
export const addSql = (data) => {
return request({
url: '/custom/query/sql/uni',
method: 'post',
data
})
}
// 修改Sql
export const editSql = (data) => {
return request({
url: '/custom/query/sql/uni',
method: 'put',
data
})
}
// 删除Sql
export const delSql =(idList) => {
return request({
url: '/custom/query/sql/uni/' + idList,
method: 'delete'
})
}

View File

@@ -1,70 +0,0 @@
import request from '@/utils/request.js'
//获取表格维护列表
export const getTableInfo = (params) => {
return request({
url: '/custom/query/table',
method: 'get',
params
})
}
export const getDynamicTableList = (params) => {
return request({
url: '/custom/query/dynamic/table',
method: 'get',
params
})
}
//根据数据源获取到表格option信息
export const getAssociationTableOption = (datasourceId) => {
return request({
url: '/custom/query/table/option/' + datasourceId,
method: 'get'
})
}
//获取表格字段option信息
export const getAssociationFieldOption = (tableId) => {
return request({
url: '/custom/query/table/column/option/' + tableId,
method: 'get'
})
}
// 获取详细信息
export const getTableDetails = (tableId) => {
return request({
url: '/custom/query/table/' + tableId,
method: 'get'
})
}
// 导入表信息
export const addTableInfo= (data) => {
return request({
url: '/custom/query/table/import',
method: 'post',
data
})
}
// 修改自定义查询表格维护
export const editTable = (data) => {
return request({
url: '/custom/query/table',
method: 'put',
data
})
}
// 同步数据库
export const syncDatabase = (tableId) => {
return request({
url: '/custom/query/table/sync/'+ tableId,
method: 'put'
})
}
// 删除自定义查询表格维护
export const delTable=(tableId) => {
return request({
url: '/custom/query/table/' + tableId,
method: 'delete'
})
}

View File

@@ -1,47 +0,0 @@
import request from '@/utils/request.js'
// 获取topo拖拽数据信息
export const getTopoDragInfo = (queryId) => {
return request({
url: '/custom/query/topo/search/' + queryId,
method: 'get'
})
}
export const saveTopo = (data) => {
return request({
url: '/custom/query/topo/search',
method: 'post',
data
})
}
export const previewTopo = (data,pageInfo) => {
return request({
url: '/custom/query/topo/search/preview',
method: 'post',
data,
params:pageInfo,
})
}
export const previewTopologyData = (data,pageInfo) => {
return request({
url: '/custom/query/topo/search/preview/data',
method: 'post',
data,
params:pageInfo,
})
}
export const topoToLine = (data) => {
return request({
url: '/custom/query/topo/search/publish',
method: 'post',
data
})
}
export const topoDownLine = (queryId) => {
return request({
url: '/custom/query/topo/search/cancel/'+queryId,
method: 'put'
})
}

View File

@@ -1,42 +0,0 @@
import request from '@/utils/request.js'
// 获取topoList
export const getTopoList = (params) => {
return request({
url: '/custom/query/topo/uni',
method: 'get',
params
})
}
// 获取topo详情
export const getTopoDetails = (topoId) => {
return request({
url: '/custom/query/topo/uni/' + topoId,
method: 'get'
})
}
// 新增topo
export const addTopo = (data) => {
return request({
url: '/custom/query/topo/uni',
method: 'post',
data
})
}
// 修改topo
export const editTopo = (data) => {
return request({
url: '/custom/query/topo/uni',
method: 'put',
data
})
}
// 删除topo
export const delTopo =(idList) => {
return request({
url: '/custom/query/topo/uni/' + idList,
method: 'delete'
})
}

View File

@@ -0,0 +1,81 @@
import request from '@/utils/request.js'
import axios from "axios";
import {getToken} from "@/utils/auth";
export const addAllocation = (data) => {
return request({
url:'/workflow/mosr/cost/allocation',
method: "post",
data
});
};
export const getAllocationDetail = (allocationId) => {
return request({
url: `/workflow/mosr/cost/allocation/info/${allocationId}`,
method: "get"
});
};
export const getAllocationDetails = (allocationId) => {
return request({
url: `/workflow/mosr/cost/allocation/usr/detail/${allocationId}`,
method: "get"
});
};
export const getAllocationSummaryDetails = (params) => {
return request({
url: '/workflow/mosr/cost/allocation/collect',
method: "get",
params:params
});
};
export const getAllocationProcess = () => {
return request({
url: '/workflow/mosr/cost/allocation/process',
method: "get"
});
};
export const getAllocationDetailList = (params) => {
return request({
url: '/workflow/mosr/cost/allocation/usr',
method: "get",
params:params
});
};
export const getResearchUser = () => {
return request({
url: '/admin/mosr/user/research',
method: "get"
});
};
export const getProjectOption = () => {
return request({
url: '/workflow/mosr/project/implementation/in/implementation/option',
method: "get"
});
};
export const editAllocation = (data) => {
return request({
url: '/workflow/mosr/cost/allocation/edit',
method: "post",
data
});
};
export const deleteAllocation = (id) => {
return request({
url: `/workflow/mosr/cost/allocation/${id}`,
method: "delete"
});
};
export const shareExportExcel = (allocationId) => {
return axios.get(
`${import.meta.env.VITE_BASE_URL}/workflow/mosr/cost/allocation/collect/${allocationId}`,
{
responseType: 'blob',
headers: {
Authorization: getToken()
}
}
);
};

View File

@@ -7,6 +7,7 @@ export const getCodeImg = () => {
})
}
export const login = (data) => {
return request({
url: '/auth/login',
@@ -14,6 +15,12 @@ export const login = (data) => {
data
})
}
export const switchAccount = (userId) => {
return request({
url: `/auth/switch/account/${userId}`,
method: 'post',
})
}
export const getUserInfo = () => {
return request({
@@ -21,3 +28,9 @@ export const getUserInfo = () => {
method: 'get',
})
}
export const getAuthInfo = () => {
return request({
url: '/admin/mosr/user/detail/info',
method: 'get',
})
}

View File

@@ -60,9 +60,31 @@ export const deleteFile = (fileId) => {
method: "delete"
});
};
export const downloadFile = (fileId) => {
return request({
url: '/workflow/process/file/download',
method: "get",
responseType:'blob',
params:{
fileId:fileId
}
});
};
export const getCompanyOption = () => {
return request({
url: '/admin/mosr/sub/company/companyOption',
method: "get"
});
};
export const deleteDemand = (id) => {
return request({
url: `/workflow/mosr/requirement/${id}`,
method: "delete"
});
};
export const getRequirementStatePerm = () => {
return request({
url: '/workflow/mosr/requirement/prem/state',
method: "get"
});
};

View File

@@ -0,0 +1,91 @@
import request from '@/utils/request'
export const fileUp = (url, data) => {
return request({
url,
method: 'post',
data,
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
export const requirementReported = (data) => {
return request({
url: '/workflow/mosr/requirement/reported',
method: "post",
data: data
});
};
//获取需求上报 流程信息
export const getProcessInfo = (specialFund) => {
return request({
url: `/workflow/mosr/requirement/collect/process/${specialFund}`,
method: "get"
});
};
export const getDetail = (projectId) => {
return request({
url: `/workflow/mosr/requirement/collect/info/${projectId}`,
method: "get"
});
};
export const resubmitReported = (data) => {
return request({
url: '/workflow/mosr/requirement/collect/resubmit',
method: "post",
data: data
});
};
export const getCollectAttachment = (params) => {
return request({
url: '/workflow/mosr/requirement/collect/attachments',
method: "get",
params:params
});
};
export const uploadCollectAttachment= (data) => {
return request({
url: '/workflow/mosr/requirement/collect/upload',
method: "post",
data: data
});
};
// 年度计划
export const addPlan= (data) => {
return request({
url: '/workflow/annual/plan',
method: "post",
data: data
});
};
export const editPlan= (data) => {
return request({
url: '/workflow/annual/plan',
method: "put",
data: data
});
};
export const getPlan= (annualPlanId) => {
return request({
url: `/workflow/annual/plan/info/${annualPlanId}`,
method: "get"
});
};
export const deletePlan= (annualPlanId) => {
return request({
url: `/workflow/annual/plan/${annualPlanId}`,
method: "delete"
});
};
export const approvePlan= (data) => {
return request({
url: '/workflow/annual/plan/approve',
method: "post",
data: data
});
};

View File

@@ -0,0 +1,31 @@
import request from '@/utils/request.js'
export const searchFileList = (params) => {
return request({
url: `/workflow/mosr/attachment/list`,
method: "get",
params: params
});
};
export const uploadFileList = (data) => {
return request({
url: '/workflow/mosr/attachment/upload',
method: "post",
data: data
});
};
export const searchImplementationFileList = (params) => {
return request({
url: '/workflow/mosr/attachment/implementation/list',
method: "get",
params: params
});
};
export const switchAttachmentState = (data) => {
return request({
url: '/workflow/mosr/project/filing/attachment/switch',
method: "post",
data
});
};

View File

@@ -0,0 +1,181 @@
import request from '@/utils/request.js'
import axios from "axios";
import {getToken} from "@/utils/auth";
//项目立项
export const getApplyProcess = (projectId) => {
return request({
url: `/workflow/mosr/project/approval/initiation/process/${projectId}`,
method: "get"
});
};
export const projectApply = (data) => {
return request({
url: '/workflow/mosr/project/approval/initiation/apply',
method: "post",
data: data
});
};
export const getApplyDetail = (ProjectId) => {
return request({
url: `/workflow/mosr/project/approval/info/${ProjectId}`,
method: "get"
});
};
export const resubmitApply = (data) => {
return request({
url: '/workflow/mosr/project/approval/initiation/resubmit',
method: "post",
data: data
});
};
export const getInitiationAttachment = (params) => {
return request({
url: '/workflow/mosr/project/approval/attachments',
method: "get",
params: params
});
};
//项目实施
export const getCheckDetail = (projectId) => {
return request({
url: `/workflow/mosr/project/implementation/info/${projectId}`,
method: "get"
});
};
export const resubmitCheck = (data) => {
return request({
url: '/workflow/mosr/project/implementation/resubmit',
method: "post",
data: data
});
};
export const projectCheck = (data) => {
return request({
url: '/workflow/mosr/project/implementation/initiation/check',
method: "post",
data: data
});
};
export const getProjectCheckProcess = (projectId) => {
return request({
url: `/workflow/mosr/project/implementation/process/${projectId}`,
method: "get"
});
};
export const addLedger = (data) => {
return request({
url: '/workflow/mosr/expense/ledger',
method: "post",
data: data
});
};
export const getTags = (projectId) => {
return request({
url: `/workflow/mosr/attachment/option/${projectId}`,
method: "get"
});
};
export const getPhaseProcess = () => {
return request({
url: '/workflow/phase/change/process',
method: "get"
});
};
export const submitPhaseChange = (data) => {
return request({
url: '/workflow/phase/change',
method: "post",
data: data
});
};
export const getPhaseDetail = (projectId) => {
return request({
url: `/workflow/phase/change/info/${projectId}`,
method: "get"
});
};
export const getPhaseForm = (projectId) => {
return request({
url: `/workflow/phase/change/from/${projectId}`,
method: "get"
});
};
export const resubmitPhaseForm = (data) => {
return request({
url: '/workflow/phase/change/resubmit',
method: "post",
data: data
});
};
//项目归档
export const getConclusionDetail = (ProjectId) => {
return request({
url: `/workflow/mosr/project/filing/info/${ProjectId}`,
method: "get"
});
};
export const resubmitConclusion = (data) => {
return request({
url: '/workflow/mosr/project/filing/resubmit',
method: "post",
data: data
});
};
export const projectConclusion = (data) => {
return request({
url: '/workflow/mosr/project/filing/project/entry',
method: "post",
data: data
});
};
export const getProjectConclusionProcess = () => {
return request({
url: '/workflow/mosr/project/filing/process',
method: "get"
});
};
//获取前置流程
export const getPreProcess = () => {
return request({
url: '/workflow/details/pre/process',
method: "get"
});
};
export const updateLedger = (data) => {
return request({
url: '/workflow/mosr/expense/ledger/replenishment',
method: "post",
data: data
});
};
export const searchUpdateLedgerData = (projectId) => {
return request({
url: `/workflow/mosr/expense/ledger/${projectId}`,
method: "get"
});
};
//
// export const searchUpdateLedgerData = (projectId) => {
// return request({
// url: '/workflow/mosr/expense/ledger/import',
// method: "get"
// });
// };
export const exportExcel = (data) => {
return axios.post(
`${import.meta.env.VITE_BASE_URL}/workflow/mosr/project/implementation/export`,
data, {
responseType: 'blob',
headers: {
Authorization: getToken()
}
}
);
};

View File

@@ -0,0 +1,46 @@
import request from '@/utils/request.js'
export const getFundDetail = (specialFundId) => {
return request({
url: `/workflow/mosr/special/fund/from/${specialFundId}`,
method: "get"
});
};
export const getFundDetailProcess = (specialFundId) => {
return request({
url: `/workflow/mosr/special/fund/info/${specialFundId}`,
method: "get"
});
};
export const getFundOption = () => {
return request({
url: '/workflow/mosr/special/fund/option',
method: "get"
});
};
export const getFundProcess = (specialFundId) => {
return request({
url: '/workflow/mosr/special/fund/process',
method: "get"
});
};
export const addFund= (data) => {
return request({
url: '/workflow/mosr/special/fund',
method: "post",
data
});
};
export const resubmitFund= (data) => {
return request({
url: '/workflow/mosr/special/fund/resubmit',
method: "post",
data
});
};
export const deleteFund = (id) => {
return request({
url: `/workflow/mosr/special/fund/${id}`,
method: "delete"
});
};

View File

@@ -14,3 +14,9 @@ export const getDepartmentList=(params)=>{
params
})
}
export const getCompanyDetail=(companyId)=>{
return request({
url:`/admin/mosr/sub/company/info/${companyId}`,
method:'get'
})
}

View File

@@ -18,6 +18,13 @@ export const getConfigDetails = (configId) => {
method: 'get'
})
}
// 获取参数配置表详情
export const getConfigByKey = (configKey) => {
return request({
url: '/admin/config/key/' + configKey,
method: 'get'
})
}
// 新增参数配置表
export const addConfig = (data) => {

View File

@@ -49,3 +49,10 @@ export const delDictType =(dictTypeId) => {
method: 'delete'
})
}
//字典刷新缓存
export const refreshDict =() => {
return request({
url: 'admin/dict/type/refresh',
method: 'post'
})
}

View File

@@ -50,4 +50,4 @@ export const getMenuOptRole = (roleId) => {
url: '/admin/menu/option/role/'+roleId,
method: 'get'
})
}
}

View File

@@ -15,6 +15,12 @@ export const getSubCompOpt = () => {
method: 'get'
})
}
export const getUserAccount = () => {
return request({
url: `/admin/mosr/user/account/list`,
method: 'get'
})
}
// 查询角色信息
export const getRolesOpt = () => {
@@ -49,9 +55,9 @@ export const getUserDetail = (userId) => {
// 操作
export const operate = (data, type) => {
console.log(type ,'type');
if(data.userId && type !== '0') return editUser(data)
else if(type == '0') return editUserOA(data)
// console.log(type ,'type');
if (data.userId && type !== '0') return editUser(data)
else if (type == '0') return editUserOA(data)
return addUser(data)
}
@@ -179,3 +185,24 @@ export const unbindAllUserByPost = (postId) => {
}
})
}
export const bindAccount = (data) => {
return request({
url: '/admin/mosr/user/bind/account',
method: 'post',
data
})
}
export const getBindAccount = (userId) => {
return request({
url: `/admin/mosr/user/bind/account/info/${userId}`,
method: 'get'
})
}
export const checkMatrix = (userId) => {
return request({
url: `/admin/mosr/user/matrix?userId=` + userId,
method: 'get'
})
}

View File

@@ -60,3 +60,19 @@ export function addProcessDefinition(param) {
data: param
})
}
export function getTypeOption() {
return request({
url: "/workflow/process/definition/type/option",
method: "get",
})
}
export function getFromPerm(processKey) {
return request({
url: "/workflow/process/definition/from/perm/"+processKey,
method: "get",
})
}

View File

@@ -1,10 +1,10 @@
import request from '@/utils/request.js'
//根据角色或者部门获取到对应的数据
export function getUserTree(type,chooseId){
export function getUserTree(type, chooseId) {
return request({
url:`/admin/user/choose/${type}/${chooseId}`,
method:'get'
url: `/admin/user/choose/${type}/${chooseId}`,
method: 'get'
})
}
@@ -15,6 +15,7 @@ export function getRole() {
method: 'get'
})
}
//获取采取树形控件的部门option
export function getDepartmentTree() {
return request({
@@ -22,3 +23,27 @@ export function getDepartmentTree() {
method: 'get'
})
}
export function getMosrUser(params) {
return request({
url: '/admin/mosr/user/choose',
method: 'get',
params: params
})
}
export function getOrganizationStructure(params) {
return request({
url: '/admin/organizational/structure/choose',
method: 'get',
params: params
})
}
export function getOrganizationStructureTree(params) {
return request({
url: '/admin/organizational/structure/tree',
method: 'get',
params: params
})
}

BIN
src/assets/kylogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

View File

@@ -377,8 +377,8 @@ html, body, #app, .el-container, .el-aside, .el-main {
//放大缩小按钮上外边距
.scale {
margin-top: 10px;
z-index: 666;
position: absolute;
//z-index: 666;
//position: static;
//top: -20px;
}
@@ -405,7 +405,9 @@ html, body, #app, .el-container, .el-aside, .el-main {
.nowrap {
white-space: pre
}
.el-empty__description {
margin-top: 0!important;
}
//SvgIcon组件的样式
.home-icon {
width: 4em;
@@ -415,7 +417,13 @@ html, body, #app, .el-container, .el-aside, .el-main {
overflow: hidden;
margin-right: 5px;
}
.oran-icon{
width: 1em;
height: 1em;
margin-right: 4px;
vertical-align: -0.21em;
}
.svg-icon {
width: 1.2em;
height: 1.2em;
@@ -547,4 +555,35 @@ html, body, #app, .el-container, .el-aside, .el-main {
position: fixed;
bottom: 15px;
right: 15px;
z-index: 5;
}
.approval-record {
//padding-top: 10px;
padding-bottom: 30px;
position: relative;
.approval-title {
display: flex;
align-items: center;
//justify-content: space-between;
.diagram {
display: flex;
align-items: center;
float: right;
.base-title {
margin-left: 10px;
margin-right: 10px;
}
//.el-switch {
// margin-left: 15px;
//}
}
}
.process {
position: relative;
}
}

View File

@@ -2,7 +2,7 @@
border-radius: 10px;
}
.logo {
height: 106px;
height: 65px;
background-color: #BEA266;
color: #ffffff;
font-weight: bold;
@@ -10,6 +10,13 @@
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
padding: 10px;
& > img {
object-fit: scale-down;
width: 100%;
height: 40px;
}
}
.port-link{
display: block;

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717294999406" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10473" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M721.7 259.8h140l-196-196v140c0 31 25 56 56 56z" fill="#2c2c2c" p-id="10474"></path><path d="M469.7 749.8c0-146.7 119.3-266 266-266 45.6 0 88.5 11.5 126 31.8V301.8h-140c-54 0-98-44-98-98v-140h-490c-30.9 0-56 25.1-56 56v784c0 30.9 25.1 56 56 56H573c-62.7-48.7-103.3-124.6-103.3-210z m-252-426.5h308c15.5 0 28 12.5 28 28s-12.5 28-28 28h-308c-15.5 0-28-12.5-28-28s12.5-28 28-28z m98 424.1h-98c-15.5 0-28-12.5-28-28s12.5-28 28-28h98c15.5 0 28 12.5 28 28s-12.6 28-28 28z m56-184h-154c-15.5 0-28-12.5-28-28s12.5-28 28-28h154c15.5 0 28 12.5 28 28s-12.6 28-28 28z" fill="#2c2c2c" p-id="10475"></path><path d="M735.7 539.8c-116 0-210 94-210 210s94 210 210 210 210-94 210-210-94.1-210-210-210z m69.1 163.5c12.9 0 23.3 10.5 23.3 23.4 0 12.9-10.4 23.3-23.3 23.3h-46.6v23.3h46.6c12.9 0 23.3 10.4 23.3 23.3s-10.4 23.3-23.3 23.3h-46.6v46.7c0 12.9-10.4 23.3-23.3 23.3s-23.3-10.4-23.3-23.3v-46.7H665c-12.9 0-23.3-10.4-23.3-23.3s10.4-23.3 23.3-23.3h46.6V750H665c-12.9 0-23.3-10.4-23.3-23.3s10.4-23.3 23.3-23.3h37.3l-53.9-53.8c-9.1-9.1-9.1-23.9 0-33 9.1-9.1 23.9-9.1 33 0l53.4 53.3 55.5-53.6c9.2-8.9 24-8.7 33 0.6 9 9.2 8.7 24-0.6 33l-55.5 53.3h37.6z" fill="#2c2c2c" p-id="10476"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

1
src/assets/svg/fee.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717295020643" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11515" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M683.604677 560.04317c-28.140302-46.866394-27.62866-47.68502-27.62866-47.685021s-97.007295 27.219346-115.017088-65.797142h-56.178275s-15.451584 93.118817-114.607775 65.592486c-28.651944 47.787349-29.675227 49.219946-29.675227 49.322274 0 0 77.564905 54.234036 0 127.808134l30.08454 49.526931s85.648846-36.940542 113.68682 63.955232h56.894573s17.805136-92.811832 114.198462-65.387829c27.424003-46.866394 27.833317-47.275707 27.833316-47.275707s-72.755471-62.829619 0.409314-130.059358zM511.590687 690.102528c-36.224243 0-65.592485-29.368242-65.592486-65.592485 0-36.224243 29.368242-65.592485 65.592486-65.592485 36.224243 0 65.592485 29.368242 65.592485 65.592485 0 36.224243-29.368242 65.592485-65.592485 65.592485z" fill="#2c2c2c" p-id="11516"></path><path d="M716.554412 255.718597c7.674628-12.791046 14.939942-25.684421 21.898271-38.168482 7.674628-14.121315 13.098031-24.865794 16.065554-31.210153C818.780454 77.462576 755.848506-1.22794 631.92885 35.81493c-12.381733 4.297792-30.903168 10.232837-52.903768 16.27021-13.405016 3.683821-26.912361 6.856001-40.522034 9.618867-15.349256 3.376836-31.005496 5.321075-46.764065 5.730389-11.767763 0-25.991406-1.534926-42.261617-4.40012-32.540422-6.242031-64.466873-15.04227-95.677026-26.093734C228.141101 0 166.437094 76.541621 230.187669 188.386529c2.455881 5.321075 8.80024 17.907465 17.805136 34.280004 9.107225 16.577196 18.930748 33.25672 29.265914 49.833917C116.296193 366.540222 9.874688 533.233137 9.874688 729.089637c0 47.889677 6.242031 95.063056 18.419106 140.701509 1.432597 9.925852 5.116419 22.409913 10.335166 34.075347l1.22794 3.479165 7.879285 22.61457h5.730388c30.596183 42.568602 83.090637 66.820426 146.431898 66.820426h625.32867c92.607175 0 159.836914-51.47117 170.888378-131.389628 11.870091-44.512841 17.702808-90.355951 17.60048-136.301389 0-209.159189-120.747477-386.187269-297.161587-473.37104zM930.727691 852.395323c-6.958329 48.810633-44.717498 77.564905-105.50055 77.564905H199.898471c-48.094334 0-82.476666-18.521435-98.030579-48.810633l-1.330268-2.353552-0.204657-0.818627c-3.274508-7.060658-5.423404-14.632957-6.651344-22.307585-11.153792-41.340662-16.884181-83.909264-16.98651-126.682522 0-183.372439 106.626162-337.78595 263.08624-414.327571l34.791646-16.884181-21.898271-31.824123c-23.637854-34.586989-44.717498-70.811232-63.341261-108.365744-34.893974-61.397022-22.716898-76.439292 43.591885-56.996902 9.925852 3.683821 29.368242 10.02818 52.699111 16.372539 17.907465 4.911762 35.303288 9.004897 51.880484 11.870091 19.851704 3.581493 37.963825 5.525732 54.131707 5.525732 17.293495 0 37.247527-2.455881 59.964425-6.958329 14.4283-2.865194 29.675227-6.549016 45.126811-10.846807 18.82842-5.116419 37.452183-10.846807 55.871291-17.293495 64.262216-19.135405 77.360248-3.069851 42.67093 55.564305-3.888478 7.879285-8.80024 17.702808-15.963226 30.698511-11.870091 21.898271-25.172779 44.512841-39.601079 66.615769L617.398221 286.519436l37.963826 15.144599C825.94344 369.507745 946.690916 533.130808 946.690916 728.987309c0 41.954632-5.525732 83.295293-15.963225 123.408014z m0 0" fill="#2c2c2c" p-id="11517"></path></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717294973537" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9231" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M736.3 722.8c-15.9 0-31.5-0.6-46.6-1.8-5.4 19-12.7 37.8-23.7 54.3-9.1 18-21.6 33.8-36.2 47.9 32 5.6 68.5 8.8 106.5 8.8 119.6 0 223.7-31.2 223.7-72.8v-93.6c-46.8 31.2-124.8 57.2-223.7 57.2zM192.5 201.1c7.7 5.2 15.5 10.4 20.7 18.1 7.7 5.2 12.9 12.9 18.1 20.7 2.6 5.2 7.7 10.3 10.4 15.5 5.2 5.2 7.7 10.3 10.3 15.5 2.6 5.2 7.7 12.9 10.3 18.1h173.3c2.6-5.2 7.7-10.3 10.4-18.1 2.6-5.2 5.2-10.3 10.3-15.5 2.6-2.6 5.2-5.2 7.7-10.4 5.2-7.7 10.3-15.5 15.5-20.7 5.2-7.7 12.9-12.9 23.2-20.7 5.2-2.6 10.3-5.2 12.9-10.3 2.6-5.2 5.2-7.7 5.2-12.9s0-7.7-2.6-12.9-5.2-7.7-10.3-10.3c-5.2-2.6-10.3-2.6-12.9-2.6-2.6 0-7.7 2.6-10.4 2.6-2.6 0-7.7 2.6-10.3 5.2-2.6 2.6-7.7 2.6-12.9 2.6s-10.3 0-12.9-2.6c-2.6-2.6-7.7-5.2-10.4-7.7-2.6-2.6-5.2-5.2-10.3-7.7-2.6-2.6-7.7-5.2-12.9-7.7-10.3-5.2-20.7-5.2-25.9-2.6-7.7 2.6-12.9 7.7-20.7 12.9-5.2 5.2-10.3 10.4-12.9 10.4-2.6 0-2.6 2.6-5.2 2.6-2.6-2.6-5.2-2.6-10.3-5.2-2.6-2.6-5.2-2.6-7.7-5.2l-7.7-7.7c-2.6-2.6-10.3-5.2-18.1-7.7-7.7-2.6-15.5 0-23.2 5.2-10.3 5.2-15.5 10.3-20.7 15.5-5.2 5.2-10.3 7.7-18.1 7.7h-15.5c-2.6-2.6-7.7-2.6-12.9-5.2s-10.3-2.6-15.5-2.6c-5.2 0-10.3 0-12.9 2.6-7.7 5.2-10.4 12.9-7.7 23.2 2.2 7.6 7.4 12.7 12.6 17.9z m447.6 393.2c-5.2-28.4-10.3-51.7-20.7-72.4-10.3-20.7-23.2-38.8-36.2-54.3-12.9-15.5-28.4-28.4-41.4-41.4-15.5-12.9-31-25.9-41.4-38.8-10.4-12.9-23.2-23.2-31.1-31.1-10.3-10.3-18.1-20.7-25.9-28.4H257.1c-5.2 10.3-15.5 20.7-23.2 31.1-7.7 10.3-18.1 20.7-28.4 31-10.3 10.3-25.9 23.2-38.8 36.2-15.5 15.5-31 31-46.6 49.1-15.5 18.1-25.9 38.8-36.2 59.5-10.4 20.7-15.5 43.9-18.1 69.8-2.6 25.9-2.6 51.8 2.6 77.6 5.2 23.2 12.9 49.1 28.4 72.4 12.9 23.2 31 46.6 56.9 67.3s51.7 36.2 85.3 49.1c33.7 13 72.6 18.2 116.5 18.2 41.4 0 80.2-5.2 113.8-15.5 33.6-10.4 62.1-25.9 85.3-43.9 23.2-18.1 43.9-38.8 56.9-64.6 15.5-23.2 23.2-51.7 28.4-77.6 2.7-33.8 5.3-64.9 0.2-93.3zM430.5 697.8c15.5 0 23.2 5.2 23.2 18.1 0 5.2 0 10.3-5.2 12.9-2.6 2.6-7.7 2.6-12.9 2.6h-56.9v15.5c0 5.2-2.6 10.3-5.2 15.5-5.2 5.2-10.3 7.7-15.5 5.2-7.7 0-12.9-2.6-15.5-5.2-5.2-2.6-7.7-7.7-7.7-15.5v-15.5h-59.5c-5.2 0-10.3-2.6-12.9-5.2-2.6-2.6-5.2-7.7-5.2-10.3 0-5.2 2.6-7.7 5.2-12.9 2.6-2.6 7.7-5.2 12.9-5.2h57v-28.4h-56.9c-5.2 0-10.3-2.6-12.9-5.2-2.6-2.6-5.2-7.7-5.2-10.4 0-2.6 2.6-7.7 5.2-12.9 2.6-2.6 7.7-5.2 12.9-5.2h56.9v-18.1L303.7 589c-7.7-7.7-12.9-15.5-20.7-20.7l-10.4-12.8c-2.6-2.6-5.2-7.7-7.7-12.9s0-12.9 2.6-18.1c5.2-5.2 10.3-7.7 18.1-5.2 7.7 2.6 12.9 5.2 18.1 10.3 2.6 2.6 5.2 7.7 10.3 12.9l41.4 41.4c10.3-7.7 18.1-15.5 25.9-23.2 7.7-5.2 12.9-12.9 20.7-18.1s10.3-10.3 12.9-12.9c5.2-5.2 10.3-7.7 15.5-7.7s10.4 2.6 15.5 7.7c7.7 7.7 5.2 18.1-7.7 28.4l-15.5 15.6-46.6 46.6v12.9h54.3c7.7 0 12.9 2.6 18.1 5.2 5.2 2.6 5.2 7.7 5.2 12.9s-2.6 10.3-5.2 12.9c-2.6 2.6-7.7 5.2-15.5 5.2h-54.3v28.4h51.8zM736.3 556.4c-16.3 0-31.9-0.6-46.9-1.7 2.8 11.2 5.1 23.1 7.5 36 4.7 25.9 3.4 53.9 1.1 83.9 12.3 1 25.1 1.5 38.2 1.5 119.6 0 208.1-41.6 223.7-83.2v-93.6c-46.7 36.3-124.7 57.1-223.6 57.1zM736.3 337.9c-72.8 3.2-139.7 17.9-181 39.5 10.2 10.5 22.8 21 35.4 31.5 14 14 30.7 28 44.7 44.7 12.6 15 25 32.5 35.5 52 20.4 2.5 42.3 3.9 65.4 3.9 119.6 0 208.1-41.6 223.7-83.2 0-46.8-98.8-88.4-223.7-88.4z" fill="#2c2c2c" p-id="9232"></path></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717295344332" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22536" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M0 307.2h66.56l79.36 94.72H870.4L947.2 307.2h76.8v512c0 112.64-92.16 204.8-204.8 204.8H204.8c-112.64 0-204.8-92.16-204.8-204.8V307.2z m340.48 325.12V563.2c0-17.92-15.36-33.28-33.28-33.28s-33.28 15.36-33.28 33.28v102.4c0 17.92 15.36 33.28 33.28 33.28h427.52c17.92 0 33.28-15.36 33.28-33.28v-102.4c0-17.92-15.36-33.28-33.28-33.28s-33.28 15.36-33.28 33.28v69.12H340.48zM102.4 204.8h819.2v69.12L852.48 358.4h-680.96L102.4 273.92V204.8z m0-204.8h819.2v69.12L852.48 153.6h-680.96L102.4 69.12V0z" fill="#3B3B47" p-id="22537"></path></svg>

After

Width:  |  Height:  |  Size: 865 B

1
src/assets/svg/home.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717296104869" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6006" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M554.965333 101.248l406.954667 373.034667a34.133333 34.133333 0 0 1-23.04 59.306666l-40.277333-0.042666v298.666666a85.333333 85.333333 0 0 1-85.333334 85.333334h-597.333333a85.333333 85.333333 0 0 1-85.333333-85.333334v-298.666666h-40.234667a34.133333 34.133333 0 0 1-23.04-59.264l406.912-373.034667a59.733333 59.733333 0 0 1 80.725333 0zM312.448 591.36a42.666667 42.666667 0 0 0 0 60.330667 279.978667 279.978667 0 0 0 395.946667 0 42.666667 42.666667 0 0 0-60.330667-60.330667 194.645333 194.645333 0 0 1-275.242667 0 42.666667 42.666667 0 0 0-60.373333 0z" fill="#2c2c2c" p-id="6007"></path></svg>

After

Width:  |  Height:  |  Size: 933 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717295325359" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21461" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M854.016 889.514667l-41.642667-43.690667c10.922667-11.605333 25.941333-18.432 41.642667-18.432 32.768 0 59.392-27.989333 59.392-62.122667V144.725333c0-34.133333-26.624-62.122667-59.392-62.122666H263.509333c-32.768 0-59.392 27.989333-59.392 62.122666v5.461334c0 17.066667-6.826667 32.768-17.066666 43.690666L145.408 150.186667v-5.461334C145.408 75.776 197.973333 20.48 263.509333 20.48h591.189334c65.536 0 118.101333 55.296 118.101333 124.245333v620.544c-0.682667 68.949333-53.248 124.245333-118.784 124.245334zM86.016 268.970667v620.544c0 34.133333 26.624 62.122667 59.392 62.122666h591.189333c32.768 0 59.392-27.989333 59.392-62.122666V268.970667c0-34.133333-26.624-62.122667-59.392-62.122667H145.408c-32.768 0-59.392 27.989333-59.392 62.122667z m649.898667-124.245334c65.536 0 118.101333 55.296 118.101333 124.245334v620.544c0 68.266667-53.248 124.245333-118.101333 124.245333H145.408c-65.536 0-118.101333-55.296-118.101333-124.245333V268.970667c0-68.266667 53.248-124.245333 118.101333-124.245334h590.506667z" p-id="21462" fill="#2c2c2c"></path><path d="M735.914667 1024H145.408c-70.997333 0-128.341333-60.074667-128.341333-134.485333V268.970667c0-70.314667 52.565333-129.024 118.784-133.802667 4.096-69.632 60.074667-124.928 127.658666-124.928h591.189334c70.997333 0 128.341333 60.074667 128.341333 134.485333v620.544c0 70.314667-52.565333 129.024-118.784 133.802667-4.778667 70.314667-60.757333 124.928-128.341333 124.928zM135.850667 154.965333c-55.296 4.778667-98.986667 53.930667-98.986667 113.322667v620.544c0 62.805333 48.469333 114.005333 107.861333 114.005333h591.189334c58.026667 0 105.813333-49.152 107.861333-109.909333L805.546667 853.333333v36.181334c0 39.594667-31.402667 72.362667-69.632 72.362666H145.408c-38.229333 0-69.632-32.768-69.632-72.362666V268.970667c0-39.594667 31.402667-72.362667 69.632-72.362667h30.72l-40.277333-41.642667z m9.557333 62.122667c-26.624 0-49.152 23.210667-49.152 51.882667v620.544c0 28.672 21.845333 51.882667 49.152 51.882666h591.189333c26.624 0 49.152-23.210667 49.152-51.882666V268.970667c0-28.672-21.845333-51.882667-49.152-51.882667H145.408z m718.848 619.861333v41.642667c54.613333-5.461333 97.621333-53.930667 97.621333-113.322667V144.725333c0-62.805333-48.469333-114.005333-107.861333-114.005333H263.509333c-55.978667 0-102.4 45.738667-107.178666 103.765333h38.912c4.778667-34.816 33.450667-62.122667 68.949333-62.122666h591.189333c38.229333 0 69.632 32.768 69.632 72.362666v620.544c-1.365333 36.181333-27.306667 66.901333-60.757333 71.68z m-36.864 9.557334l17.066667 17.749333v-25.258667c-6.826667 1.365333-12.288 4.096-17.066667 7.509334zM197.973333 196.608h537.941334c38.229333 0 69.632 32.768 69.632 72.362667v569.344c10.24-10.922667 23.893333-17.749333 38.912-20.48V268.970667c0-62.805333-48.469333-114.005333-107.861334-114.005334H214.357333c-0.682667 15.018667-6.826667 30.037333-16.384 41.642667z m17.749334-62.122667h520.874666c70.997333 0 128.341333 60.074667 128.341334 134.485334v547.498666c21.845333-4.778667 38.912-25.941333 38.912-50.517333v-621.226667c0-28.672-21.845333-51.882667-49.152-51.882666H263.509333c-23.893333 0-43.690667 17.749333-47.786666 41.642666z m-51.882667 20.48l21.845333 23.210667c4.096-6.826667 6.826667-15.018667 7.509334-23.210667H163.84z" fill="#2c2c2c" p-id="21463"></path><path d="M162.474667 289.450667h372.736c17.066667 0 30.72 13.653333 30.72 30.72s-13.653333 30.72-30.72 30.72H162.474667c-17.066667 0-30.72-13.653333-30.72-30.72s13.653333-30.72 30.72-30.72z m559.104 62.122666c-17.066667 0-30.72-13.653333-30.72-30.72s13.653333-30.72 30.72-30.72 30.72 13.653333 30.72 30.72-13.653333 30.72-30.72 30.72zM69.632 434.176h744.789333v62.122667H69.632v-62.122667z" p-id="21464" fill="#2c2c2c"></path><path d="M824.661333 506.538667H59.392V423.936h765.269333v82.602667z m-744.789333-20.48h724.309333v-41.642667H79.872v41.642667z m641.706667-124.245334c-22.528 0-40.96-18.432-40.96-40.96s18.432-40.96 40.96-40.96 40.96 18.432 40.96 40.96-18.432 40.96-40.96 40.96z m0-62.122666c-11.605333 0-20.48 9.557333-20.48 20.48 0 11.605333 9.557333 20.48 20.48 20.48 11.605333 0 20.48-9.557333 20.48-20.48 0-11.605333-8.874667-20.48-20.48-20.48zM535.210667 361.813333H162.474667c-22.528 0-40.96-18.432-40.96-40.96s18.432-40.96 40.96-40.96h372.736c22.528 0 40.96 18.432 40.96 40.96s-18.432 40.96-40.96 40.96z m-372.736-62.122666c-11.605333 0-20.48 9.557333-20.48 20.48 0 11.605333 9.557333 20.48 20.48 20.48h372.736c11.605333 0 20.48-9.557333 20.48-20.48 0-11.605333-9.557333-20.48-20.48-20.48H162.474667z" fill="#2c2c2c" p-id="21465"></path></svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717295270657" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16717" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M419.84 952.32c-10.24 0-15.36 0-25.6-5.12l-225.28-61.44c-46.08-15.36-76.8-61.44-61.44-107.52l168.96-640C286.72 92.16 337.92 61.44 384 76.8l230.4 56.32c46.08 10.24 76.8 61.44 61.44 107.52L506.88 885.76c-5.12 25.6-20.48 40.96-40.96 56.32-15.36 5.12-30.72 10.24-46.08 10.24z m-56.32-803.84h-5.12s-5.12 5.12-5.12 10.24l-174.08 640c0 5.12 0 15.36 10.24 15.36l225.28 61.44h10.24s5.12-5.12 5.12-10.24l174.08-640c0-5.12 0-15.36-10.24-15.36l-230.4-61.44c5.12 0 0 0 0 0z" p-id="16718"></path><path d="M604.16 168.96l-225.28-56.32c-25.6-10.24-56.32 5.12-61.44 35.84l-174.08 640c-5.12 25.6 10.24 56.32 35.84 61.44l225.28 61.44c25.6 5.12 56.32-10.24 61.44-35.84l174.08-640c5.12-30.72-10.24-56.32-35.84-66.56z m-128 348.16c-5.12 15.36-20.48 30.72-35.84 30.72h-10.24l-92.16-25.6c-20.48-5.12-35.84-25.6-25.6-51.2 5.12-15.36 20.48-30.72 35.84-30.72h10.24l92.16 25.6c20.48 10.24 30.72 30.72 25.6 51.2zM512 404.48c-5.12 15.36-20.48 25.6-35.84 25.6h-10.24l-97.28-25.6c-20.48-5.12-30.72-25.6-25.6-46.08 5.12-15.36 20.48-30.72 40.96-30.72h10.24l92.16 25.6c20.48 5.12 30.72 25.6 25.6 51.2z m240.64 532.48c-20.48 0-40.96-15.36-40.96-40.96V215.04c0-20.48 15.36-40.96 40.96-40.96s40.96 15.36 40.96 40.96V896c-5.12 25.6-20.48 40.96-40.96 40.96z m87.04-10.24c-5.12 0-15.36-5.12-15.36-15.36V209.92c0-5.12 5.12-15.36 15.36-15.36s15.36 5.12 15.36 15.36v701.44c-5.12 10.24-10.24 15.36-15.36 15.36z m40.96 0c-5.12 0-15.36-5.12-15.36-15.36V209.92c0-5.12 5.12-15.36 15.36-15.36S896 199.68 896 209.92v701.44c0 10.24-5.12 15.36-15.36 15.36z" p-id="16719"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

1
src/assets/svg/oran.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1720946136639" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4221" xmlns:xlink="http://www.w3.org/1999/xlink" width="128.125" height="128"><path d="M992.090881 443.129l-388.66-404.16C579.320881 13.934 546.998881 0.023 512.424881 0.023s-66.896 13.776-91.006 38.946L32.889881 443.129c-40.138 41.728-34.972 77.759-28.348 92.86 4.769 10.731 20.665 40.005 66.63 40.005l56.961 0 0 310.902c0 70.604 50.736 137.104 122.797 137.104l165.454 0L416.383881 694.949c0-35.236-5.298-54.974 30.733-54.974l130.745 0c36.031 0 30.733 19.605 30.733 54.974L608.594881 1024l165.321 0c72.063 0 122.797-66.499 122.797-137.104L896.712881 575.994l56.961 0c45.966 0 61.862-29.407 66.63-40.005C1026.927881 520.888 1032.094881 484.856 992.090881 443.129L992.090881 443.129zM953.676881 512.013 832.601881 512.013l0 374.884c0 35.237-22.784 72.99-58.815 72.99L672.446881 959.887 672.446881 694.949c0-70.604-22.652-118.956-94.717-118.956L446.985881 575.993c-72.063 0-94.717 48.352-94.717 118.956l0 265.069L250.929881 960.018c-36.031 0-58.816-37.754-58.816-72.99L192.113881 512.145 71.038881 512.145c-1.191 0-2.118-4.371-3.047-4.503 2.253-3.843 6.094-13.646 12.452-20.269l388.66-403.895c11.525-12.187 27.95-19.473 43.848-19.34 15.895-0.132 31.262 7.285 42.919 19.34L944.398881 487.24c6.358 6.623 10.199 16.426 12.32 20.269-0.796 0.132-1.856 4.503-3.047 4.503L953.676881 512.013z" fill="#909399" p-id="4222"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717295208831" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15626" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M179.28 124.787c21.504 0 35.84 14.357 35.84 35.86 0 21.505-14.336 35.86-35.84 35.86-21.524 0-35.86-14.355-35.86-35.86 0-21.503 14.336-35.86 35.86-35.86z m0 358.541c21.504 0 35.84 14.356 35.84 35.86 0 21.524-14.336 35.86-35.84 35.86-21.524 0-35.86-14.336-35.86-35.86 0-21.504 14.336-35.86 35.86-35.86z m0 358.56h143.4c21.525 0 35.86 14.337 35.86 35.84 0 21.525-14.335 35.86-35.86 35.86H179.3c-21.524 0-35.86-14.335-35.86-35.86 0-21.503 14.336-35.84 35.86-35.84z" fill="#2c2c2c" p-id="15627"></path><path d="M888.41 318.163H125.832c-55.678 0.341-85.073-26.102-84.731-81.76V103.745c0.34-55.677 20.82-87.843 76.498-88.204h293.728s6.927-0.261 14.557 0c15.32 0.562 19.195 10.561 19.355 18.512 0.362 17.267 0 8.634 0 26.905 0 2.149-0.803 21.223-22.327 21.745-13.653 0.341-278.187 1.285-278.187 1.285-26.764 0.341-34.133 13.694-34.514 34.495v96.637c0 25.179 7.57 34.656 34.534 34.515h724.691c29.676 0.16 34.676-22.367 34.515-34.535v-96.597c0.924-11.344-4.819-35.58-34.515-35.78 0 0-465.177 0.823-478.77 0-17.83-1.064-22.387-8.071-22.428-20.68-0.06-17.69-0.662-8.574 0-26.183 0.382-9.939-2.61-19.737 22.609-20.28 6.224-0.16 11.284 0 11.284 0H883.21c55.657 0.342 89.59 45.98 89.931 101.658v119.186c0.342 55.657-29.113 82.12-84.73 81.759z m0 351.372H125.832c-55.678 0.342-85.073-26.102-84.731-81.759V455.118c0.34-55.678 20.82-87.843 76.498-88.205h293.728s6.927-0.26 14.557 0c15.32 0.562 19.195 10.562 19.355 18.513 0.362 17.267 0 8.633 0 26.905 0 2.148-0.803 21.223-22.327 21.745-13.653 0.34-278.187 1.285-278.187 1.285-26.764 0.341-34.133 13.693-34.514 34.494v96.638c0 25.178 7.57 34.655 34.534 34.515h724.691c29.676 0.16 34.676-22.368 34.515-34.535v-96.618c0.924-11.344-4.819-35.579-34.515-35.78 0 0-465.177 0.824-478.77 0-17.83-1.064-22.387-8.07-22.428-20.68-0.06-17.69-0.662-8.574 0-26.182 0.382-9.94-2.61-19.738 22.609-20.28 6.224-0.16 11.284 0 11.284 0H883.21c55.657 0.342 89.59 45.98 89.931 101.657v119.186c0.342 55.657-29.113 82.12-84.73 81.76z m0 351.373H125.832c-55.678 0.341-85.073-26.102-84.731-81.76V806.49c0.34-55.677 20.82-87.843 76.498-88.204h293.728s6.927-0.261 14.557 0c15.32 0.562 19.195 10.561 19.355 18.512 0.362 17.268 0 8.634 0 26.905 0 2.149-0.803 21.223-22.327 21.745-13.653 0.341-278.187 1.285-278.187 1.285-26.764 0.342-34.133 13.694-34.514 34.495v96.637c0 25.179 7.57 34.656 34.534 34.515h724.691c29.676 0.16 34.676-22.367 34.515-34.535v-96.617c0.924-11.344-4.819-35.58-34.515-35.78 0 0-465.177 0.823-478.77 0-17.83-1.064-22.387-8.071-22.428-20.68-0.06-17.69-0.662-8.574 0-26.183 0.382-9.939-2.61-19.737 22.609-20.28 6.224-0.16 11.284 0 11.284 0H883.21c55.657 0.342 89.59 45.98 89.931 101.658v119.186c0.342 55.657-29.113 82.12-84.73 81.759z" fill="#2c2c2c" p-id="15628"></path></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717295421269" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23541" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M918.112262 0.279019H282.088283c-57.896458 0-105.050681 43.805995-105.050681 97.656676v53.013624H60.965668C27.762398 150.949319 0.837057 177.874659 0.837057 211.077929v752.653951c0 33.20327 26.925341 60.12861 60.128611 60.12861h736.889373c33.20327 0 60.12861-26.925341 60.12861-60.12861v-33.900817h60.26812c57.896458 0 105.050681-43.805995 105.050681-97.656676V97.935695c-0.13951-53.850681-47.293733-97.656676-105.19019-97.656676zM734.378202 343.751499c0 20.089373-16.183106 36.27248-36.27248 36.272479h-417.133515c-20.089373 0-36.27248-16.183106-36.272479-36.272479s16.183106-36.27248 36.272479-36.27248h417.133515c20.089373 0 36.27248 16.183106 36.27248 36.27248z m0 251.814714c0 20.089373-16.183106 36.27248-36.27248 36.272479h-417.133515c-20.089373 0-36.27248-16.183106-36.272479-36.272479s16.183106-36.27248 36.272479-36.27248h417.133515c20.089373 0 36.27248 16.183106 36.27248 36.27248zM146.345504 879.607629c-20.089373 0-36.27248-16.183106-36.272479-36.272479s16.183106-36.27248 36.272479-36.27248 36.27248 16.183106 36.27248 36.27248c0 19.949864-16.183106 36.27248-36.27248 36.272479z m0-247.768937c-20.089373 0-36.27248-16.183106-36.272479-36.272479s16.183106-36.27248 36.272479-36.27248 36.27248 16.183106 36.27248 36.27248-16.183106 36.27248-36.27248 36.272479z m0-251.814714c-20.089373 0-36.27248-16.183106-36.272479-36.272479s16.183106-36.27248 36.272479-36.27248 36.27248 16.183106 36.27248 36.27248c0 19.949864-16.183106 36.27248-36.27248 36.272479z m551.760218 499.583651h-417.133515c-20.089373 0-36.27248-16.183106-36.272479-36.272479s16.183106-36.27248 36.272479-36.27248h417.133515c20.089373 0 36.27248 16.183106 36.27248 36.27248 0 19.949864-16.183106 36.27248-36.27248 36.272479z m252.512262-47.572752c0 13.671935-14.92752 25.111717-32.505722 25.111717h-60.26812V210.93842c0-33.20327-26.925341-60.12861-60.128611-60.128611H249.582561v-53.013624c0-13.671935 14.92752-25.111717 32.505722-25.111716H917.972752c17.578202 0 32.505722 11.579292 32.505722 25.111716v734.238692z" p-id="23542"></path></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717295441926" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="24673" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M834.021053 560.505263l-56.589474-56.589474c-10.778947-10.778947-26.947368-10.778947-37.726316 0l-245.221052 245.221053c-8.084211 40.421053-13.473684 80.842105-21.557895 118.568421 40.421053-5.389474 80.842105-13.473684 121.263158-21.557895l245.221052-245.221052c8.084211-8.084211 10.778947-21.557895 5.389474-29.642105-5.389474 0-8.084211-5.389474-10.778947-10.778948zM747.789474 673.684211c-10.778947 5.389474-24.252632 5.389474-32.336842-2.694737l-40.421053-40.421053c-5.389474-5.389474-8.084211-16.168421-8.084211-24.252632 2.694737-10.778947 8.084211-18.863158 18.863158-21.557894 10.778947-2.694737 18.863158 0 26.947369 5.389473l37.726316 37.726316c5.389474 5.389474 8.084211 8.084211 8.08421 16.168421 2.694737 10.778947-2.694737 21.557895-10.778947 29.642106z m59.28421-61.978948c-5.389474 8.084211-16.168421 10.778947-26.947368 10.778948-5.389474 0-10.778947-2.694737-16.168421-8.084211L726.231579 576.673684c-2.694737-2.694737-5.389474-8.084211-8.084211-13.473684-2.694737-13.473684 8.084211-29.642105 21.557895-32.336842 8.084211-2.694737 16.168421 0 24.252632 5.389474l32.336842 32.336842 10.778947 10.778947c8.084211 13.473684 8.084211 24.252632 0 32.336842z" p-id="24674"></path><path d="M993.010526 102.4c-5.389474-18.863158-13.473684-37.726316-24.252631-51.2C949.894737 26.947368 925.642105 10.778947 896 2.694737c-10.778947 0-21.557895-2.694737-32.336842-2.694737H146.863158C79.494737 8.084211 28.294737 61.978947 25.6 129.347368v762.610527c2.694737 64.673684 48.505263 118.568421 113.178947 129.347368 5.389474 2.694737 13.473684 2.694737 21.557895 2.694737h706.021053c8.084211 0 16.168421 0 21.557894-2.694737 53.894737-10.778947 97.010526-53.894737 107.789474-107.789474 2.694737-13.473684 2.694737-26.947368 2.694737-43.115789v-727.578947c-2.694737-13.473684-2.694737-26.947368-5.389474-40.421053zM243.873684 223.663158h530.863158c10.778947 0 18.863158 5.389474 24.252632 13.473684 2.694737 5.389474 5.389474 10.778947 5.389473 13.473684 0 13.473684-13.473684 26.947368-26.947368 26.947369H246.568421c-13.473684 0-26.947368-13.473684-26.947368-26.947369s10.778947-26.947368 24.252631-26.947368z m-18.863158 231.747368c5.389474-5.389474 8.084211-8.084211 16.168421-10.778947h296.421053c5.389474 0 10.778947 2.694737 16.168421 5.389474 13.473684 8.084211 16.168421 26.947368 8.084211 37.726315-5.389474 8.084211-13.473684 10.778947-24.252632 10.778948H246.568421c-5.389474 0-10.778947-2.694737-16.168421-5.389474-13.473684-8.084211-16.168421-26.947368-5.389474-37.726316z m164.378948 245.221053c-5.389474 8.084211-13.473684 13.473684-21.557895 13.473684H241.178947c-8.084211 0-16.168421-8.084211-18.863158-13.473684-2.694737-5.389474-2.694737-13.473684-2.694736-18.863158 2.694737-10.778947 13.473684-18.863158 24.252631-21.557895h121.263158c5.389474 0 8.084211 0 13.473684 2.694737 10.778947 8.084211 16.168421 24.252632 10.778948 37.726316z m487.747368-59.284211l-250.610526 250.610527c-5.389474 5.389474-13.473684 8.084211-21.557895 8.08421l-161.68421 26.947369c-13.473684 2.694737-26.947368-5.389474-29.642106-18.863158v-13.473684l29.642106-164.378948c0-5.389474 2.694737-10.778947 5.389473-13.473684 59.284211-59.284211 118.568421-118.568421 177.852632-180.547368l53.894737-53.894737c10.778947-13.473684 24.252632-24.252632 37.726315-32.336842 8.084211-5.389474 18.863158-8.084211 26.947369-8.084211 24.252632-2.694737 48.505263 5.389474 67.368421 21.557895l61.978947 61.978947c10.778947 10.778947 18.863158 21.557895 21.557895 35.031579 8.084211 32.336842 0 61.978947-18.863158 80.842105z" p-id="24675"></path></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717295133873" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12684" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M568.917333 852.48h-277.703111a27.306667 27.306667 0 0 1-27.306666-27.221333 27.335111 27.335111 0 0 1 27.306666-27.278223h71.111111l99.555556-99.356444 0.824889-0.739556a27.818667 27.818667 0 0 1 3.925333-2.986666H158.606222a53.020444 53.020444 0 0 1-52.963555-52.963556V245.703111a53.020444 53.020444 0 0 1 52.963555-52.963555h659.911111a53.191111 53.191111 0 0 1 53.048889 52.963555v266.268445h-259.982222a42.666667 42.666667 0 0 0-42.666667 42.666666v140.060445H495.786667a20.906667 20.906667 0 0 1 4.664889 3.754666 4.835556 4.835556 0 0 1 1.109333 1.194667l67.384889 67.470222v85.333334z m-114.887111-349.866667v52.849778h52.878222V502.613333h79.274667v-52.849777h-79.274667v-26.396445h79.274667v-52.878222h-54.044444l41.728-42.012445-37.262223-37.262222-55.978666 55.978667-56.064-55.978667-37.546667 37.262222 42.012445 42.012445h-54.044445v52.878222h79.274667v26.396445h-79.274667v52.849777z" p-id="12685" fill="#2c2c2c"></path><path d="M909.482667 583.765333A43.150222 43.150222 0 0 0 866.161778 540.444444h-225.479111a43.150222 43.150222 0 0 0-43.320889 43.320889v226.247111A43.150222 43.150222 0 0 0 640.682667 853.333333h226.247111a43.150222 43.150222 0 0 0 43.320889-43.320889z m-81.464889 104.049778v0.369778a19.484444 19.484444 0 0 1-26.652445 0l-34.446222-33.336889v138.496a18.887111 18.887111 0 0 1-37.774222-0.369778v-139.235555l-35.157333 35.185777a18.602667 18.602667 0 0 1-25.912889-26.652444l65.422222-65.422222a18.488889 18.488889 0 0 1 12.970667-5.176889 19.000889 19.000889 0 0 1 12.600888 4.807111c0.369778 0.739556 1.109333 1.109333 1.479112 1.479111a0.369778 0.369778 0 0 0 0.369777 0.369778l0.369778 0.369778 66.275556 63.687111 0.369777 0.369778a17.664 17.664 0 0 1 0.085334 25.059555z" p-id="12686" fill="#2c2c2c"></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717295457045" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="25716" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M170.666667 34.133333h659.911111c34.133333 0 68.266667 17.066667 96.711111 39.822223 22.755556 22.755556 34.133333 51.2 34.133333 85.333333V534.755556c-5.688889 11.377778-22.755556 17.066667-34.133333 11.377777-45.511111-22.755556-91.022222-28.444444-142.222222-28.444444-39.822222 0-79.644444 11.377778-119.466667 34.133333-56.888889 34.133333-102.4 85.333333-125.155556 147.911111-22.755556 68.266667-22.755556 142.222222 5.688889 210.488889 5.688889 17.066667 11.377778 28.444444 22.755556 39.822222l5.688889 5.688889c5.688889 5.688889 5.688889 17.066667 0 22.755556-5.688889 5.688889-11.377778 11.377778-22.755556 11.377778H170.666667c-34.133333 0-62.577778-11.377778-85.333334-39.822223-22.755556-22.755556-39.822222-56.888889-34.133333-91.022222V153.6c0-28.444444 5.688889-51.2 22.755556-73.955556 17.066667-28.444444 51.2-51.2 85.333333-56.888888 0 11.377778 5.688889 11.377778 11.377778 11.377777z m73.955555 210.488889c-11.377778 0-17.066667 11.377778-17.066666 17.066667 0 5.688889 0 17.066667 5.688888 22.755555 5.688889 5.688889 11.377778 5.688889 17.066667 5.688889h506.311111c11.377778-5.688889 17.066667-17.066667 17.066667-28.444444s-11.377778-22.755556-22.755556-22.755556H250.311111c0 5.688889-5.688889 5.688889-5.688889 5.688889m5.688889 204.8c-5.688889 0-11.377778 5.688889-17.066667 11.377778-5.688889 11.377778-5.688889 22.755556 0 28.444444 5.688889 5.688889 11.377778 11.377778 17.066667 11.377778h273.066667c5.688889 0 17.066667-5.688889 22.755555-11.377778 5.688889-5.688889 5.688889-17.066667 0-28.444444-5.688889-5.688889-11.377778-11.377778-22.755555-11.377778H250.311111z" fill="#2c2c2c" p-id="25717"></path><path d="M625.777778 989.866667c-11.377778-5.688889-28.444444-11.377778-45.511111-17.066667 17.066667-39.822222 28.444444-73.955556 39.822222-113.777778l45.511111 17.066667c-11.377778 45.511111-22.755556 85.333333-39.822222 113.777778z m5.688889-159.288889v-170.666667h79.644444l-34.133333-51.2 56.888889-17.066667c17.066667 17.066667 28.444444 39.822222 45.511111 62.577778l-17.066667 5.688889h62.577778c17.066667-28.444444 34.133333-51.2 39.822222-68.266667l56.888889 17.066667c-11.377778 17.066667-22.755556 34.133333-39.822222 51.2h79.644444v170.666667h-159.288889c5.688889 5.688889 22.755556 28.444444 51.2 62.577778l-45.511111 34.133333c-17.066667-28.444444-34.133333-51.2-51.2-68.266667l39.822222-28.444444h-164.977777z m56.888889-125.155556v73.955556h216.177777v-73.955556h-216.177777z m56.888888 307.2c-22.755556 0-34.133333-5.688889-45.511111-17.066666-11.377778-11.377778-17.066667-28.444444-17.066666-51.2v-85.333334h51.2v73.955556c0 22.755556 11.377778 34.133333 34.133333 28.444444h56.888889c11.377778 0 22.755556 0 28.444444-5.688889 5.688889-5.688889 11.377778-11.377778 11.377778-17.066666 0-11.377778 5.688889-22.755556 5.688889-39.822223l51.2 17.066667c-5.688889 28.444444-11.377778 45.511111-11.377778 56.888889-5.688889 17.066667-11.377778 22.755556-22.755555 34.133333-11.377778 5.688889-28.444444 11.377778-45.511111 11.377778h-96.711112z m216.177778-34.133333c-22.755556-39.822222-39.822222-73.955556-56.888889-102.4l45.511111-22.755556c22.755556 39.822222 45.511111 73.955556 62.577778 102.4l-51.2 22.755556z" fill="#2c2c2c" p-id="25718"></path></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,407 @@
<template>
<el-form :model="formData" ref="applyForm" :rules="rules" :label-position="labelPosition">
<el-row>
<el-col :span="24">
<el-form-item :label="label" prop="attachment" label-width="125">
<template v-if="preview&&JSON.stringify(singleFile) !== '{}'&&JSON.stringify(singleFile)!=='null'">
<el-button type="primary" link @click="handleDownload(singleFile)" style="font-size: 16px">
{{ singleFile ? singleFile?.originalFileName : formData.singleFile?.originalFileName }}
</el-button>
<el-button type="danger" link @click="deleteSingleFile(singleFile?singleFile:formData.singleFile,1)">删除
</el-button>
</template>
<template
v-else-if="!preview||JSON.stringify(singleFile) == '{}'||singleFile==null||formData.singleFile==null">
<file-upload @getFile="getAttachment" :multiple="false"
:disabled="isSingleFile" ref="fileUploadRef"/>
<!-- :showFileList="showFileList" @delete="deleteAttachment"-->
<fvTable style="width: 100%;max-height: 80px;" v-if="showSingleTable" height="80" :tableConfig="singleTableConfig"
:data="_singleFileValue" :isSettingCol="false" :pagination="false">
</fvTable>
</template>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="其他文件" label-width="125">
<file-upload @getFile="getOtherFile"/>
<fvTable style="width: 100%;max-height: 162px;" v-if="showTable" height="162" :tableConfig="tableConfig"
:data="allFileList" :isSettingCol="false" :pagination="false">
<template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script setup lang="jsx">
import FileUpload from '@/components/FileUpload.vue'
import {deleteFile, downloadFile} from "@/api/project-demand";
import {ElMessageBox, ElNotification} from "element-plus";
const props = defineProps({
showFileList: {
type: Boolean,
default: false
},
label: {
type: String,
default: '项目附件'
},
showTable: {
type: Boolean,
default: false
},
showSingleTable: {
type: Boolean,
default: false
},
preview: {
type: Boolean,
default: false
},
singleList: {
type: Array,
default: []
},
otherFileList: {
type: Array,
default: []
},
formData: {
type: Object,
default: {}
},
labelPosition: {
type: String,
default: ''
},
tag: {
type: String,
default: ''
}
})
const emit = defineEmits(["getAttachment", "getOtherFile","update:singleList"])
const tableConfig = reactive({
columns: [
{
prop: 'index',
type: 'index',
label: '序号',
align: 'center',
width: '80',
},
{
prop: 'originalFileName',
label: '文件名',
align: 'center',
},
{
prop: 'tag',
label: '标签',
align: 'center'
},
{
prop: 'size',
label: '文件大小',
align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
},
{
prop: 'oper',
label: '操作',
align: 'center',
showOverflowTooltip: false,
currentRender: ({row, index}) => {
let btn = []
btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'})
// if (row.newFile) {
// btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'})
// }
return (
<div style={{width: '100%'}}>
{
btn.map(item => (
<el-button
type={item.type}
onClick={() => item.func()}
link
>
{item.label}
</el-button>
))
}
{
row.newFile || props.preview || !props.preview ?
<popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
// perm={['']}
onDelete={() => handleDelete(row)}/>
: ''
}
</div>
)
}
}
]
})
const singleTableConfig = reactive({
columns: [
{
prop: 'index',
type: 'index',
label: '序号',
align: 'center',
width: '80',
},
{
prop: 'originalFileName',
label: '文件名',
align: 'center',
},
{
prop: 'tag',
label: '标签',
align: 'center'
},
{
prop: 'size',
label: '文件大小',
align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
},
{
prop: 'oper',
label: '操作',
align: 'center',
showOverflowTooltip: false,
currentRender: ({row, index}) => {
let btn = []
btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'})
// if (row.newFile) {
// btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'})
// }
return (
<div style={{width: '100%'}}>
{
btn.map(item => (
<el-button
type={item.type}
onClick={() => item.func()}
link
>
{item.label}
</el-button>
))
}
{
row.newFile || props.preview || !props.preview ?
<popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
// perm={['']}
onDelete={() => handleSingleDelete(row)}/>
: ''
}
</div>
)
}
}
]
})
const fileUploadRef = ref()
const rules = reactive({
attachment: [{required: true, message: '请上传附件', trigger: ['blur', 'change']}],
})
const applyForm = ref()
const singleFile = ref(props.formData.singleFile)
const isSingleFile = ref(false)
const allFileList = ref([])
const deleteFileVal = ref({})
const singleFileList = ref([])
if(localStorage.getItem('singleFile')){
singleFile.value = JSON.parse(localStorage.getItem('singleFile'))
}
const _singleFileValue = computed({
get() {
return props.singleList;
},
set(value) {
emit('update:singleList', value)
}
})
// console.log('_singleFileValue',_singleFileValue.value)
const _otherFileListValue = computed({
get() {
return props.otherFileList;
},
set(value) {
emit('update:otherFileList', value)
}
})
if(_otherFileListValue.value&&_otherFileListValue.value.length>0){
_otherFileListValue.value.forEach(item=>{
allFileList.value.push(item)
})
}
watch(() => props.showSingleTable, (newVal) => {
props.showSingleTable = newVal
}, {deep: true})
watch(() => props.formData.fileList, (newVal) => {
if (props.preview) {
newVal?.forEach(item => {
allFileList.value.push(item)
})
}
}, {immediate: true})
// watch(() => props.otherFileList, (newVal) => {
// props.otherFileList=newVal
// if (props.preview) {
// console.log('newotherFileList', newVal,props.preview,props.formData.fileList)
// if (props.formData.fileList === null || props.formData.fileList?.length === 0) {
// allFileList.value = newVal
// } else {
// console.log('props.otherFileList',props.otherFileList)
// // props.otherFileList?.forEach(item => {
// // allFileList.value.push(item)
// // })
// }
// } else {
// allFileList.value = newVal
// }
// }, {deep: true})
watch(() => props.showTable, (newVal) => {
props.showTable = newVal
}, {deep: true})
// watch(() => props.singleList, (newVal) => {
// console.log('singleFile', newVal)
// singleFileList.value = newVal
// }, {deep: true})
watch(() => props.formData.singleFile, (newVal) => {
// console.log('singleFile', newVal)
singleFile.value = newVal
props.formData.singleFile=newVal
}, {deep: true})
watch(() => isSingleFile.value, (newVal) => {
isSingleFile.value = newVal
}, {deep: true})
watch(() => singleFile.value, (newVal) => {
singleFile.value = newVal
}, {deep: true})
const handleDelete = (row, type) => {
deleteFile(row.fileId).then(res => {
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
if (type === 'single') {
_singleFileValue.value.splice(_singleFileValue.value.findIndex((item) => item.fileId === row.fileId), 1);
isSingleFile.value = false
} else {
allFileList.value.splice(allFileList.value.findIndex((item) => item.fileId === row.fileId), 1);
}
}
});
}
const handleSingleDelete = (row) => {
// console.log('row',row)
// fileUploadRef.value.handleRemove(deleteFileVal.value.id)
handleDelete(row, 'single')
}
const getAttachment = (val) => {
// console.log('getAttachment', val)
isSingleFile.value = true
// deleteFileVal.value=val
emit('getAttachment', val)
}
const compositeParam = (item) => {
return {
fileId: item.id,
size: item.size,
originalFileName: item.originalFilename,
fileType: item.fileType,
url: item.url,
newFile: true,
tag: props.tag
}
}
const getOtherFile = (val) => {
if (props.preview) {
allFileList.value.push(compositeParam(val))
} else {
allFileList.value = _otherFileListValue.value
}
emit('getOtherFile', val)
}
const deleteAttachment = (val) => {
deleteFile(val).then(res => {
if (res.code === 1000) {
ElNotification({
title: '提示',
message: "删除成功",
type: 'success'
})
isSingleFile.value = false
singleFile.value = null
}
});
}
const deleteSingleFile = (row, type) => {
ElMessageBox.confirm(`确认删除名称为${row.originalFileName}的文件吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteFile(row.fileId).then(res => {
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
isSingleFile.value = false
if (type === 1) {
singleFile.value = null
} else {
props.otherFileList.splice(props.otherFileList.findIndex((item) => item.fileId === row.fileId), 1);
}
}
});
}).catch(() => {
ElNotification({
title: '提示',
message: "用户取消删除! ",
type: 'warning'
})
})
}
const handleDownload = (row) => {
downloadFile(row.fileId).then(res => {
const blob = new Blob([res])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = row.originalFileName
a.click()
})
}
defineExpose({
validate() {
return applyForm.value.validate()
},
clearValidate() {
return applyForm.value.clearValidate()
},
allFileList,
singleFile,
isSingleFile
})
</script>
<style scoped>
:deep(.el-table--fit ) {
height: 300px !important;
}
</style>

View File

@@ -0,0 +1,111 @@
<template>
<el-button color="#DED0B2" style="float: right;margin: 0 10px 10px 0" @click="exportExcelHandler">导出</el-button>
<el-table ref="table" :data="tableData" style="width: 100%;height: 479px" :show-summary="true" border
:summary-method="getSummaries" v-loading="loading" :header-cell-style="{background:'#f5f7fa'}">
<el-table-column type="index" label="序号" align="center" width="60"/>
<el-table-column prop="projectName" label="项目名称" align="center"/>
<el-table-column prop="projectCost" label="费用性质" align="center">
<template #default="scope">
<div v-if="scope.row.projectCost !== null">
<Tag dictType="project_cost" :value="scope.row.projectCost"/>
</div>
<div v-else>--</div>
</template>
</el-table-column>
<el-table-column prop="researchStage" label="研发阶段" align="center">
<template #default="scope">
<div v-if="scope.row.researchStage !== null && scope.row.researchStage !== null && scope.row.researchStage !== undefined">
<el-tag effect="plain">{{scope.row.researchStage==1?'开发阶段':'研究阶段'}}</el-tag>
</div>
<div v-else>--</div>
</template>
</el-table-column>
<el-table-column prop="afterTax" label="分摊金额" align="center">
<template #default="scope">
<div v-if="scope.row.afterTax !== null">
<!-- {{ toThousands(scope.row.afterTax) }}-->
{{ scope.row.afterTax }}
</div>
</template>
</el-table-column>
</el-table>
<!-- <Tag dictType="research_stage" :value="scope.row.researchStage"/>-->
</template>
<script setup>
import {getAllocationSummaryDetails} from "@/api/expense-manage";
import {shareExportExcel} from "@/api/expense-manage";
const props = defineProps({
allocationName :{
type: String,
default: ''
}
})
const tableData = ref()
const loading = ref(false)
const table = ref()
const route = useRoute()
const getSummaries = (param) => {
const {columns, data} = param
const sums = []
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '小计'
} else if (index === 4) {
const values = data.map((item) => Number(item[column.property]))
if (!values.every((value) => Number.isNaN(value))) {
sums[index] = `${values.reduce((prev, curr) => {
const value = Number(curr)
if (!Number.isNaN(value)) {
return prev + curr
} else {
return prev
}
}, 0)}`
sums[index] = parseFloat(sums[index]).toFixed(2)
// sums[index] = toThousands(sums[index])
} else {
sums[index] = '-'
}
}
})
return sums
}
// const exportTable = () => {
// const $e = table.value.$el
// let $table = $e.querySelector('.el-table__fixed')
// if (!$table) {
// $table = $e
// }
// exportExcel($table, (5 + (Object.keys(tableData.value[0]).length - 5) * 5), "四川省国有资产经营投资管理有限责任公司科技创新项目费用分摊表", 2)
// }
const exportExcelHandler = () => {
shareExportExcel(route.query.id).then(res => {
console.log(res)
let fileName = `科技创新项目费用分摊表-${props.allocationName}.zip`
const blob = new Blob([res.data])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = fileName
a.click()
})
}
const init = () => {
loading.value = true
let params = {
allocationId: route.query.id
}
getAllocationSummaryDetails(params).then(res => {
tableData.value = res.data
loading.value = false
})
}
init()
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,446 @@
<template>
<div v-loading="loading">
<el-row v-if="type==='execute'">
<el-col :span="24">
<baseTitle :title="'附件信息'"></baseTitle>
</el-col>
<el-form :model="attachmentParam" inline style="margin-top: 15px">
<el-form-item label="标签" prop="tag">
<el-select v-model="attachmentParam.tag" placeholder="请选择标签" clearable filterable style="width: 300px">
<el-option
v-for="item in tagsOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleSearchImplementationFileList" color="#DED0B2">搜索</el-button>
</el-form-item>
</el-form>
<fvTable style="width: 100%;min-height:162px;max-height: 162px" v-if="showAttachmentTable" height="162"
:tableConfig="tableConfig"
:data="otherAttachmentList" :isSettingCol="false" :pagination="false">
<template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</el-row>
<baseTitle v-if="type!='phase'" :title="getTagName(type)+getTitleInfo(data.taskId)"></baseTitle>
<fvForm :schema="schema" @getInstance="(e)=>form = e"></fvForm>
<el-form :model="formData" label-width="auto" style="margin-top: -15px">
<file-component :title="getTagName(type)+'附件'" :tag="getTagName(type)"
v-model:value="formData.fileList" :processViewer="processViewer"
:file-list-show="fileListShow"/>
</el-form>
<div v-if="data.taskId">
<baseTitle title="审核意见"></baseTitle>
<el-form-item prop="_value">
<el-input
v-model="_value"
:rows="3"
type="textarea"
placeholder="请输入审核意见"
/>
</el-form-item>
</div>
<div class="approval-record">
<div class="approval-title" style="margin-top: -15px">
<baseTitle title="审批记录"></baseTitle>
<div class="diagram">
<div class="base-title">流程图</div>
<el-switch
v-model="changeDiagram"
style="--el-switch-on-color:#BEA266 ; --el-switch-off-color:#cecdcd"
/>
</div>
</div>
<div class="process">
<operation-render v-if="processViewer && data.operationList && data.operationList.length > 0&&!changeDiagram"
:operation-list="data.operationList"
:state="data.state"/>
<process-diagram-viewer v-if="processViewer&&changeDiagram" :id-name="idName?idName:type"/>
</div>
</div>
</div>
</template>
<script setup lang="jsx">
import OperationRender from '@/views/workflow/common/OperationRender.vue'
import ProcessDiagramViewer from '@/views/workflow/common/ProcessDiagramViewer.vue';
import {ElLoading, ElNotification} from 'element-plus';
import {downloadFile} from "@/api/project-demand";
import {searchImplementationFileList} from "@/api/project-manage/attachment";
import {getTags} from "@/api/project-manage";
const attachmentParam = reactive({
tag: ''
})
const tagsOption = ref([])
const uploadState = ref(false)
const showAttachmentTable = ref(true)
const otherAttachmentList = ref([])
const tableConfig = reactive({
columns: [
{
prop: 'index',
type: 'index',
label: '序号',
align: 'center',
width: '80',
},
{
prop: 'originalFileName',
label: '文件名',
align: 'center',
},
{
prop: 'tag',
label: '标签',
align: 'center'
},
{
prop: 'size',
label: '文件大小',
align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
},
{
prop: 'oper',
label: '操作',
align: 'center',
showOverflowTooltip: false,
currentRender: ({row, index}) => {
return (
<div>
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
</div>
)
}
}
]
})
const changeDiagram = ref(false)
const props = defineProps({
formData: {
type: Object,
default: {}
},
data: {
type: Object,
default: {}
},
processViewer: {
type: Boolean,
default: false
},
companyOption: {
type: Array,
default: []
},
fileListShow: {
type: String,
default: 'READ'
},
// approval 立项, execute 实施, 归档 archivist
type: {
type: String,
default: 'approval'
},
loading: {
type: Boolean,
default: false
},
value: {
type: String,
default: ''
},
idName: {
type: String,
default: ''
}
})
const form = ref()
const schema = computed(() => {
let arr
if (props.type == 'approval') {
arr = [
{
label: '项目负责人',
prop: 'projectChargePerson',
colProps: {
span: 24
},
component: () => (
<div>
{
props.formData.projectChargePerson ?
<span>{props.formData.projectChargePerson.name} </span>
: <span>{'--'}</span>
}
</div>
)
},
{
label: '项目成员',
prop: 'projectPersonList',
colProps: {
span: 24
},
component: () => (
<div>
{
props.formData.projectPersonList ? props.formData.projectPersonList.map(item => {
return <span>{item.name} </span>
}) : <span>{'--'}</span>
}
</div>
)
},
{
label: '前置流程',
prop: 'preProcess',
colProps: {
span: 24
},
component: () => (
<div>
{
props.formData.preProcess ? props.formData.preProcess.map(item => {
return <span><a target="_blank" style={{color: '#409EFF', cursor: 'pointer'}}
href={props.formData.preProcessBaseUrl + item.requestId}>{item.requestName}</a> </span>
}) : <span>{'--'}</span>
}
</div>
)
},
{
label: '项目立项附件',
prop: 'singleFile',
colProps: {
span: 24
},
component: () => (
<div>
{
props.formData.singleFile?.originalFileName ?
<span
style={{color: '#409EFF', cursor: 'pointer'}}
onClick={() => handleDownload(props.formData.singleFile)}
>
{props.formData.singleFile?.originalFileName}
</span> :
<span>{'--'}</span>
}
</div>
)
},
]
} else if (props.type == 'execute') {
arr = [
{
label: '前置流程',
prop: 'preProcess',
colProps: {
span: 24
},
component: () => (
<div>
{
props.formData.preProcess ? props.formData.preProcess.map(item => {
return <span><a target="_blank" style={{color: '#409EFF', cursor: 'pointer'}}
href={props.formData.preProcessBaseUrl + item.requestId}>{item.requestName}</a> </span>
}) : <span>{'--'}</span>
}
</div>
)
},
{
label: '项目验收附件',
prop: 'singleFile',
colProps: {
span: 24
},
component: () => (
<div>
{
props.formData.singleFile?.originalFileName ?
<span
style={{color: '#409EFF', cursor: 'pointer'}}
onClick={() => handleDownload(props.formData.singleFile)}
>
{props.formData.singleFile?.originalFileName}
</span> :
<span>{'--'}</span>
}
</div>
)
},
]
} else if (props.type == 'archivist') {
arr = [
{
label: '项目归档附件',
prop: 'singleFile',
colProps: {
span: 24
},
component: () => (
<div>
{
props.formData.singleFile?.originalFileName ?
<span
style={{color: '#409EFF', cursor: 'pointer'}}
onClick={() => handleDownload(props.formData.singleFile)}
>
{props.formData.singleFile?.originalFileName}
</span> :
<span>{'--'}</span>
}
</div>
)
},
]
} else if (props.type == 'phase') {
arr = [
{
label: '阶段变更附件',
prop: 'singleFile',
colProps: {
span: 24
},
component: () => (
<div>
{
props.formData.singleFile?.originalFileName ?
<span
style={{color: '#409EFF', cursor: 'pointer'}}
onClick={() => handleDownload(props.formData.singleFile)}
>
{props.formData.singleFile?.originalFileName}
</span> :
<span>{'--'}</span>
}
</div>
)
},
]
}
return arr
})
const route = useRoute()
const emit = defineEmits(['update:value'])
const _value = computed({
get() {
return props.value;
},
set(val) {
emit("update:value", val);
}
})
const getTagsOption = () => {
if (!route.query.projectId) return
getTags(route.query.projectId).then(res => {
if (res.code === 1000) {
tagsOption.value = res.data
} else {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
})
}
const handleSearchImplementationFileList = () => {
let params = {
targetId: route.query.projectId,
targetState: "40"
}
if (attachmentParam.tag) {
tagsOption.value.forEach(item => {
if (item.value === attachmentParam.tag) {
attachmentParam.tag = item.label
}
})
params.tag = attachmentParam.tag
}
searchImplementationFileList(params).then(res => {
showAttachmentTable.value = false
if (res.code === 1000) {
otherAttachmentList.value = res.data.fileList
uploadState.value = res.data.upload
nextTick(() => {
showAttachmentTable.value = true
})
} else {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
})
}
const getTitleInfo = (taskId) => {
if (taskId) {
return '审批'
} else {
return '信息'
}
}
const getTagName = (type) => {
switch (type) {
case 'approval':
return '项目立项'
case 'execute':
return '项目验收'
case 'archivist':
return '项目归档'
case 'phase':
return '阶段变更'
}
}
const handleDownload = (row) => {
const loading = ElLoading.service({fullscreen: true})
downloadFile(row.fileId).then(res => {
const blob = new Blob([res])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = row.originalFileName
a.click()
loading.close()
})
}
watchEffect(() => {
Object.keys(props.formData).length && (form.value?.setValues(props.formData))
})
onMounted(() => {
// if (props.formData.mode == 'view' && props.type == 'execute') {
// handleSearchImplementationFileList()
// getTagsOption()
// }
})
if (props.formData.mode == 'view' && props.type == 'execute') {
handleSearchImplementationFileList()
getTagsOption()
}
watch(() => props.loading, (newVal) => {
props.loading = newVal
}, {deep: true})
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,194 @@
<template>
<div v-loading="loading">
<baseTitle title="需求征集信息" v-if="type!=='singleDetail'"></baseTitle>
<el-form :model="formData">
<el-row>
<el-col :span="6" v-if="type==='singleDetail'">
<el-form-item label="征集名称">
<span>{{ formData.requirementName }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="征集类型">
<span>{{ formData.collectType }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="需求上报截止时间">
<span>{{ formData.deadline }}</span>
</el-form-item>
</el-col>
<el-col :span="6" v-if="formData.isSpecialFund">
<el-form-item label="专项资金名称">
<span>{{ formData.specialFund }}</span>
</el-form-item>
</el-col>
<el-col :span="24" v-if="type==='singleDetail'">
<el-form-item label="征集公司">
<span :class="showExpendClass(showMoreCompany,formData.companyIds)">{{
getCompanyName(formData.companyIds)
}}</span>
<div style="color: #2a99ff;text-align: center;width: 100%;font-size: 15px;cursor: pointer"
@click="handleExpend">{{ showExpendText }}
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<baseTitle title="征集说明"></baseTitle>
<el-form-item>
<el-card style="width: 100%">
<div v-html="formData.collectExplain">
</div>
</el-card>
</el-form-item>
</el-col>
<baseTitle v-if="fileListShow === 'READ' || fileListShow === 'EDIT'" title="附件列表"></baseTitle>
<el-col :span="24">
<file-component title="" tag="需求征集"
v-model:value="formData.fileList" :processViewer="processViewer"
:file-list-show="fileListShow"/>
</el-col>
<el-col :span="24">
<div v-if="data.taskId">
<baseTitle title="审核意见"></baseTitle>
<el-form-item prop="_value">
<el-input
v-model="_value"
:rows="3"
type="textarea"
placeholder="请输入审核意见"
/>
</el-form-item>
</div>
</el-col>
</el-row>
<div class="approval-record">
<div class="approval-title">
<baseTitle title="审批记录"></baseTitle>
<div class="diagram">
<div class="base-title">流程图</div>
<el-switch
v-model="changeDiagram"
style="--el-switch-on-color:#BEA266; --el-switch-off-color:#cecdcd"
/>
</div>
</div>
<div class="process">
<operation-render v-if="processViewer && data.operationList && data.operationList.length > 0&&!changeDiagram"
:operation-list="data.operationList"
:state="data.state"/>
<process-diagram-viewer v-if="processViewer&&changeDiagram" id-name="collectionProcess"/>
</div>
</div>
</el-form>
</div>
</template>
<script setup lang="jsx">
import OperationRender from '@/views/workflow/common/OperationRender.vue'
import ProcessDiagramViewer from '@/views/workflow/common/ProcessDiagramViewer.vue'
import {downloadFile} from "@/api/project-demand";
const emit = defineEmits(['update:value'])
const showExpendText = ref('')
const showMoreCompany = ref(false)
const props = defineProps({
formData: {
type: Array,
default: []
},
data: {
type: Array,
default: []
},
processViewer: {
type: Boolean,
default: false
},
companyOption: {
type: Array,
default: []
},
loading: {
type: Boolean,
default: false
},
fileListShow: {
type: String,
default: ''
},
type: {
type: String,
default: ''
},
value: {
type: String,
default: ''
}
})
const changeDiagram = ref(false)
const _value = computed({
get() {
return props.value;
},
set(val) {
emit("update:value", val);
}
})
const getCompanyName = (data) => {
if (data) {
return data.join('')
}
}
const handleExpend = () => {
showMoreCompany.value = !showMoreCompany.value;
showExpendClass(showMoreCompany.value, props.formData.companyIds)
}
const showExpendClass = (showMoreCompany, data) => {
if (!showMoreCompany) {
if (data && data.length > 14) {
showExpendText.value = '展开'
return 'company-style'
}
} else {
showExpendText.value = '收缩'
return ''
}
}
const handleDownload = (row) => {
downloadFile(row.fileId).then(res => {
const blob = new Blob([res])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = row.originalFileName
a.click()
})
}
watch(() => props.loading, (newVal) => {
props.loading = newVal
}, {deep: true})
watch(() => props.processViewer, (newVal) => {
props.processViewer = newVal
}, {deep: true})
</script>
<style scoped lang="scss">
:deep(.el-empty__description) {
margin-top: 0;
}
.company-style {
//width: 98%;
min-height: 30px;
max-height: 60px;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
display: -webkit-box;
-webkit-box-orient: vertical;
}
</style>

View File

@@ -0,0 +1,406 @@
<template>
<el-dialog custom-class="custom-dialog" class="border" :border="false" width="1000px" style="height: 676px"
:title="title" :show-close="false" :visible.sync="visible" v-model="visible" append-to-body :close-on-click-modal="true" @close="closeDialog">
<div class="picker">
<div class="candidate" v-loading="loading">
<el-input v-model="filterText"
clearable placeholder="输入公司进行搜索">
<template #append>
<el-button @click="getList()">搜索</el-button>
</template>
</el-input>
<fvCheckbox style="margin-left: 10px" :options="checkOptions" v-model="checkList" @change="checkBoxChange"/>
<!-- 人员选择 -->
<el-empty :image-size="100" description="似乎没有数据" v-show="dataList.length === 0"/>
<el-scrollbar style="height:87%;">
<div class="tree">
<el-tree :data="dataList" ref="tree" :props="defaultProps" empty-text="" node-key="value"
:show-checkbox="showCheckbox" highlight-current default-expand-all
:default-checked-keys="defaultChecked" :disabled="disabled"
:check-strictly="!checkStrictly" @node-click="(node,check)=>handle(node,check)"
@check-change="handleChange" :filter-node-method="filterNode">
<template #default="{ node, data }">
<div class="tree-node">
<div style="display: flex;align-items: center;padding: 3px 0">
{{ node.label }}
</div>
</div>
</template>
</el-tree>
</div>
</el-scrollbar>
</div>
<div class="selected">
<div class="count">
<span>已选 {{ selectList.length }} 项</span>
<span @click="clearSelected">清空</span>
</div>
<div class="org-items">
<el-empty :image-size="100" description="请点击左侧列表选择数据" v-show="selectList.length === 0"/>
<div v-for="(selectItem, selectIndex) in selectList" :key="selectIndex" class="org-item">
{{ selectItem.label }}
<el-icon @click="noSelected(selectItem)" size="20" style="margin-left: 10px;cursor: pointer;">
<CircleClose/>
</el-icon>
</div>
</div>
</div>
</div>
<div class="footer">
<el-button size="mini" @click="visible = false">取 消</el-button>
<el-button size="mini" color="#DED0B2" @click="selectConfirm">确 定</el-button>
</div>
</el-dialog>
</template>
<script setup>
import {ElMessageBox} from "element-plus";
import {getSubCompOpt} from "@/api/user/user";
const checkList = ref(['1'])
const checkStrictly = ref(false)
const isExpand = ref('展开')
const expandedKeys = ref(['-1']);
const checkOptions = ref([
{
label: isExpand.value,
value: '1'
},
// {
// label: '父子联动',
// value: '2'
// },
])
const props = defineProps({
value: {
type: Array,
default: () => {
return [];
}
},
multiple: { //是否多选
default: true,
type: Boolean
},
showCheckbox: { //是否显示左侧选择框
default: true,
type: Boolean
}
});
let selectItem = reactive({
type: -1,
value: "0"
});
const visible = ref(false);
const loading = ref(false);
const title = ref("请选择");
const selectList = ref([]);
const filterText = ref("");
const dataList = ref([]);
const defaultChecked = ref([]);
const tree = ref([]);
const defaultProps = {
value: "value",
label: "label",
children: "children",
disabled: "disabled",
};
const emit = defineEmits(['update:modelValue'])
const _value = computed({
get() {
return props.value;
},
set(value) {
emit('update:modelValue', value)
}
});
watch(() => filterText.value, (newVal) => {
tree.value.filter(newVal);
});
const closeDialog=()=>{
console.log('关闭')
visible.value=false
filterText.value=''
}
const checkBoxChange = (val) => {
checkStrictly.value = val.includes('2')
let nodes = tree.value.store.nodesMap
if (val.includes('1')) {
for (const node in nodes) {
nodes[node].expanded = true;
}
isExpand.value = '折叠'
} else {
for (const node in nodes) {
nodes[node].expanded = false;
}
isExpand.value = '展开'
}
}
const getList = () => {
getSubCompOpt().then(res => {
dataList.value = [
{
label: "所有公司",
value: -1,
},
...res.data
]
});
};
//通过关键字过滤树节点
const filterNode = (value, data) => {
//通过关键字过滤树节点
if (!value) return true;
return data.label.indexOf(value) !== -1;
};
//用于用户选择
const show = () => {
//用于弹开部门选择
visible.value = true;
selectList.value = _value.value
defaultChecked.value = _value.value.map(item => item.value)
getList()
};
const updateTreeCheck = (list, flag) => {
list.forEach(item => {
if (item.value !== -1) {
tree.value.setChecked(item, flag)
if (item.children !== undefined) {
updateTreeCheck(item.children, flag)
}
}
})
}
const handleChange = (data, checked) => {
if (data.value == -1) {
if(checked){
updateTreeCheck(dataList.value, false)
tree.value.setChecked(data,true);
}
}
if(tree.value.getCheckedKeys().length>1&&tree.value.getCheckedKeys().indexOf(-1)!==-1){
tree.value.setChecked(-1,false);
}
// 左侧有选择框 + 多选
if (props.multiple) {
//不添加重复的数据到右边
for (let i = 0; i < selectList.value.length; i++) {
if (selectList.value[i].value === data.value) {
selectList.value.splice(i, 1);
break;
}
}
if (checked) {
// if (data.children === undefined) {
selectList.value.push(data);
// }
} else if (data === "1") {
tree.value.setCheckedKeys([]);
selectList.value = [];
}
} else {// 左侧有选择框 + 单选
//不添加重复的数据到右边
for (let i = 0; i < selectList.value.length; i++) {
if (selectList.value[i].value === data.value) {
selectList.value.splice(i, 1);
break;
}
}
if (checked) {
tree.value.setCheckedNodes([data]);
selectList.value = [data];
} else if (data === "1") {
selectList.value = [];
tree.value.setCheckedKeys([]);
}
}
};
const handle = (node, check) => {
if (check.isLeaf !== false) {
if (props.multiple) {
//不添加重复的数据到右边
for (let i = 0; i < selectList.value.length; i++) {
if (selectList.value[i].value === node.value) {
selectList.value.splice(i, 1);
break;
}
}
check.checked = true;
selectList.value.push(node);
} else {
check.checked = true;
selectList.value = [node];
}
}
// _value.value = selectList.value
};
const noSelected = (selectItem) => {
//左侧无选择框时,右侧显示×
for (let i = 0; i < selectList.value.length; i++) {
if (selectList.value[i].value === selectItem.value) {
tree.value.setChecked(selectList.value[i].value, false);
selectList.value.splice(i, 1);
break;
}
}
if (props.showCheckbox) {
// 左侧有选择框 + 单选
if (props.multiple === false) {
tree.value.setCheckedKeys([]);
}
}
};
const clearSelected = () => {
//清空
ElMessageBox.confirm("您确定要清空已选中的项?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
if (!props.showCheckbox) {
selectList.value = [];
} else {
handleChange("1");
}
});
};
const selectConfirm = () => {
//确定按钮
emit("ok", selectList.value);
dataList.value = []
visible.value = false;
};
defineExpose({
show
});
getList()
</script>
<style lang="scss" scoped>
$containWidth: 480px;
:deep(.tree) {
.el-tree-node__content {
height: 34px;
.tree-node {
font-size: 18px;
}
}
//.el-tree-node {
// .is-leaf + .el-checkbox .el-checkbox__inner {
// display: inline-block;
// }
//
// .el-checkbox .el-checkbox__inner {
// display: none;
// }
//}
}
.footer {
float: right;
margin-top: 10px;
}
.picker {
height: 560px;
position: relative;
text-align: left;
.candidate {
position: absolute;
display: block;
width: $containWidth;
height: 100%;
border: 1px solid #e8e8e8;
:deep(.el-input) {
height: 40px;
.el-input__inner, .el-input-group__append {
font-size: 16px;
}
}
}
.selected {
right: 0;
top: 0;
position: absolute;
display: inline-block;
width: 450px;
height: 100%;
border: 1px solid #e8e8e8;
.count {
width: 100%;
padding: 10px;
display: inline-block;
border-bottom: 1px solid #e8e8e8;
margin-bottom: 5px;
font-size: 16px;
> span:nth-child(2) {
float: right;
color: #c75450;
cursor: pointer;
margin-left: 10px;
}
}
.org-items {
overflow-y: auto;
height: 90%;
.el-icon-close {
position: absolute;
right: 5px;
cursor: pointer;
font-size: larger;
}
.org-item {
margin: 0 5px;
border-radius: 5px;
position: relative;
padding: 7px 5px;
display: flex;
align-items: center;
font-size: 16px;
&:hover {
background: #f1f1f1;
}
> span {
margin-left: 5px;
}
}
}
}
}
.el-scrollbar .el-scrollbar__wrap {
overflow-x: hidden;
}
::-webkit-scrollbar {
float: right;
width: 4px;
height: 4px;
background-color: white;
}
::-webkit-scrollbar-thumb {
border-radius: 16px;
background-color: #efefef;
}
</style>

View File

@@ -0,0 +1,255 @@
<template>
<el-button color="#DED0B2" style="float: right;margin: 0 10px 10px 0" @click="exportTable">导出</el-button>
<el-table ref="reportTable" :data="tableData" style="width: 100%;height: 479px"
:span-method="objectSpanMethod" v-loading="loading">
<el-table-column label="四川省国有资产经营投资管理有限责任公司科技创新项目人工成本分摊明细表" align="center">
<el-table-column v-for="column in columnInfo" :prop="column.prop" :label="column.label" align="center"
:fixed="(!column.children) ? ((column.prop === 'totalSeparation' || column.prop === 'totalSeparationCost') ? 'right' : 'left') : false"
:width="(column.prop === 'totalSeparation' || column.prop === 'totalSeparationCost') ? 160:130">
<template #default="scope">
<template v-if="column.children">
<el-table-column v-for="childColumn in column.children"
:prop="column.prop + '.'+ childColumn.prop"
:label="childColumn.label"
:width="childColumn.prop === 'subtotal' ? 160 : 130">
<template #default="columnScope">
<template v-if="(tableData.length -1) !== columnScope.$index">
{{
columnScope.row[column.prop][childColumn.prop] ? columnScope.row[column.prop][childColumn.prop] : '/'
}}
</template>
<template v-else>
{{ columnScope.row[column.prop][childColumn.prop] }}
</template>
</template>
</el-table-column>
</template>
<template v-else>
<!--分摊金额合计与分摊金额总计计算-->
<template
v-if="(column.prop === 'totalSeparation' || column.prop === 'totalSeparationCost') && (tableData.length -1) !== scope.$index">
{{ getTotalSeparation(scope.row, column.prop) }}
</template>
<template
v-else-if="(tableData.length -1) === scope.$index && (column.prop === 'totalSeparation' || column.prop === 'totalSeparationCost')">
{{ getTotalSummary(scope.row, column.prop) }}
</template>
<template v-else>
{{ scope.row[column.prop] }}
</template>
</template>
</template>
</el-table-column>
</el-table-column>
</el-table>
</template>
<script setup lang="jsx">
import {getResearchUser, getAllocationDetails} from "@/api/expense-manage";
import {exportExcel} from "@/utils/export-excel";
import {ElNotification} from "element-plus";
const route = useRoute()
const tableIns = ref()
const reportTable = ref({});
const columnInfo = ref([])
const monthConcat = new Map()
const tableData = ref([])
const loading = ref(false)
const researchOptions = ref([])
const objectSpanMethod = ({row, column, rowIndex, columnIndex}) => {
if (columnIndex === 0) {
if (monthConcat.has(rowIndex)) {
return {
rowspan: monthConcat.get(rowIndex),
colspan: 1,
}
} else {
return {
rowspan: 0,
colspan: 0,
}
}
} else {
let length = Object.keys(row).length
// console.log(length)
if (length > 5) {
if (concatColumn(columnIndex, length, rowIndex)) {
if (rowIndex % 5 === 0) {
return {
rowspan: 5,
colspan: 1,
}
} else {
return {
rowspan: 0,
colspan: 0,
}
}
}
}
}
}
const getTotalSeparation = (row, prop) => {
let totalSeparation = 0.00
for (let key of Object.keys(row)) {
if (key.startsWith('personInfo')) {
let value = prop === 'totalSeparation' ? (row[key].separationAmount ? row[key].separationAmount : 0) : row[key].subtotal
if ("/" !== value) {
try {
totalSeparation += parseFloat(value)
} catch (e) {
}
}
}
}
if (totalSeparation !== 0) {
return totalSeparation.toFixed(2);
} else {
return "/"
}
}
const getTotalSummary = (row, prop) => {
let key;
if (prop === 'totalSeparation') {
key = 'separationAmount'
} else {
key = 'subtotal'
}
let result = 0
for (const rowKey of Object.keys(row)) {
if (rowKey.startsWith('personInfo')) {
let value = row[rowKey][key]
if (value && "/" !== value) {
try {
result += parseFloat(value)
} catch (e) {
}
}
}
}
return result.toFixed(2);
}
const concatColumn = (columnIndex, length, rowIndex) => {
if (rowIndex === tableData.value.length - 1) {
return false
}
let columnLength = 5 + (length - 5) * 5
if (columnIndex === 1
|| columnIndex === columnLength - 1) {
return true;
}
for (let i = 0; i < length - 5; i++) {
if (columnIndex === 4 + (i * 5)
|| columnIndex === 5 + (i * 5)
|| columnIndex === 7 + (i * 5)) {
return true
}
}
return false
}
const init = () => {
loading.value = true
getAllocationDetails(route.query.id).then(res => {
if (res.code !== 1000) {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
columnInfo.value = res.data.columns
let tableDataLet = res.data.tableData;
let personInfoKey = []
columnInfo.value.forEach(item => {
if (item.prop.startsWith('personInfo')) {
personInfoKey.push(item.prop)
}
})
tableData.value = []
let rowIndex = 0;
let summary = {
month: "",
salaryType: '',
projectName: "合计",
totalSeparation: 10,
totalSeparationCost: 10
}
for (const key of personInfoKey) {
summary[key] = {
researchDuration: "",
separationAmount: 0,
subtotal: 0,
wagesPayable: "",
workday: "",
}
}
tableDataLet.forEach((tableDatum) => {
let rowspan = tableDatum.rows.length * 5
monthConcat.set(rowIndex, rowspan)
rowIndex += rowspan
for (const tableDatumElement of tableDatum.rows) {
tableData.value = tableData.value.concat(tableDatumElement)
let row = tableDatumElement[0]
for (const key of personInfoKey) {
try {
if (row[key].subtotal && '/' !== row[key].subtotal) {
summary[key].subtotal += parseFloat(row[key].subtotal)
}
} catch (e) {
}
}
}
})
for (const row of tableData.value) {
for (const key of personInfoKey) {
try {
if (row[key].separationAmount && '/' !== row[key].separationAmount) {
summary[key].separationAmount += parseFloat(row[key].separationAmount)
}
} catch (e) {
}
}
}
for (const key of personInfoKey) {
summary[key].subtotal = summary[key].subtotal.toFixed(2)
summary[key].separationAmount = summary[key].separationAmount.toFixed(2)
}
monthConcat.set(rowIndex, 1)
tableData.value.push(summary)
loading.value = false
})
}
const getResearchOptions = async () => {
const res = await getResearchUser()
researchOptions.value = res.data
}
const search = (val) => {
tableConfig.params = {
allocationId: route.query.id,
...val
}
tableIns.value.refresh()
}
getResearchOptions()
init()
const exportTable = () => {
const $e = reportTable.value.$el
let $table = $e.querySelector('.el-table__fixed')
if (!$table) {
$table = $e
}
exportExcel($table, (5 + (Object.keys(tableData.value[0]).length - 5) * 5), "四川省国有资产经营投资管理有限责任公司科技创新项目人工成本分摊明细表", 2)
}
</script>

View File

@@ -0,0 +1,169 @@
<template>
<el-form :label-position="labelAlign">
<el-form-item :label="title?'其他文件':''" v-if="fileListShow === 'READ' || fileListShow === 'EDIT'" :label-position="labelAlign" :label-width="title?95:''">
<file-upload @getFile="getOtherFile" v-if="fileListShow === 'EDIT'"/>
<fvTable style="width: 100%;max-height: 162px;" v-if="processViewer" height="162" :tableConfig="tableConfig"
:data="_value" :isSettingCol="false" :pagination="false">
<template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</el-form-item>
</el-form>
</template>
<script setup lang="jsx">
import {downloadFile, deleteFile} from "@/api/project-demand";
import {ElNotification} from "element-plus";
const props = defineProps({
title: {
type: String,
default: ''
},
tag: {
type: String,
default: ''
},
fileListShow: {
type: String,
default: 'READ'
},
value: {
type: Array,
default: []
},
processViewer: {
type: Boolean,
default: false
},
labelAlign: {
type: String,
default: 'right'
}
})
const emit = defineEmits(['update:value'])
const tableConfig = reactive({
columns: [
{
prop: 'index',
type: 'index',
label: '序号',
align: 'center',
width: 85,
},
{
prop: 'originalFileName',
label: '文件名',
align: 'center',
},
{
prop: 'tag',
label: '标签',
align: 'center'
},
{
prop: 'size',
label: '文件大小',
align: 'center',
width: 150,
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
},
{
prop: 'oper',
label: '操作',
align: 'center',
showOverflowTooltip: false,
currentRender: ({row, index}) => {
let btn = []
btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'})
// if (row.newFile) {
// btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'})
// }
return (
<div style={{width: '100%'}}>
{
btn.map(item => (
<el-button
type={item.type}
onClick={() => item.func()}
link>
{item.label}
</el-button>
))
}
{
row.newFile ? <popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
perm={['mosr:requirement:del']}
onDelete={() => handleDelete(row)}/>
: ''
}
</div>
)
}
}
]
})
const _value = computed({
get() {
return props.value;
},
set(val) {
emit("update:value", val);
}
})
const getOtherFile = (val) => {
props.processViewer = false
let fileObj = compositeParam(val)
_value.value.push(fileObj)
nextTick(() => {
props.processViewer = true
})
}
const compositeParam = (item, type) => {
return {
fileId: item.id,
size: item.size,
originalFileName: item.originalFilename,
fileType: item.fileType,
url: item.url,
newFile: true,
tag: props.tag
}
}
const handleDownload = (row) => {
downloadFile(row.fileId).then(res => {
const blob = new Blob([res])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = row.originalFileName
a.click()
})
}
const handleDelete = (row) => {
deleteFile(row.fileId).then(res => {
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
_value.value.splice(_value.value.findIndex((item) => item.fileId === row.fileId), 1);
}
});
}
watch(() => props.processViewer, (newVal) => {
props.processViewer = newVal
}, {deep: true})
</script>
<style scoped lang="scss">
:deep(.el-table--fit ) {
height: 162px !important;
}
</style>

View File

@@ -0,0 +1,168 @@
<template>
<!-- <baseTitle title="审核意见"></baseTitle>-->
<!-- <fvForm :schema="schema" @getInstance="(e)=>form = e"></fvForm>-->
<div class="oper-page-btn">
<el-button type="danger" @click="handleReject">驳回</el-button>
<el-button color="#DED0B2" @click="handleAgree">同意</el-button>
</div>
</template>
<script setup lang="jsx">
import {ElNotification} from 'element-plus';
import {agreeTask, rejectTask} from "@/api/project-demand/index.js";
import {useTagsView} from '@/stores/tagsview.js'
const tagsViewStore = useTagsView()
const route = useRoute()
const router = useRouter()
const props = defineProps({
taskId: {
type: String,
default: ''
},
formData: {
type: Object,
default: {}
},
value: {
type: String,
default: ''
}
})
const form = ref()
const schema = computed(() => {
return [
{
label: '',
prop: 'auditOpinion',
component: 'el-input',
colProps: {
span: 24
},
props: {
placeholder: '请输入审核意见',
type: 'textarea',
rows: 3
}
}
]
})
const _value = computed({
get() {
return props.value;
},
set(val) {
emit("update:value", val);
}
})
const back = () => {
switch (route.name) {
case 'Initiation/detail':
router.push({name: 'Initiation'})
break;
case 'Filing/detail':
router.push({name: 'Filing'})
break;
case 'Implementation/detail':
if (route.query.source === 'home') {
router.push('/home')
} else {
if (route.query.step === '10') {
router.push({name: 'Summary'})
} else if (route.query.step === '20') {
router.push({name: 'Initiation'})
} else if (route.query.step === '40') {
router.push({name: 'Implementation'})
} else if (route.query.step === '50') {
router.push({name: 'Filing'})
} else if (route.query.step === '00') {
router.push({name: 'Requirement'})
}
}
break;
case 'Summary/detail':
if (route.query.source === 'home') {
router.push('/home')
} else {
router.push({name: 'Summary'})
}
break;
case 'Requirement/detail':
if (route.query.source === 'home') {
router.push('/home')
} else {
router.push({name: 'Requirement'})
}
break;
case 'Fund/detail':
if (route.query.source === 'home') {
router.push('/home')
} else {
router.push({name: 'Fund'})
}
break;
case 'Share/detail':
if (route.query.source === 'home') {
router.push('/home')
} else {
router.push({name: 'Expense/share'})
}
break;
case 'Phase/detail':
if (route.query.source === 'home') {
router.push('/home')
} else {
router.push({name: 'Implementation'})
}
break;
}
}
// 驳回
const handleReject = async () => {
// const values = form.value.getValues()
if (!_value.value) {
ElNotification({
title: '提示',
message: '请填写审核意见',
type: 'warning'
})
return
}
const params = {
taskId: props.taskId,
// ...values
auditOpinion: _value.value
}
// console.log('params', params)
const res = await rejectTask(params)
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
back()
}
const handleAgree = async () => {
// const values = form.value.getValues()
const params = {
taskId: props.taskId,
formData: props.formData,
auditOpinion: _value.value
}
const res = await agreeTask(params)
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
back()
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,763 @@
<template>
<div class="apply-block">
<el-row v-if="title==='check'">
<el-col :span="24">
<baseTitle :title="'附件信息'"></baseTitle>
</el-col>
<el-form :model="attachmentParam" inline style="margin-top: 15px">
<el-form-item label="标签" prop="tag">
<el-select v-model="attachmentParam.tag" placeholder="请选择标签" clearable filterable style="width: 300px">
<el-option
v-for="item in tagsOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleSearch" color="#DED0B2">搜索</el-button>
<el-button v-if="uploadState" color="#DED0B2" @click="handleUpload">上传附件</el-button>
</el-form-item>
</el-form>
<fvTable style="width: 100%;min-height:162px;max-height: 162px" v-if="showAttachmentTable" height="162"
:tableConfig="tableConfig"
:data="otherAttachmentList" :isSettingCol="false" :pagination="false">
<template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</el-row>
<baseTitle :title="getTitleName(title)+'信息'"></baseTitle>
<el-form :model="localFormData" ref="formRef" label-width="auto" v-if="step!=='50'">
<el-row>
<el-col :span="24" v-if="title==='apply'">
<el-form-item label="项目负责人" :required="true" prop=""
label-width="125">
<el-button style="margin-right: 10px" color="#DED0B2" @click="handleShowProjectChargePersonTable">
<!-- {{ localFormData.projectChargePerson ? '更改' : '请选择' }}-->
{{ projectChargePersonUserList.length !== 0 ? '更改' : '请选择' }}
</el-button>
<div v-for="item in projectChargePersonUserList" :key="item.id" style="margin-right: 5px">
{{ item.name }}
</div>
<user-picker :multiple="false" ref="projectChargePersonUserPicker" title="请选择项目负责人"
v-model:value="projectChargePersonUserList" @ok="projectChargePersonUserPickerOk"/>
</el-form-item>
</el-col>
<el-col :span="24" v-if="title==='apply'">
<el-form-item label="项目成员" :required="true" prop=""
label-width="125">
<el-button color="#DED0B2" style="margin-right: 10px" @click="handleShowProjectPersonTable">
<!-- {{ localFormData.projectPersonIds ? '更改' : '请选择' }}-->
{{ projectPersonUserList.length !== 0 ? '更改' : getProjectPerson(projectPersonUserList) ? '更改' : '请选择' }}
</el-button>
<div v-for="item in getProjectPerson(projectPersonUserList)" :key="item.id" style="margin-right: 5px">
{{ item.name }}
</div>
<user-picker :multiple="true" ref="projectPersonUserPicker" title="请选择项目成员"
v-model:value="projectPersonUserList" @ok="projectPersonUserPickerOk"/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="前置流程" :required="preProcessRequired" prop="preProcess" label-width="125">
<el-button color="#DED0B2" @click="handleShowPreTable" style="margin-right: 10px">
{{
localFormData.preProcess && localFormData.preProcess.length > 0 ? '更改' : sessionParams.preProcess && sessionParams.preProcess.length > 0 ? '更改' : '请选择'
}}
</el-button>
<div v-for="item in getRequestName(localFormData.preProcess)" :key="item.requestId">
<a :href="item.baseUrl" target="_blank"
style="color: #2a99ff;margin-right: 10px;cursor: pointer">{{ item.requestName }}
</a>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<!-- v-if="showAttachment"-->
<AttachmentUpload ref="attachment" :label="getTitleName(title)+'附件'" :showTable="showTable"
v-model:otherFileList="otherFileList" :tag="getTitleName(props.title)"
@getAttachment="getAttachment" v-model:singleList="singleList" :showSingleTable="showSingleTable"
@getOtherFile="getOtherFile" :showFileList="true" :formData="localFormData"
:preview="mode == 'resubmit'"/>
<div>
<div class="approval-record">
<div class="approval-title">
<baseTitle title="审批记录" v-if="mode === 'resubmit'"></baseTitle>
<div v-else></div>
<div class="diagram">
<div class="base-title">流程图</div>
<el-switch
v-model="changeDiagram"
style="--el-switch-on-color:#BEA266 ; --el-switch-off-color:#cecdcd"
/>
</div>
</div>
<div class="process">
<operation-render v-if="mode === 'resubmit'&&!changeDiagram" :operation-list="data.operationList"
:state="data.state"/>
<process-diagram-viewer mode="view" :idName="title" v-if="processDiagramViewer&&changeDiagram"/>
</div>
</div>
</div>
<div class="oper-page-btn">
<el-button color="#DED0B2" v-if="mode === 'submit'" @click="handleSubmit">提交</el-button>
<el-button color="#DED0B2" v-else-if="mode === 'resubmit'" @click="handleSubmit">重新提交</el-button>
<el-button @click="handleBack">返回</el-button>
</div>
<el-dialog v-if="showPreTable" title="前置流程" v-model="showPreTable" width="80%">
<el-form :model="preProcessForm" inline @submit.prevent="searchPreProcess">
<el-form-item label="请求名称">
<el-input v-model="preProcessForm.requestName" placeholder="请输入请求名称" clearable>
</el-input>
</el-form-item>
<el-form-item>
<el-button color="#DED0B2" @click="searchPreProcess">搜索</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
<el-table :data="preProcessList" v-loading="loading"
@select="handleSelect" @select-all="handleSelect" row-key="requestId" ref="preProcessTable">
<el-table-column type="selection" width="55" :reserve-selection="true"/>
<el-table-column prop="requestId" label="请求id"></el-table-column>
<el-table-column prop="requestName" label="请求名称"></el-table-column>
<el-table-column prop="lastOperatorName" label="最后操作人名称"></el-table-column>
<el-table-column prop="lastOperateTime" label="最后操作时间"></el-table-column>
<el-table-column prop="currentNodeName" label="当前节点"></el-table-column>
<el-table-column prop="creatorName" label="创建人"></el-table-column>
<el-table-column prop="createTime" label="创建时间"></el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<!-- <el-button type="primary" @click="choosePreProcess(scope.row)" link>选择</el-button>-->
<a :href="scope.row.baseUrl" target="_blank" style="color: #2a99ff;margin-left: 10px">查看流程</a>
</template>
</el-table-column>
</el-table>
<paging :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :page-sizes="[10, 20, 30, 40,50]"
:total="total" @changeSize="handleSizeChange" @goPage="handleCurrentChange"/>
<div class="oper">
<el-button color="#DED0B2" @click="choosePreProcess">确定</el-button>
<el-button @click="handleCancel">取消</el-button>
</div>
</el-dialog>
</div>
</template>
<script setup lang="jsx">
import OperationRender from '@/views/workflow/common/OperationRender.vue'
import ProcessDiagramViewer from '@/views/workflow/common/ProcessDiagramViewer.vue';
import {ElNotification} from "element-plus";
import {getTags} from "@/api/project-manage";
import {
getApplyProcess,
getPreProcess,
getProjectCheckProcess,
getProjectConclusionProcess,
projectApply,
projectCheck,
projectConclusion,
resubmitApply,
resubmitCheck,
resubmitConclusion
} from "@/api/project-manage";
import {useProcessStore} from '@/stores/processStore.js';
import {useTagsView} from '@/stores/tagsview.js'
import Paging from "@/components/pagination/index.vue";
import UserPicker from "@/views/workflow/process/common/UserPicker.vue";
import {searchImplementationFileList} from "@/api/project-manage/attachment";
const router = useRouter()
const route = useRoute()
const changeDiagram = ref(false)
const formRef = ref()
const showSingleTable = ref(false)
const projectChargePersonUserList = ref([])
const projectChargePersonUserPicker = ref()
const projectPersonUserList = ref([])
const projectPersonUserPicker = ref()
const singleList = ref([])
const tagsOption = ref([])
const uploadState = ref(false)
const showAttachmentTable = ref(true)
const otherAttachmentList = ref([])
const attachmentParam = reactive({
tag: ''
})
const tableConfig = reactive({
columns: [
{
prop: 'index',
type: 'index',
label: '序号',
align: 'center',
width: '80',
},
{
prop: 'originalFileName',
label: '文件名',
align: 'center',
},
{
prop: 'tag',
label: '标签',
align: 'center'
},
{
prop: 'size',
label: '文件大小',
align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
},
{
prop: 'oper',
label: '操作',
align: 'center',
showOverflowTooltip: false,
currentRender: ({row, index}) => {
return (
<div>
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
</div>
)
}
}
]
})
const emit = defineEmits(["getAttachment", "getOtherFile"])
const props = defineProps({
title: {
type: String,
default: 'apply'
},
showTable: {
type: Boolean,
default: false
},
mode: {
type: String,
default: "view"
},
data: {
type: Object,
default: {}
},
formData: {
type: Object,
default: {}
},
step: {
type: String,
default: "20"
}
})
const preProcessList = ref([])
//暂存数据
const currentList = ref([])
const preProcessRequired = ref(false)
const total = ref(0)
const preProcessForm = reactive({
requestName: ''
})
const pageInfo = reactive({
pageNum: 1,
pageSize: 10,
})
// const rules = reactive({
// preProcess: [{required: true, message: '请选择前置流程', trigger: 'blur'}],
// projectChargePerson: [{required: true, message: '请选择项目负责人', trigger: 'blur'}],
// projectPerson: [{required: true, message: '请选择项目成员', trigger: 'blur'}],
// })
const tagsViewStore = useTagsView()
const processStore = useProcessStore()
const localProjectPerson = ref([])
const otherFileList = ref([])
const localFormData = ref({
projectPersonIds: [],
projectChargePerson: null,
preProcess: [
// {
// requestId: null,
// requestName: '',
// baseUrl: ''
// }
]
})
const attachment = ref()
const deploymentData = ref({})
const showPreTable = ref(false)
const showTable = ref(true)
const loading = ref(false)
const processDiagramViewer = ref(false)
const name = ref(router.currentRoute.value.name)
const deploymentId = ref()
const selectRows = ref([])
const projectId = ref(route.query.projectId)
const sessionParams = ref({})
if (localStorage.getItem('preProcess')) {
let param = JSON.parse(localStorage.getItem('preProcess'))
localFormData.value.preProcess = param
sessionParams.value.preProcess = param
localStorage.setItem('preProcess', JSON.stringify(param))
}
if (localStorage.getItem('singleFile')) {
let param = JSON.parse(localStorage.getItem('singleFile'))
localFormData.value.singleFile = param
singleList.value = [param]
localStorage.setItem('singleFile', JSON.stringify(param))
showSingleTable.value = false
nextTick(() => {
showSingleTable.value = true
})
}
if (localStorage.getItem('otherFileList')) {
let param = JSON.parse(localStorage.getItem('otherFileList'))
localFormData.value.otherFileList = param
otherFileList.value = param
localStorage.setItem('otherFileList', JSON.stringify(param))
showTable.value = false
nextTick(() => {
showTable.value = true
})
}
if (localStorage.getItem('projectChargePersonUserList')) {
let param = JSON.parse(localStorage.getItem('projectChargePersonUserList'))
projectChargePersonUserList.value = param
localStorage.setItem('projectChargePersonUserList', JSON.stringify(param))
}
if (localStorage.getItem('projectPersonUserList')) {
let param = JSON.parse(localStorage.getItem('projectPersonUserList'))
projectPersonUserList.value = param
localProjectPerson.value = param
localStorage.setItem('projectPersonUserList', JSON.stringify(param))
}
const getProjectPerson = (list) => {
if (!list || list && list.length === 0) {
if (localStorage.getItem('projectPersonUserList')) {
let param = JSON.parse(localStorage.getItem('projectPersonUserList'))
projectPersonUserList.value = param
return projectPersonUserList.value
}
} else {
return list
}
}
const getRequestName = (list) => {
if (!list || (list && list.length === 0)) {
if (sessionParams.value.preProcess) {
return sessionParams.value.preProcess
}
} else {
return list
}
}
const getTagsOption = () => {
if (!route.query.projectId) return
getTags(route.query.projectId).then(res => {
if (res.code === 1000) {
tagsOption.value = res.data
} else {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
})
}
const handleSearch = () => {
let params = {
targetId: route.query.projectId,
targetState: "40"
}
if (attachmentParam.tag) {
tagsOption.value.forEach(item => {
if (item.value === attachmentParam.tag) {
attachmentParam.tag = item.label
}
})
params.tag = attachmentParam.tag
}
searchImplementationFileList(params).then(res => {
showAttachmentTable.value = false
if (res.code === 1000) {
otherAttachmentList.value = res.data.fileList
uploadState.value = res.data.upload
nextTick(() => {
showAttachmentTable.value = true
})
} else {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
})
}
const handleUpload = () => {
router.push({
name: 'Implementation/upload',
query: {
id: route.query.id,
projectId: route.query.projectId,
state: route.query.state,
step: '40'
}
})
}
const getProjectChargePersonUser = () => {
if (projectChargePersonUserList.value.length !== 0) {
return projectChargePersonUserList.value.map(item => item.name).join()
}
}
const handleSelect = async (selection) => {
selectRows.value = selection
}
const handleCancel = () => {
showPreTable.value = false
}
const searchPreProcess = () => {
getPreProcessList()
}
const handleReset = () => {
preProcessForm.requestName = ''
getPreProcessList()
}
const handleShowPreTable = () => {
showPreTable.value = true
getPreProcessList()
}
const handleShowProjectChargePersonTable = () => {
projectChargePersonUserPicker.value.showUserPicker()
}
const projectChargePersonUserPickerOk = (userList) => {
projectChargePersonUserList.value = userList
localStorage.setItem('projectChargePersonUserList', JSON.stringify(projectChargePersonUserList.value))
}
const handleShowProjectPersonTable = () => {
projectPersonUserPicker.value.showUserPicker()
}
const projectPersonUserPickerOk = (userList) => {
projectPersonUserList.value = userList
localStorage.setItem('projectPersonUserList', JSON.stringify(userList))
// let userIds = []
// for (const user of userList) {
// userIds.push(user.id)
// }
}
const getPreProcessList = () => {
loading.value = true
getPreProcess().then(res => {
loading.value = false
let searchArray = []
let regexPattern = ("%" + preProcessForm.requestName + "%").replace(/%/g, '.*').replace(/_/g, '.');
let regex = new RegExp('^' + regexPattern + '$');
res.data.filter((item) => {
if (regex.test(item.requestName)) {
searchArray.push(item)
}
})
// res.data.forEach((item) => {
// localFormData.value.preProcess.forEach((item1) => {
// if (item.requestId == item1.requestId) {
// preProcessTable.value.toggleRowSelection(item)
// }
// })
// })
total.value = searchArray.length
currentList.value = searchArray
preProcessList.value = currentList.value.slice(0, 10)
})
}
const choosePreProcess = () => {
let preProcessObj = {}
let preProcessArray = []
selectRows.value.forEach((item) => {
preProcessObj = {
requestId: item.requestId,
requestName: item.requestName,
baseUrl: item.baseUrl
}
preProcessArray.push(preProcessObj)
})
localFormData.value.preProcess = preProcessArray
showPreTable.value = false
localStorage.setItem('preProcess', JSON.stringify(preProcessArray))
}
//切换每页显示条数
const handleSizeChange = (val) => {
pageInfo.pageSize = val;
preProcessList.value = currentList.value.slice((pageInfo.pageNum - 1) * val, pageInfo.pageNum * val)
};
//点击页码进行分页功能
const handleCurrentChange = (val) => {
pageInfo.pageNum = val;
preProcessList.value = currentList.value.slice((val - 1) * pageInfo.pageSize, val * pageInfo.pageSize)
};
const getTitleName = (type) => {
switch (type) {
case 'apply':
return '项目立项'
case 'check':
return '项目验收'
case 'filing':
return '项目归档'
}
}
const handleBack = () => {
history.back()
}
const compositeParam = (item) => {
return {
fileId: item.id,
size: item.size,
originalFileName: item.originalFilename,
fileType: item.fileType,
url: item.url,
newFile: true,
tag: getTitleName(props.title)
}
}
const getAttachment = (val) => {
// console.log('上传文件getAttachment', val)
showSingleTable.value = false
localFormData.value.singleFile = compositeParam(val)
singleList.value.push(compositeParam(val))
nextTick(() => {
showSingleTable.value = true
if (attachment.value.singleFile == null) {
attachment.value.validate()
ElNotification({
title: '提示',
message: '请上传附件',
type: 'error'
})
return;
} else {
attachment.value.clearValidate()
}
})
localStorage.setItem('singleFile', JSON.stringify(compositeParam(val)))
}
watch(() => singleList.value, (newVal) => {
showSingleTable.value = newVal.length !== 0;
}, {deep: true})
const getOtherFile = (val) => {
// console.log('上传文件getOtherFile', val)
showTable.value = false
let fileObj = compositeParam(val)
otherFileList.value.push(fileObj)
nextTick(() => {
showTable.value = true
})
// localFormData.value.otherFileList = otherFileList.value
localStorage.setItem('otherFileList', JSON.stringify(otherFileList.value))
}
const getFileParam = (item) => {
return {
fileId: item.fileId,
tag: item.tag
}
}
const handleSubmit = async () => {
if (deploymentData.value.deploymentName === '重大项目立项' || deploymentData.value.deploymentName === '重大项目验收') {
if (localFormData.value.preProcess == undefined) {
if (JSON.parse(localStorage.getItem('preProcess'))?.length > 0) {
} else {
ElNotification({
title: '提示',
message: '请选择前置流程!',
type: 'error'
})
return;
}
}
}
let files = []
if (props.mode === 'resubmit') {
attachment.value.allFileList.forEach(item => {
files.push(getFileParam(item))
})
} else {
otherFileList.value.forEach(item => {
files.push(getFileParam(item))
})
}
if (attachment.value.singleFile == null) {
attachment.value.validate()
ElNotification({
title: '提示',
message: '请上传附件',
type: 'error'
})
return;
} else {
attachment.value.clearValidate()
}
let projectPersonIds = []
for (const item of projectPersonUserList.value) {
projectPersonIds.push(parseInt(item.id))
}
let params = {
deploymentId: deploymentId.value,
requirementId: route.query.id,
fileList: files,
singleFile: attachment.value.singleFile,
projectId: projectId.value,
preProcess: JSON.stringify(localFormData.value.preProcess)
}
if (sessionParams.value.preProcess && !localFormData.value.preProcess) {
params.preProcess = JSON.stringify(sessionParams.value.preProcess)
}
// console.log(params.preProcess)
let res
if (props.step === '20') {
if (projectChargePersonUserList.value && projectChargePersonUserList.value.length === 0) {
ElNotification({
title: '提示',
message: '请选择项目负责人!',
type: 'error'
})
return;
}
if (projectPersonUserList.value && projectPersonUserList.value.length === 0) {
ElNotification({
title: '提示',
message: '请选择项目成员!',
type: 'error'
})
return;
}
params.projectChargePerson = parseInt(projectChargePersonUserList.value[0].id)
params.projectPersonIds = projectPersonIds
if (props.mode === 'resubmit') {
res = await resubmitApply(params)
} else {
res = await projectApply(params)
}
} else if (props.step === '40') {
if (props.mode === 'resubmit') {
res = await resubmitCheck(params)
} else {
res = await projectCheck(params)
}
} else if (props.step === '50') {
if (props.mode === 'resubmit') {
res = await resubmitConclusion(params)
} else {
res = await projectConclusion(params)
}
}
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
if (props.step === '20') {
await router.push({
name: 'Initiation'
})
} else if (props.step === '40') {
await router.push({
name: 'Implementation'
})
} else if (props.step === '50') {
await router.push({
name: 'Filing'
})
}
}
}
const init = async () => {
if (props.title && props.title === 'check') {
handleSearch()
getTagsOption()
}
let id = projectId.value
if (!id) return;
processDiagramViewer.value = false
let res
if (props.step === '20') {
res = await getApplyProcess(id)
} else if (props.step === '40') {
res = await getProjectCheckProcess(id)
} else if (props.step === '50') {
res = await getProjectConclusionProcess(id)
}
if (res.code === 1000) {
let data = res.data
deploymentId.value = data.deploymentId
deploymentData.value = data
preProcessRequired.value = data.deploymentName === '重大项目立项' || data.deploymentName === '重大项目验收';
processStore.setDesign(data)
processStore.runningList.value = data.runningList;
processStore.endList.value = data.endList;
processStore.noTakeList.value = data.noTakeList;
processStore.refuseList.value = data.refuseList;
processStore.passList.value = data.passList;
nextTick(() => {
processDiagramViewer.value = true
})
} else {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
}
watchEffect(() => {
if (props.formData.projectChargePerson == null) {
// projectChargePersonUserList.value = []
} else {
projectChargePersonUserList.value = [props.formData.projectChargePerson]
}
// console.log('props.formData.projectPersonList',props.formData.projectPersonList)
projectPersonUserList.value = props.formData.projectPersonList ? props.formData.projectPersonList : []
let flag = Object.keys(props.formData).length && (localFormData.value = props.formData)
if (props.formData.projectChargePerson != null) {
localFormData.value.projectChargePerson = props.formData.projectChargePerson.id
}
// if(props.formData.fileList&&props.formData.fileList.length>0){
// otherFileList.value=props.formData.fileList
// }
// localFormData.value.projectPersonIds = []
// if (projectPersonUserList.value){
// projectPersonUserList.value.forEach(item => {
// localFormData.value.projectPersonIds.push(item.id)
// })
// }
// console.log('projectPersonUserList.value',projectPersonUserList.value)
return flag
})
onActivated(() => {
init()
})
onMounted(async () => {
await init()
})
</script>
<style scoped>
.oper {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
</style>

View File

@@ -0,0 +1,234 @@
<template>
<div v-loading="loading">
<baseTitle title="专项资金详情"></baseTitle>
<el-form :model="formData" ref="form" label-width="auto">
<el-row>
<el-col :span="12">
<el-form-item label="专项名称">
<span>{{ formData.name }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="金额(元)">
<span>{{ toThousands(formData.fundAmount) }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="剩余金额(元)">
<span>{{ toThousands(formData.residualAmount) }}</span>
</el-form-item>
</el-col>
<baseTitle title="介绍"></baseTitle>
<el-col :span="24">
<el-form-item>
<el-card style="width: 100%">
<div v-html="formData.introduce">
</div>
</el-card>
</el-form-item>
</el-col>
<baseTitle title="关联项目" v-if="!data.taskId"></baseTitle>
<el-col :span="24" v-if="!data.taskId">
<el-form-item>
<fvTable style="width: 100%;max-height:162px" height="162" v-if="showTable" :tableConfig="projectTable"
:data="formData.projects" :isSettingCol="false" :pagination="false">
<template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</el-form-item>
</el-col>
<baseTitle title="附件列表"></baseTitle>
<el-col :span="24">
<el-form-item>
<fvTable style="width: 100%;max-height: 162px;" height="162" v-if="showTable" :tableConfig="fileTable"
:data="formData.files" :isSettingCol="false" :pagination="false">
<template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</el-form-item>
</el-col>
<el-col :span="24">
<div v-if="data.taskId">
<baseTitle title="审核意见"></baseTitle>
<el-form-item prop="auditOpinion">
<el-input
v-model="formData.auditOpinion"
:rows="3"
type="textarea"
placeholder="请输入审核意见"
/>
</el-form-item>
</div>
</el-col>
</el-row>
<div class="approval-record">
<div class="approval-title">
<baseTitle title="审批记录"></baseTitle>
<div class="diagram">
<div class="base-title">流程图</div>
<el-switch
v-model="changeDiagram"
style="--el-switch-on-color:#BEA266 ; --el-switch-off-color:#cecdcd"
/>
</div>
</div>
<div class="process">
<operation-render v-if="processViewer && data.operationList && data.operationList.length > 0&&!changeDiagram"
:operation-list="data.operationList"
:state="data.state"/>
<process-diagram-viewer v-if="processViewer&&changeDiagram" id-name="fundProcess"/>
</div>
</div>
</el-form>
<opinion v-if="data.taskId" :formData="data.formData" :taskId="data.taskId"
v-model:value="formData.auditOpinion"></opinion>
</div>
</template>
<script setup lang="jsx">
import {toThousands} from '@/utils/changePrice.js'
import OperationRender from '@/views/workflow/common/OperationRender.vue'
import ProcessDiagramViewer from '@/views/workflow/common/ProcessDiagramViewer.vue'
import {downloadFile} from "@/api/project-demand";
const changeDiagram = ref(false)
const emit = defineEmits(['getInfo', "update:formData"])
const form = ref()
const router = useRouter()
const props = defineProps({
formData: {
type: Array,
default: []
},
data: {
type: Array,
default: []
},
processViewer: {
type: Boolean,
default: false
}, showTable: {
type: Boolean,
default: false
},
loading: {
type: Boolean,
default: false
}
})
const projectTable = reactive({
columns: [
{
prop: 'index',
type: 'index',
label: '序号',
align: 'center',
width: '80',
},
{
prop: 'projectName',
label: '项目名称',
align: 'center',
},
{
prop: 'specialFundAmount',
label: '项目金额',
align: 'center',
currentRender:({row})=>{
return <span>{toThousands(row.specialFundAmount)}</span>
}
},
{
prop: 'startTime',
label: '项目时间',
align: 'center'
},
{
prop: 'oper',
label: '操作',
align: 'center',
currentRender: ({row, index}) => {
return (
<el-button type="primary" link onClick={() => handleView(row)}>查看</el-button>
)
}
}
]
})
const fileTable = reactive({
columns: [
{
prop: 'index',
type: 'index',
label: '序号',
align: 'center',
width: '80',
},
{
prop: 'originalFileName',
label: '文件名',
align: 'center',
},
{
prop: 'tag',
label: '标签',
align: 'center'
},
{
prop: 'size',
label: '文件大小',
align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
},
{
prop: 'oper',
label: '操作',
align: 'center',
currentRender: ({row, index}) => {
return (
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
)
}
}
]
})
const handleView=(row)=>{
router.push({
name: 'Implementation/detail',
query: {
id: row.requirementId,
projectId: row.projectId,
step: '10'
}
})
}
const handleDownload = (row) => {
downloadFile(row.fileId).then(res => {
const blob = new Blob([res])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = row.originalFileName
a.click()
})
}
watch(() => props.loading, (newVal) => {
props.loading = newVal
}, {deep: true})
watch(() => props.processViewer, (newVal) => {
props.processViewer = newVal
}, {deep: true})
watch(() => props.showTable, (newVal) => {
props.showTable = newVal
}, {deep: true})
</script>
<style scoped lang="scss">
:deep(.el-table--fit ) {
height: 300px !important;
}
</style>

View File

@@ -0,0 +1,370 @@
<template>
<div class="detail-block" v-loading="loading">
<baseTitle title="需求上报信息"></baseTitle>
<el-form :model="localFormData" ref="summaryForm" :rules="rules">
<el-row gutter="50">
<el-col :span="8">
<el-form-item label="项目名称" prop="projectName">
<span>{{ localFormData.projectName }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开始时间" prop="startTime">
<span>{{ localFormData.startTime }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="结束时间" prop="endTime">
<span>{{ localFormData.endTime }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="项目类型" prop="projectType">
<span>{{ filterDict(cacheStore.getDict('project_type'), localFormData.projectType) }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="研发主体" prop="rdSubject">
<span>{{ filterDict(cacheStore.getDict('rd_subject'), localFormData.rdSubject) }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="出资类型" prop="investmentType">
<span>{{ filterDict(cacheStore.getDict('invest_type'), localFormData.investmentType) }}</span>
</el-form-item>
</el-col>
<!-- <el-col :span="8">-->
<!-- <el-form-item label="项目影响" prop="projectImpact">-->
<!-- <span>{{ filterDict(cacheStore.getDict('project_impact'), localFormData.projectImpact) }}</span>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="8">
<el-form-item label="所属业务板块" prop="businessSegment">
<span>{{ filterDict(cacheStore.getDict('business_segment'), localFormData.businessSegment) }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="预期技术标准制定" prop="technicalStandard">
<span>{{ filterDict(cacheStore.getDict('technical_standard'), localFormData.technicalStandard) }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产学研联合" prop="industryUniversityResearch">
<span>{{
filterDict(cacheStore.getDict('industry_university'), localFormData.industryUniversityResearch)
}}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开展政府申报" prop="governmentDeclaration">
<span>{{
filterDict(cacheStore.getDict('government_declaration'), localFormData.governmentDeclaration)
}}</span>
</el-form-item>
</el-col>
<el-col :span="8" v-if="localFormData.isSpecialFund">
<el-form-item label="专项资金名称" prop="specialFund">
<span>{{
localFormData.specialFundId === 0 ? localFormData.specialFund : changeName(fundOption, localFormData.specialFundId)
}}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="知识产权状况" prop="intellectualProperty">
<span>{{
filterDict(cacheStore.getDict('intellectual_property'), localFormData.intellectualProperty)
}}</span>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="预期成果形式" prop="resultForm">
<span>{{ filterDict(cacheStore.getDict('result_form'), localFormData.resultForm) }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<baseTitle title="预期知识产权"></baseTitle>
</el-col>
<el-col :span="8">
<el-form-item label="发明专利(项)" prop="inventionPatent">
<span>{{ localFormData.inventionPatent }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="实用性新型专利(项)" prop="newPatent">
<span>{{ localFormData.newPatent }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="软件著作权(项)" prop="softwareCopyright">
<span>{{ localFormData.softwareCopyright }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="著作权(项)" prop="copyright">
<span>{{ localFormData.copyright }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="其他(项)" prop="other">
<span>{{ localFormData.other }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="经济预算(元)" prop="economicEstimate">
<span>{{ toThousands(localFormData.economicEstimate) }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="其中申请公司总部科技创新专项资金(元)" prop="specialFundAmount"
v-if="localFormData.isSpecialFund">
<span>{{ toThousands(localFormData.specialFundAmount) }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="现有业务描述" prop="serviceDescription">
<span>{{ localFormData.serviceDescription }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="研发项目关键内容描述" prop="contentDescription">
<span>{{ localFormData.contentDescription }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<baseTitle title="需求上报申请书"></baseTitle>
</el-col>
<el-col :span="24">
<el-form-item>
<el-button type="primary" link @click="handleDownload(localFormData.singleFile)" style="font-size: 16px">
{{ localFormData.singleFile?.originalFileName }}
</el-button>
</el-form-item>
</el-col>
<el-col :span="24">
<baseTitle title="附件列表"></baseTitle>
</el-col>
<el-col :span="24">
<file-component tag="需求上报"
v-model:value="localFormData.fileList" :processViewer="processViewer"
:file-list-show="fileListShow"/>
</el-col>
<el-col :span="24">
<div v-if="data.taskId||data.state==='4'">
<baseTitle title="审核意见"></baseTitle>
<el-form-item prop="_value">
<el-input
v-model="_value"
:rows="3"
type="textarea"
placeholder="请输入审核意见"
/>
</el-form-item>
</div>
</el-col>
</el-row>
<div class="approval-record">
<div class="approval-title">
<baseTitle title="审批记录"></baseTitle>
<div class="diagram">
<div class="base-title">流程图</div>
<el-switch
v-model="changeDiagram"
style="--el-switch-on-color:#BEA266 ; --el-switch-off-color:#cecdcd"
/>
</div>
</div>
<div class="process">
<operation-render v-if="processViewer && data.operationList && data.operationList.length > 0&&!changeDiagram"
:operation-list="data.operationList"
:step="'report'"
:state="data.state"/>
<process-diagram-viewer v-if="processViewer&&changeDiagram" id-name="summaryProcess"/>
</div>
</div>
</el-form>
<div class="oper-page-btn" v-perm="['annual:plan:approve']" v-if="data.state==='4'">
<el-button type="danger" @click="handleRejectPlan">驳回年度计划</el-button>
<el-button color="#DED0B2" @click="handleAgreePlan">通过年度计划</el-button>
</div>
</div>
</template>
<script setup lang="jsx">
import {toThousands} from '@/utils/changePrice.js'
import {downloadFile, deleteFile} from "@/api/project-demand";
import OperationRender from '@/views/workflow/common/OperationRender.vue'
import ProcessDiagramViewer from '@/views/workflow/common/ProcessDiagramViewer.vue'
import {useTagsView} from '@/stores/tagsview.js'
import {getFundOption} from "@/api/special-fund";
import {useCacheStore} from '@/stores/cache.js'
import {getSubCompOpt} from "@/api/user/user";
import FileComponent from "./FileComponent.vue";
import {ElNotification} from "element-plus";
import {approvePlan} from "@/api/project-demand/summary";
const emit = defineEmits(['update:value'])
const tagsViewStore = useTagsView()
const cacheStore = useCacheStore()
const props = defineProps({
formData: {
type: Object,
default: {}
},
data: {
type: Object,
default: {
state: '1'
}
},
processViewer: {
type: Boolean,
default: false
},
fileListShow: {
type: String,
default: 'READ'
},
loading: {
type: Boolean,
default: false
},
value: {
type: String,
default: ''
}
})
const changeDiagram = ref(false)
const localFormData = ref({})
const route = useRoute()
const router = useRouter()
const fundOption = ref([])
const companyOption = ref([])
const dictName = ref({})
const rules = reactive({
auditOpinion: [{required: true, message: '请输入审核意见', trigger: 'blur'}],
})
const _value = computed({
get() {
return props.value;
},
set(val) {
emit("update:value", val);
}
})
const handleRejectPlan = async () => {
// const values = form.value.getValues()
// console.log('route',route.query.projectId)
if (!_value.value) {
ElNotification({
title: '提示',
message: '请填写审核意见',
type: 'warning'
})
return
}
const params = {
auditOpinion:_value.value,
projectId:parseInt(route.query.projectId),
state:false
}
// console.log('params', params)
const res = await approvePlan(params)
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
router.push({
name: 'Summary'
})
}
const handleAgreePlan = async () => {
const params = {
auditOpinion:_value.value,
projectId:parseInt(route.query.projectId),
state:true
}
// console.log('params', params)
const res = await approvePlan(params)
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
router.push({
name: 'Summary'
})
}
const filterDict = (data, value) => {
if (data === undefined || value === undefined) return;
let label = ''
let result = []
if (value instanceof Array) {
value.forEach(item1 => {
data.find(item => {
if (item.value == item1) {
result.push(item.label)
}
})
})
label = result.map(item => item).join('')
} else {
if (data instanceof Array) {
data.find(item => {
if (item.value == value) {
label = item.label
}
})
}
}
return label
}
const getFundOptions = async () => {
const resFund = await getFundOption()
fundOption.value = resFund.data
const res = await getSubCompOpt()
companyOption.value = res.data
}
const changeName = (option, value) => {
let name = ''
option.forEach(item => {
if (item.value == value) {
name = item.label
}
})
return name
}
const handleDownload = (row) => {
downloadFile(row.fileId).then(res => {
const blob = new Blob([res])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = row.originalFileName
a.click()
})
}
watch(() => props.processViewer, (newVal) => {
props.processViewer = newVal
}, {deep: true})
watch(() => props.loading, (newVal) => {
props.loading = newVal
}, {deep: true})
watchEffect(() => {
return Object.keys(props.formData).length && (localFormData.value = props.formData)
})
getFundOptions()
</script>
<style scoped lang="scss">
.detail-block {
overflow-x: hidden;
overflow-y: auto;
padding-bottom: 0!important;
}
</style>

View File

@@ -4,26 +4,29 @@
:headers="headers"
:limit="maxSize"
with-credentials
:multiple="maxSize > 0"
:multiple="multiple"
:data="uploadParams"
:show-file-list="false"
:show-file-list="showFileList"
:auto-upload="true"
:before-upload="beforeUpload"
:on-success="handleUploadSuccess"
:on-error="uploadError"
:before-remove="beforeRemove"
:on-remove="handleRemove"
>
<el-button color="#DED0B2" :loading="loading">上传文件</el-button>
<el-button color="#DED0B2" :loading="loading" :disabled="disabled">上传文件</el-button>
</el-upload>
</template>
<script setup>
import {ElMessage} from "element-plus";
import { ElMessageBox, ElNotification} from "element-plus";
import {getToken} from '@/utils/auth'
const baseURL = import.meta.env.VITE_BASE_URL
const uploadFileUrl = ref(baseURL + "/workflow/process/file/upload")
const headers = reactive({
authorization: getToken()
})
const disabled = ref(false)
const loading = ref(false)
const showTable = ref(false)
const uploadParams = ref({})
@@ -37,10 +40,22 @@ const props = defineProps({
maxSize: {
type: Number,
default: 30
},
showFileList: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: true
}
})
const emit = defineEmits(["input", "getFile"])
const emit = defineEmits(["input", "getFile", "delete"])
const fileList = ref([])
const _value = computed({
get() {
@@ -50,34 +65,44 @@ const _value = computed({
emit("input", val);
}
})
const beforeRemove = (file) => {
return ElMessageBox.confirm(`确认删除名称为${file.name}的文件吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => true)
}
const beforeUpload = (file) => {
// const FileExt = file.name.replace(/.+\./, "");
// if (['zip', 'rar', 'pdf', 'doc', 'docx', 'xlsx'].indexOf(FileExt.toLowerCase()) === -1) {
// ElMessage.warning('请上传后缀名为pdf、doc、docx、xlsx、zip或rar的文件');
// return false;
// } else
// if (props.maxSize > 0 && file.size / 1024 / 1024 > props.maxSize) {
// ElMessage.warning(`每个文件最大不超过 ${props.maxSize}MB`)
// } else {
const handleRemove = (file) => {
emit("delete", file.response.data.id)
}
const beforeUpload = () => {
loading.value = true
return true
// }
}
const handleUploadSuccess = (res, file) => {
if (res.code !== 1000) {
loading.value = false
ElMessage.error("上传失败")
} else {
loading.value = false
ElMessage.success("上传成功")
}
const handleUploadSuccess = (res) => {
ElNotification({
title: '提示',
message: res.code === 1000 ? '上传成功' : '上传失败',
type: res.code === 1000 ? 'success' : 'error'
})
loading.value = false
showTable.value = true
let data = res.data
fileList.value.push(data)
emit("getFile", fileList.value)
emit("getFile", res.data)
}
const uploadError = () => {
loading.value = false
ElNotification({
title: '提示',
message: "上传失败,请稍后再试!",
type: 'error'
})
}
defineExpose({
handleRemove
})
</script>
<style lang="scss" scoped>
@@ -85,4 +110,8 @@ a {
font-size: 14px;
color: #2a99ff;
}
:deep(.el-upload-list) {
width: 400px;
}
</style>

View File

@@ -0,0 +1,117 @@
<template>
<el-upload :file-list="[]"
:limit="maxSize"
with-credentials
:multiple="multiple"
:http-request="httpRequestHandle"
:data="uploadParams"
:auto-upload="true"
:show-file-list="false"
:before-upload="beforeUpload"
:before-remove="beforeRemove"
:on-remove="handleRemove"
>
<el-button color="#DED0B2" style="margin-left: 10px; margin-right: 10px;" :disabled="disabled">导入</el-button>
</el-upload>
</template>
<script setup>
import {ElMessageBox, ElNotification} from "element-plus";
import {getToken} from '@/utils/auth'
import axios from "axios";
const props = defineProps({
value: {
type: Array,
default: () => {
return []
}
},
maxSize: {
type: Number,
default: 30
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
projectId: {
type: Number,
default: 0
}
})
const baseURL = import.meta.env.VITE_BASE_URL
const uploadFileUrl = ref(baseURL + "/workflow/mosr/expense/ledger/import?projectId=" + props.projectId)
const headers = reactive({
authorization: getToken()
})
// const loading = ref(false)
const uploadParams = ref({})
const emit = defineEmits(["input", "getFile", "delete"])
const beforeRemove = (file) => {
return ElMessageBox.confirm(`确认删除名称为${file.name}的文件吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => true)
}
const handleRemove = (file) => {
emit("delete", file.response.data.id)
}
const beforeUpload = () => {
// loading.value = true
console.log('水电费水电费,beforeUpload')
return true
}
const httpRequestHandle = (param) => {
let file = param.file
axios.post(uploadFileUrl.value, {
file: file
}, {
headers: {
'Content-Type': 'multipart/form-data',
...headers
}
}).then(res => {
handleUploadSuccess(res)
}).catch(error => {
uploadError(error)
})
}
const handleUploadSuccess = (res) => {
let data = res.data
ElNotification({
title: '提示',
message: data.code === 1000 ? '上传成功' : '上传失败',
type: data.code === 1000 ? 'success' : 'error'
})
emit("success")
}
const uploadError = (error) => {
// loading.value = false
ElNotification({
title: '提示',
message: "上传失败,请稍后再试!",
type: 'error'
})
}
defineExpose({
handleRemove
})
</script>
<style lang="scss" scoped>
a {
font-size: 14px;
color: #2a99ff;
}
</style>

View File

@@ -0,0 +1,107 @@
<template>
<div style="display: block">
<slot name="pre"></slot>
<div class="user-audit">
<div class="circle-user">
<Tooltip :content="user.name" placement="bottom-start" width="45px"/>
<div v-if="user.icon"
class="el-timeline-item__node" :style="{
backgroundColor: user.color
}">
<el-icon v-if="user.icon" size="15" :class="user.class">
<component :is="user.icon"/>
</el-icon>
</div>
</div>
</div>
</div>
</template>
<script setup>
import {Loading, Close, CircleCheckFilled, MoreFilled} from '@element-plus/icons-vue'
const props = defineProps({
row: {
type: Number,
default: 1
},
hoverTip: {
type: Boolean,
default: false
},
user: {
type: Object,
default: {}
},
mode: {
type: String,
default: 'design'
}
})
const init = () => {
// for (let user of props.userInfo) {
initUser(props.user)
// }
}
const initUser = (user) => {
let state = user.state
//创建节点
if (state === 'CREATE') {
user["icon"] = CircleCheckFilled
user["color"] = "#0bbd87"
}
//审批通过
if (state === 'AGREE' || state === 'AUTO_PASS') {
user["icon"] = CircleCheckFilled
user["color"] = "#0bbd87"
}
//审批处理中
if (state === 'RUNNING') {
user["icon"] = Loading
user["color"] = "#f78f5f"
user["class"] = 'is-loading'
}
//拒绝后评论
if (state === 'REFUSE') {
user["icon"] = Close
user["color"] = "#f56c6c"
}
if (state === 'PASS') {
user["icon"] = MoreFilled
user["color"] = "#c0c4cc"
}
return user;
}
init()
</script>
<style scoped lang="scss">
.user-audit {
display: flex;
flex-direction: column;
align-items: center;
.circle-user {
width: 46px;
height: 46px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
border: 1px solid #ACACAC;
position: relative;
background-color: #8a7243;
color: #fff;
.el-timeline-item__node {
position: absolute;
bottom: 0;
right: 1px;
}
}
}
</style>

View File

@@ -9,7 +9,8 @@
@cancel="handleCancel"
>
<template #reference>
<el-button :type="btnType" size="mini" v-perm="perm" :disabled="isDisabled" :icon="btnIcon" :plain="isPlain">
<!-- v-perm="perm"-->
<el-button :type="btnType" size="mini" :disabled="isDisabled" :icon="btnIcon" :plain="isPlain" :link="link">
{{ btnText }}
</el-button>
</template>
@@ -24,12 +25,16 @@ const props = defineProps({
},
btnType: {
type: String,
default: 'text'
default: 'danger'
},
type: {
type: String,
default: ''
},
link: {
type: Boolean,
default: true
},
btnIcon: {
type: String,
default: ''

View File

@@ -0,0 +1,168 @@
<template>
<div v-loading="_value">
<el-form :model="attachment" inline>
<el-form-item label="名称" prop="fileName">
<el-input v-model="attachment.fileName" placeholder="请输入附件名称查询" clearable filterable style="width: 300px"/>
</el-form-item>
<el-form-item label="标签" prop="tag" v-if="type==='40'">
<el-select v-model="attachment.tag" placeholder="请选择标签" clearable filterable style="width: 300px">
<el-option
v-for="item in tagsOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleSearch" color="#DED0B2">搜索</el-button>
<el-button @click="handleReset">重置</el-button>
<el-button v-if="uploadState" color="#DED0B2" @click="handleUpload">上传附件</el-button>
</el-form-item>
</el-form>
<el-card style="width: 100%">
<fvTable style="width: 100%;max-height: 300px" v-if="showTable" height="300" :tableConfig="tableConfig"
:data="fileList" :isSettingCol="false" :pagination="false">
<template #empty>
<el-empty :image-size="99" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</el-card>
</div>
</template>
<script setup lang="jsx">
import {downloadFile} from "@/api/project-demand";
import {ElNotification} from "element-plus";
import {getTags} from "@/api/project-manage";
import {computed} from "vue";
const route = useRoute()
const router = useRouter()
const attachment = reactive({})
const emit = defineEmits(['search','update:modelValue'])
const props = defineProps({
fileList: {
type: Array,
default: []
},
type: {
type: String,
default: '00'
},
uploadState: {
type: Boolean,
default: false
},
loading: {
type: Boolean,
default: true
}
})
const tagsOption = ref([])
const tableConfig = reactive({
columns: [
{
prop: 'originalFileName',
label: '附件名称',
align: 'center',
},
{
prop: 'tag',
label: '标签',
align: 'center'
},
{
prop: 'size',
label: '文件大小',
align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
},
{
prop: 'createTime',
label: '上传时间',
align: 'center',
},
{
prop: 'oper',
label: '操作',
align: 'center',
showOverflowTooltip: false,
currentRender: ({row, index}) => {
return (
<div>
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
</div>
)
}
}
]
})
const showTable = ref(true)
const _value = computed({
get() {
return props.loading || ""
},
set(value) {
emit('update:modelValue', value)
}
})
const getTagsOption = () => {
if (!route.query.id) return
getTags(route.query.id).then(res => {
if (res.code === 1000) {
tagsOption.value = res.data
} else {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
})
}
const handleSearch = () => {
emit('search', attachment)
}
const handleReset=()=>{
attachment.fileName=''
attachment.tag=null
emit('search', {})
}
const handleUpload = () => {
emit('upload')
}
const handleDownload = (row) => {
downloadFile(row.fileId).then(res => {
const blob = new Blob([res])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = row.originalFileName
a.click()
})
}
watch(() => props.type, (val) => {
props.type = val
})
watch(() => props.fileList, (val) => {
showTable.value = false
nextTick(() => {
showTable.value = true
})
props.fileList = val
})
if (props.type === '40') {
getTagsOption()
}
onActivated(()=>{
if (props.type === '40') {
getTagsOption()
}
handleSearch()
})
</script>
<style scoped>
</style>

View File

@@ -1,9 +1,9 @@
<template>
<div class="tag-style">
<el-tag v-if="tagConfig.isType" :type="tagConfig.listClass" :effect="tagConfig.theme || 'plain'">
<el-tag v-if="tagConfig?.isType" :type="tagConfig?.listClass" :effect="tagConfig?.theme || 'plain'">
{{ filterDict(cacheStore.getDict(dictType), value) }}
</el-tag>
<el-tag v-else :color="tagConfig.listClass" :effect="tagConfig.theme || 'plain'"
<el-tag v-else :color="tagConfig?.listClass" :effect="tagConfig?.theme || 'plain'"
:class="{'null-tag':filterDict(cacheStore.getDict(dictType), value)===undefined}">
{{ filterDict(cacheStore.getDict(dictType), value) }}
</el-tag>
@@ -31,7 +31,7 @@ const props = defineProps({
const tagConfig = ref({})
const filterDict = (data, value) => {
if (!data) return
if (!data || value == null) return
if (data instanceof Array) {
if (value == true || value == false) {
tagConfig.value = data.find(item => item.value == value.toString())
@@ -45,7 +45,7 @@ const filterDict = (data, value) => {
tagConfig.value = data.find(item => item.value == value)
}
}
return tagConfig.value.label
return tagConfig.value?.label || '未知'
}
</script>

View File

@@ -0,0 +1,120 @@
<template>
<baseTitle title="标签名称"></baseTitle>
<el-form :model="formData" ref="tagForm" label-width="auto" :rules="rules">
<el-form-item label="标签名称" prop="tagName">
<el-input v-model="formData.tagName" placeholder="请输入标签名称" style="width: 300px" v-if="showInput"/>
<el-select v-model="formData.tagName" placeholder="请选择标签" clearable filterable style="width: 300px" v-else>
<el-option
v-for="item in tagsOption"
:key="item.label"
:label="item.value"
:value="item.label"
/>
</el-select>
</el-form-item>
</el-form>
<baseTitle title="其他文件"></baseTitle>
<el-card style="width: 100%;margin: 15px 0">
<file-upload @getFile="getFiles"/>
<fvTable style="width: 100%;max-height: 162px;height: 162px" height="162" v-if="showTable" :tableConfig="tableConfig"
:data="fileList" :isSettingCol="false" :pagination="false">
<template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</el-card>
<div class="oper-page-btn">
<el-button color="#DED0B2" @click="handleSubmit(tagForm)">提交</el-button>
</div>
</template>
<script setup lang="jsx">
const props = defineProps({
tagsOption: {
type: Array,
default: []
}, formData: {
type: Array,
default: []
}, showInput: {
type: Boolean,
default: true
},
})
const rules = reactive({
tagName: [{required: true, message: '请输入标签名称', trigger: ['blur', 'change']}],
})
const tagForm = ref()
const showTable = ref(true)
const emits = defineEmits(['getFile'])
const fileList = ref([])
const tableConfig = reactive({
columns: [
{
prop: 'index',
type: 'index',
label: '序号',
align: 'center',
width: '80',
},
{
prop: 'originalFileName',
label: '附件名称',
align: 'center',
},
{
prop: 'tag',
label: '标签',
align: 'center'
},
{
prop: 'tag',
label: '文件大小',
align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
},
{
prop: 'oper',
label: '操作',
align: 'center',
currentRender: ({row, index}) => {
return (
<div>
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
</div>
)
}
}
]
})
const compositeParam = (item) => {
return {
fileId: item.id,
size: item.size,
originalFileName: item.originalFilename,
fileType: item.fileType,
url: item.url,
newFile: true,
tag: formData.value.tagName,
}
}
const getFiles = (val) => {
showTable.value = false
let fileObj = compositeParam(val)
// emit("getFile", fileObj)
fileList.value.push(fileObj)
nextTick(() => {
showTable.value = true
})
}
watch(() => fileList.value, (val) => {
fileList.value = val
})
defineExpose({
fileList
})
</script>
<style scoped>
</style>

View File

@@ -74,7 +74,7 @@ const props = defineProps({
},
height:{
type: Number,
default: 450
default: 500
}
})
const content = ref(props.value);

View File

@@ -0,0 +1,52 @@
<template>
<el-tooltip
effect="dark"
:content="props.content"
placement="bottom-start"
:disabled="isShow"
>
<div :class="lines?'content-lines':'content'" :style="{width: props.width}" @mouseover="isShowTooltip">
<span ref="contentRef">
<slot name="content">{{ props.content }}</slot>
</span>
</div>
</el-tooltip>
</template>
<script setup>
const props = defineProps({
content: {
type: String,
default: ''
},
width: {
type: String,
default: '100%'
},
lines: {
type: Boolean,
default: false
}
})
const contentRef = ref()
const isShow = ref(false)
const isShowTooltip = () => {
isShow.value = props.width > contentRef.value.offsetWidth;
}
</script>
<style>
.content {
width: 45px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.content-lines{
word-break:break-all;
overflow:hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
display: -webkit-box;
-webkit-box-orient: vertical;
}
</style>

View File

@@ -0,0 +1,49 @@
<template>
<baseTitle title="公司详情"></baseTitle>
<fv-Form :schema="schema" @getInstance="(e)=>form = e"></fv-Form>
</template>
<script setup>
import {getCompanyDetail} from "@/api/subsidiary";
const props=defineProps({
value:{
type:String,
default:''
}
})
const form = ref()
const schema = reactive([
{
label: '公司名称:',
prop: 'companyName',
},
{
label: '公司编码:',
prop: 'companyCode'
},
{
label: '创建时间:',
prop: 'createTime'
}
])
const emit = defineEmits(['update:value'])
const _value = computed({
get() {
return props.value;
},
set(value) {
emit('update:value', value)
}
})
const getInfo = async () => {
const { data } = await getCompanyDetail(_value.value)
form.value.setValues(data)
}
getInfo()
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,172 @@
<template>
<baseTitle title="公司详情"></baseTitle>
<fv-Form :schema="companySchema" @getInstance="(e)=>companyForm = e"></fv-Form>
<baseTitle title="部门详情"></baseTitle>
<fv-Form :schema="schema" @getInstance="(e)=>form = e"></fv-Form>
<UserPicker ref="usrPickershipIds" @ok="editshipIds"></UserPicker>
<UserPicker ref="usrPickerHeadIds" @ok="editheadIds"></UserPicker>
<UserPicker ref="departmentalDeputyIds" @ok="editdeputyIds"></UserPicker>
</template>
<script setup lang="jsx">
import UserPicker from '@/views/workflow/process/common/UserPicker.vue';
import Ttsup from '@/views/system/department/components/ToolToShowUserPicker.vue'
import {getInfoById,setDeptInfo} from '@/views/system/department/api'
const props=defineProps({
value:{
type:String,
default:''
}
})
const form = ref()
const companyForm = ref()
const usrPickershipIds = ref()
const usrPickerHeadIds = ref()
const usrPickerDeputyIds = ref()
const departmentChargeLeadershipNames = ref()
const departmentHeadNames = ref()
const departmentalDeputyNames = ref()
const departmentChargeLeadershipIds = ref()
const departmentHeadIds = ref()
const departmentalDeputyIds = ref()
const companySchema = reactive([
{
label: '公司名称:',
prop: 'companyName',
},
{
label: '公司编码:',
prop: 'companyCode'
},
{
label: '创建时间:',
prop: 'createTime'
}
])
const schema = reactive([
{
label: '部门名字:',
prop: 'departmentName',
},
{
label: '部门标志:',
prop: 'departmentMark'
},
{
label: '部门分管领导:',
prop: 'departmentChargeLeadershipIds',
component: ()=><Ttsup modelValue={departmentChargeLeadershipNames.value} onClick={()=>{usrPickershipIds.value.showUserPicker()} } />
},
{
label: '部门负责人:',
prop: 'departmentHeadIds',
component: ()=><Ttsup modelValue={departmentHeadNames.value} onClick={()=>{usrPickerHeadIds.value.showUserPicker()} } />
},
{
label: '部门副职用户:',
prop: 'departmentalDeputyIds',
component: ()=><Ttsup modelValue={departmentalDeputyNames.value} onClick={()=>{departmentalDeputyIds.value.showUserPicker()} } />
},
{
label: '创建时间:',
prop: 'createTime'
}
])
const emit = defineEmits(['update:value'])
const _value = computed({
get() {
return props.value;
},
set(value) {
emit('update:value', value)
}
})
const getInfo = async () => {
const { data } = await getInfoById(_value.value)
companyForm.value.setValues(data.company)
const params = {
createTime: data.createTime,
departmentMark: data.departmentMark,
departmentName: data.departmentName
}
departmentChargeLeadershipIds.value = data.departmentChargeLeadershipIds
departmentHeadIds.value = data.departmentHeadIds
departmentalDeputyIds.value = data.departmentalDeputyIds
params.departmentChargeLeadershipIds = formatIdsToNames(data.departmentChargeLeadershipIds, data.departmentChargeLeadershipInfo, 'userId', 'nickName')
departmentChargeLeadershipNames.value = params.departmentChargeLeadershipIds
params.departmentHeadIds = formatIdsToNames(data.departmentHeadIds, data.departmentHeadInfo, 'userId', 'nickName')
departmentHeadNames.value = params.departmentHeadIds
params.departmentalDeputyIds = formatIdsToNames(data.departmentalDeputyIds, data.departmentalDeputyInfo, 'userId', 'nickName')
departmentalDeputyNames.value = params.departmentalDeputyIds
form.value.setValues(params)
}
getInfo()
const formatIdsToNames = (ids, infoList, key, viewKey) => {
const resArr = []
if(!ids?.length) return
ids.forEach(item=>{
infoList.forEach(v=>{
item == v[key] && resArr.push(v[viewKey])
})
})
return resArr.join(',')
}
const editshipIds = (list) => {
// console.log("🚀 ~ editshipIds ~ list:", list)
const arr = list.map(item=>item.name)
departmentChargeLeadershipIds.value = list.map(item=>item.id)
departmentChargeLeadershipNames.value = arr.join(',')
setDeptmentInfo({
departmentChargeLeadershipIds: departmentChargeLeadershipIds.value,
departmentalDeputyIds: departmentalDeputyIds.value,
departmentHeadIds: departmentHeadIds.value
})
}
const editheadIds = (list) => {
// console.log("🚀 ~ editshipIds ~ list:", list)
const arr = list.map(item=>item.name)
departmentHeadIds.value = list.map(item=>item.id)
departmentHeadNames.value = arr.join(',')
setDeptmentInfo({
departmentChargeLeadershipIds: departmentChargeLeadershipIds.value,
departmentalDeputyIds: departmentalDeputyIds.value,
departmentHeadIds: departmentHeadIds.value
})
}
const editdeputyIds = (list) => {
// console.log("🚀 ~ editshipIds ~ list:", list)
const arr = list.map(item=>item.name)
departmentalDeputyIds.value = list.map(item=>item.id)
departmentalDeputyNames.value = arr.join(',')
setDeptmentInfo({
departmentChargeLeadershipIds: departmentChargeLeadershipIds.value,
departmentalDeputyIds: departmentalDeputyIds.value,
departmentHeadIds: departmentHeadIds.value
})
}
const setDeptmentInfo = async ({ departmentChargeLeadershipIds = [], departmentHeadIds = [], departmentalDeputyIds = []}) => {
const params = {
departmentChargeLeadershipIds,
departmentHeadIds,
departmentalDeputyIds,
departmentId: _value.value
}
const res = await setDeptInfo(params)
// console.log(res.data);
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,15 @@
import request from '@/utils/request'
export const getBaseInfoApi = (projectId) => {
return request({
url: '/workflow/details/info/'+projectId,
method: 'get',
})
}
export const getMapProjectStateInfo = (projectId, state) => {
return request({
url: `/workflow/details/${projectId}/${state}`,
method: 'get'
})
}

View File

@@ -0,0 +1,362 @@
<template>
<baseTitle title="基础信息"></baseTitle>
<fvForm :schema="schema" @getInstance="(e)=>baseForm = e"></fvForm>
<div class="steps-box">
<el-steps v-if="stepsShow" :active="localActive" finish-status="success">
<el-step
v-for="(item, index) in localSteps"
:key="item.key"
:title="item.title"
:class="stepClass(index)"
@click="handleStep(item.key, index)"
>
<template #icon>
<el-icon style="font-size: 20px;" :class="index == localActive ? 'is-active' : 'is-end'"
v-if="localStepSuccess.includes(index)">
<SuccessFilled/>
</el-icon>
<el-icon style="font-size: 20px; color: gray;" v-else>
<WarningFilled/>
</el-icon>
</template>
</el-step>
</el-steps>
</div>
<!-- 步骤内容 -->
<div>
<slot name="content" :localActive="localActive"></slot>
<!-- <template v-for="(item, index) in stepList" :key="item.key">
<component v-if="localActive == index" v-bind="item.props || {}" :is="item.component" />
</template> -->
</div>
</template>
<script setup lang="jsx">
import {ElLoading, ElNotification} from 'element-plus';
import {computed, onMounted, reactive, ref, watchEffect} from 'vue';
import {useRoute} from 'vue-router';
import {getBaseInfoApi} from './api';
const props = defineProps({
// 步骤对应内容list
stepList: {
type: Array,
default: []
},
// 当前显示步骤
active: {
type: Number,
default: 0
},
// 已完成的工作流步骤
stepSuccess: {
type: Array,
default: ['00']
},
//直接上报/需求征集
reportType: {
type: String,
default: ''
}
})
const route = useRoute()
const emits = defineEmits(['stepChange', 'setDetail'])
const localData = reactive({})
const localActive = ref(0) // 当前激活步骤
const stepsShow = ref(false)
const localSteps = ref([
{
title: '需求征集',
key: 'collect',
},
{
title: '需求上报',
key: 'report',
},
{
title: '项目立项',
key: 'approve',
},
{
title: '项目验收',
key: 'execute',
},
{
title: '项目归档',
key: 'archivist',
},
// {
// title: '项目结项',
// key: 'end',
// },
])
const baseForm = ref()
const schema = computed(() => {
return [
{
label: '项目名称',
prop: 'projectName',
colProps: {
span: 8
}
},
{
label: '征集公司',
prop: 'affiliatedCompany',
colProps: {
span: 8
}
},
{
label: '征集名称',
prop: 'requirementName',
colProps: {
span: 8
}
},
{
label: '征集描述',
prop: 'collectExplain',
colProps: {
span: 24
}
},
]
})
const localStepSuccess = ref([])
// 格式化详情步骤条
const formatProcedure = (data) => {
let arr = []
if (data instanceof Array) {
data.forEach(item => {
if (props.reportType === 'direct') {
switch (item) {
case '10':
arr.push(0)
break
case '20':
arr.push(1)
break
case '40':
arr.push(2)
break
case '50':
arr.push(3)
break
}
} else {
switch (item) {
case '00':
arr.push(0)
break
case '10':
arr.push(1)
break
case '20':
arr.push(2)
break
case '40':
arr.push(3)
break
case '50':
arr.push(4)
break
}
}
})
}
return arr
}
// 反向格式化
const formatReProcedure = (data) => {
let arr = []
if (data instanceof Array) {
data.forEach(item => {
switch (item) {
case 0:
arr.push('00')
break
case 1:
arr.push('10')
break
case 2:
arr.push('20')
break
// case 3: arr.push('30')
// break
case 3:
arr.push('40')
break
case 4:
arr.push('50')
break
}
})
}
}
const formatActive = (val) => {
let newVal
if (props.reportType === 'direct') {
newVal = val + 1
} else {
newVal = val
}
let active = ''
newVal == 0 && (active = '00')
newVal == 1 && (active = '10')
newVal == 2 && (active = '20')
// val == 3 && (active = '30')
newVal == 3 && (active = '40')
newVal == 4 && (active = '50')
return active
}
const stepClass = (val) => {
if (localStepSuccess.value.includes(val)) {
return 'step-success'
}
return 'step-error'
}
const handleStep = (key, index) => {
if (localStepSuccess.value.includes(index)) {
let active = ''
localActive.value = index
if (props.reportType === 'direct') {
switch (index) {
case 0:
active = '10'
break
case 1:
active = '20'
break
case 2:
active = '40'
break
case 3:
active = '50'
break
}
} else {
switch (index) {
case 0:
active = '00'
break
case 1:
active = '10'
break
case 2:
active = '20'
break
case 3:
active = '40'
break
case 4:
active = '50'
break
}
}
emits('stepChange', {key, active})
return
}
ElNotification({
title: '提示',
message: '不能查看未完成的工作流信息',
type: 'warning'
})
}
const getBaseInfo = async () => {
const loading = ElLoading.service({fullscreen: true})
stepsShow.value = false
try {
const {code, data} = await getBaseInfoApi(route.query.projectId)
// console.log('data.procedure', data.procedure, route.query.step)
if (route.query.step === '40') {
if (data.procedure.indexOf('40') == -1) {
data.procedure.push('40')
}
} else if (route.query.step === '50') {
if (data.procedure.indexOf('50') == -1) {
data.procedure.push('50')
}
}
localStepSuccess.value = formatProcedure(data.procedure)
baseForm.value.setValues(data)
emits('setDetail', formatActive(localActive.value))
loading.close()
nextTick(() => {
stepsShow.value = true
})
} catch {
loading.close()
nextTick(() => {
stepsShow.value = true
})
}
}
getBaseInfo()
// onActivated(() => {
// getBaseInfo()
// })
watchEffect(() => {
localActive.value = props.active
})
watchEffect(() => {
if (props.reportType === 'direct') {
let steps = []
for (const step of localSteps.value) {
if (step.key !== 'collect'){
steps.push(step)
}
}
localSteps.value = steps
}
})
</script>
<style lang="scss" scoped>
.steps-box {
padding: 10px 0;
}
.step-success {
cursor: pointer;
}
.step-error {
cursor: not-allowed;
}
.is-active {
color: #67c23a;
}
.is-end {
color: #BEA266;
}
:deep(.el-step__title.is-success) {
color: #A8abb2;
}
:deep(.el-step__head.is-success) {
border-color: #A8abb2;
}
</style>

View File

@@ -8,7 +8,7 @@ export const hasPerm = (el, binding, vnode) => {
if (value && value instanceof Array && value.length > 0) {
const permissiosFlag = value
const hasPermission = permisstions.some(permission => {
return permissiosFlag[0] === allPermission || permissiosFlag[0] === permission
return permission === allPermission || permissiosFlag.includes(permission) || permissiosFlag.includes(allPermission)
})
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)

View File

@@ -23,6 +23,7 @@
v-bind="item.props || {}"
v-on="item.on || {}"
v-model="form[item.prop]"
@keyup.enter.native="getValues"
>
</component>
</template>
@@ -66,15 +67,15 @@ const filterConfig = computed(() => {
})
// 搜索功能表单元素默认值
const setDefaultFormValues = () => {
filterConfig.value.forEach(item => {
form.value[item.prop] = item.props?.defaultValue || null
})
}
// const setDefaultFormValues = () => {
// filterConfig.value.forEach(item => {
// form.value[item.prop] = item.props?.defaultValue || null
// })
// }
watchEffect(() => {
if (filterConfig.value.length) {
setDefaultFormValues()
// setDefaultFormValues()
}
})
@@ -86,7 +87,7 @@ const getValues = () => {
//重置
const handleReset = () => {
form.value = {}
setDefaultFormValues()
// setDefaultFormValues()
emits('search', form.value)
}

View File

@@ -3,64 +3,71 @@
<!-- 表格头部按钮 -->
<div class="fv-table-btn" v-if="tableConfig.btns">
<div class="table-head-btn">
<el-button
v-for="btn in tableConfig.btns"
:key="btn.key"
:type="btn.type || ''"
v-perm="btn.auth || ['*:*:*']"
@click="handleClickBtns(btn.key)"
<el-button
v-for="btn in tableConfig.btns"
:key="btn.key"
:type="btn.type || ''"
:color="btn.color || ''"
v-perm="btn.auth || ['*:*:*']"
@click="handleClickBtns(btn.key)"
>
{{ btn.name }}
</el-button>
</div>
<!-- 列显示配置 -->
<div v-if="isSettingCol">
<el-tooltip effect="dark" content="列配置" placement="bottom">
<el-button ref="buttonRef" link>
<el-icon size="18"><Setting /></el-icon>
</el-button>
</el-tooltip>
<el-popover
placement="bottom"
:width="200"
</div>
<!-- 列显示配置 -->
<div v-if="isSettingCol" style="float: right">
<el-button v-if="tableConfig.export && tableConfig.export.open" @click="exportTable" color="#DED0B2"
style="margin-bottom: 10px">导出
</el-button>
<el-tooltip effect="dark" content="列配置" placement="bottom">
<el-button ref="buttonRef" link>
<el-icon size="18">
<Setting/>
</el-icon>
</el-button>
</el-tooltip>
<el-popover
placement="bottom"
:width="200"
ref="popoverRef"
:virtual-ref="buttonRef"
virtual-triggering
trigger="click">
<div class="col-setting-checkall">
<el-checkbox label="列展示" v-model="localData.allColShow" :indeterminate="localData.indeterminate" @change="changeIsShowAll"></el-checkbox>
</div>
<div class="col-setting-list">
<el-checkbox-group v-model="localData.checkGroup" @change="changeColShow">
<el-space direction="vertical" alignment="flex-start" :size="0">
<el-checkbox
v-for="item in tableConfig.columns"
:key="item.prop"
:label="item.label"
<div class="col-setting-checkall">
<el-checkbox label="列展示" v-model="localData.allColShow" :indeterminate="localData.indeterminate"
@change="changeIsShowAll"></el-checkbox>
</div>
<div class="col-setting-list">
<el-checkbox-group v-model="localData.checkGroup" @change="changeColShow">
<el-space direction="vertical" alignment="flex-start" :size="0">
<el-checkbox
v-for="item in tableConfig.columns"
:key="item.prop"
:label="item.label"
:value="item.prop"
/>
</el-space>
</el-checkbox-group>
</div>
</el-popover>
</div>
/>
</el-space>
</el-checkbox-group>
</div>
</el-popover>
</div>
<!-- 表格部分 -->
<div class="fv-table">
<el-table
:data="localData.list"
v-loading="localData.loading"
:row-key="tableConfig?.rowKey || 'id'"
v-bind="$attrs"
table-layout="auto"
:show-overflow-tooltip="true"
highlight-current-row
@selection-change="selectionChange"
@row-click="rowClick"
@row-dblclick="rowDblclick"
@cell-click="cellClick"
v-tabh
ref="tableInstance"
:data="localData.list"
v-loading="localData.loading"
:row-key="tableConfig?.rowKey || 'id'"
v-bind="$attrs"
table-layout="auto"
:show-overflow-tooltip="true"
highlight-current-row
@selection-change="selectionChange"
@row-click="rowClick"
@row-dblclick="rowDblclick"
@cell-click="cellClick"
v-tabh
ref="tableInstance"
>
<template #default>
<fvTableColumn v-for="column in localData.columns" :key="column.prop" :columns="column">
@@ -81,22 +88,23 @@
</el-table>
<!-- 分页 -->
<fvPagination
v-if="pagination"
:current-page="localData.query.pageNum"
:page-size="localData.query.pageSize"
:page-sizes="[10, 20, 30, 40,50]"
:total="localData.total"
@changeSize="handleSizeChange"
@goPage="handleCurrentChange"
>
v-if="pagination"
:current-page="localData.query.pageNum"
:page-size="localData.query.pageSize"
:page-sizes="[10, 20, 30, 40,50]"
:total="localData.total"
@changeSize="handleSizeChange"
@goPage="handleCurrentChange"
>
</fvPagination>
</div>
</div>
</template>
<script setup>
import { ElMessage } from 'element-plus';
import { requestList } from '../../api/common';
import {ElNotification} from 'element-plus';
import {requestList} from '../../api/common';
import {exportExcel} from "@/utils/export-excel";
const props = defineProps({
//表格配置
@@ -125,6 +133,20 @@ const tableInstance = ref()
const buttonRef = ref()
const popoverRef = ref()
const exportTable = () => {
const $e = tableInstance.value.$el
let $table = $e.querySelector('.el-table__fixed')
if (!$table) {
$table = $e
}
let fileName = ""
if (props.tableConfig.export && props.tableConfig.export) {
fileName = props.tableConfig.export.fileName
}
exportExcel($table, Object.keys(localData.list[0]), fileName)
}
const localData = reactive({
list: [], // 表格数据
query: {
@@ -140,15 +162,15 @@ const localData = reactive({
checkGroup: []
})
const emits = defineEmits(['headBtnClick', 'selectionChange', 'rowClick', 'rowDblclick', 'getBaseQuery', 'cellClick'])
const emits = defineEmits(['headBtnClick', 'selectionChange', 'rowClick', 'rowDblclick', 'getBaseQuery', 'cellClick', 'getTotal'])
const handleClickBtns = (key) => {
emits('headBtnClick', key)
}
const filterColumns = () => {
localData.columns = props.tableConfig.columns.map(item=>{
if(item.prop) {
localData.columns = props.tableConfig.columns.map(item => {
if (item.prop) {
return {
...item
}
@@ -157,10 +179,10 @@ const filterColumns = () => {
}
const changeIsShowAll = (val) => {
if(val) {
if (val) {
filterColumns()
localData.indeterminate = false
localData.checkGroup = props.tableConfig.columns.map(item=>item.prop)
localData.checkGroup = props.tableConfig.columns.map(item => item.prop)
} else {
localData.columns.length = 0
localData.checkGroup.length = 0
@@ -169,10 +191,10 @@ const changeIsShowAll = (val) => {
}
const changeColShow = (val) => {
if(val.length == props.tableConfig.columns.length) {
if (val.length == props.tableConfig.columns.length) {
localData.indeterminate = false
localData.allColShow = true
} else if(val.length !== props.tableConfig.columns.length && val.length != 0) {
} else if (val.length !== props.tableConfig.columns.length && val.length != 0) {
localData.allColShow = false
localData.indeterminate = true
} else {
@@ -180,9 +202,9 @@ const changeColShow = (val) => {
localData.allColShow = false
}
const template = []
props.tableConfig.columns.forEach(item=>{
val.forEach(v=>{
if(item.prop == v) {
props.tableConfig.columns.forEach(item => {
val.forEach(v => {
if (item.prop == v) {
template.push(item)
}
})
@@ -193,22 +215,43 @@ const changeColShow = (val) => {
filterColumns()
const getList = async () => {
const { api, params } = props.tableConfig
const {api, params} = props.tableConfig
const queryParmas = {...localData.query, ...params}
if(api) {
if (api) {
localData.loading = true
try {
const { code, data, msg } = await requestList(api, queryParmas)
if ( code === 1000 ) {
localData.list = data.rows
const {code, data, msg} = await requestList(api, queryParmas).then(res=>{
// console.log(res)
return res
})
// console.log(code,data,msg)
if (code === 1000) {
if (data.rows) {
localData.list = data.rows
} else {
localData.list = data
}
localData.total = data.total
emits('getTotal', localData.total)
localData.loading = false
} else {
ElMessage.error(msg)
ElNotification({
title: '提示',
message: msg,
type: 'error'
})
localData.loading = false
}
} catch (error) {
ElMessage.error('请求数据失败')
console.log("error",error)
if (!error){
return
}
ElNotification({
title: '提示',
message: '请求数据失败',
type: 'error'
})
localData.loading = false
}
} else {
@@ -245,13 +288,13 @@ const handleCurrentChange = (val) => {
getList()
}
watchEffect(()=>{
if(localData.allColShow) {
localData.checkGroup = props.tableConfig.columns.map(item=>item.prop)
watchEffect(() => {
if (localData.allColShow) {
localData.checkGroup = props.tableConfig.columns.map(item => item.prop)
}
})
//刷新
const refresh = ({resetPage=false}={}) => {
const refresh = ({resetPage = false} = {}) => {
resetPage ? localData.query.pageNum = 1 : null
getList()
}
@@ -264,30 +307,40 @@ const getQuery = () => {
return localData.query
}
defineExpose({ refresh, updateLoading, getQuery, tableInstance })
defineExpose({refresh, updateLoading, getQuery, tableInstance})
onMounted(() => {
getList()
})
</script>
<style lang="scss" scoped>
.col-setting-checkall {
border-bottom: 1px solid rgb(210, 210, 213);
}
.col-setting-list {
max-height: 45vh;
overflow-y: auto;
}
.table-head-btn {
display: flex;
justify-content: flex-start;
align-items: center;
}
.fv-table-btn {
display: flex;
justify-content: space-between;
align-content: center;
}
.fv-table {
:deep(.el-tooltip) {
width: 100% !important;
}
}
</style>

View File

@@ -3,7 +3,7 @@
<router-view v-slot="{ Component, route }">
<transition name="fade-transform" type="transition" appear mode="out-in">
<div>
<template v-if="!route.meta.noCache">
<template v-if="route.meta.noCache">
<keep-alive>
<suspense>
<component :is="Component" :key="route.fullPath" />

View File

@@ -1,10 +1,10 @@
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item v-for="(item, index) in breadcrumbList" :key="item.path">
<span v-if="item.meta.noRedirect || index === breadcrumbList.length-1" class="no-redirect">
<span v-if="item.meta.noRedirect || index === breadcrumbList.length-1" class="no-redirect font">
{{ item.meta.title }}
</span>
<router-link v-else :to="item.redirect || item.path">
<router-link class="font" v-else :to="item.redirect || item.path">
{{ item.meta.title }}
</router-link>
</el-breadcrumb-item>
@@ -12,13 +12,13 @@
</template>
<script setup>
import { useRoute, useRouter } from 'vue-router';
import {useRoute, useRouter} from 'vue-router';
const route = useRoute()
const router = useRouter()
watch(route, ()=> {
watch(route, () => {
getBreadcrumb()
})
@@ -29,7 +29,7 @@ const breadcrumbList = ref([])
const getBreadcrumb = () => {
let matched = route.matched.filter(item => item.meta && item.meta.title)
const first = matched[0]
if(!isDashboard(first)) {
if (!isDashboard(first)) {
matched = [{path: '/home', meta: {title: '首页'}}].concat(matched)
}
breadcrumbList.value.length = 0;
@@ -39,7 +39,7 @@ const getBreadcrumb = () => {
const isDashboard = (meta) => {
const name = meta && meta.name
if(!name) {
if (!name) {
return
}
return name.trim().toLocaleLowerCase() === 'Home'.toLocaleLowerCase()
@@ -47,3 +47,9 @@ const isDashboard = (meta) => {
getBreadcrumb()
</script>
<style scoped lang="scss">
.font {
// font-size: 18px;
}
</style>

View File

@@ -2,6 +2,7 @@
<div class="toggle" @click="toggleClick">
<component :is="siderbarStore.getSiderBarStatus() ? 'Fold' : 'Expand'" class="icon"></component>
</div>
<span class="sys-name">科技创新项目管理平台</span>
</template>
<script setup>
@@ -13,8 +14,14 @@ const toggleClick = () => {
</script>
<style lang="scss" scoped>
.sys-name {
padding: 0 10px;
font-weight: bold;
}
.toggle{
line-height: 65px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
padding: 0 15px;
cursor: pointer;
&:hover {

View File

@@ -3,16 +3,55 @@
<Hamburger></Hamburger>
<Breadcrumb></Breadcrumb>
<div class="right-bar">
<bell-socket/>
<!-- <bell-socket/>-->
<div class="user-box">
<div>
<!-- <img :src="userInfo.avatar" alt="" @click.stop="handleVisitedP">-->
<span @click.stop="handleVisitedP">欢迎回来{{userInfo.userName}}</span>
</div>
<div @click.stop="handleVisitedP">
<el-avatar>{{ userInfo.nickName }}</el-avatar>
<div>{{ userInfo.nickName }}
<el-icon style="margin-left: 5px">
<ArrowDownBold/>
</el-icon>
</div>
</div>
<div class="person" v-if="visitedP">
<ul>
<li @click="handleToAuth">个人中心</li>
<li @click="handleLogout">退出登录</li>
<li>主次账号切换</li>
<li class="avatar-li" v-for="item in accountList" @click="accountChange(item.userId)">
<el-badge :value="item.taskCount" v-if="item.taskCount!==0">
<el-avatar>{{ item.nickName }}</el-avatar>
</el-badge>
<el-avatar v-else>{{ item.nickName }}</el-avatar>
<div class="right-li">
<div class="name-line">
<span v-if="item.accountType==='0'" class="zhu"></span>
<span class="nickName">{{ item.nickName }}</span>
<span :title="item.jobActivityDesc">{{ item.jobActivityDesc }}</span>
</div>
<div>
<span :title="item.companyName+'/'+item.departmentName">{{ item.companyName }}/{{
item.departmentName
}}</span>
</div>
</div>
<div>
<el-icon color="#3f89dc" size="20" v-if="item.current">
<SuccessFilled/>
</el-icon>
</div>
<!-- <li v-for="item in accountList" :label="item.userName" :value="item.userId"/>-->
</li>
<li @click="handleToAuth">
<el-icon color="gray" size="20" style="margin-right: 5px">
<UserFilled/>
</el-icon>
个人中心
</li>
<li @click="handleLogout">
<el-icon color="gray" size="20" style="margin-right: 5px">
<SwitchButton/>
</el-icon>
退出登录
</li>
</ul>
</div>
</div>
@@ -25,14 +64,20 @@ import {useRouter} from 'vue-router';
import Breadcrumb from './Breadcrumb.vue';
import Hamburger from './Hamburger.vue';
import {useAuthStore} from '@/stores/userstore.js'
import BellSocket from "./BellSocket.vue";
import {getUserInfo} from "../../api/login";
import {usePermisstionStroe} from '@/stores/permisstion'
import {useTagsView} from '@/stores/tagsview';
import {getUserAccount} from "@/api/user/user";
import {switchAccount} from "@/api/login";
import {setToken} from "../../utils/auth";
import {ElNotification} from "element-plus";
const authStore = useAuthStore()
const permisstionStore = usePermisstionStroe()
const tagsViewStore = useTagsView()
const userInfo = ref({})
const visitedP = ref(false)
const accountList = ref([])
const route = useRoute()
const router = useRouter()
onMounted(() => {
setUserInfo()
@@ -41,16 +86,37 @@ onMounted(() => {
onBeforeUnmount(() => {
document.removeEventListener('click', nullBlockClick)
})
const setUserInfo = () => {
getUserInfo().then(res=>{
userInfo.value = res.data.user
})
const setUserInfo = () => {
userInfo.value = authStore.userinfo
}
const nullBlockClick = () => {
visitedP.value = false
}
const handleVisitedP = () => {
visitedP.value = !visitedP.value
getUserAccount().then(res => {
if (res.code !== 1000) {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
accountList.value = res.data
nextTick(() => {
visitedP.value = !visitedP.value
})
})
}
const accountChange = (userId) => {
switchAccount(userId).then(res => {
if (res.code === 1000) {
visitedP.value = !visitedP.value
authStore.userLogout()
setToken(res.data)
window.location.href = "/home"
}
})
}
const handleToAuth = () => {
@@ -61,11 +127,34 @@ const handleLogout = () => {
visitedP.value = !visitedP.value
authStore.userLogout()
permisstionStore.removeMenu()
permisstionStore.setIsSuccessReq()
tagsViewStore.removeAllTagView()
router.push('/login')
}
</script>
<style lang="scss" scoped>
:deep(.el-avatar--circle) {
display: inline-block;
line-height: 40px;
margin-right: 14px;
background-color: #8a7243;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
:deep(.el-badge) {
padding: 0 2px;
}
:deep(.el-badge__content.is-fixed) {
position: absolute;
right: 26px;
top: 2px;
}
.navbar {
height: 65px;
padding: 0 15px 0 0;
@@ -74,22 +163,27 @@ const handleLogout = () => {
align-items: center;
background-color: #fff;
border-radius: 10px;
.right-bar {
margin-left: auto;
display: flex;
justify-content: flex-start;
align-items: center;
.user-box{
.user-box {
cursor: pointer;
margin-left: 10px;
position: relative;
>div:first-child{
display:flex;
> div:first-child {
display: flex;
align-items: center;
>span{
margin-left: 5px;
> div {
display: flex;
align-items: center;
}
img {
width: 40px;
height: 40px;
@@ -101,24 +195,85 @@ const handleLogout = () => {
.person {
font-size: 14px;
color: #666666;
position: absolute;
width: 80px;
width: 280px;
right: 0;
z-index: 300;
bottom: -70px;
padding: 10px 5px;
top: 54px;
padding: 5px 0;
border-radius: 4px;
background-color: #fff;
box-shadow: 2px 2px 2px 1px rgb(171, 167, 167);
.avatar-li {
display: flex;
height: 60px;
.right-li {
color: #909090;
display: flex;
flex-direction: column;
.name-line {
margin-bottom: 5px;
width: 184px;
-webkit-line-clamp: 1;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
.zhu {
display: inline-block;
width: 20px;
height: 20px;
line-height: 20px;
background-color: #fa0;
color: #fff;
text-align: center;
}
.nickName {
color: #4d7ad8;
}
> span {
margin-right: 5px;
}
}
> div:last-child {
width: 194px;
-webkit-line-clamp: 1;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
}
}
li {
text-align: center;
padding: 0 6px;
height: 28px;
display: flex;
align-items: center;
text-align: left;
font-size: 14px;
line-height: 1.5;
cursor: pointer;
border-bottom: 1px solid #e6e6e6;
&:hover {
color: #79bbff;
color: #666666 !important;
background-color: #eaeaea;
}
&:first-child:hover {
background-color: #fff;
}
&:last-child {
border-bottom: none;
}
}
}

View File

@@ -1,7 +1,7 @@
<template>
<!-- 有子菜单 -->
<template v-for="item in menuItem" :key="item.path">
<el-sub-menu v-if="item?.children?.length>0 && !item.hidden" :index="item.path">
<el-sub-menu v-if="checkMenuItem(item)" :index="item.path">
<template #title>
<svg-icon :name="item.icon"/>
<span>{{ item.title }}</span>
@@ -17,7 +17,9 @@
</a>
</div>
<div v-else>
<svg-icon :name="item.icon"/>
<el-icon>
<svg-icon :name="item.icon" class="menu-item-icon"/>
</el-icon>
<span>{{ item.title }}</span>
</div>
</template>
@@ -44,5 +46,26 @@ const handleGo = (path) => {
}
}
const checkMenuItem = (item) => {
let children = item.children
let childState = false;
if (children){
for (let child of children) {
if (!child.hidden) {
childState = true
break
}
}
}
return item?.children?.length>0 && !item.hidden && childState
}
</script>
<!-- <style lang="scss" scoped>
.menu-item-icon {
width: 18px !important;
height: 18px !important;
margin-left: 0;
}
</style> -->

View File

@@ -1,6 +1,8 @@
<template>
<div class="logo" ref="logo">
<span v-if="!siderbarStore.isCollapse">科研管理平台</span>
<img src="../../assets/kylogo.png" alt="">
<!-- <span v-if="!siderbarStore.isCollapse">科研管理平台</span> -->
<span v-if="!siderbarStore.isCollapse"></span>
</div>
<el-scrollbar :height="`calc(100vh - ${logoHeight}px)`" style="background-color: #ffffff">
<el-menu

View File

@@ -25,6 +25,36 @@ const router = createRouter({
name: 'casLogin',
component: () => import('@/views/cas-login/index.vue'),
},
{
path: '/projectdetail/mobile',
name: 'projectDetailMobile',
component: () => import('@/views/project-management/mobledetail/index.vue')
},
{
path: '/fund/mobile',
name: 'specialFundDetailMobile',
component: () => import('@/views/project-management/mobledetail/SpecialFundDetailMobile.vue')
},
{
path: '/share/mobile',
name: 'shareDetailMobile',
component: () => import('@/views/project-management/mobledetail/ShareDetailMobile.vue')
},
{
path: '/projectDemand/requirement/moblie',
name: 'projectDemandRequirementMoblie',
component: () => import('@/views/project-demand/requirement/moblieDetail/index.vue')
},
{
path: '/expenseManagement/share/moblie',
name: 'expenseManagementMoblie',
component: () => import('@/views/expense-management/share/moblieDetail/index.vue')
},
{
path: '/phase/detail/moblie',
name: 'phaseDetailMoblie',
component: () => import('@/views/project-management/phaseDetailMoblie/index.vue')
},
{
path: '/',
name: 'layout',
@@ -52,15 +82,6 @@ const router = createRouter({
breadcrumb: true
}
},
{
path: '/rapid/gen/edit/:tableId(\\d+)',
name: 'genEdit',
component: () => import('@/views/rapid/gen/editTable.vue'),
meta: {
title: '数据库生成配置',
breadcrumb: true
}
},
{
path: '/workflow/process/edit/:deploymentId',
name: 'processEdit',
@@ -80,7 +101,7 @@ const router = createRouter({
}
},
{
path: '/workflow/process/edit',
path: '/workflow/process/add',
name: 'processAdd',
component: () => import('@/views/workflow/process/ProcessEdit.vue'),
meta: {
@@ -124,53 +145,58 @@ const router = createRouter({
breadcrumb: false
}
},
// 项目详情
{
path: '/custom/query/sql/design/:queryId',
name: 'sql',
component: () => import('@/views/custom-query/sql/SqlDesign.vue'),
path: '/project/management/implementation/implementation/detail',
name: 'Implementation/detail',
component: () => import('@/views/project-management/implementation/detail.vue'),
meta: {
title: '自定义sql查询配置',
breadcrumb: true
title: '项目详情',
breadcrumb: false
}
},
// 需求征集详情
{
path: '/custom/query/data/adapter/design/:queryId',
name: 'dataAdapter',
component: () => import('@/views/custom-query/data-adapter/DataAdapterDesign.vue'),
path: '/project/demand/requirement/requirement/detail',
name: 'Requirement/detail',
component: () => import('@/views/project-demand/requirement/detail.vue'),
meta: {
title: '自定义数据适配器',
breadcrumb: true
title: '需求征集-详情',
breadcrumb: false
}
},
// 需求汇总详情
{
path: '/custom/query/echarts/design/:queryId',
name: 'echarts',
component: () => import('@/views/custom-query/echarts-editor/EchartsDesign.vue'),
path: '/project/demand/summary/summary/detail',
name: 'Summary/detail',
component: () => import('@/views/project-demand/summary/detail.vue'),
meta: {
title: '自定义echarts查询配置',
breadcrumb: true
title: '需求汇总-详情',
breadcrumb: false
}
},
// 专项资金详情
{
path: '/rapid/data/:dsId(\\d+)',
name: 'rapid',
component: () => import('@/views/rapid/gen/index.vue'),
path: '/special/fund/fund/detail',
name: 'Fund/detail',
component: () => import('@/views/special-fund/detail.vue'),
meta: {
title: '数据源关联数据',
breadcrumb: true
title: '专项资金-详情',
breadcrumb: false
}
},
// 费用分摊详情
{
path: '/expense/management/expense/share/share/detail',
name: 'Share/detail',
component: () => import('@/views/expense-management/share/detail.vue'),
meta: {
title: '费用分摊-详情',
breadcrumb: false
}
},
]
},
{
path: '/topo/design/:queryId',
name: 'topEdit',
component: () => import('@/views/custom-query/topo/topologyDesign.vue'),
meta: {
title: 'top',
breadcrumb: false
}
},
{
path: '/forbidden',
name: 'forbidden',
@@ -203,7 +229,7 @@ router.beforeEach(async (to, form, next) => {
NProgress.done()
} else {
permisstionStore.setIsLoadRoutes(true)
if (permisstionStore.isLoadRoutes && permisstionStore.asyncRouters.length == 0) {
if (permisstionStore.isLoadRoutes && !permisstionStore.isSussessReq) {
await permisstionStore.setAsyncRouters()
await authStore.setUserInfo()
next({...to, replace: true})

View File

@@ -1,5 +1,5 @@
import { defineStore } from "pinia";
import { defineAsyncComponent, ref } from "vue";
import { defineAsyncComponent, ref, toRaw } from "vue";
import { getRouters } from "@/api/system/menu";
import Layout from '@/layout/index.vue'
import ParentView from '@/components/ParentView.vue'
@@ -10,6 +10,7 @@ export const usePermisstionStroe = defineStore('permisstion', () => {
const asyncRouters = ref([])
//定义是否加载路由变量
const isLoadRoutes = ref(false)
const isSussessReq = ref(false)
const menuList = ref([
{
name: 'home',
@@ -21,19 +22,28 @@ export const usePermisstionStroe = defineStore('permisstion', () => {
}
}
])
// 二级页面路由list
const slRouters = ref([])
const setIsLoadRoutes = (status) => {
return isLoadRoutes.value = status
}
const setIsSuccessReq = () => {
return isSussessReq.value = false
}
const setAsyncRouters = async () => {
await getRouters().then(res => {
if (res.code === 1000) {
const sRouter = JSON.parse(JSON.stringify(res.data))
const mData = JSON.parse(JSON.stringify(res.data))
asyncRouters.value = formatAsyncRouters(sRouter)
console.log(JSON.parse(JSON.stringify(sRouter)), 'sRouter');
const firstFormat = setRouterLevel(JSON.parse(JSON.stringify(sRouter)))
asyncRouters.value = formatAsyncRouters(JSON.parse(JSON.stringify(firstFormat)))
menuList.value = [...menuList.value, ...generateMenu(mData)]
addAsyncRouters(asyncRouters.value)
isLoadRoutes.value = false
isSussessReq.value = true
} else {
isLoadRoutes.value = true
setTimeout(() => setAsyncRouters(), 3000)
@@ -41,6 +51,23 @@ export const usePermisstionStroe = defineStore('permisstion', () => {
})
}
const setRouterLevel = (routers) => {
return routers.filter(item=>{
if(item.component === 'Layout') {
if(item.children) {
item.children.forEach(v=>{
if(v.children) {
slRouters.value = [...toRaw(slRouters.value), ...v.children]
delete v.children
}
})
item.children = [...item.children, ...toRaw(slRouters.value)]
}
}
return true
})
}
const formatAsyncRouters = (routers) => {
return routers.filter(route => {
if (route.component) {
@@ -48,8 +75,7 @@ export const usePermisstionStroe = defineStore('permisstion', () => {
route.component = Layout
} else if (route.component === 'ParentView') {
route.component = ParentView
}
else {
} else {
route.component = loadView(route.component)
}
}
@@ -126,8 +152,10 @@ export const usePermisstionStroe = defineStore('permisstion', () => {
asyncRouters,
menuList,
isLoadRoutes,
isSussessReq,
setAsyncRouters,
setIsLoadRoutes,
removeMenu
removeMenu,
setIsSuccessReq
}
})
})

View File

@@ -39,8 +39,8 @@ export const useProcessStore = defineStore('process', () => {
}
const delProcess = (delNode) => {
processData.value.process.splice(processData.value.process.indexOf(delNode), 1)
console.log("删除数据")
console.log(processData.value.process)
// console.log("删除数据")
// console.log(processData.value.process)
}
const getDesign = () => {

View File

@@ -53,7 +53,11 @@ export const useTagsView = defineStore('tagsView',()=>{
//路由到末尾标签页
const toLastTagView = (view) => {
const lastTagView = view.value.slice(-1)[0]
router.push(lastTagView.path)
router.push({path: lastTagView.path, query: lastTagView.query})
}
const removeAllTagView = () => {
visitedViews.value.length = 0
}
return {
@@ -61,6 +65,7 @@ export const useTagsView = defineStore('tagsView',()=>{
addVisitedViews,
delVisitedViews,
delOtherVisitedViews,
delViewAndGoView
delViewAndGoView,
removeAllTagView
}
})

View File

@@ -9,7 +9,7 @@ export const useAuthStore = defineStore('auth', () => {
const permisstions = ref([])
const roles = ref([])
const casToken = (token) => {
console.log('getToken()!==token',getToken()!==token)
// console.log('getToken()!==token',getToken()!==token)
let flag=''
if(getToken()!==token){//切换token
setToken(token)

9
src/utils/changePrice.js Normal file
View File

@@ -0,0 +1,9 @@
export const toThousands = (num) => {
let newNum=Number(num)
if (newNum == undefined || newNum == null) return '--';
const options = {
style: 'currency',
currency: 'CNY',
};
return (newNum).toLocaleString('zh-CN', options)
}

42
src/utils/date.js Normal file
View File

@@ -0,0 +1,42 @@
export const dateFormat = (time = new Date().getTime(),flag) => { //YYYY年MM月DD日 星期d
const _time = time.toString().length > 10 ? time : time * 1000
const weekList = ["日","一", "二", "三", "四", "五", "六" ];
const date = new Date(_time);
const Y = date.getFullYear();
const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1);
const Mm = (date.getMonth() + 1 < 10 ? (date.getMonth() + 1) : date.getMonth() + 1);
const D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
const h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours());
const m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes());
const s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
let weekDay = new Date().getDay();
const week= weekList[weekDay]
// const strDate = `${Y}/${M}/${D} ${h}:${m}:${s}`
if(flag){
return `${Mm}`;
}else {
return `${Y}${M}${D}日 星期${week}`;
}
}
export const getNowFormatDate = (flag) => {
let date = new Date(),
year = date.getFullYear(), //获取完整的年份(4位)
month = date.getMonth() + 1, //获取当前月份(0-11,0代表1月)
strDate = date.getDate() // 获取当前日(1-31)
if (month < 10) month = `0${month}` // 如果月份是个位数在前面补0
if (strDate < 10) strDate = `0${strDate}` // 如果日是个位数在前面补0
if(flag){
return `${year}-${month}-${strDate}`
}else {
return `${year}-${month}`
}
}
export default {
dateFormat,
getNowFormatDate
}

131
src/utils/export-excel.js Normal file
View File

@@ -0,0 +1,131 @@
import {utils} from "xlsx";
import FileSaver from 'file-saver'
import XLSX from "xlsx-style-vite";
/**
* 导出excel
* @param $table 表格html dom元素
* @param columnLength 列长度
* @param excelName 导出文件名称
* @param bigWidthIndex 更宽列的索引
* @param bigWidthArray 更宽列数组索引
*/
export function exportExcel($table, columnLength, excelName, bigWidthIndex,bigWidthArray) {
//从el-table表生成工作簿对象
//使用原始的格式,保留表格中的格式如%、小数末尾的0等
let workbook = utils.table_to_book($table, {
raw: true
});
//列宽需要导出的表格有多少列这里的i就小于多少
// if(bigWidthArray&&bigWidthArray.length>0){
// for (let i = 1; i < columnLength; i++) {
// for (let j = 0; j < bigWidthArray.length; j++) {
// console.log('bigWidthArray[j]',bigWidthArray[j])
// if (i === bigWidthArray[j]) {
// workbook.Sheets.Sheet1["!cols"].push({wpx: 300});
// }
// }
// workbook.Sheets.Sheet1["!cols"].push({wpx: 100});
// }
// }else {
for (let i = 1; i < columnLength; i++) {
if (i === bigWidthIndex) {
workbook.Sheets.Sheet1["!cols"].push({wpx: 300});
}
workbook.Sheets.Sheet1["!cols"].push({wpx: 100});
}
// }
//设置单元格样式
for (const key in workbook.Sheets.Sheet1) {
if (
key !== "!cols" &&
key !== "!fullref" &&
key !== "!merges" &&
key !== "!ref" &&
key !== "!rows"
) {
//这里的s就是具体的样式如果想设置不一样的样式可以看xlsx-style文档
workbook.Sheets.Sheet1[key].s = {
//边框
border: {
top: {style: "thin"},
bottom: {style: "thin"},
left: {style: "thin",},
right: {style: "thin",}
},
//对齐
alignment: {
horizontal: "center",
vertical: "center",
wrapText: true
}
};
}
}
//修改合并单元格样式
let arr = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
//由于导出时合并单元格只识别左上角的单元格,合并单元格中其他单元格
//并不会存在,所以需要识别合并单元格中除左上角单元格外的单元格并添加
//带样式的单元格到其中不理解可以看四中的第2点。
try {
for (let item of workbook.Sheets.Sheet1["!merges"]) {
let style = {
border: {
top: {style: "thin"},
bottom: {style: "thin"},
left: {style: "thin",},
right: {style: "thin",}
},
alignment: {
horizontal: "center",
vertical: "center",
wrapText: true
}
};
let merge_s = {t: "s", v: "", s: style};
if (item.s.c === item.e.c) {
//纵向合并其中c为字母r为数字
let star = item.s.r;
let end = item.e.r;
for (let i = star + 1; i <= end; i++) {
workbook.Sheets.Sheet1[arr[item.s.c] + (i + 1)] = merge_s;
}
} else {
//横向合并
let star = item.s.c;
let end = item.e.c;
for (let i = star; i < end; i++) {
workbook.Sheets.Sheet1[arr[i + 1] + Number(item.s.r + 1)] = merge_s;
}
}
}
} catch (e) {
}
//将表格数据中的字符串转ArrayBuffer
function s2ab(s) {
let buf = new ArrayBuffer(s.length);
let view = new Uint8Array(buf);
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
return buf;
}
//这里的属性可以参考xlsx-style文档
let wbout = XLSX.write(workbook, {
bookType: "xlsx",
bookSST: false,
type: "binary"
});
try {
FileSaver.saveAs(
new Blob([s2ab(wbout)], {type: "application/octet-stream"}),
`${excelName}.xlsx`
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
}

13
src/utils/matterTree.js Normal file
View File

@@ -0,0 +1,13 @@
export const matterTree = (array,data, id) => {
if (id) {
data.forEach(item => {
if (item.value == id) {
array.push(item.label);
}
if (item.children && item.children.length > 0) {
matterTree(array,item.children,id)
}
})
return array;
}
}

View File

@@ -6,97 +6,105 @@ import {getToken, removeToken} from "./auth";
axios.defaults.headers['Content-Type'] = 'application/json'
const serveice = axios.create({
baseURL: import.meta.env.VITE_BASE_URL,
timeout: 6000
baseURL: import.meta.env.VITE_BASE_URL,
timeout: 6000
})
const axiosCanceler = new AxiosCanceler()
serveice.interceptors.request.use(config => {
const ACCESS_TOKEN = getToken() || ''
if (ACCESS_TOKEN !== undefined && ACCESS_TOKEN !== '') {
config.headers['Authorization'] = ACCESS_TOKEN
}
// 检查是否有重复请求, 有则取消掉
axiosCanceler.removePendingRequest(config)
// 将请求加入pendingMap
axiosCanceler.addPendingRequest(config)
return config
const ACCESS_TOKEN = getToken() || ''
if (ACCESS_TOKEN !== undefined && ACCESS_TOKEN !== '') {
config.headers['Authorization'] = ACCESS_TOKEN
}
// 检查是否有重复请求, 有则取消掉
axiosCanceler.removePendingRequest(config)
// 将请求加入pendingMap
axiosCanceler.addPendingRequest(config)
return config
}, error => {
Promise.reject(error)
Promise.reject(error)
})
serveice.interceptors.response.use(response => {
axiosCanceler.removePendingRequest(response.config)
//二进制数据直接返回
if (response.request.responseType === 'blob' || response.request.responseType === 'arraybuffer') {
return response.data
}
axiosCanceler.removePendingRequest(response.config)
// console.log(response,"response")
//二进制数据直接返回
if (response.request.responseType === 'blob' || response.request.responseType === 'arraybuffer') {
return response.data
}
// console.log("1")
return response.data
}, error => {
let response = error.response
const status = response.status;
switch (status) {
case 401:
ElMessageBox.confirm('登录状态已过期,请重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false
}).then(() => {
removeToken()
let path = window.location.pathname;
let query = window.location.search
sessionStorage.setItem('toView', JSON.stringify({
path: path,
query: query
}))
window.location.href = `${window.location.origin}/api/auth/cas/login`
})
return Promise.reject('会话已过期,请重新登录')
case 402:
break;
case 403:
console.log(response)
ElNotification({
title: '系统提示',
message: response.data.msg,
type: 'warning'
})
break;
case 404:
ElNotification({
title: '系统提示',
message: '不存在的地址',
type: 'error'
})
break;
case 405:
ElNotification({
title: '系统提示',
message: '传输格式错误,请检查',
type: 'error'
})
break;
case 511:
ElNotification({
title: '系统提示',
message: '禁止访问',
type: 'error'
})
removeToken()
window.location = '/forbidden'
break;
case 500:
if (response.data) {
return response.data
} else {
ElNotification({
title: '系统提示',
message: '系统未知错误',
type: 'error'
})
break;
}
}
return Promise.reject(error)
// console.log(error)
let response = error.response
if (!response) {
return Promise.reject()
}
const status = response.status;
if (!status) {
return Promise.reject()
}
switch (status) {
case 401:
// ElMessageBox.confirm('登录状态已过期,请重新登录', '系统提示', {
// confirmButtonText: '重新登录',
// cancelButtonText: '取消',
// type: 'warning',
// closeOnClickModal: false
// }).then(() => {
removeToken()
let path = window.location.pathname;
let query = window.location.search
sessionStorage.setItem('toView', JSON.stringify({
path: path,
query: query
}))
window.location.href = `${window.location.origin}/api/auth/cas/login`
// })
return Promise.reject('会话已过期,请重新登录')
case 402:
break;
case 403:
ElNotification({
title: '系统提示',
message: response.data.msg,
type: 'warning'
})
break;
case 404:
ElNotification({
title: '系统提示',
message: '不存在的地址',
type: 'error'
})
break;
case 405:
ElNotification({
title: '系统提示',
message: '传输格式错误,请检查',
type: 'error'
})
break;
case 511:
ElNotification({
title: '系统提示',
message: '禁止访问',
type: 'error'
})
removeToken()
window.location = '/forbidden'
break;
case 500:
if (response.data) {
return response.data
} else {
ElNotification({
title: '系统提示',
message: '系统未知错误',
type: 'error'
})
break;
}
}
return Promise.reject(error)
})
export default serveice

View File

@@ -6,37 +6,91 @@
<!-- 标题 -->
<template #header>
<div class="card-header">
<span>个人信息</span>
<div>个人信息</div>
</div>
</template>
<div class="userDetail">
<!-- 头像上传 -->
<div class="userImg">
<el-image class="avatar" :src="userParams.avatar" fit="fill"/>
<div class="userInfo_item">
<div style="display: flex;align-items: center">
<el-icon size="18" style="margin-right: 5px">
<User/>
</el-icon>
用户名:
</div>
<div>{{ userParams.userName }}</div>
</div>
<div class="userInfo_item">
<el-icon>
<UserFilled />
</el-icon>
用户呢称: <span>{{ userParams.nickName }}</span>
<div style="display: flex;align-items: center">
<el-icon size="18" style="margin-right: 5px">
<User/>
</el-icon>
用户名称:
</div>
<div>{{ userParams.nickName }}</div>
</div>
<div class="userInfo_item">
<div style="display: flex;align-items: center">
<el-icon size="18" style="margin-right: 5px">
<Notification/>
</el-icon>
工号:
</div>
<div>{{ userParams.workCode }}</div>
</div>
<div class="userInfo_item">
<div style="display: flex;align-items: center">
<el-icon size="18" style="margin-right: 5px">
<Phone/>
</el-icon>
电话号码:
</div>
<div>{{ userParams.mobile }}</div>
</div>
<div class="userInfo_item">
<div style="display: flex;align-items: center">
<el-icon size="18" style="margin-right: 5px">
<House/>
</el-icon>
所属公司:
</div>
<div>{{ userParams.subCompanyName }}</div>
</div>
<div class="userInfo_item">
<div style="display: flex;align-items: center">
<el-icon size="18" style="margin-right: 5px">
<FolderOpened/>
</el-icon>
所属部门:
</div>
<div>{{ userParams.departmentName }}</div>
</div>
<div class="userInfo_item">
<div style="display: flex;align-items: center">
<el-icon size="18" style="margin-right: 5px">
<Folder/>
</el-icon>
岗位:
</div>
<div>{{ userParams.jobActivityDesc }}</div>
</div>
<div class="userInfo_item">
<div style="display: flex;align-items: center">
<el-icon size="18" style="margin-right: 5px">
<Wallet/>
</el-icon>
账号类型:
</div>
<div>{{ userParams.accountType === '0' ? '主账号' : '次账号' }}</div>
</div>
<div class="userInfo_item">
<div style="display: flex;align-items: center">
<el-icon size="18" style="margin-right: 5px">
<User/>
</el-icon>
所属角色:
</div>
<div>{{ belongToRole(userParams.roles) }}</div>
</div>
<div class="userInfo_item"><el-icon>
<Iphone />
</el-icon>电话号码: <span>{{ userParams.phoneNumber }}</span> </div>
<div class="userInfo_item"><el-icon>
<Message />
</el-icon>用户邮箱:<span>{{ userParams.email }}</span> </div>
<div class="userInfo_item"><el-icon>
<HomeFilled />
</el-icon>所属部门: <span>{{ userParams.city }}</span> </div>
<div class="userInfo_item"><el-icon>
<OfficeBuilding />
</el-icon>所属角色: <span>{{ userParams.createBy }}</span> </div>
<div class="userInfo_item"><el-icon>
<Calendar />
</el-icon>创建日期:<span>{{ userParams.loginDate }}</span> </div>
</div>
<div>
</div>
</el-card>
</el-col>
@@ -45,143 +99,138 @@
<!-- 标题 -->
<template #header>
<div class="card-header">
<span>基本资料</span>
<div>{{ isInitPassword ? '修改密码' : '初始化密码' }}</div>
</div>
</template>
<el-tabs class="demo-tabs" v-model="activeName">
<el-tab-pane label="基本资料" name="first" >
<el-form
:model="userParams"
label-width="120px"
class="demo-ruleForm"
>
<el-form-item label="用户昵称" prop="userName" :required="true" style="text-align:left">
<el-input v-model="userParams.nickName"/>
</el-form-item>
<el-form-item label="手机号码" :required="true" style="text-align:left">
<el-input v-model="userParams.phoneNumber"/>
</el-form-item>
<el-form-item label="邮箱" prop="email" :required="true" style="text-align:left">
<el-input v-model="userParams.email"/>
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="userParams.sex">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">保存</el-button>
<el-button @click="close">关闭</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="修改密码" name="second">
<el-form label-width="120px" :model="userPassword">
<el-form-item label="旧密码" :required="true" style="text-align:left">
<el-input placeholder="请输入旧密码" v-model="userPassword.oldPassWord"/>
</el-form-item>
<el-form-item label="新密码" :required="true" style="text-align:left">
<el-input placeholder="请输入新密码" v-model="userPassword.newPassWord"/>
</el-form-item>
<el-form-item label="确认密码" :required="true" style="text-align:left">
<el-input placeholder="请确认新密码" v-model="userPassword.querenPassWord"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit2">保存</el-button>
<el-button @click="close">关闭</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
<el-form label-width="120px" ref="passwordRef" :model="userPassword" :rules="rules">
<el-form-item label="旧密码" prop="oldPassword" :required="true" style="text-align:left" v-if="isInitPassword">
<el-input placeholder="请输入旧密码" v-model="userPassword.oldPassword" type="password"/>
</el-form-item>
<el-form-item label="新密码" prop="newPassword" :required="true" style="text-align:left">
<el-input placeholder="请输入新密码" v-model="userPassword.newPassword" type="password"/>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword" :required="true" style="text-align:left">
<el-input placeholder="请确认新密码" v-model="userPassword.confirmPassword" type="password"/>
</el-form-item>
<el-form-item>
<el-button color="#DED0B2" @click="handleSubmit">提交</el-button>
<el-button @click="close">关闭</el-button>
</el-form-item>
</el-form>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script setup>
import {getUserInfo} from '@/api/login';
import {ref} from "vue";
import {modifyUser} from '@/api/auth/auth'
import { ElMessage } from 'element-plus'
import { useTagsView } from '@/stores/tagsview.js'
var userParams = ref({})
var userPassword=ref({
oldPassWord:'',
newPassWord:'',
querenPassWord:''
})
const activeName = ref('first')
import {ElNotification} from 'element-plus'
import {useTagsView} from '@/stores/tagsview.js'
import {getAuthInfo} from "@/api/login";
import {editPassword, initPassword} from "@/api/auth/auth";
const isInitPassword = ref(false);
const userParams = ref({});
const passwordRef = ref();
const router = useRouter()
const userPassword = ref({
oldPassword: '',
newPassword: '',
confirmPassword: ''
});
const tagsViewStore = useTagsView()
const getuserinfo=async ()=>{
await getUserInfo().then(res=>{
userParams.value=res.data.user
})
}
const validatePasswordComplexity = (rule, value, callback) => {
const reg = /^(?=.*[a-zA-Z])(?=.*\d).{1,9}$/; //密码必须是至少包含字母、数字1-9位
if (!reg.test(value)) {
callback(new Error("密码必须是至少包含字母、数字1-9位"));
} else {
callback();
}
};
// 修改资料
const submit=async ()=>{
await modifyUser({
userName:userParams.value.userName,
nickName:userParams.value.nickName,
phoneNumber:userParams.value.phoneNumber,
email:userParams.value.email,
sex:userParams.value.sex,
userId:userParams.value.userId
}).then(res=>{
console.log(res)
})
const validatePasswordEquality = (rule, value, callback) => {
if (userPassword.value.newPassword != value) {
callback(new Error("两次输入密码不一致!"));
} else {
callback();
}
}
// 修改密码
const submit2=async ()=>{
await getUserInfo().then( res=>{
if(res.data!=''){
console.log(res.data.user.password)
if (userPassword.value.oldPassWord==res.data.user.password && userPassword.value.newPassWord==userPassword.value.querenPassWord){
modifyUser({
userName:userParams.value.userName,
nickName:userParams.value.nickName,
password:userPassword.value.newPassWord,
userId:userParams.value.userId
}).then(res=>{
ElMessage({
message: '修改密码成功',
type: 'success',
})
})
}else if(userPassword.value.oldPassWord!=res.data.user.password && userPassword.value.newPassWord==userPassword.value.querenPassWord){
ElMessage({
message: '旧密码错误',
type: 'error',
})
}else if(userPassword.value.oldPassWord==res.data.user.password && userPassword.value.newPassWord!=userPassword.value.querenPassWord){
ElMessage({
message: '新密码与确认密码不同',
type: 'error',
})
}
}else{
ElMessage({
message: '请求错误',
type: 'error',
})
const rules = reactive({
oldPassword: [
{required: true, message: "旧密码不能为空", trigger: ["change", "blur"]},
],
newPassword: [
{required: true, message: "新密码不能为空", trigger: ["change", "blur"]},
{
required: true,
trigger: ["change", "blur"],
validator: validatePasswordComplexity
}
],
confirmPassword: [
{required: true, message: "确认密码不能为空", trigger: ["change", "blur"]},
{
required: true,
trigger: ["change", "blur"],
validator: validatePasswordEquality
}
],
})
const getInfo = async () => {
await getAuthInfo().then(res => {
userParams.value = res.data.user
isInitPassword.value = res.data.initPassword
})
}
const belongToRole = (roles) => {
if (!roles) return;
return roles.map(item => item.roleName).join('')
}
// 修改密码
const handleSubmit = async () => {
if (isInitPassword.value) {
editPassword({
...userPassword.value
}).then(res => {
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
passwordRef.value.resetFields()
}
})
} else {
initPassword({
newPassword: userPassword.value.newPassword,
confirmPassword: userPassword.value.confirmPassword
}).then(res => {
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
passwordRef.value.resetFields()
}
})
}
}
// 关闭
const close = () => {
tagsViewStore.delVisitedViews({
path:"/auth",meta:{hidden: false, title: '个人中心', breadcrumb: true}})
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
router.push('/')
}
onMounted(()=>{
getuserinfo()
onMounted(() => {
getInfo()
})
</script>
<style lang="scss">
body,div {
body, div {
margin: 0;
padding: 0;
}
@@ -189,32 +238,39 @@ body,div {
.my {
margin: 0 auto;
margin-top: 20px;
.userDetail {
.userImg {
height: 170px;
text-align: center;
border-bottom-style: solid;
border-color: #daddd2;
border-width: 1px;
.avatar {
width: 150px;
height: 150px;
border-radius: 50%;
}
}
}
.userInfo_item {
height: 40px;
.userDetail {
.userImg {
height: 170px;
text-align: center;
border-bottom-style: solid;
border-color: #daddd2;
border-width: 1px;
text-align: left;
line-height: 40px;
}
.userInfo_item > span {
float: right;
.avatar {
width: 150px;
height: 150px;
border-radius: 50%;
}
}
}
</style>
.userInfo_item {
display: flex;align-items: center;
justify-content: space-between;
height: 40px;
border-bottom-style: solid;
border-color: #daddd2;
border-width: 1px;
//text-align: left;
//line-height: 40px;
}
//
//.userInfo_item > div {
// float: right;
//}
}
</style>

View File

@@ -1,71 +0,0 @@
<template>
<el-form ref="queryForm" class="query-form" :model="queryParams">
<el-row :gutter="20">
<el-col :span="16">
<div class="code-editor">
<java-code-edit v-model="queryParams.code" :editor-placeholder="'请输入java代码'" :editor-height="250"
:tab-size="2"/>
</div>
</el-col>
<el-col :span="8">
<el-form-item label="模拟数据" prop="mockData">
<el-input v-model="queryParams.mockData" placeholder="请输入模拟数据" :rows="4" type="textarea" clearable>
</el-input>
</el-form-item>
<el-button type="primary" @click="handleSave">保存</el-button>
<el-button type="primary" @click="handleExecute">执行</el-button>
</el-col>
</el-row>
</el-form>
</template>
<script setup>
import JavaCodeEdit from "@/components/codeEdit/JavaCodeEdit.vue";
import {ElMessage} from "element-plus";
import {executeAdapterMockData, getDataAdapterDetails,editDataAdapter} from "@/api/custom-query/adapter";
import {useRouter} from "vue-router";
const router = useRouter();
const queryId = reactive(router.currentRoute.value.params.queryId)
const queryParams = ref({
adapterName:null,
type:null,
source:"CUSTOM",
code: null,
mockData: null
})
const getDetails = async () => {
await getDataAdapterDetails(queryId).then(res => {
if (res.code === 1000) {
queryParams.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
getDetails()
const handleSave=()=>{
editDataAdapter(queryParams.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
} else {
ElMessage.error(res.msg)
}
})
}
const handleExecute = () => {
executeAdapterMockData(queryParams.value).then(res => {
console.log('handleExecute',res)
if (res.code === 1000) {
ElMessage.success(res.msg)
} else {
ElMessage.error(res.msg)
}
})
}
</script>
<style scoped>
</style>

View File

@@ -1,285 +0,0 @@
<template>
<el-form :model="queryParams" inline class="query-form" ref="queryForm">
<el-form-item label="适配器名称" prop="adapterName">
<el-input v-model="queryParams.adapterName" placeholder="请输适配器名称"></el-input>
</el-form-item>
<el-form-item label="适配器来源" prop="source">
<el-select v-model="queryParams.source" placeholder="请选择适配器来源" clearable filterable>
<el-option
v-for="item in cacheStore.getDict('data_adapter_source')"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="代码类型" prop="type">
<el-select v-model="queryParams.type" placeholder="请选择数据适配器代码类型" clearable filterable>
<el-option
v-for="item in cacheStore.getDict('data_adapter_type')"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList" :icon="Search">搜索</el-button>
<el-button @click="handleReset" :icon="Refresh">重置</el-button>
</el-form-item>
</el-form>
<div class="query-btn">
<el-button type="primary" v-perm="['query:adapter:add']" @click="handleAdd" :icon="Plus" plain>新增</el-button>
<el-button type="danger" :icon="Delete" v-perm="['query:adapter:del']"
@click="handleMoreDelete(adapterIds)" :disabled="disabled" plain>删除
</el-button>
<el-button type="warning" v-perm="['query:adapter:export']" @click="handleExport" :icon="Download" plain>导出
</el-button>
</div>
<div class="table">
<el-table
:data="list"
row-key="adapterId"
:lazy="true"
ref="singleTable"
v-loading="loading"
@select="handleSelect"
v-tabh
>
<el-table-column type="selection" width="55"/>
<el-table-column label="序号" type="index" width="60"/>
<el-table-column prop="adapterName" label="适配器名称" align="center"/>
<el-table-column prop="type" label="代码类型" align="center">
<template #default="scope">
<tag dict-type="data_adapter_type" :value="scope.row.type"/>
</template>
</el-table-column>
<el-table-column prop="source" label="适配器来源" align="center">
<template #default="scope">
<tag dict-type="data_adapter_source" :value="scope.row.source"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button type="primary" size="mini" v-perm="['query:adapter:edit']"
@click="handleEdit(scope.row.adapterId)" link>编辑
</el-button>
<el-button type="primary" size="mini"
@click="handleDesign(scope.row)" link>设计
</el-button>
<popover-delete :name="scope.row.adapterName" :type="'适配器'" :perm="['query:adapter:del']"
@delete="handleDelete(scope.row.adapterId)"/>
</template>
</el-table-column>
</el-table>
</div>
<paging :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :page-sizes="[10, 20, 30, 40,50]"
:total="total" @changeSize="handleSizeChange" @goPage="handleCurrentChange"/>
<el-dialog v-model="isVisited" :title="title" width="700px">
<el-form :model="form" ref="formInstance" class="dialog-form">
<el-row>
<el-col :span="24">
<el-form-item label="适配器名称" prop="adapterName">
<el-input v-model="form.adapterName" placeholder="请输入适配器名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="数据适配器代码类型" prop="type">
<el-select v-model="form.type" placeholder="请选择数据适配器代码类型" clearable filterable>
<el-option
v-for="item in cacheStore.getDict('data_adapter_type')"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="适配器来源" prop="source">
<el-select v-model="form.source" placeholder="请选择适配器来源" clearable filterable>
<el-option
v-for="item in cacheStore.getDict('data_adapter_source')"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="11">
</el-col>
</el-row>
</el-form>
<template #footer>
<span>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit(formInstance)">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
getDataAdapterList,
getDataAdapterDetails,
addDataAdapter,
editDataAdapter,
delDataAdapter
} from "@/api/custom-query/adapter";
import {ElMessage, ElMessageBox} from "element-plus";
import {Search, Refresh, Delete, Plus, Edit, Download} from '@element-plus/icons-vue'
import Paging from "@/components/pagination/index.vue";
import {useCacheStore} from "@/stores/cache";
import {useRouter} from "vue-router";
const router = useRouter()
const cacheStore = useCacheStore()
const queryParams = reactive({
adapterName: '',
source: '',
type: '',
})
const pageInfo = reactive({
pageNum: 1,
pageSize: 10,
})
const list = ref([])
const queryForm = ref([])
const loading = ref(true)
const disabled = ref(true)
const total = ref()
const title = ref('')
const isVisited = ref(false)
const form = ref()
const formInstance = ref()
const adapterIds = ref([])
const adapterNameList = ref([])
//获取数据
const getList = async () => {
let params = {
...queryParams,
...pageInfo
}
loading.value = true
getDataAdapterList(params).then(res => {
if (res.code === 1000) {
list.value = res.data.rows
total.value = res.data.total
loading.value = false
} else {
ElMessage.error(res.msg)
}
})
}
//重置from表单
const restFrom = () => {
form.value = {
adapterName: null,
source: "CUSTOM",
type: null
}
}
//添加
const handleAdd = async () => {
restFrom()
title.value = "新增数据源适配器"
isVisited.value = true
nextTick(() => {
// 清空校验
formInstance.value.clearValidate()
})
}
//修改
const handleEdit = async (id) => {
restFrom()
getDataAdapterDetails(id).then(res => {
if (res.code === 1000) {
form.value = res.data
title.value = "编辑数据源适配器"
isVisited.value = true
nextTick(() => {
// 清空校验
formInstance.value.clearValidate()
})
} else {
ElMessage.error(res.msg)
}
})
}
//设计
const handleDesign = (row) => {
router.push({path: `/custom/query/data/adapter/design/${row.adapterId}`})
}
//删除
const handleDelete = async (adapterId) => {
delDataAdapter(adapterId).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
} else {
ElMessage.error(res.msg)
}
})
}
//多删
const handleMoreDelete=(adapterIds)=>{
ElMessageBox.confirm(`确认删除名称为${adapterNameList.value}的适配器吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
handleDelete(adapterIds)
})
}
//勾选table数据行事件
const handleSelect = async (selection) => {
if (selection.length !== 0) {
disabled.value = false
adapterIds.value = selection.map(item => item.adapterId).join()
adapterNameList.value = selection.map(item => item.adapterName).join()
} else {
disabled.value = true
}
}
//取消
const handleCancel = () => {
restFrom()
isVisited.value = false
}
//提交
const handleSubmit = async (instance) => {
if (!instance) return
instance.validate(async (valid) => {
if (!valid) return
if (title.value === '新增数据源适配器') {
addDataAdapter(form.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
isVisited.value = false
} else {
ElMessage.error(res.msg)
}
})
} else {
editDataAdapter(form.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
isVisited.value = false
} else {
ElMessage.error(res.msg)
}
})
}
})
}
getList()
</script>
<style scoped>
</style>

View File

@@ -1,392 +0,0 @@
<template>
<div>
<el-form :model="queryParams" inline class="query-form" ref="queryForm">
<el-form-item label="数据模型名称" prop="dsName">
<el-input v-model="queryParams.dsName" placeholder="请输入数据模型名称" clearable></el-input>
</el-form-item>
<el-form-item label="数据库名称" prop="dbName">
<el-input v-model="queryParams.dbName" placeholder="请输入数据库名称" clearable></el-input>
</el-form-item>
<el-form-item label="配置类型" prop="configType">
<el-select v-model="queryParams.configType" placeholder="请选择配置类型" clearable filterable>
<el-option label="主机" value="1"/>
<el-option label="JDBC" value="2"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch" :icon="Search">搜索</el-button>
<el-button @click="handleReset" :icon="Refresh">重置</el-button>
</el-form-item>
</el-form>
<div class="query-btn">
<el-button type="primary" v-perm="['query:source:add']" @click="handleAdd" :icon="Plus" plain>新增</el-button>
<el-button type="danger" :icon="Delete" v-perm="['query:source:del']"
@click="handleMoreDelete(sourceId,sourceName)" :disabled="disabled" plain>删除
</el-button>
<el-button type="warning" v-perm="['query:source:export']" @click="handleExport" :icon="Download" plain>导出
</el-button>
</div>
<div class="table">
<el-table
:data="list"
row-key="id"
:lazy="true"
ref="singleTable"
v-loading="loading"
@select="handleSelect"
v-tabh
>
<el-table-column type="selection" width="55"/>
<el-table-column label="序号" type="index" width="60" align="center"/>
<el-table-column prop="dsName" label="数据模型名称" align="center"/>
<el-table-column prop="dbName" label="数据库名称" align="center"/>
<el-table-column prop="username" label="数据模型用户名" align="center"/>
<el-table-column prop="type" label="数据模型类型" align="center"/>
<el-table-column prop="confType" label="数据模型配置类型" align="center">
<template #default="scope">
<tag dict-type="data_source_config" :value="scope.row.configType"/>
</template>
</el-table-column>
<el-table-column prop="url" label="数据模型连接地址" align="center">
<template #default="scope">
<div class="formatterUrl">{{ scope.row.url }}</div>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button type="primary" size="mini" v-perm="['query:source:edit']"
@click="handleEdit(scope.row.id)" link>编辑
</el-button>
<popover-delete :name="scope.row.dsName" :type="'数据模型'" :perm="['query:source:del']"
@delete="handleDelete(scope.row.id)"/>
</template>
</el-table-column>
</el-table>
</div>
<paging :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :page-sizes="[10, 20, 30, 40,50]"
:total="total" @changeSize="handleSizeChange" @goPage="handleCurrentChange"/>
<el-dialog v-model="isVisited" :title="title" width="900px">
<el-form :model="form" ref="formInstance" :rules="formRules" class="dialog-form" :validate-on-rule-change="false">
<el-row>
<el-col :span="11">
<el-form-item label="数据模型名称" prop="dsName">
<el-input v-model="form.dsName" placeholder="请输入数据模型名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="数据模型用户名" prop="username">
<el-input v-model="form.username" placeholder="请输入数据模型用户名"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="数据模型密码" prop="password">
<el-input v-model="form.password" placeholder="请输入数据模型密码"></el-input>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="数据模型类型" prop="type">
<el-select v-model="form.type" placeholder="请选择数据模型类型" filterable @change="handleTypeChange(form.type)">
<el-option
v-for="typeItem in typeList"
:key="typeItem.value"
:label="typeItem.label"
:value="typeItem.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="配置类型" prop="configType">
<el-radio-group v-model="form.configType">
<el-radio border :label="1">主机</el-radio>
<el-radio border :label="2">JDBC</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2" v-if="form.configType === 1">
<el-form-item label="数据模型端口" prop="port">
<el-input-number v-model="form.port"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="11" v-if="form.configType === 1">
<el-form-item label="数据模型服务地址" prop="host">
<el-input v-model="form.host" placeholder="请输入数据模型服务地址"></el-input>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="数据库名称" prop="dbName" v-if="form.configType === 1">
<el-input v-model="form.dbName" placeholder="请输入数据库名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="24" v-if="form.configType === 2">
<el-form-item label="数据模型连接地址" prop="url">
<el-input v-model="form.url" :rows="4"
type="textarea" placeholder="请输入数据模型连接地址"></el-input>
</el-form-item>
</el-col>
<el-col :span="24" v-if="form.configType === 1">
<el-form-item label="配置参数" prop="args">
<el-input v-model="form.args" :rows="4"
type="textarea" placeholder="请输入配置参数"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="服务名称" prop="params.serviceName" v-if="form.type === 'ORACLE' && form.configType===1">
<el-input v-model="form.params.serviceName" placeholder="请输入服务名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="命名空间" prop="params.namespace" v-if="form.type === 'POSTGRES' && form.configType===1">
<el-input v-model="form.params.namespace" placeholder="请输入命名空间"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit(formInstance)">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import {
getDataSourceManageList,
getDataSourceManageDetails,
addDataSourceManage,
editDataSourceManage,
delDataSourceManage,
getDataSourceType
} from "@/api/custom-query/datamodel";
import {Search, Refresh, Delete, Plus, Edit, Download} from '@element-plus/icons-vue'
import {ElMessage, ElMessageBox} from "element-plus";
import {downLoadExcel} from "@/utils/downloadZip";
import Paging from "@/components/pagination/index.vue";
//查询参数
const queryParams = reactive({
dsName: '',
dbName: '',
type: '',
})
//页面信息
const pageInfo = reactive({
pageNum: 1,
pageSize: 10,
})
const disabled = ref(true)
const typeList = ref([])
const list = ref([])
const queryForm = ref([])
const loading = ref(true)
const total = ref()
const sourceId = ref()
const sourceName = ref()
const singleTable = ref()
const title = ref('')
const isVisited = ref(false)
const form = ref()
const formInstance = ref()
const formRules = ref({
dsName: [{required: true, message: '请输入数据模型名称', trigger: 'blur'}],
username: [{required: true, message: '请输入数据模型用户名', trigger: 'blur'}],
password: [{required: true, message: '请输入数据模型密码', trigger: 'blur'}],
type: [{required: true, message: '请选择数据模型类型', trigger: 'blur'}],
configType: [{required: true, message: '请选择配置类型', trigger: 'blur'}],
port: [{required: true, message: '请输入数据模型端口', trigger: 'blur'}],
host: [{required: true, message: '请输入数据模型服务地址', trigger: 'blur'}],
dbName: [{required: true, message: '请输入数据库名称', trigger: 'blur'}],
url: [{required: true, message: '请输入数据模型连接地址', trigger: 'blur'}],
params: {
serviceName: [{required: true, message: '请输入服务名称', trigger: 'blur'}],
namespace: [{required: true, message: '请输入命名空间', trigger: 'blur'}]
}
})
const getTypeOption = () => {
getDataSourceType().then(res => {
typeList.value = res.data
})
}
const handleTypeChange = (type) => {
if (form.value.configType !== 1) {
return;
}
if (type === 'ORACLE') {
form.value.params = {
serviceName: ''
}
}
if (type === 'POSTGRES') {
form.value.params = {
namespace: ''
}
}
}
//搜索功能
const handleSearch = () => {
getList()
}
//重置搜索
const handleReset = () => {
queryForm.value.resetFields()
getList()
}
//获取数据
const getList = async () => {
let params = {
...queryParams,
...pageInfo
}
loading.value = true
getDataSourceManageList(params).then(res => {
if (res.code === 1000) {
list.value = res.data.rows
total.value = res.data.total
loading.value = false
} else {
ElMessage.error(res.msg)
}
})
}
//重置from表单
const restFrom = () => {
form.value = {
dsName: null,
username: null,
password: null,
host: null,
port: 0,
type: null,
dbName: null,
configType: 1,
url: null,
args: null,
params: {}
}
}
//取消
const handleCancel = () => {
restFrom()
isVisited.value = false
}
//提交
const handleSubmit = async (instance) => {
if (!instance) return
instance.validate(async (valid) => {
if (!valid) return
if (title.value === '新增数据模型管理') {
addDataSourceManage(form.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
isVisited.value = false
} else {
ElMessage.error(res.msg)
}
})
} else {
editDataSourceManage(form.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
isVisited.value = false
} else {
ElMessage.error(res.msg)
}
})
}
})
}
//添加
const handleAdd = async () => {
formRules.value.password[0].required = true
restFrom()
title.value = "新增数据模型管理"
isVisited.value = true
nextTick(() => {
// 清空校验
formInstance.value.clearValidate()
})
}
//修改
const handleEdit = async (id) => {
restFrom()
getDataSourceManageDetails(id).then(res => {
if (res.code === 1000) {
console.log('res', res.data)
formRules.value.password[0].required = false
form.value = res.data
title.value = "编辑数据模型管理"
isVisited.value = true
nextTick(() => {
// 清空校验
formInstance.value.clearValidate()
})
} else {
ElMessage.error(res.msg)
}
})
}
//导出excel
const handleExport = () => {
downLoadExcel('/query/query/source/export', {...queryParams})
}
//勾选table数据行的 Checkbox
const handleSelect = async (selection) => {
if (selection.length !== 0) {
disabled.value = false
sourceId.value = selection.map(item => item.id).join()
sourceName.value = selection.map(item => item.dsName).join()
} else {
disabled.value = true
}
}
//切换每页显示条数
const handleSizeChange = async (val) => {
pageInfo.pageSize = val
await getList()
}
//点击页码进行分页功能
const handleCurrentChange = async (val) => {
pageInfo.pageNum = val
await getList()
}
//删除
const handleDelete = async (id) => {
delDataSourceManage(id).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
} else {
ElMessage.error(res.msg)
}
})
}
//多删
const handleMoreDelete = (sourceId, sourceName) => {
ElMessageBox.confirm(`确认删除名称为${sourceName}的数据模型吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
handleDelete(sourceId)
})
}
getTypeOption()
getList()
</script>
<style scoped>
.formatterUrl {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
</style>

View File

@@ -1,233 +0,0 @@
<template>
<div>
<EchartsEditor :info="initInfo" :line-data="lineChartsItem" :bar-data="barChartsItem" :pie-data="pieChartsItem"
:radar-data="radarChartsItem" :radar-indicator="indicator" @getFinalInfo="getFinalInfo"/>
</div>
</template>
<script setup>
import EchartsEditor from "./components/EchartsEditor.vue";
//入参
const lineChartsItem = ref([
{
id: 1,
unit: '年份',
type: '',
dataType: 'key',
color: '',
label: '年份',
symbol: "",
symbolSize: 0,
showSymbol: false,
lineStyle: {
shadowColor: '',//阴影颜色
shadowBlur: 0,//图形阴影的模糊大小
opacity: 1
},
data: ['2013', '2014', '2015', '2016', '2017', '2018']
},
{
id: 2,
unit: '年销量',
type: 'line',
dataType: 'value',
color: '#9a60b4',//图形颜色
label: '华北',
symbol: "triangle",//标记的图形circle:圆形,rect:矩形,triangle:三角形,diamond:钻石形,roundRect:圆角矩形,pin:圆钉形,arrow:箭头形,none:不显示标记
symbolSize: 8,//标记的大小
showSymbol: true,//是否显示标记,如果 false 则只有在 tooltip hover 的时候显示。
lineStyle: {
shadowColor: '',//阴影颜色
shadowBlur: 0,//图形阴影的模糊大小
opacity: 1//图形透明度
},
data: [40, 80, 20, 120, 140, 50]
},
{
id: 3,
unit: '年销量',
type: 'line',
dataType: 'value',
color: '#3ba272',
label: '华东',
symbol: "circle",
symbolSize: 8,
showSymbol: true,
lineStyle: {
shadowColor: '',//阴影颜色
shadowBlur: 0,//图形阴影的模糊大小
opacity: 1
},
data: [140, 180, 120, 40, 50, 150]
},
{
id: 4,
unit: '年销量',
type: 'line',
dataType: 'value',
color: '#5470c6',
label: '华南',
symbol: "rect",
symbolSize: 8,
showSymbol: true,
lineStyle: {
shadowColor: '',//阴影颜色
shadowBlur: 0,//图形阴影的模糊大小
opacity: 1
},
data: [110, 143, 68, 90, 120, 130]
}
])
const barChartsItem = ref([
{
id: 1,
unit: '年份',
type: '',
dataType: 'key',
color: '',
label: '年份',
showBackground: false,
backgroundStyle: {
color: '',
borderWidth: 0,
borderColor: '',
borderType: 'solid',
},
data: ['2013', '2014', '2015', '2016', '2017', '2018']
},
{
id: 2,
unit: '销售金额',
type: 'bar',
dataType: 'value',
color: '#9a60b4',//图形颜色
label: '王五',
showBackground: true,//是否显示柱条的背景色
backgroundStyle: {
color: '#e5e2e2',//柱条的颜色
borderWidth: 0,//柱条的描边宽度,默认不描边。
borderColor: '#000',//柱条的描边颜色
borderType: 'dotted',//柱条的描边类型,默认为实线,支持 'dashed', 'dotted'
},
data: [40, 80, 20, 120, 140, 50]
},
{
id: 3,
unit: '销售金额',
type: 'bar',
dataType: 'value',
color: '#3ba272',
label: '李四',
showBackground: true,
backgroundStyle: {
color: '#e5e2e2',
borderWidth: 0,
borderColor: '#000',
borderType: 'dashed',
},
data: [140, 180, 120, 40, 50, 150]
},
{
id: 4,
unit: '销售金额',
type: 'bar',
dataType: 'value',
color: '#2644a4',
label: '张三',
showBackground: true,
backgroundStyle: {
color: '#e5e2e2',
borderWidth: 0,
borderColor: '#000',
borderType: 'solid',
},
data: [110, 143, 68, 90, 120, 130]
}
])
const pieChartsItem = ref([
{id: 1, label: '京东', dataType: 'value', value: 335},
{id: 2, label: '菜鸟', dataType: 'value', value: 310},
{id: 3, label: '总部', dataType: 'value', value: 234},
{id: 4, label: '小电商', dataType: 'value', value: 135},
])
const radarChartsItem = ref([
{label: 'Allocated Budget', dataType: 'value', data: [4200, 3000, 20000, 35000, 50000, 18000]},
{label: 'Actual Spending', dataType: 'value', data: [5000, 14000, 28000, 26000, 42000, 21000]},
])
//定义好echarts的配置数据
let initInfo = reactive({
xValueAxis: [],
yValueAxis: [],
//echarts配置数据
echartsOptions: {
//图例
legend: {
data: [],
selected: {},
selectedMode: false
},
//离容器四侧的距离
grid: {
left: 40, // 左边距
right: 60, // 右边距
top: 40, // 顶边距
bottom: 20, // 底边距
// containLabel: true,
},
//提示框组件
tooltip: {
show: true,
trigger: 'axis'
},
//工具栏
// toolbox: {
// feature: {
// //重置按钮显示
// restore: {
// show: true,
// title: '重置'
// }
// }
// },
//X轴
xAxis: {
name: '',
type: 'category',
data: [],
axisLine: {
show: true
}
},
//Y轴
yAxis: {
name: '',
type: 'value',
data: [],
axisLine: {
show: true
}
},
radar: {
// shape: 'circle',
},
//配置项
series: []
}
})
const indicator= ref([
{ name: 'Sales', max: 6500 },
{ name: 'Administration', max: 16000 },
{ name: 'Information Technology', max: 30000 },
{ name: 'Customer Support', max: 38000 },
{ name: 'Development', max: 52000 },
{ name: 'Marketing', max: 25000 }
])
//获取到拖拽后的数据
const getFinalInfo = (val) => {
// console.log('父组件获取最终数据', val)
if (val !== undefined) {
initInfo = val
}
}
getFinalInfo()
</script>

View File

@@ -1,538 +0,0 @@
<template>
<div>
<el-card class="box-card box-card-h">
<el-row justify="space-between" class="x-y-axis">
<el-text>值轴/{{ boxName }}</el-text>
<el-tooltip
effect="dark"
:content="boxName+',数据类型必须一致!'"
placement="bottom"
>
<el-icon>
<Warning/>
</el-icon>
</el-tooltip>
</el-row>
<div class="drag-block">
<draggable
class="list-group"
:list="dragList"
itemKey="id"
:group="group"
@start="startDrag"
@change="dragChartItem"
>
<template #item="{ element,index }">
<div :id="element.dataType==='value'?'card_'+index:''" tabindex="1"
@click.stop="handleClickValueCard(element,index)">
<el-card shadow="hover" class="cards x-y-cards"
:style="{borderWidth:1,borderColor:element.dataType==='value'?element.color:'#e4e7ed'}">
<el-col :span="3">
<div>{{ element.label }}</div>
</el-col>
<el-col :span="13">
<div v-if="element.dataType==='value'" class="update-color">
<div class="update-color" @click.stop>
<span>图形</span>
<el-color-picker v-model="element.color" :color="element.color"
@change="changeEchartsColor($event,index)" @active-change="handleActiveChange"/>
</div>
<div v-if="currentChart==='line'" class="update-color" @click.stop>
<span>阴影</span>
<el-color-picker v-model="element.lineStyle.shadowColor" :color="element.lineStyle.shadowColor"
@change="changeShadowColor($event,index)" @active-change="handleActiveChange"/>
</div>
<div v-if="currentChart==='bar'" class="update-color" @click.stop>
<span>背景: </span>
<el-color-picker v-model="element.backgroundStyle.color" :color="element.backgroundStyle.color"
@change="changeBackgroundColor($event,index)" @active-change="handleActiveChange"/>
</div>
<div v-if="currentChart==='bar'" class="update-color" @click.stop>
<span >描边: </span>
<el-color-picker v-model="element.backgroundStyle.borderColor" :color="element.backgroundStyle.borderColor"
@change="changeBackgroundBorderColor($event,index)" @active-change="handleActiveChange"/>
</div>
</div>
</el-col>
<el-col :span="4">
<div class="cards-right">
<span>{{ element.dataType }}</span>
<el-icon size="20" color="red" @click.stop="handleCancelAxis(element,index)"
style="cursor: pointer">
<CircleClose/>
</el-icon>
</div>
</el-col>
</el-card>
</div>
</template>
</draggable>
</div>
</el-card>
</div>
</template>
<script setup>
import draggable from 'vuedraggable'
const emit = defineEmits(["editBasicSettingList"])
const props = defineProps({
//box名字
boxName: {
type: String,
default: ''
},
//可供拖动的选项列表
dragOptions: {
type: Array,
default: []
},
//用于拖拽区域存放选项列表
dragList: {
type: Array,
default: []
},
//用于X轴区域存放拖动的选项
xAxisList: {
type: Array,
default: []
},
//用于Y轴区域存放拖动的选项
yAxisList: {
type: Array,
default: []
},
//标记正在拖动选项的数据类型是否value
flag: {
type: Boolean,
default: false
},
//获取正在拖动选项的数据类型
startDataType: {
type: String,
default: ''
},
//初始化加载echarts函数
initCharts: {
type: Function,
default: null
},
//echarts的配置属性
chartOption: {
type: Array,
default: []
},
//当前echarts图形
currentChart: {
type: String,
default: 'line'
}
})
//基础设置列表
const lineChartBasicSettingList = ref()
const barChartBasicSettingList = ref()
//选中类型为value的item所处的list列表
const valueCardInList = ref([])
//简化代码
let xList = reactive(props.xAxisList)
let yList = reactive(props.yAxisList)
let option = reactive(props.chartOption)
//路由刷新
const reload = inject("reload")
//自定义X/Y分组的拖入拖出事件
const group = ref({
name: 'people',
pull: true,
put: props.flag === true ? false : (props.boxName === 'X轴' ? () => handleGroupPut(xList, yList) : () => handleGroupPut(yList, xList))
})
//将改变的数据传到父组件
watch(() => lineChartBasicSettingList.value, (newVal) => {
emit("getLineChartBasicSettingList", newVal)
})
//将改变的数据传到父组件
watch(() => barChartBasicSettingList.value, (newVal) => {
emit("getBarChartBasicSettingList", newVal)
})
onMounted(() => {
document.addEventListener('click', nullBlockClick)
})
onBeforeUnmount(() => {
document.removeEventListener('click', nullBlockClick)
})
/**
* 设置chart的lineStyle
* @param sItem chartItem
* @param opacity 透明度
*/
const handleChangeLineStyle = (sItem, opacity) => {
sItem.lineStyle = {
shadowColor: sItem.lineStyle.shadowColor,
shadowBlur: sItem.lineStyle.shadowBlur,
opacity: opacity
}
}
/**
* 用于取消charts选中透明度
*/
const handleChangeOpacity = (type, item) => {
if (props.currentChart === 'line') {
option.series.forEach((sItem) => {
if (type === 'more') {
if (sItem.name === item.label) {
handleChangeLineStyle(sItem, 1)
} else {
handleChangeLineStyle(sItem, 0.2)
}
} else if (type === 'single') {
handleChangeLineStyle(sItem, 1)
} else {
if (sItem.name !== item.label) {
handleChangeLineStyle(sItem, 1)
}
}
})
}
}
/**
* 点击空白处, 清除选项选中状态
*/
const nullBlockClick = () => {
if (valueCardInList.value.length === 0) return;
valueCardInList.value.forEach((aItem, aIndex) => {
const card = document.getElementById('card_' + aIndex)
card.classList.remove('card-active')
})
clearBasicSetting()
//加载echarts
props.initCharts()
}
/**
* 封装自定义X/Y分组的拖入事件
* @param aType 传入x/y区域数组
* @param bType 传入x/y区域数组
* @returns {boolean} 返回 true/false
*/
const handleGroupPut = (aType, bType) => {
let flag = false
let aLen = aType.length
let bLen = bType.length
if (aLen === 0 && bLen === 0) {
flag = props.startDataType === 'key';
} else if (aLen === 0 && bLen !== 0) {
flag = bType[0].dataType === 'key';
} else if (aLen !== 0 && bLen !== 0) {
const dragType = localStorage.getItem('dragType')
flag = props.startDataType === aType[0].dataType;
if (dragType === 'key') {
flag = aType[0].dataType !== 'value';
}
}
return flag
}
/**
* 封装切换坐标轴数据类型为Category
* @param item 拖动的项
* @param label 坐标轴名称
* @param type 切换x/y轴
*/
const changeTypeToCategory = (item, label, type) => {
let axis
if (type === 'xAxis') {
axis = option.xAxis
} else {
axis = option.yAxis
}
axis.type = 'category'
axis.name = label
axis.data = item.data
}
/**
* 封装清除坐标轴数据
* @param type 标志清除x/y轴
*/
const clearAxisData = (type) => {
let axis
if (type === 'xAxis') {
axis = option.xAxis
} else {
axis = option.yAxis
}
axis.name = ''
axis.data = []
}
/**
* 封装key拖入左侧时的重置事件
* @param aList x/yList
* @param type x/yAxis
* @param item 选项item
* @param label 选项名
*/
const restoreChart = (aList, type,item,label) => {
let axis
if (type === 'xAxis') {
axis = option.xAxis
} else {
axis = option.yAxis
}
if (aList[0].dataType === 'value') {
aList.map((item) => {
props.dragOptions.unshift(item)
option.legend.selected[item.label] = false
})
aList.splice(0, aList.length)
option.legend.data.splice(0, option.legend.data.length)
option.series.splice(0, option.series.length)
axis.name = ''
option.xAxis.type = 'category'
option.yAxis.type = 'value'
} else {
changeTypeToCategory(item, label, type)
}
}
/**
* 拖拽类型为key的选项事件
* @param item 选项item
* @param label 选项名
*/
const dragTypeToKey = (item, label) => {
if (xList.length !== 0 && yList.length === 0) {
restoreChart(xList, 'xAxis',item,label)
clearAxisData('yAxis')
} else if (xList.length === 0 && yList.length !== 0) {
restoreChart(yList, 'yAxis',item,label)
clearAxisData('xAxis')
} else if (xList.length === 0 && yList.length === 0) {
//移入左侧待选列表
clearAxisData('xAxis')
clearAxisData('yAxis')
}
}
/**
* 拖拽类型为value的选项事件
* @param label 选项名
*/
const dragTypeToValue = (label) => {
//删除选中选项的图例
const legendIndex = option.legend.data.findIndex(object => object === label);
option.legend.data.splice(legendIndex, 1)
//删除echarts配置项series中符合该拖拽选项的item
const objectIndex = option.series.findIndex(object => object.name === label);
option.legend.selected[label] = false
option.series.splice(objectIndex, 1)
if (xList.length === 0) {
option.xAxis.name = ''
} else if (yList.length === 0) {
option.yAxis.name = ''
}
clearBasicSetting()
handleDeleteClassName(xList, yList)
}
/**
* 封装清空基本设置
*/
const clearBasicSetting=()=>{
if(props.currentChart==='line'){
lineChartBasicSettingList.value = []
handleChangeOpacity('single')
}else if(props.currentChart==='bar'){
barChartBasicSettingList.value=[]
}
}
/**
* 开始拖拽事件
* @param event event事件
*/
const startDrag = (event) => {
localStorage.setItem('dragType', event.item._underlying_vm_.dataType)
}
/**
* 从X轴/Y轴区域移动选项到左/右侧结束事件
* @param event event事件
*/
const dragChartItem = (event) => {
if (event.removed === undefined) return;
let item = event.removed.element
let label = item.label
//拖动key的选项
if (item.dataType === "key") {
dragTypeToKey(item, label)
} else {
dragTypeToValue(label)
}
props.initCharts()
localStorage.removeItem('dragType')
}
/**
* 选中数据类型为value的点击事件
* @param item 点击的选项item
* @param index 点击选项的下标
*/
const handleClickValueCard = (item, index) => {
document.addEventListener('click', nullBlockClick)
if (item.dataType === 'value' ) {
if(props.currentChart === 'line'){
changeCardActive(props.dragList, item)
lineChartBasicSettingList.value = [item]
}else if(props.currentChart === 'bar'){
changeCardActive(props.dragList, item)
barChartBasicSettingList.value = [item]
}
}
props.initCharts()
}
/**
* 封装选中类型为value的数据高亮
* @param list x/y区域list
* @param item 点击选项的item
*/
const changeCardActive = (list, item) => {
valueCardInList.value = list
emit('getCardActiveList',list)
if (list.length !== 0 && list[0].dataType === 'value') {
handleChangeOpacity('more', item)
list.forEach((aItem, aIndex) => {
const card = document.getElementById('card_' + aIndex)
if (aItem.label === item.label) {
card.classList.add('card-active')
} else {
card.classList.remove('card-active')
}
})
}
}
/**
* 基础设置: 修改echarts数据颜色
* @param val 修改的标记大小
* @param index 修改的chart项下标
*/
const changeEchartsColor = (val, index) => {
document.addEventListener('click', nullBlockClick)
option.series[index].color = val
props.initCharts()
}
/**
* 当选择颜色时移除空白点击事件
*/
const handleActiveChange = () => {
document.removeEventListener('click', nullBlockClick)
}
/**
* 基础设置: 修改echarts数据颜色
* @param val 修改的标记大小
* @param index 修改的chart项下标
*/
const changeShadowColor = (val, index) => {
option.series[index].lineStyle.shadowColor = val
props.initCharts()
}
/**
* 基础设置:修改柱条背景颜色
* @param val 柱条颜色
* @param index 修改的chart项下标
*/
const changeBackgroundColor = (val, index) => {
option.series[index].backgroundStyle.color = val
props.initCharts()
}
/**
* 基础设置:修改柱条描边颜色
* @param val 柱条描边颜色
* @param index 修改的chart项下标
*/
const changeBackgroundBorderColor = (val, index) => {
option.series[index].backgroundStyle.borderColor = val
props.initCharts()
}
/**
* 封装从右侧区域拖出事件
* @param element 获取点击该拖出的选项事件
* @param index 点击该拖出选项的索引
* @param aList x/y区域的值
* @param bList x/y区域的值
* @param aAxis echarts配置项的x/y轴
* @param bAxis echarts配置项的x/y轴
*/
const handleCancel = (element, index, aList, bList, aAxis, bAxis) => {
aList.splice(index, 1)
props.dragOptions.push(element)
if (element.dataType === "key") {
aAxis.name = ''
aAxis.data = []
bAxis.name=''
bList.map((item) => {
props.dragOptions.unshift(item)
option.legend.selected[item.label] = false
})
bList.splice(0, bList.length)
option.legend.data.splice(0, option.legend.data.length)
option.series.splice(0, option.series.length)
// reload
props.initCharts()
} else {
if (bList.length !== 0 && aList.length === 0) {
if (bList[0].dataType === 'key') {
aAxis.name = ''
} else {
bAxis.name = ''
}
}
option.legend.data.splice(index, 1)
const objectIndex = option.series.findIndex(object => object.name === element.label);
option.legend.selected[element.label] = false
option.series.splice(objectIndex, 1)
props.initCharts()
}
if(props.currentChart==='line'){
handleChangeOpacity('not', element)
if (lineChartBasicSettingList.value === undefined) return;
lineChartBasicSettingList.value.splice(0, 1)
}else if(props.currentChart==='bar'){
if (barChartBasicSettingList.value === undefined) return;
barChartBasicSettingList.value.splice(0, 1)
}
// const basicIndex = lineChartBasicSettingList.value.findIndex(object => object.label === element.label)
// if (basicIndex !== -1) {
// lineChartBasicSettingList.value.splice(basicIndex, 1)
// }
handleDeleteClassName(aList, bList)
props.initCharts()
}
/**
* 拖拽选项后,清除选中选项阴影
* @param aList x/y list
* @param bList x/y list
*/
const handleDeleteClassName = (aList, bList) => {
let axis = []
if (aList.length !== 0 && aList[0].dataType === 'value') {
axis = aList
} else if (bList.length !== 0 && bList[0].dataType === 'value') {
axis = bList
}
axis.forEach((aItem, aIndex) => {
const card = document.getElementById('card_' + aIndex)
card.classList.remove('card-active')
})
}
/**
* 从右侧x/y轴区域取消选项
* @param element 该取消的项
* @param index 该取消项的下标
*/
const handleCancelAxis = (element, index) => {
if (props.boxName === 'X轴') {
handleCancel(element, index, xList, yList, option.xAxis, option.yAxis)
} else {
handleCancel(element, index, yList, xList, option.yAxis, option.xAxis)
}
}
</script>

View File

@@ -1,307 +0,0 @@
<template>
<div>
<el-card class="box-card">
<div class="drag-block">
<draggable
class="list-group"
:list="dragOptions"
itemKey="id"
group="people"
@start="startDrag"
@change="changeChartItem"
>
<template #item="{element}">
<el-card shadow="hover" class="cards">
<el-row justify="space-between">
<span>{{ element.label }}</span>
<span>{{ element.dataType }}</span>
</el-row>
</el-card>
</template>
</draggable>
</div>
</el-card>
</div>
</template>
<script setup>
import draggable from 'vuedraggable'
import {ElMessage} from "element-plus";
const emit = defineEmits(["editValueFlag", "editStartDataType"])
const props = defineProps({
//可供拖动的选项列表
dragOptions: {
type: Array,
default: []
},
//echarts的配置属性
chartOption: {
type: Object,
default: {}
},
//初始化加载echarts函数
initCharts: {
type: Function,
default: null
},
//用于X轴区域存放拖动的选项
xAxisList: {
type: Array,
default: []
},
//用于Y轴区域存放拖动的选项
yAxisList: {
type: Array,
default: []
},
//当前echarts图形
currentChart: {
type: String,
default: 'line'
},
//雷达图指示器
radarIndicator: {
type: Array,
default: []
}
})
//简化代码
let xList = reactive(props.xAxisList)
let yList = reactive(props.yAxisList)
let option = reactive(props.chartOption)
let chart = reactive(props.currentChart)
//获取正在拖动选项的数据类型
const startDragType = ref()
//标记正在拖动选项的数据类型是否value
const flag = ref(false)
//将改变的数据传到父组件
watch(() => flag.value, (newVal) => {
emit("editValueFlag", newVal)
})
watch(() => props.currentChart, (newVal) => {
chart = newVal
})
watch(() => startDragType.value, (newVal) => {
emit("editStartDataType", newVal)
})
/**
* 设置修改后的echarts属性
* @param item 拖动的项
* @param label 拖拽选项的名称
* @returns Object
*/
const settingChartItem = (item, label) => {
if (chart === 'line') {
return {
id: item.id,//组件 ID
name: label,
// type: echartsValue.value ? echartsValue.value : item.type,
type: chart,
data: item.data,
smooth: true,
color: item.color,
symbol: item.symbol,
symbolSize: item.symbolSize,
showSymbol: item.showSymbol,
lineStyle: item.lineStyle,
// emphasis: item.emphasis
}
} else if (chart === 'bar') {
return {
id: item.id,
name: label,
type: chart,
data: item.data,
color: item.color,
showBackground: item.showBackground,
backgroundStyle: item.backgroundStyle
}
}
}
/**
* 封拖拽数据类型为value
* @param item 拖动的项
* @param label 拖拽选项的名称
* @param selectedObj 图例选中状态表
*/
const dragValue = (item, label, selectedObj) => {
dragChart(item, label, 2)
option.legend.data.push(label)
let chartItem = settingChartItem(item, label)
option.series.push(chartItem)
for (const propertyName in selectedObj) {
if (propertyName === label) {
selectedObj[propertyName] = true
}
}
}
/**
* 封装切换坐标轴数据类型为Category
* @param item 拖动的项
* @param label 坐标轴名称
* @param type 切换x/y轴
*/
const changeTypeToCategory = (item, label, type) => {
let axis
if (type === 'xAxis') {
axis = option.xAxis
} else {
axis = option.yAxis
}
axis.type = 'category'
axis.name = item.unit
axis.data = item.data
}
/**
* 封装切换坐标轴数据类型为Value
* @param item 拖动的项item
* @param type 切换x/y轴
*/
const changeTypeToValue = (item, type) => {
let axis
if (type === 'xAxis') {
axis = option.xAxis
} else {
axis = option.yAxis
}
axis.type = 'value'
axis.name = item.unit
}
/**
* 封装拖拽选项修改echarts属性
* @param item 拖动的项
* @param label 拖拽选项的名称
* @param index 区分拖的选项数据:1是key,2是value
*/
const dragChart = (item, label, index) => {
if (xList.length !== 0 && yList.length === 0) {
// console.log('x轴有值')
if (index === 1) {
changeTypeToCategory(item, label, 'xAxis')
} else {
changeTypeToValue(item, 'xAxis')
option.yAxis.type = 'category'
}
} else if (xList.length !== 0 && yList.length !== 0) {
// console.log('xy有值')
if (xList[0].dataType === 'value') {
if (index === 1) {
changeTypeToCategory(item, label)
}
changeTypeToValue(item, 'xAxis')
} else if (yList[0].dataType === 'value') {
if (index === 1) {
changeTypeToCategory(item, label, 'xAxis')
}
changeTypeToValue(item)
}
} else if (xList.length === 0 && yList.length !== 0) {
// console.log('y轴有值')
if (index === 1) {
changeTypeToCategory(item, label, 'yAxis')
} else {
option.xAxis.type = 'category'
changeTypeToValue(item)
}
}
}
/**
* 从左侧区域移动选项到右侧
* @param event 拖拽成功event事件
*/
const changeChartItem = (event) => {
if (event.removed === undefined) return;
let item = event.removed.element
if (chart === 'line'||chart === 'bar') {
let label = item.label
let selectedObj = option.legend.selected
if (item.dataType === "key") {
dragChart(item, label, 1)
} else {
if (flag.value) return;
dragValue(item, label, selectedObj)
}
} else if (chart === 'pie') {
let arr = []
xList.forEach(item => {
let obj = {
name: item.label,
value: item.value
}
arr.push(obj)
})
for (const propertyName in option.legend.selected) {
if (propertyName === item.label) {
option.legend.selected[propertyName] = true
}
}
if (item.dataType !== "key") {
option.legend.data.push(item.label)
}
option.series = [
{
type: 'pie',
radius: '50%',
data: arr
}
]
} else if (chart === 'radar') {
let arr = []
xList.forEach(item => {
let obj = {
name: item.label,
value: item.data
}
arr.push(obj)
})
console.log('arr',arr)
for (const propertyName in option.legend.selected) {
if (propertyName === item.label) {
option.legend.selected[propertyName] = true
}
}
if (item.dataType !== "key") {
option.legend.data.push(item.label)
}
option.radar={
indicator:props.radarIndicator
}
option.series = [
{
type: 'radar',
data: arr
}
]
}
props.initCharts()
}
/**
* 左侧区域开始拖拽事件
* @param event 开始拖拽的event事件
*/
const startDrag = (event) => {
startDragType.value = event.item._underlying_vm_.dataType
if (xList.length === 0 && yList.length === 0) {
if (chart === 'line' || chart === 'bar') {
if (startDragType.value === "value") {
flag.value = true
ElMessage({
message: '请先拖动数据类型为key的选项到x轴/y轴.',
type: 'warning',
})
} else {
flag.value = false
}
} else if (chart === 'pie') {
console.log('拖动饼图')
flag.value = false
}else if (chart === 'radar') {
console.log('拖动雷达')
flag.value = false
}
}
}
</script>

View File

@@ -1,307 +0,0 @@
<template>
<div>
<el-row :gutter="6">
<el-col :span="6">
<el-select v-model="echartsValue" filterable placeholder="请选择图形状" style="width: 100%" size="large"
@change="handleChangeEcharts">
<el-option v-for="chartItem in chartType"
:key="chartItem.value"
:label="chartItem.label"
:value="chartItem.value"/>
</el-select>
<!--左侧选项区域-->
<charts-options @editValueFlag="editValueFlag" @editStartDataType="editStartDataType"
:drag-options="ChartsItem" :chart-option="option" :init-charts="initChart"
:x-axis-list="xValueAxis" :y-axis-list="yValueAxis"
:current-chart="echartsValue" :radar-indicator="radarIndicator"/>
</el-col>
<!--X轴区域-->
<el-col :span="9" v-if="echartsValue==='bar'||echartsValue==='line'">
<axis-box :box-name="'X轴'" :drag-list="xValueAxis" :drag-options="ChartsItem" :x-axis-list="xValueAxis"
:y-axis-list="yValueAxis" :flag="valueFlag"
:start-data-type="startDataType" :chart-option="option" :init-charts="initChart"
@getLineChartBasicSettingList="getLineChartBasicSettingList"
@getBarChartBasicSettingList="getBarChartBasicSettingList" :current-chart="echartsValue"/>
</el-col>
<!--Y轴区域-->
<el-col :span="9" v-if="echartsValue==='bar'||echartsValue==='line'">
<axis-box :box-name="'Y轴'" :drag-list="yValueAxis" :drag-options="ChartsItem" :x-axis-list="xValueAxis"
:y-axis-list="yValueAxis" :flag="valueFlag"
:start-data-type="startDataType" :chart-option="option" :init-charts="initChart"
@getLineChartBasicSettingList="getLineChartBasicSettingList"
@getBarChartBasicSettingList="getBarChartBasicSettingList" :current-chart="echartsValue"/>
</el-col>
<el-col :span="9" v-if="echartsValue==='pie'">
<pie-box :drag-list="xValueAxis" :init-charts="initChart" :chart-option="option"/>
</el-col>
<el-col :span="9" v-if="echartsValue==='radar'">
<radar-box :drag-list="xValueAxis" :init-charts="initChart" :chart-option="option"/>
</el-col>
</el-row>
<el-button @click.stop="saveData">保存</el-button>
<el-button v-if="echartsValue==='line'" @click.stop="openAdvancedSettings">高级设置</el-button>
<el-row :gutter="6">
<el-col :span="16">
<div id="container" ref="chart" @click.stop></div>
</el-col>
<!--基础设置-->
<el-col :span="8">
<!-- 折线图基础设置-->
<line-chart-basic-setting v-if="echartsValue==='line'" :basic-list="lineChartBasicSettingList"
:init-charts="initChart"
:chart-option="option"/>
<!-- 柱状图基础设置-->
<bar-chart-basic-setting v-if="echartsValue==='bar'" :basic-list="barChartBasicSettingList"
:init-charts="initChart"
:chart-option="option"/>
<!-- 饼图基础设置-->
<!-- <pie-chart-basic-setting v-if="echartsValue==='pie'"/>-->
</el-col>
</el-row>
<!--高级设置-->
<!-- 折线图高级设置-->
<line-chart-advanced-settings v-if="echartsValue==='line'" ref="advancedSettings" :init-charts="initChart"
:chart-option="option"/>
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import draggable from 'vuedraggable'
import ChartsOptions from "./ChartsOptions.vue";
import AxisBox from "./AxisBox.vue";
import LineChartBasicSetting from "./lineChart/BasicSetting.vue";
import LineChartAdvancedSettings from "./lineChart/AdvancedSettings.vue";
import BarChartBasicSetting from "./barChart/BasicSetting.vue";
// import PieChartBasicSetting from "./pieChart/BasicSetting.vue";
import PieBox from "./pieChart/PieBox.vue";
import RadarBox from "./radarChart/RadarBox.vue";
// import BarChartAdvancedSettings from "./barChart/AdvancedSettings.vue";
const emit = defineEmits(["getFinalInfo"])
const props = defineProps({
info: {
type: Object,
default: {}
},
lineData: {
type: Array,
default: []
},
barData: {
type: Array,
default: []
},
pieData: {
type: Array,
default: []
},
radarData: {
type: Array,
default: []
},
radarIndicator: {
type: Array,
default: []
}
})
//图形: 1:折线图 2.柱状图 3.饼图
const chartType = reactive([
{
value: 'line',
label: '折线图',
},
{
value: 'bar',
label: '柱状图',
},
{
value: 'pie',
label: '饼图',
},
{
value: 'radar',
label: '雷达图',
}
])
//基础设置列表
const lineChartBasicSettingList = ref([])
const barChartBasicSettingList = ref([])
const advancedSettings = ref()
//获取父组件传来的初始数据
const initInfo = reactive(props.info)
//从左侧获取拖动的选项的数据类型
const startDataType = ref()
//标记从左侧拖动选项数据类型是否是value
const valueFlag = ref(false)
//简化代码
let xValueAxis = reactive(initInfo.xValueAxis)
let yValueAxis = reactive(initInfo.yValueAxis)
const line_data = reactive(props.lineData)
const bar_data = reactive(props.barData)
const pie_data = reactive(props.pieData)
const radar_data = reactive(props.radarData)
let option = reactive(initInfo.echartsOptions)
//页面左上角select选择框绑定数据
const echartsValue = ref('line')
//可供拖动的选项列表
const ChartsItem = ref([])
//获取到container容器实例
const chart = ref(null);
//定义echarts实例
let myEcharts = reactive({});
onMounted(() => {
if (ChartsItem.value.length === 0) {
ChartsItem.value = line_data
}
//初始化echarts(不显示图)
let selectLegend = {}
ChartsItem.value.forEach(item => {
if (item.dataType !== 'key') {
selectLegend[item.label] = false
}
})
option.legend.selected = selectLegend
if (echartsValue.value === 'pie'||echartsValue.value === 'radar') {
isShowAxisLine(false)
} else {
isShowAxisLine(true)
}
//加载echarts
initChart();
})
/**
* 修改valueFlag
* @param val 子组件传的动态值
*/
const editValueFlag = (val) => {
valueFlag.value = val
}
/**
* 修改startDataType
* @param str 子组件传的动态值
*/
const editStartDataType = (str) => {
startDataType.value = str
}
/**
* 用于其他组件获取基础设置列表
* @param str 子组件传的动态值
*/
const getLineChartBasicSettingList = (str) => {
lineChartBasicSettingList.value = str
}
/**
* 修改option
* @param str 子组件传的动态值
*/
const getBarChartBasicSettingList = (str) => {
barChartBasicSettingList.value = str
}
/**
* 切换echarts图类型事件
* @param e event事件
*/
const handleChangeEcharts = (e) => {
if (xValueAxis.length !== 0 || yValueAxis.length !== 0) {
xValueAxis.map((item) => {
ChartsItem.value.unshift(item)
option.legend.selected[item.label] = false
})
xValueAxis.splice(0, xValueAxis.length)
yValueAxis.map((item) => {
ChartsItem.value.unshift(item)
option.legend.selected[item.label] = false
})
yValueAxis.splice(0, yValueAxis.length)
option.legend.data.splice(0, option.legend.data.length)
option.series.splice(0, option.series.length)
option.xAxis.name = ''
option.xAxis.data = []
option.xAxis.type = 'category'
option.yAxis.name = ''
option.yAxis.data = []
option.yAxis.type = 'value'
initChart()
}
echartsValue.value = e
if (e === 'line') {
ChartsItem.value = line_data
isShowAxisLine(true)
option.radar={}
} else if (e === 'bar') {
ChartsItem.value = bar_data
isShowAxisLine(true)
option.radar={}
} else if (e === 'pie') {
ChartsItem.value = pie_data
isShowAxisLine(false)
option.radar={}
}else if (e === 'radar') {
ChartsItem.value = radar_data
isShowAxisLine(false)
option.radar.indicator = props.radarIndicator
}
let selectLegend = {}
ChartsItem.value.forEach(item => {
if (item.dataType !== 'key') {
selectLegend[item.label] = false
}
})
option.legend.selected = selectLegend
initChart()
}
/**
* 是否显示x/y轴线
* @param type
*/
const isShowAxisLine = (type) => {
option.xAxis.axisLine.show = type
option.yAxis.axisLine.show = type
if (type === false) {
option.tooltip.trigger = 'item'
} else {
option.tooltip.trigger = 'axis'
}
}
/**
* 初始化echarts实例方法
*/
const initChart = () => {
console.log('initChartoption', option)
//3.初始化container容器
myEcharts = echarts.init(chart.value);
//5.传入数据
myEcharts.setOption(option,true);
//图表大小自适应窗口大小变化
window.onresize = () => {
myEcharts.resize();
}
//点击事件
// myEcharts.on('click', function (params) {
// console.log('dddd点击事件', params);
// });
// myEcharts.restore();
localStorage.removeItem('dragType')
}
/**
* 保存数据
*/
const saveData = () => {
console.log('最终initInfo', initInfo)
emit("getFinalInfo", initInfo)
}
/**
* 打开高级设置弹框
*/
const openAdvancedSettings = () => {
advancedSettings.value.showDrawer()
}
</script>

View File

@@ -1,86 +0,0 @@
<template>
<el-drawer v-model="drawerVisible" direction="rtl">
<template #header>
<h4>高级设置</h4>
</template>
<template #default>
<el-form :model="settingsForm" class="advanced-setting">
<el-form-item label="是否点击图例改变图显示状态">
<el-switch active-text="" inactive-text="" v-model="settingsForm.isClickLegendToShow"
@change="changeIsClickLegend"/>
</el-form-item>
<el-form-item label="是否显示提示框组件">
<el-switch active-text="" inactive-text="" v-model="settingsForm.isShowTooltip"
@change="changeIsShowTooltip"/>
</el-form-item>
</el-form>
</template>
<template #footer>
<el-button @click="cancelSettings">取消</el-button>
<el-button type="primary" @click="confirmSettings">确认</el-button>
</template>
</el-drawer>
</template>
<script setup>
const props = defineProps({
//初始化加载echarts函数
initCharts: {
type: Function,
default: null
},
//echarts的配置属性
chartOption: {
type: Array,
default: []
},
})
let option = reactive(props.chartOption)
//高级设置抽屉是否展开
const drawerVisible = ref(false)
//高级设置属性
const settingsForm = reactive({
isClickLegendToShow: option.legend.selectedMode,//打开点击图例改变图显示状态
isShowTooltip: option.tooltip.show//是否显示提示框组件
})
/**
* 打开高级设置弹窗
*/
const showDrawer = () => {
drawerVisible.value = true
}
/**
* 高级设置: 取消按钮
*/
const cancelSettings = () => {
drawerVisible.value = false
}
/**
* 高级设置: 确认按钮
*/
const confirmSettings = () => {
drawerVisible.value = false
props.initCharts()
}
/**
* 高级设置:打开点击图例改变图显示状态
* @param val
*/
const changeIsClickLegend = (val) => {
option.legend.selectedMode = val
}
/**
* 高级设置:是否显示提示框组件
* @param val
*/
const changeIsShowTooltip = (val) => {
option.tooltip.show = val
}
defineExpose({
showDrawer
})
</script>

View File

@@ -1,140 +0,0 @@
<template>
<el-scrollbar height="450px">
<div class="basic-setup" @click.stop>
柱状图基本设置
</div>
<div v-for="(settingItem) in basicList" class="setting" @click.stop>
<div class="setting-title">{{ settingItem.label }}</div>
<div class="setting-item">
<span>显示柱条背景: </span>
<el-switch active-text="" inactive-text="" v-model="settingItem.showBackground"
@change="changeIsShowBackground($event,settingItem)"/>
</div>
<div v-if="settingItem.showBackground!==false">
<div class="setting-item">
<span>柱条描边宽度: </span>
<el-input-number v-model="settingItem.backgroundStyle.borderWidth" :min="0"
@change="changeBorderWidth($event,settingItem)"/>
</div>
<!-- <div class="setting-item" v-if="settingItem.backgroundStyle.borderWidth!==0">-->
<!-- <span>柱条描边颜色: </span>-->
<!-- <el-color-picker v-model="settingItem.backgroundStyle.borderColor"-->
<!-- :color="settingItem.backgroundStyle.borderColor"-->
<!-- @change="changeBorderColor($event,settingItem)"/>-->
<!-- </div>-->
<div class="setting-item" v-if="settingItem.backgroundStyle.borderWidth!==0">
<span>柱条描边类型: </span>
<el-select v-model="settingItem.backgroundStyle.borderType" @change="switchBorderType($event,settingItem)">
<el-option
v-for="symbolItem in borderTypeList"
:key="symbolItem.value"
:label="symbolItem.label"
:value="symbolItem.value"
/>
</el-select>
</div>
</div>
</div>
</el-scrollbar>
</template>
<script setup>
const props = defineProps({
//基础设置列表
basicList: {
type: Array,
default: []
},
//初始化加载echarts函数
initCharts: {
type: Function,
default: null
},
//echarts的配置属性
chartOption: {
type: Array,
default: []
},
})
let option = reactive(props.chartOption)
//图形标记列表
const borderTypeList = ref([
{value: 'solid', label: '实线'},
{value: 'dashed', label: '虚线'},
{value: 'dotted', label: '点线'}
])
/**
* 封装基本设置修改echarts属性事件
* @param item 修改的项
* @param type option.series中的属性名
* @param val 获取修改的值
*/
const changeSingleParams = (item, type, val) => {
option.series.forEach((sItem, sIndex) => {
if (sItem.name === item.label) {
getSeriesParams(type, sIndex, val)
}
})
}
/**
* 根据changeSingleParams方法传的动态type,封装数据修改事件
* @param type option.series中的属性名
* @param index 修改某项属性的下标
* @param val 获取修改的值
*/
const getSeriesParams = (type, index, val) => {
let seriesItem = option.series[index]
switch (type) {
case 'showBackground':
return seriesItem.showBackground = val
case 'color':
return seriesItem.backgroundStyle.color = val
case 'borderWidth':
return seriesItem.backgroundStyle.borderWidth = val
case 'borderColor':
return seriesItem.backgroundStyle.borderColor = val
case 'borderType':
return seriesItem.backgroundStyle.borderType = val
}
}
/**
* 基础设置:修改是否显示柱条背景
* @param val 是否显示
* @param item 修改的chart项
*/
const changeIsShowBackground = (val, item) => {
changeSingleParams(item, 'showBackground', val)
props.initCharts()
}
/**
* 基础设置:修改柱条描边宽度
* @param val 宽度
* @param item 修改的chart项
*/
const changeBorderWidth = (val, item) => {
changeSingleParams(item, 'borderWidth', val)
props.initCharts()
}
/**
* 基础设置:修改柱条的描边颜色
* @param val 颜色
* @param item 修改的chart项
*/
const changeBorderColor = (val, item) => {
changeSingleParams(item, 'borderColor', val)
props.initCharts()
}
/**
* 基础设置:修改柱条的描边类型
* @param val 类型
* @param item 修改的chart项
*/
const switchBorderType = (val, item) => {
changeSingleParams(item, 'borderType', val)
props.initCharts()
}
</script>

View File

@@ -1,86 +0,0 @@
<template>
<el-drawer v-model="drawerVisible" direction="rtl">
<template #header>
<h4>高级设置</h4>
</template>
<template #default>
<el-form :model="settingsForm" class="advanced-setting">
<el-form-item label="是否点击图例改变图显示状态">
<el-switch active-text="" inactive-text="" v-model="settingsForm.isClickLegendToShow"
@change="changeIsClickLegend"/>
</el-form-item>
<el-form-item label="是否显示提示框组件">
<el-switch active-text="" inactive-text="" v-model="settingsForm.isShowTooltip"
@change="changeIsShowTooltip"/>
</el-form-item>
</el-form>
</template>
<template #footer>
<el-button @click="cancelSettings">取消</el-button>
<el-button type="primary" @click="confirmSettings">确认</el-button>
</template>
</el-drawer>
</template>
<script setup>
const props = defineProps({
//初始化加载echarts函数
initCharts: {
type: Function,
default: null
},
//echarts的配置属性
chartOption: {
type: Array,
default: []
},
})
let option = reactive(props.chartOption)
//高级设置抽屉是否展开
const drawerVisible = ref(false)
//高级设置属性
const settingsForm = reactive({
isClickLegendToShow: option.legend.selectedMode,//打开点击图例改变图显示状态
isShowTooltip: option.tooltip.show//是否显示提示框组件
})
/**
* 打开高级设置弹窗
*/
const showDrawer = () => {
drawerVisible.value = true
}
/**
* 高级设置: 取消按钮
*/
const cancelSettings = () => {
drawerVisible.value = false
}
/**
* 高级设置: 确认按钮
*/
const confirmSettings = () => {
drawerVisible.value = false
props.initCharts()
}
/**
* 高级设置:打开点击图例改变图显示状态
* @param val
*/
const changeIsClickLegend = (val) => {
option.legend.selectedMode = val
}
/**
* 高级设置:是否显示提示框组件
* @param val
*/
const changeIsShowTooltip = (val) => {
option.tooltip.show = val
}
defineExpose({
showDrawer
})
</script>

View File

@@ -1,160 +0,0 @@
<template>
<el-scrollbar height="450px">
<div class="basic-setup" @click.stop>
折线图基本设置
</div>
<div v-for="(settingItem) in basicList" class="setting" @click.stop>
<div class="setting-title">{{ settingItem.label }}</div>
<!-- <div class="setting-item">-->
<!-- <span>图形: </span>-->
<!-- <el-select v-model="settingItem.type" @change="switchChart($event,settingItem)">-->
<!-- <el-option-->
<!-- v-for="chartItem in [{value: 'line',label: '折线图'},{value: 'bar',label: '柱状图'}]"-->
<!-- :key="chartItem.value"-->
<!-- :label="chartItem.label"-->
<!-- :value="chartItem.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </div>-->
<div class="setting-item">
<span>显示标记: </span>
<el-switch active-text="" inactive-text="" v-model="settingItem.showSymbol"
@change="changeIsShowSymbol($event,settingItem)"/>
</div>
<div class="setting-item" v-if="settingItem.showSymbol===true">
<span>标记: </span>
<el-select v-model="settingItem.symbol" @change="switchSymbol($event,settingItem)">
<el-option
v-for="symbolItem in symbolList"
:key="symbolItem.value"
:label="symbolItem.label"
:value="symbolItem.value"
/>
</el-select>
</div>
<div class="setting-item" v-if="settingItem.showSymbol===true">
<span>标记大小: </span>
<el-input-number v-model="settingItem.symbolSize" :min="1" @change="changeSymbolSize($event,settingItem)"/>
</div>
<div class="setting-item">
<span>阴影模糊大小: </span>
<el-input-number v-model="settingItem.lineStyle.shadowBlur" :min="0" @change="changeShadowBlur($event,settingItem)"/>
</div>
</div>
</el-scrollbar>
</template>
<script setup>
const props = defineProps({
//基础设置列表
basicList: {
type: Array,
default: []
},
//初始化加载echarts函数
initCharts: {
type: Function,
default: null
},
//echarts的配置属性
chartOption: {
type: Array,
default: []
},
})
//图形标记列表
const symbolList = ref([
{value: 'none', label: '不显示标记'},
{value: 'circle', label: '圆形'},
{value: 'rect', label: '矩形'},
{value: 'triangle', label: '三角形'},
{value: 'diamond', label: '钻石形'},
{value: 'roundRect', label: '圆角矩形'},
{value: 'pin', label: '圆钉形'},
{value: 'arrow', label: '箭头形'},
])
let option = reactive(props.chartOption)
/**
* 封装基本设置修改echarts属性事件
* @param item 修改的项
* @param type option.series中的属性名
* @param val 获取修改的值
*/
const changeSingleParams = (item, type, val) => {
option.series.forEach((sItem, sIndex) => {
if (sItem.name === item.label) {
getSeriesParams(type, sIndex, val)
}
})
}
/**
* 根据changeSingleParams方法传的动态type,封装数据修改事件
* @param type option.series中的属性名
* @param index 修改某项属性的下标
* @param val 获取修改的值
*/
const getSeriesParams = (type, index, val) => {
let seriesItem = option.series[index]
switch (type) {
case 'type':
return seriesItem.type = val
case 'showSymbol':
return seriesItem.showSymbol = val
case 'symbol':
return seriesItem.symbol = val
case 'symbolSize':
return seriesItem.symbolSize = val
case 'shadowBlur':
return seriesItem.lineStyle.shadowBlur = val
}
}
/**
* 基础设置:是否显示标记
* @param val 修改的标记大小
* @param item 修改的chart项
*/
const changeIsShowSymbol = (val, item) => {
changeSingleParams(item, 'showSymbol', val)
props.initCharts()
}
/**
* 基础设置:切换chart的形状
* @param val 修改的标记大小
* @param item 修改的chart项
*/
const switchChart = (val, item) => {
changeSingleParams(item, 'type', val)
props.initCharts()
}
/**
* 基础设置:修改标记
* @param val 修改的标记大小
* @param item 修改的chart项
*/
const switchSymbol = (val, item) => {
changeSingleParams(item, 'symbol', val)
props.initCharts()
}
/**
* 基础设置:修改标记大小
* @param val 修改的标记大小
* @param item 修改的chart项
*/
const changeSymbolSize = (val, item) => {
changeSingleParams(item, 'symbolSize', val)
props.initCharts()
}
/**
* 基础设置:修改图形阴影的模糊大小
* @param val 修改的阴影的模糊大小
* @param item 修改的chart项
*/
const changeShadowBlur = (val, item) => {
changeSingleParams(item, 'shadowBlur', val)
props.initCharts()
}
</script>

Some files were not shown because too many files have changed in this diff Show More