72 Commits

Author SHA1 Message Date
dj
f053eb80cd refactor(project-management): 注释掉打印按钮
在 StepsMoblie.vue 文件中,添加了对打印按钮的注释。使用 <!-- --> 注释掉该按钮,以便在需要时可以轻松恢复功能。
2025-09-02 23:24:21 +08:00
dj
29a7766635 refactor(special-fund):优化专项资金详情获取逻辑
-移除了接口成功调用时的重复通知
- 增加了接口调用失败时的错误通知
- 优化了代码结构,提高了用户体验
2025-08-31 21:02:40 +08:00
dj
8c20ecacab feat(mobile): 专项资金、项目管理、需求详情页面增加手机端驳回提示
- 在专项资金详情、项目管理详情和需求详情页面中添加了手机端驳回提示
- 提示内容为:"当前版本不支持手机端驳回重新提交,请在电脑网页上执行重新提交操作"
- 该提示在数据状态为 3 时显示
2025-08-29 12:00:13 +08:00
dj
05ac715461 feat(mobile): 增加需求征集操作限制提示
- 在移动端需求征集页面添加操作限制提示
- 提示用户当前版本不支持手机端需求上报
- 建议用户在电脑网页上执行需求上报操作
-调整了移动端按钮布局
2025-08-28 21:56:31 +08:00
dj
cffe7d61e3 refactor: 优化多个组件的返回逻辑
- 在 Requirement、Summary、Fund 组件中,将 history.back() 替换为 router.push(),以指定具体的路由名称- 在 ProjectApply 组件中,根据 step 值选择不同的路由页面
- 这些修改提高了组件的可测试性和灵活性,避免了依赖浏览器历史记录
2025-08-27 09:45:15 +08:00
dj
dc4b33cf89 style:移除主项目选择框的多余属性
移除了主项目选择框(el-select)组件的 remote 属性,该属性在当前场景下不需要,删除后可以简化代码结构。
2025-08-26 17:47:49 +08:00
dj
6b3e74fab9 feat(project-demand): 修改需求征集表单的编辑权限
- 扩展了表单编辑权限,允许 'Requirement/add' 路由的用户进行编辑
-调整了提交按钮的显示逻辑,移除了多余的条件判断
- 优化了文件删除按钮的显示条件,增加了对路由名称的判断
2025-08-24 17:09:17 +08:00
25f1f40957 更新 README.md 2025-08-22 16:42:26 +00:00
1ead008f53 更新 README.md 2025-08-22 15:35:00 +00:00
dj
a76ab5adaf refactor(project-demand): 动态修改需求征集页面标题
- 新增功能:根据需求状态动态修改页面标签和面包屑标题
- 优化了标题修改的逻辑,提高用户体验
- 更新了 API代理配置,指向新的服务器地址
2025-08-22 18:17:51 +08:00
dj
f2ac70f9e3 feat(project-demand): 根据需求状态显示不同表单
- 添加了 v-if="formData.state=='3'" 条件,以根据需求状态显示不同表单元素
- 为征集名称、类型、截止时间等字段添加了只读显示逻辑
- 调整了专项资金相关字段的显示逻辑
- 优化了附件上传和文件列表的显示条件
- 根据状态控制提交、返回按钮的显示
2025-08-22 17:38:46 +08:00
dj
0efd2a7db2 feat(project-demand): 优化需求提交按钮显示逻辑
- 在 routerName 为 Requirement/add 且 formData.state 为 '3' 时显示提交按钮
- 在 routerName为 Requirement/edit 且 formData.state为 '3' 时显示重新提交按钮
- 为 formData 添加 state 字段初始化为 ''
2025-08-22 16:19:41 +08:00
dj
83c01575e6 style:优化日期选择器样式
- 调整年份选择器的宽度为 100%,以适应页面布局
2025-08-20 09:22:49 +08:00
dj
5808145c01 fix(views): 修改日期选择器的格式为单月显示
- 在 expense-management 模块下的 cost-detail 和 expend-detail 页面中
- 将日期选择器的 format 和 valueFormat 属性从 'MM' 修改为 'M'
- 这个修改使得日期选择器显示单个月份,而不是两位数的月份
2025-08-20 00:02:29 +08:00
dj
e1543e05b4 refactor(expense-management):恢复并优化日期选择功能
- 在成本详情、支出详情和分摊详情页面中重新启用年份和月份选择功能
-优化日期选择器的格式和价值格式
- 在搜索时去除月份参数的前置0,确保正确传递参数
- 调整搜索表单的样式,移除多余的样式属性
2025-08-20 00:00:44 +08:00
dj
d20b968307 feat(expense-management): 为成本明细页面添加年份和月份筛选功能
- 在成本明细、支出明细和分摊明细页面的搜索表单中添加了年份和月份选择器
- 优化了搜索表单的样式和布局- 注释掉了部分未使用的代码
2025-08-19 16:14:23 +08:00
dj
7735d20021 feat(expense-management): 添加项目名称搜索的本地存储功能
- 在成本明细、支出明细和共享明细页面中,为大师项目名称和子项目名称的搜索框添加本地存储功能
- 当用户输入搜索值时,从本地存储中获取已保存的项目名称选项
- 当用户清空搜索框时,将当前加载的项目名称选项保存到本地存储
- 优化了项目名称搜索的用户体验,减少了重复请求服务器的次数
2025-08-19 16:07:29 +08:00
831f017482 Merge pull request 'refactor(plan): 将年度计划相关文案统一修改为项目计划' (#1104) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1104
2025-08-06 14:08:49 +00:00
dj
827978f7bd refactor(plan): 将年度计划相关文案统一修改为项目计划
- 修改了多个组件和 API 中的年度计划名称、提示文本等
- 统一使用项目计划替代年度计划,提高文案一致性
2025-08-06 22:06:17 +08:00
b16893955d Merge pull request 'master' (#1103) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1103
2025-08-06 14:02:48 +00:00
dj
41830600bf feat(project-demand): 添加需求汇总行键值
在项目需求汇总视图中添加了行键值属性,以优化数据展示和操作。
2025-08-06 22:02:27 +08:00
76a5ebbeb9 Merge pull request 'prod' (#1102) from prod into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1102
2025-08-04 02:03:30 +00:00
dj
a26088a756 feat(expense-management): 优化项目名称远程搜索功能
- 在项目需求概览页面添加主项目列表缓存到本地存储
-重构费用管理模块中项目名称远程搜索方法,提高代码复用性
- 优化主项目和子项目名称的加载和搜索逻辑
2025-08-04 10:02:50 +08:00
4229cb9d74 Merge pull request 'refactor(expense-management): 优化费用管理三个模块中搜索配置的选项处理' (#1101) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1101
2025-08-03 11:41:45 +00:00
dj
a64715717b refactor(expense-management): 优化费用管理三个模块中搜索配置的选项处理
- 移除了 cost-detail、expend-detail 和 share-detail 组件中不必要的条件判断
-简化了选项对象的创建和添加到 Map 中的逻辑
- 提高了代码的可读性和维护性
2025-08-03 19:41:29 +08:00
f18ae8b1ee Merge pull request 'feat(project-demand): 实现主子项目名称模糊查询功能' (#1100) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1100
2025-08-03 10:56:46 +00:00
dj
19c566cd0d feat(project-demand): 实现主子项目名称模糊查询功能
- 在项目需求汇总、成本明细、支出明细和共享明细页面添加主子项目名称模糊查询功能
- 新增相关 API 接口和方法以支持模糊查询
- 优化 fvSelect 组件以适配远程搜索功能
2025-08-03 18:55:53 +08:00
3c459f4be2 Merge pull request 'fix(filling): 修改用户管理归属部门显示' (#1099) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1099
2025-08-01 15:14:10 +00:00
dj
1ad6e021a1 fix(filling): 修改用户管理归属部门显示 2025-08-01 22:50:59 +08:00
6cbc3f83e6 Merge pull request 'master' (#1098) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1098
2025-07-27 12:40:09 +00:00
dj
9560a964e7 fix(filling): 修改下属公司归档状态 2025-07-27 20:39:21 +08:00
94bd9930b6 Merge pull request 'prod' (#1097) from prod into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1097
2025-07-22 16:24:29 +00:00
f2e80e4874 Merge pull request 'fix : 需求上报部分字段默认null' (#1096) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1096
2025-07-22 16:23:07 +00:00
dj
62e98b9e3f fix : 需求上报部分字段默认null 2025-07-23 00:21:28 +08:00
zhangkaihuai
a620b248f4 更新 .drone.yml 2025-07-22 07:52:07 +00:00
zhangkaihuai
e2e4d3226f 更新 .drone.yml 2025-07-22 07:45:47 +00:00
zhangkaihuai
af2788583f 更新 .drone.yml 2025-07-22 07:42:40 +00:00
zhangkaihuai
ba58089e94 更新 .drone.yml 2025-07-22 07:29:18 +00:00
zhangkaihuai
88dcbf3196 更新 .drone.yml 2025-07-22 07:26:24 +00:00
9092b1e960 Merge pull request 'master' (#1095) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1095
2025-07-22 07:13:45 +00:00
dj
3ddd24cc70 fix : 修复支出明细-项目类型字段 2025-07-22 15:13:22 +08:00
1fb3345afe Merge pull request 'fix : 屏蔽账号编辑' (#1094) from prod into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1094
2025-07-11 02:27:43 +00:00
dj
d1fe0faad1 fix : 屏蔽账号编辑 2025-07-11 10:24:32 +08:00
64d10a711d Merge pull request 'fix : 修复角色修改权限' (#1093) from prod into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1093
2025-07-11 02:19:47 +00:00
dj
1d5e8a23ed fix : 修复角色修改权限 2025-07-11 10:12:48 +08:00
2973bbe6a7 Merge pull request 'prod' (#1092) from prod into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1092
2025-07-10 03:34:00 +00:00
zhangkaihuai
8974282b44 更新 docker.sh 2025-07-10 03:26:55 +00:00
zhangkaihuai
81705482a8 更新 docker.sh 2025-07-10 03:22:00 +00:00
9cc8d337be Merge pull request 'fix : 修复实施图片' (#1091) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1091
2025-07-09 14:59:44 +00:00
973dc0f2e4 fix : 修复实施图片 2025-07-09 22:56:09 +08:00
db696ca389 Merge pull request 'feat(components): 调整分页组件默认页码和每页条数' (#1090) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1090
2025-07-03 15:30:50 +00:00
dj
64e2ff0647 feat(components): 调整分页组件默认页码和每页条数
- 将 fvPagination 组件的默认每页条数从 10 调整为 20
- 在 pageSizes 数组中添加 100 选项
- 更新 fvTable 组件中的默认每页条数和 pageSizes 配置
- 修改首页专项资金项目和研发投入资金的相关文案
2025-07-03 23:30:22 +08:00
53b0e4b240 Merge pull request 'master' (#1089) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1089
2025-07-03 15:08:34 +00:00
dj
17010a15a3 fix : 修复首页数量 2025-07-03 23:08:16 +08:00
f74743c00f Merge pull request 'fix : 修复首页数量' (#1088) from prod into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1088
2025-07-03 15:01:37 +00:00
dj
e14b6d676c fix : 修复首页数量 2025-07-03 18:41:57 +08:00
3ecea87de8 Merge pull request 'prod' (#1087) from prod into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1087
2025-06-25 10:05:41 +00:00
dj
cb290acf09 test : ci/cd 2025-06-25 17:52:27 +08:00
f6cabee345 Merge pull request 'feat(upload): 优化文件上传组件逻辑' (#1086) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1086
2025-06-25 09:41:38 +00:00
dj
8b03d62a75 feat(upload): 优化文件上传组件逻辑
- 在删除文件时,将删除的文件信息存储到本地存储中
- 在选择文件时,检查本地存储中是否有删除的文件信息,并从选择的文件中移除
- 优化了文件上传流程,提高了用户体验
2025-06-25 17:41:15 +08:00
1674d1acd0 Merge pull request 'fix(ProjectAttachment): 优化附件删除逻辑' (#1085) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1085
2025-06-25 07:38:49 +00:00
dj
41a455338f fix(ProjectAttachment): 优化附件删除逻辑
- 在删除其他附件时,同时从 allFiles 中移除对应文件
- 移除删除附件后不必要的重新获取附件列表操作
2025-06-25 15:38:22 +08:00
5b67f97021 Merge pull request 'master' (#1084) from master into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1084
2025-06-20 01:57:33 +00:00
dj
a451f7481e style(fvTable): 移除表格单元格悬停时的宽度限制
- 注释掉 .fv-table :deep(.el-tooltip) 中的 width: 100% !important 样式
-此修改解决了单元格内容过长时导致的表格布局问题
2025-06-20 09:57:06 +08:00
2400660b1f Merge pull request 'prod' (#1083) from prod into master
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1083
2025-06-14 16:37:37 +00:00
dj
26e0009ebd test : ci/cd 2025-06-15 00:36:56 +08:00
dj
34b0b88f07 test : ci/cd 2025-06-15 00:31:01 +08:00
dj
37a3cd75a2 test : ci/cd 2025-06-15 00:25:25 +08:00
dj
81d4002034 test : ci/cd 2025-06-15 00:10:47 +08:00
dj
5c000cdba3 test : ci/cd 2025-06-15 00:06:42 +08:00
zhangkaihuai
5dcdbe9ae1 Merge pull request 'zhangkaihuai-patch-1' (#1082) from zhangkaihuai-patch-1 into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1082
2025-06-14 15:25:46 +00:00
zhangkaihuai
bf2f28960f Merge pull request '更新 .drone.yml' (#1081) from zhangkaihuai-patch-1 into prod
Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/1081
2025-06-14 14:56:58 +00:00
337 changed files with 62703 additions and 61992 deletions

View File

@@ -1,41 +1,41 @@
### Java template ### Java template
# Compiled class file # Compiled class file
*.class *.class
# Log file # Log file
*.log *.log
# BlueJ files # BlueJ files
*.ctxt *.ctxt
# Mobile Tools for Java (J2ME) # Mobile Tools for Java (J2ME)
.mtj.tmp/ .mtj.tmp/
# Package Files # # Package Files #
*.jar *.jar
*.war *.war
*.nar *.nar
*.ear *.ear
*.zip *.zip
*.tar.gz *.tar.gz
*.rar *.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid* hs_err_pid*
### Maven template ### Maven template
target/ target/
pom.xml.tag pom.xml.tag
pom.xml.releaseBackup pom.xml.releaseBackup
pom.xml.versionsBackup pom.xml.versionsBackup
pom.xml.next pom.xml.next
release.properties release.properties
dependency-reduced-pom.xml dependency-reduced-pom.xml
buildNumber.properties buildNumber.properties
.mvn/timing.properties .mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar # https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar .mvn/wrapper/maven-wrapper.jar
### Example user template template ### Example user template template
### Example user template ### Example user template
# IntelliJ project files # IntelliJ project files
.idea .idea
*.iml *.iml
out out
gen gen
!build !build
!default.conf !default.conf
!nginx.conf !nginx.conf

View File

@@ -29,8 +29,9 @@ steps:
- npm config set registry https://registry.npmmirror.com - npm config set registry https://registry.npmmirror.com
- set NODE_OPTIONS=--openssl-legacy-provider - set NODE_OPTIONS=--openssl-legacy-provider
- npm install --legacy-peer-deps - npm install --legacy-peer-deps
- npm install patch-package - npm install codemirror
- npx patch-package # - npm install patch-package
# - npx patch-package
# - npm info unplugin-icons # - npm info unplugin-icons
- npm list package-manager-detector - npm list package-manager-detector
# - npm install unplugin-icons@latest @antfu/install-pkg@latest package-manager-detector@latest # - npm install unplugin-icons@latest @antfu/install-pkg@latest package-manager-detector@latest

View File

@@ -1,2 +1,2 @@
# 开发环境基地址 # 开发环境基地址
VITE_BASE_URL='/api' VITE_BASE_URL='/api'

View File

@@ -1,3 +1,3 @@
# 生产环境基地址 # 生产环境基地址
VITE_BASE_URL='/api' VITE_BASE_URL='/api'

56
.gitignore vendored
View File

@@ -1,28 +1,28 @@
# Logs # Logs
logs logs
*.log *.log
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
pnpm-debug.log* pnpm-debug.log*
lerna-debug.log* lerna-debug.log*
node_modules node_modules
.DS_Store .DS_Store
dist dist
dist-ssr dist-ssr
coverage coverage
*.local *.local
/cypress/videos/ /cypress/videos/
/cypress/screenshots/ /cypress/screenshots/
# Editor directories and files # Editor directories and files
.vscode .vscode
!.vscode/extensions.json !.vscode/extensions.json
.idea .idea
*.suo *.suo
*.ntvs* *.ntvs*
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?

View File

@@ -1,19 +1,19 @@
FROM 10.7.127.190:38080/nginx:latest FROM 10.7.127.190:38080/nginx:latest
RUN rm -rf /etc/nginx/conf.d/default.conf RUN rm -rf /etc/nginx/conf.d/default.conf
RUN rm -rf /etc/nginx/nginx.conf RUN rm -rf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d COPY default.conf /etc/nginx/conf.d
COPY nginx.conf /etc/nginx/ COPY nginx.conf /etc/nginx/
#COPY mosr.feashow.cn_chain.crt /etc/nginx/ #COPY mosr.feashow.cn_chain.crt /etc/nginx/
#COPY private.key /etc/nginx/ #COPY private.key /etc/nginx/
#RUN useradd -b /home/clay -m -s /bin/bash clay #RUN useradd -b /home/clay -m -s /bin/bash clay
#RUN chmod a+xr -R /home/clay && chown clay:clay -R /home/clay #RUN chmod a+xr -R /home/clay && chown clay:clay -R /home/clay
#USER clay #USER clay
COPY ./dist /home/clay COPY ./dist /home/clay
WORKDIR /home/clay WORKDIR /home/clay
EXPOSE 80 EXPOSE 80

View File

@@ -1,19 +1,19 @@
server { server {
listen 80; listen 80;
listen [::]:80; listen [::]:80;
location /api { location /api {
proxy_pass http://gateway.dev.svc.cluster.local:8080; proxy_pass http://gateway.dev.svc.cluster.local:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Port $server_port;
#proxy_set_header Host $host; #proxy_set_header Host $host;
rewrite "^/api/(.*)$" /$1 break; rewrite "^/api/(.*)$" /$1 break;
} }
location / { location / {
root /home/clay; root /home/clay;
index index.html index.htm; index index.html index.htm;
} }
} }

View File

@@ -1,51 +1,51 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: $DRONE_REPO_NAME name: $DRONE_REPO_NAME
spec: spec:
type: NodePort type: NodePort
ports: ports:
- name: $PORTS_NAME - name: $PORTS_NAME
nodePort: $PORTS_PORT nodePort: $PORTS_PORT
port: 80 port: 80
protocol: TCP protocol: TCP
targetPort: 80 targetPort: 80
selector: selector:
app: $DRONE_REPO_NAME app: $DRONE_REPO_NAME
--- ---
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: $DRONE_REPO_NAME name: $DRONE_REPO_NAME
spec: spec:
replicas: 1 replicas: 1
selector: selector:
matchLabels: matchLabels:
app: $DRONE_REPO_NAME app: $DRONE_REPO_NAME
template: template:
metadata: metadata:
labels: labels:
app: $DRONE_REPO_NAME app: $DRONE_REPO_NAME
spec: spec:
imagePullSecrets: imagePullSecrets:
- name: harbor - name: harbor
containers: containers:
- image: $REGISTRY/$REGISTRY_NAMESPACE/$DRONE_REPO_NAME:$DRONE_COMMIT - image: $REGISTRY/$REGISTRY_NAMESPACE/$DRONE_REPO_NAME:$DRONE_COMMIT
name: $DRONE_REPO_NAME name: $DRONE_REPO_NAME
imagePullPolicy: Always imagePullPolicy: Always
env: env:
- name: TIME_ZONE - name: TIME_ZONE
value: Asia/Shanghai value: Asia/Shanghai
- name: REF_NAME - name: REF_NAME
value: dev value: dev
resources: resources:
requests: requests:
memory: 0.1Gi memory: 0.1Gi
cpu: 0.1 cpu: 0.1
limits: limits:
memory: 2Gi memory: 2Gi
cpu: 2 cpu: 2
ports: ports:
- containerPort: 80 - containerPort: 80
name: app-port name: app-port

View File

@@ -8,6 +8,7 @@ app_version=$DRONE_COMMIT
echo ${app_version} echo ${app_version}
# 打包编译docker镜像 # 打包编译docker镜像
echo '----build image start----' echo '----build image start----'
echo ${group_name}/${app_name}
docker build -t ${group_name}/${app_name} . docker build -t ${group_name}/${app_name} .
echo '----build image success----' echo '----build image success----'
docker tag ${group_name}/${app_name} $REGISTRY/$REGISTRY_NAMESPACE/${app_name}:${app_version} docker tag ${group_name}/${app_name} $REGISTRY/$REGISTRY_NAMESPACE/${app_name}:${app_version}

View File

@@ -1,13 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>科技创新项目管理平台</title> <title>科技创新项目管理平台</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<script type="module" src="/src/main.js"></script> <script type="module" src="/src/main.js"></script>
</body> </body>
</html> </html>

View File

@@ -1,72 +1,72 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIG3DCCBMSgAwIBAgIQDzIS+rldpl8FKv9qt1IuQDANBgkqhkiG9w0BAQsFADBb MIIG3DCCBMSgAwIBAgIQDzIS+rldpl8FKv9qt1IuQDANBgkqhkiG9w0BAQsFADBb
MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg
SW5jLjElMCMGA1UEAxMcVHJ1c3RBc2lhIERWIFRMUyBSU0EgQ0EgMjAyNTAeFw0y SW5jLjElMCMGA1UEAxMcVHJ1c3RBc2lhIERWIFRMUyBSU0EgQ0EgMjAyNTAeFw0y
NTAzMTkwMDAwMDBaFw0yNTA2MTcyMzU5NTlaMBoxGDAWBgNVBAMTD21vc3IuZmVh NTAzMTkwMDAwMDBaFw0yNTA2MTcyMzU5NTlaMBoxGDAWBgNVBAMTD21vc3IuZmVh
c2hvdy5jbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK92bSayd6Wo c2hvdy5jbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK92bSayd6Wo
wFJz+ldX8QEgQiUjEPyQB0rV+Op9/eZSmpC6y+DuS/CddOPaXs+t1fV9L2kQ1yWD wFJz+ldX8QEgQiUjEPyQB0rV+Op9/eZSmpC6y+DuS/CddOPaXs+t1fV9L2kQ1yWD
Byc7cZK2PnzGb8+Uh9BR3UtVaCxISGqxjvt2V1lIwXbBDOUjtkVVlchhGR+BrNzP Byc7cZK2PnzGb8+Uh9BR3UtVaCxISGqxjvt2V1lIwXbBDOUjtkVVlchhGR+BrNzP
YGyMLhgdBDxhKK4ogBNOx23AzCpTGFsU7sL996qwYo2rhIE8UuYcw3deS4RtfMUx YGyMLhgdBDxhKK4ogBNOx23AzCpTGFsU7sL996qwYo2rhIE8UuYcw3deS4RtfMUx
zt58wn1s+9kki6Qti7dLw3Bg0eCXop+7/FC09fg5Nh3EygMlZvLyvNOFig+o/Fk3 zt58wn1s+9kki6Qti7dLw3Bg0eCXop+7/FC09fg5Nh3EygMlZvLyvNOFig+o/Fk3
6ibp2N56yFLEfe+WNj4xPCad/3Cevh5BIgTsSAPBh6J5Jk4IXoL8PuCSc96d79Bg 6ibp2N56yFLEfe+WNj4xPCad/3Cevh5BIgTsSAPBh6J5Jk4IXoL8PuCSc96d79Bg
SVGNGhRuCgcCAwEAAaOCAtswggLXMB8GA1UdIwQYMBaAFLQSKKW0wB2fKXFpPNkR SVGNGhRuCgcCAwEAAaOCAtswggLXMB8GA1UdIwQYMBaAFLQSKKW0wB2fKXFpPNkR
lkp1aVDAMB0GA1UdDgQWBBTL9/e/QUue1NxlPXspxQ/RzXhzxTAaBgNVHREEEzAR lkp1aVDAMB0GA1UdDgQWBBTL9/e/QUue1NxlPXspxQ/RzXhzxTAaBgNVHREEEzAR
gg9tb3NyLmZlYXNob3cuY24wPgYDVR0gBDcwNTAzBgZngQwBAgEwKTAnBggrBgEF gg9tb3NyLmZlYXNob3cuY24wPgYDVR0gBDcwNTAzBgZngQwBAgEwKTAnBggrBgEF
BQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIF BQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIF
oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIweQYIKwYBBQUHAQEEbTBr oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIweQYIKwYBBQUHAQEEbTBr
MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUH MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUH
MAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9UcnVzdEFzaWFEVlRMU1JT MAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9UcnVzdEFzaWFEVlRMU1JT
QUNBMjAyNS5jcnQwDAYDVR0TAQH/BAIwADCCAX8GCisGAQQB1nkCBAIEggFvBIIB QUNBMjAyNS5jcnQwDAYDVR0TAQH/BAIwADCCAX8GCisGAQQB1nkCBAIEggFvBIIB
awFpAHYATnWjJ1yaEMM4W2zU3z9S6x3w4I4bjWnAsfpksWKaOd8AAAGVrKDPywAA awFpAHYATnWjJ1yaEMM4W2zU3z9S6x3w4I4bjWnAsfpksWKaOd8AAAGVrKDPywAA
BAMARzBFAiAJkC1pvmPIhgdAkRoyPCItM4oRM5Bb8OI3zVzNvdNTkQIhAN1Fq4mU BAMARzBFAiAJkC1pvmPIhgdAkRoyPCItM4oRM5Bb8OI3zVzNvdNTkQIhAN1Fq4mU
GJYrJkOmwvJ2Mb5upB50Ic8C7KatpMdKEFM7AHYAfVkeEuF4KnscYWd8Xv340Idc GJYrJkOmwvJ2Mb5upB50Ic8C7KatpMdKEFM7AHYAfVkeEuF4KnscYWd8Xv340Idc
FKBOlZ65Ay/ZDowuebgAAAGVrKDQBwAABAMARzBFAiAT9jfX08uN94aIeK84IySz FKBOlZ65Ay/ZDowuebgAAAGVrKDQBwAABAMARzBFAiAT9jfX08uN94aIeK84IySz
jUPDa1MSWjJKsA3XusY3GAIhAJ9PvGtFx9+UM9YNNT7BZUq6hhVvhYWhlf+d0qpy jUPDa1MSWjJKsA3XusY3GAIhAJ9PvGtFx9+UM9YNNT7BZUq6hhVvhYWhlf+d0qpy
uEl9AHcAzxFW7tUufK/zh1vZaS6b6RpxZ0qwF+ysAdJbd87MOwgAAAGVrKDP+AAA uEl9AHcAzxFW7tUufK/zh1vZaS6b6RpxZ0qwF+ysAdJbd87MOwgAAAGVrKDP+AAA
BAMASDBGAiEA0c9dt1JwyAMzQtv7UsPaKEJ5sp6HDaSWe5BGIYWsYrcCIQDjS6L1 BAMASDBGAiEA0c9dt1JwyAMzQtv7UsPaKEJ5sp6HDaSWe5BGIYWsYrcCIQDjS6L1
9TF6SpcEWHH6bl952VQb6Xvt1JmmKUNX6iK2xTANBgkqhkiG9w0BAQsFAAOCAgEA 9TF6SpcEWHH6bl952VQb6Xvt1JmmKUNX6iK2xTANBgkqhkiG9w0BAQsFAAOCAgEA
0E2VWQjWgEBz968xq2cpYGv2Enfs2TWpynuoPTwY83V7h2ejNbpjgyW1gT/kQkxa 0E2VWQjWgEBz968xq2cpYGv2Enfs2TWpynuoPTwY83V7h2ejNbpjgyW1gT/kQkxa
G5k4jpkVmNMaj3CAvK4IA5jOPh6dhzBG35Qc0PwRm0eovcUdUNUd0g4EOv82p2s1 G5k4jpkVmNMaj3CAvK4IA5jOPh6dhzBG35Qc0PwRm0eovcUdUNUd0g4EOv82p2s1
ab1SWNYoxGdS+y+LHhfFZ7CoVcSvBz+LHBlPTVTkLA0SWLA0fhS3pl5oGIilMtSM ab1SWNYoxGdS+y+LHhfFZ7CoVcSvBz+LHBlPTVTkLA0SWLA0fhS3pl5oGIilMtSM
znCUUuMBtMQBv7sFX2gDEYwxGaMn3lpoqBGkpx4UBc51z/U3+X9zLqu6n/GpLC72 znCUUuMBtMQBv7sFX2gDEYwxGaMn3lpoqBGkpx4UBc51z/U3+X9zLqu6n/GpLC72
+qz6QtQVm0Np8gcjul0ebQqAPwDG4U+9jYEmdwVHZ0iUKgyZPECPU+TTtHx0TFS3 +qz6QtQVm0Np8gcjul0ebQqAPwDG4U+9jYEmdwVHZ0iUKgyZPECPU+TTtHx0TFS3
B5JXy8vbGJBqpwq6hMnu/SFm+GY3iPk7N0Aj5+9QNcl2FTF8k/nCoK3MuY71ZmxR B5JXy8vbGJBqpwq6hMnu/SFm+GY3iPk7N0Aj5+9QNcl2FTF8k/nCoK3MuY71ZmxR
E1NY6Hl5KpKzBqc7JG4iqQxJ0dD9Racn4wegGDlX0Vr2U+ohHYeETNJXOX+JT4tc E1NY6Hl5KpKzBqc7JG4iqQxJ0dD9Racn4wegGDlX0Vr2U+ohHYeETNJXOX+JT4tc
1PBdfiywbX+FCdE2ZPehWa6dt4fnPBC/9lSywrzOWLNt9z1a/Mh73N5F6ndaXq1p 1PBdfiywbX+FCdE2ZPehWa6dt4fnPBC/9lSywrzOWLNt9z1a/Mh73N5F6ndaXq1p
v/N3Q0qnXpW1RZa6Baqlfvk2vqhraRbT9YH5Y+f51DhtVB6fbELO/pJr1H5kh0XI v/N3Q0qnXpW1RZa6Baqlfvk2vqhraRbT9YH5Y+f51DhtVB6fbELO/pJr1H5kh0XI
CczHkGTGD7xZloNfTMLP2AVguIXJ0EASAAMw/MBRWvSd4He2lLHvujEqTXsTISgv CczHkGTGD7xZloNfTMLP2AVguIXJ0EASAAMw/MBRWvSd4He2lLHvujEqTXsTISgv
v+/5bZP8qBk3/oEgdLjlmqWY1sesBH84tiMZcxCkPNM= v+/5bZP8qBk3/oEgdLjlmqWY1sesBH84tiMZcxCkPNM=
-----END CERTIFICATE----- -----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIFnjCCBIagAwIBAgIQCSYyO0lk42hGFRLe8aXVLDANBgkqhkiG9w0BAQsFADBh MIIFnjCCBIagAwIBAgIQCSYyO0lk42hGFRLe8aXVLDANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0yNTAxMDgwMDAwMDBaFw0zNTAxMDcyMzU5NTlaMFsxCzAJBgNVBAYTAkNO MjAeFw0yNTAxMDgwMDAwMDBaFw0zNTAxMDcyMzU5NTlaMFsxCzAJBgNVBAYTAkNO
MSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSUwIwYDVQQD MSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSUwIwYDVQQD
ExxUcnVzdEFzaWEgRFYgVExTIFJTQSBDQSAyMDI1MIICIjANBgkqhkiG9w0BAQEF ExxUcnVzdEFzaWEgRFYgVExTIFJTQSBDQSAyMDI1MIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEA0fuEmuBIsN6ZZVq+gRobMorOGIilTCIfQrxNpR8FUZ9R AAOCAg8AMIICCgKCAgEA0fuEmuBIsN6ZZVq+gRobMorOGIilTCIfQrxNpR8FUZ9R
/GfbiekbiIKphQXEZ7N1uBnn6tXUuZ32zl6jPkZpHzN/Bmgk1BWSIzVc0npMzrWq /GfbiekbiIKphQXEZ7N1uBnn6tXUuZ32zl6jPkZpHzN/Bmgk1BWSIzVc0npMzrWq
/hrbk5+KddXJdsNpeG1+Q8lc8uVMBrztnxaPb7Rh7yQCsMrcO4hgVaqLJWkVvEfW /hrbk5+KddXJdsNpeG1+Q8lc8uVMBrztnxaPb7Rh7yQCsMrcO4hgVaqLJWkVvEfW
ULtoCHQnNaj4IroG6VxQf1oArQ8bPbwpI02lieSahRa78FQuXdoGVeQcrkhtVjZs ULtoCHQnNaj4IroG6VxQf1oArQ8bPbwpI02lieSahRa78FQuXdoGVeQcrkhtVjZs
ON98vq5fPWZX2LFv7e5J6P9IHbzvOl8yyQjv+2/IOwhNSkaXX3bI+//bqF9XW/p7 ON98vq5fPWZX2LFv7e5J6P9IHbzvOl8yyQjv+2/IOwhNSkaXX3bI+//bqF9XW/p7
+gsUmHiK5YsvLjmXcvDmoDEGrXMzgX31Zl2nJ+umpRbLjwP8rxYIUsKoEwEdFoto +gsUmHiK5YsvLjmXcvDmoDEGrXMzgX31Zl2nJ+umpRbLjwP8rxYIUsKoEwEdFoto
Aid59UEBJyw/GibwXQ5xTyKD/N6C8SFkr1+myOo4oe1UB+YgvRu6qSxIABo5kYdX Aid59UEBJyw/GibwXQ5xTyKD/N6C8SFkr1+myOo4oe1UB+YgvRu6qSxIABo5kYdX
FodLP4IgoVJdeUFs1Usa6bxYEO6EgMf5lCWt9hGZszvXYZwvyZGq3ogNXM7eKyi2 FodLP4IgoVJdeUFs1Usa6bxYEO6EgMf5lCWt9hGZszvXYZwvyZGq3ogNXM7eKyi2
20WzJXYMmi9TYFq2Fa95aZe4wki6YhDhhOO1g0sjITGVaB73G+JOCI9yJhv6+REN 20WzJXYMmi9TYFq2Fa95aZe4wki6YhDhhOO1g0sjITGVaB73G+JOCI9yJhv6+REN
D40ZpboUHE8JNgMVWbG1isAMVCXqiADgXtuC+tmJWPEH9cR6OuJLEpwOzPfgAbnn D40ZpboUHE8JNgMVWbG1isAMVCXqiADgXtuC+tmJWPEH9cR6OuJLEpwOzPfgAbnn
2MRu7Tsdr8jPjTPbD0FxblX1ydW3RG30vwLF5lkTTRkHG9epMgpPMdYP7nY/08MC 2MRu7Tsdr8jPjTPbD0FxblX1ydW3RG30vwLF5lkTTRkHG9epMgpPMdYP7nY/08MC
AwEAAaOCAVYwggFSMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLQSKKW0 AwEAAaOCAVYwggFSMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLQSKKW0
wB2fKXFpPNkRlkp1aVDAMB8GA1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485 wB2fKXFpPNkRlkp1aVDAMB8GA1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485
MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
dgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy dgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
dC5jb20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E dC5jb20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E
aWdpQ2VydEdsb2JhbFJvb3RHMi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov aWdpQ2VydEdsb2JhbFJvb3RHMi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov
L2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDARBgNV L2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDARBgNV
HSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQELBQADggEBAJ4a3svh316GY2+Z7EYx HSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQELBQADggEBAJ4a3svh316GY2+Z7EYx
mBIsOwjJSnyoEfzx2T699ctLLrvuzS79Mg3pPjxSLlUgyM8UzrFc5tgVU3dZ1sFQ mBIsOwjJSnyoEfzx2T699ctLLrvuzS79Mg3pPjxSLlUgyM8UzrFc5tgVU3dZ1sFQ
I4RM+ysJdvIAX/7Yx1QbooVdKhkdi9X7QN7yVkjqwM3fY3WfQkRTzhIkM7mYIQbR I4RM+ysJdvIAX/7Yx1QbooVdKhkdi9X7QN7yVkjqwM3fY3WfQkRTzhIkM7mYIQbR
r+y2Vkju61BLqh7OCRpPMiudjEpP1kEtRyGs2g0aQpEIqKBzxgitCXSayO1hoO6/ r+y2Vkju61BLqh7OCRpPMiudjEpP1kEtRyGs2g0aQpEIqKBzxgitCXSayO1hoO6/
71ts801OzYlqYW9OQQQ2GCJyFbD6XHDjdpn+bWUxTKWaMY0qedSCbHE3Kl2QEF0C 71ts801OzYlqYW9OQQQ2GCJyFbD6XHDjdpn+bWUxTKWaMY0qedSCbHE3Kl2QEF0C
ynZ7SbC03yR+gKZQDeTXrNP1kk5Qhe7jSXgw+nhbspe0q/M1ZcNCz+sPxeOwdCcC ynZ7SbC03yR+gKZQDeTXrNP1kk5Qhe7jSXgw+nhbspe0q/M1ZcNCz+sPxeOwdCcC
gJE= gJE=
-----END CERTIFICATE----- -----END CERTIFICATE-----

View File

@@ -1,52 +1,52 @@
user nginx; user nginx;
worker_processes auto; worker_processes auto;
error_log /var/log/nginx/error.log notice; error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid; pid /var/run/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
} }
http { http {
include /etc/nginx/mime.types; include /etc/nginx/mime.types;
default_type application/octet-stream; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" ' '$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; '"$http_user_agent" "$http_x_forwarded_for"';
add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Allow-Methods' '*'; add_header 'Access-Control-Allow-Methods' '*';
access_log /var/log/nginx/access.log main; access_log /var/log/nginx/access.log main;
sendfile on; sendfile on;
keepalive_timeout 65; keepalive_timeout 65;
server { server {
listen 80; listen 80;
listen [::]:80; listen [::]:80;
location /api { location /api {
proxy_pass http://gateway.$PROFILES.svc.cluster.local:8080; proxy_pass http://gateway.$PROFILES.svc.cluster.local:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Host $host; proxy_set_header Host $host;
rewrite "^/api/(.*)$" /$1 break; rewrite "^/api/(.*)$" /$1 break;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade'; proxy_set_header Connection 'upgrade';
client_max_body_size 30m; client_max_body_size 30m;
} }
location / { location / {
root /home/clay; root /home/clay;
index index.html index.htm; index index.html index.htm;
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }
} }
} }

View File

@@ -1,58 +1,59 @@
{ {
"name": "mosr-web", "name": "mosr-web",
"version": "0.0.0", "version": "0.0.0",
"private": true, "type": "module",
"scripts": { "private": true,
"dev": "vite", "scripts": {
"build": "vite build", "dev": "vite",
"preview": "vite preview" "build": "vite build --config vite.config.mjs",
}, "preview": "vite preview"
"overrides": { },
"package-manager-detector": "1.0.0", "overrides": {
"package-manager-detector": "1.0.0",
"@iconify/utils": "2.2.1"
}, "@iconify/utils": "2.2.1"
"dependencies": { },
"@antv/g6": "^3.5.7", "dependencies": {
"@tinymce/tinymce-vue": "^4.0.7", "@antv/g6": "^3.5.7",
"axios": "^1.4.0", "@tinymce/tinymce-vue": "^4.0.7",
"d3": "^7.8.5", "axios": "^1.4.0",
"docx-preview": "^0.3.2", "d3": "^7.8.5",
"echarts": "^5.4.2", "docx-preview": "^0.3.2",
"element-plus": "^2.6.0", "echarts": "^5.4.2",
"file-saver": "^2.0.5", "element-plus": "^2.6.0",
"highlight.js": "9.18.5", "file-saver": "^2.0.5",
"jquery": "^3.6.0", "highlight.js": "9.18.5",
"js-cookie": "^3.0.5", "jquery": "^3.6.0",
"nprogress": "^0.2.0", "js-cookie": "^3.0.5",
"pinia": "^2.0.35", "nprogress": "^0.2.0",
"sass": "^1.62.1", "pinia": "^2.0.35",
"scss": "^0.2.4", "sass": "^1.62.1",
"sql-formatter": "^2.3.4", "scss": "^0.2.4",
"tinymce": "^5.0.4", "sql-formatter": "^2.3.4",
"unplugin-icons": "^0.16.1", "tinymce": "^5.0.4",
"vite-plugin-inspect": "^0.7.26", "unplugin-icons": "^0.16.1",
"vue": "^3.2.47", "vite-plugin-inspect": "^0.7.26",
"vue-clipboard3": "^2.0.0", "vue": "^3.2.47",
"vue-codemirror": "^6.1.1", "vue-clipboard3": "^2.0.0",
"vue-json-viewer": "^3.0.4", "vue-codemirror": "^6.1.1",
"vue-router": "^4.1.6", "vue-json-viewer": "^3.0.4",
"vue3-pdf-app": "^1.0.3", "vue-router": "^4.1.6",
"vue3-print-nb": "^0.1.4", "vue3-pdf-app": "^1.0.3",
"vuedraggable": "^4.1.0", "vue3-print-nb": "^0.1.4",
"xlsx": "^0.18.5", "vuedraggable": "^4.1.0",
"xlsx-style-vite": "^0.0.2" "xlsx": "^0.18.5",
}, "xlsx-style-vite": "^0.0.2"
"devDependencies": { },
"@codemirror/lang-java": "^6.0.1", "devDependencies": {
"@codemirror/lang-javascript": "^6.1.9", "@codemirror/lang-java": "^6.0.1",
"@codemirror/lang-sql": "^6.5.4", "@codemirror/lang-javascript": "^6.1.9",
"@vitejs/plugin-vue": "^4.2.1", "@codemirror/lang-sql": "^6.5.4",
"@vitejs/plugin-vue-jsx": "^3.0.1", "@vitejs/plugin-vue": "^4.2.1",
"lodash": "^4.17.21", "@vitejs/plugin-vue-jsx": "^3.0.1",
"unplugin-auto-import": "^0.15.3", "lodash": "^4.17.21",
"unplugin-vue-components": "^0.24.1", "unplugin-auto-import": "^0.15.3",
"vite": "^4.3.4", "unplugin-vue-components": "^0.24.1",
"vite-plugin-svg-icons": "^0.4.0" "vite": "^4.3.4",
} "vite-plugin-svg-icons": "^0.4.0"
} }
}

View File

@@ -1,28 +1,28 @@
-----BEGIN PRIVATE KEY----- -----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvdm0msnelqMBS MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvdm0msnelqMBS
c/pXV/EBIEIlIxD8kAdK1fjqff3mUpqQusvg7kvwnXTj2l7PrdX1fS9pENclgwcn c/pXV/EBIEIlIxD8kAdK1fjqff3mUpqQusvg7kvwnXTj2l7PrdX1fS9pENclgwcn
O3GStj58xm/PlIfQUd1LVWgsSEhqsY77dldZSMF2wQzlI7ZFVZXIYRkfgazcz2Bs O3GStj58xm/PlIfQUd1LVWgsSEhqsY77dldZSMF2wQzlI7ZFVZXIYRkfgazcz2Bs
jC4YHQQ8YSiuKIATTsdtwMwqUxhbFO7C/feqsGKNq4SBPFLmHMN3XkuEbXzFMc7e jC4YHQQ8YSiuKIATTsdtwMwqUxhbFO7C/feqsGKNq4SBPFLmHMN3XkuEbXzFMc7e
fMJ9bPvZJIukLYu3S8NwYNHgl6Kfu/xQtPX4OTYdxMoDJWby8rzThYoPqPxZN+om fMJ9bPvZJIukLYu3S8NwYNHgl6Kfu/xQtPX4OTYdxMoDJWby8rzThYoPqPxZN+om
6djeeshSxH3vljY+MTwmnf9wnr4eQSIE7EgDwYeieSZOCF6C/D7gknPene/QYElR 6djeeshSxH3vljY+MTwmnf9wnr4eQSIE7EgDwYeieSZOCF6C/D7gknPene/QYElR
jRoUbgoHAgMBAAECggEABmJQMV6/9LKRoM5gduoXtjtGvNQsS4wv/7yOTHXeFZG+ jRoUbgoHAgMBAAECggEABmJQMV6/9LKRoM5gduoXtjtGvNQsS4wv/7yOTHXeFZG+
1vI89cel0rDf7mRlG7hO9xohbfizY0WDrp0+kiB4YJDVw587W8yGuTV3z1in7d3c 1vI89cel0rDf7mRlG7hO9xohbfizY0WDrp0+kiB4YJDVw587W8yGuTV3z1in7d3c
/nA9WF3J0DjQ78tfV+F3zC0gPWG5+OTAtOJa0PzJSSsd0Exf8JPmtKsVopqYYcPv /nA9WF3J0DjQ78tfV+F3zC0gPWG5+OTAtOJa0PzJSSsd0Exf8JPmtKsVopqYYcPv
RL2uP+NfcsxIEPz7rBBqiTGbOgsoKIpVZWiV6dmGOHLnI3ktWE8GXyIFv0VO6kp2 RL2uP+NfcsxIEPz7rBBqiTGbOgsoKIpVZWiV6dmGOHLnI3ktWE8GXyIFv0VO6kp2
fk/Z2uU9rfS9Qc9NijVdZ5AejdSh70iWNdiVMTSXZ69XLQCiY1h/376mraAPZTC1 fk/Z2uU9rfS9Qc9NijVdZ5AejdSh70iWNdiVMTSXZ69XLQCiY1h/376mraAPZTC1
T0fYAtaOdyRrYLIW3yuznZa6hz351+t4TjJHQGjAUQKBgQDe8FS3yM85Ve3qlNaV T0fYAtaOdyRrYLIW3yuznZa6hz351+t4TjJHQGjAUQKBgQDe8FS3yM85Ve3qlNaV
pzjpjkv8cn8u43Hyk88owNACxkvzUXx15YE+AGjjycVO5rbyC1mtdE2MKX8cd5T/ pzjpjkv8cn8u43Hyk88owNACxkvzUXx15YE+AGjjycVO5rbyC1mtdE2MKX8cd5T/
cA75RoSDxBTR7xi9eqBzJpQ7hm2rTaZSkHhu4P9KsthgQFFYQB6EkZgYczLOs/OV cA75RoSDxBTR7xi9eqBzJpQ7hm2rTaZSkHhu4P9KsthgQFFYQB6EkZgYczLOs/OV
UmPMuKwL7HcwuRf00jjAOoJPdwKBgQDJe7R4PS0VBAWnh3lC9R/NEbEoFQ6LUwPh UmPMuKwL7HcwuRf00jjAOoJPdwKBgQDJe7R4PS0VBAWnh3lC9R/NEbEoFQ6LUwPh
Qgmgj6LRB/1NgaC7ekDCSyfFlTtpnRDD+WqCrZDiB1ZZehyUObvr0Y0Cb4Y77Fjh Qgmgj6LRB/1NgaC7ekDCSyfFlTtpnRDD+WqCrZDiB1ZZehyUObvr0Y0Cb4Y77Fjh
lPVG0kfcKUldMpJIfeex0LPBwYHC62Y0ztNQmtgTldDjX04b4gAEgpUReHVTJtDr lPVG0kfcKUldMpJIfeex0LPBwYHC62Y0ztNQmtgTldDjX04b4gAEgpUReHVTJtDr
6S1wRPVd8QKBgHIL0+roqUmVcc5NMbEBCJZCGxEbqYBdDg+gGZupdz/UHUpt5xOQ 6S1wRPVd8QKBgHIL0+roqUmVcc5NMbEBCJZCGxEbqYBdDg+gGZupdz/UHUpt5xOQ
wprrLr1InM0OLYyIzelz06/eEo6HhgteUeqnbmbRyizS+X8E2kvN8oq47CVz5Z/b wprrLr1InM0OLYyIzelz06/eEo6HhgteUeqnbmbRyizS+X8E2kvN8oq47CVz5Z/b
FCD0rOSTtSkX/gT9WB9NM9deJyGi4PsEWNWDq0+2OgsMxPqTCEEeLUdlAoGAHNmB FCD0rOSTtSkX/gT9WB9NM9deJyGi4PsEWNWDq0+2OgsMxPqTCEEeLUdlAoGAHNmB
tdXMpr20sZBMZLIEo7Bs1XhuZLS2UYLLLhpjDds/AeIVycJvk2J/h2Me5rh+thD4 tdXMpr20sZBMZLIEo7Bs1XhuZLS2UYLLLhpjDds/AeIVycJvk2J/h2Me5rh+thD4
l02S+Upjqtw5S2AY8GNI9ZhSeDIXZ/WUSVfCwluHDbk4CPk+O8/ObWfv1KEwOU+E l02S+Upjqtw5S2AY8GNI9ZhSeDIXZ/WUSVfCwluHDbk4CPk+O8/ObWfv1KEwOU+E
In6JggRprKTw4j0yE3M/NQkyg32DXMQ+pVy6ZYECgYEAmW/+vm3X2NMj8yjr0Io2 In6JggRprKTw4j0yE3M/NQkyg32DXMQ+pVy6ZYECgYEAmW/+vm3X2NMj8yjr0Io2
P3F/9EHPkrGHNC3Qj6Q2mFus6oDe6NwOQg5Su0fFC77spHFi1g/MlGUxbzoxjVxH P3F/9EHPkrGHNC3Qj6Q2mFus6oDe6NwOQg5Su0fFC77spHFi1g/MlGUxbzoxjVxH
1wQmwCHBJuJ97H9MOJ9K2v88/pkvfFGthkTLpbcJLqX57WVEVnVKBMNhpLrlp+0r 1wQmwCHBJuJ97H9MOJ9K2v88/pkvfFGthkTLpbcJLqX57WVEVnVKBMNhpLrlp+0r
T3tV8tN010INwiQkaoqCsuw= T3tV8tN010INwiQkaoqCsuw=
-----END PRIVATE KEY----- -----END PRIVATE KEY-----

File diff suppressed because one or more lines are too long

View File

@@ -1,61 +1,61 @@
body { body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
line-height: 1.4; line-height: 1.4;
margin: 1rem; margin: 1rem;
} }
table { table {
border-collapse: collapse; border-collapse: collapse;
} }
/* Apply a default padding if legacy cellpadding attribute is missing */ /* Apply a default padding if legacy cellpadding attribute is missing */
table:not([cellpadding]) th, table:not([cellpadding]) th,
table:not([cellpadding]) td { table:not([cellpadding]) td {
padding: 0.4rem; padding: 0.4rem;
} }
/* Set default table styles if a table has a positive border attribute /* Set default table styles if a table has a positive border attribute
and no inline css */ and no inline css */
table[border]:not([border="0"]):not([style*="border-width"]) th, table[border]:not([border="0"]):not([style*="border-width"]) th,
table[border]:not([border="0"]):not([style*="border-width"]) td { table[border]:not([border="0"]):not([style*="border-width"]) td {
border-width: 1px; border-width: 1px;
} }
/* Set default table styles if a table has a positive border attribute /* Set default table styles if a table has a positive border attribute
and no inline css */ and no inline css */
table[border]:not([border="0"]):not([style*="border-style"]) th, table[border]:not([border="0"]):not([style*="border-style"]) th,
table[border]:not([border="0"]):not([style*="border-style"]) td { table[border]:not([border="0"]):not([style*="border-style"]) td {
border-style: solid; border-style: solid;
} }
/* Set default table styles if a table has a positive border attribute /* Set default table styles if a table has a positive border attribute
and no inline css */ and no inline css */
table[border]:not([border="0"]):not([style*="border-color"]) th, table[border]:not([border="0"]):not([style*="border-color"]) th,
table[border]:not([border="0"]):not([style*="border-color"]) td { table[border]:not([border="0"]):not([style*="border-color"]) td {
border-color: #ccc; border-color: #ccc;
} }
figure { figure {
display: table; display: table;
margin: 1rem auto; margin: 1rem auto;
} }
figure figcaption { figure figcaption {
color: #999; color: #999;
display: block; display: block;
margin-top: 0.25rem; margin-top: 0.25rem;
text-align: center; text-align: center;
} }
hr { hr {
border-color: #ccc; border-color: #ccc;
border-style: solid; border-style: solid;
border-width: 1px 0 0 0; border-width: 1px 0 0 0;
} }
code { code {
background-color: #e8e8e8; background-color: #e8e8e8;
border-radius: 3px; border-radius: 3px;
padding: 0.1rem 0.2rem; padding: 0.1rem 0.2rem;
} }
.mce-content-body:not([dir=rtl]) blockquote { .mce-content-body:not([dir=rtl]) blockquote {
border-left: 2px solid #ccc; border-left: 2px solid #ccc;
margin-left: 1.5rem; margin-left: 1.5rem;
padding-left: 1rem; padding-left: 1rem;
} }
.mce-content-body[dir=rtl] blockquote { .mce-content-body[dir=rtl] blockquote {
border-right: 2px solid #ccc; border-right: 2px solid #ccc;
margin-right: 1.5rem; margin-right: 1.5rem;
padding-right: 1rem; padding-right: 1rem;
} }

View File

@@ -1 +1 @@
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem} body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,211 +1,211 @@
<!doctype html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>axupimgs</title> <title>axupimgs</title>
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<style> <style>
html,body{height:100%;margin:0;padding:0;background:#fff;} html,body{height:100%;margin:0;padding:0;background:#fff;}
ul{margin:0;padding:0;list-style:none;} ul{margin:0;padding:0;list-style:none;}
#wrap{padding:10px;} #wrap{padding:10px;}
#topbar{padding:10px 0;border-bottom:1px solid #ccc;text-align:right;} #topbar{padding:10px 0;border-bottom:1px solid #ccc;text-align:right;}
#topbar button {margin:0;margin-left:5px;outline:none;padding: 4px 16px;box-sizing: border-box; #topbar button {margin:0;margin-left:5px;outline:none;padding: 4px 16px;box-sizing: border-box;
display:inline-block;border:none;border-radius:3px;text-align:center;cursor:pointer; display:inline-block;border:none;border-radius:3px;text-align:center;cursor:pointer;
font-size:14px;line-height:1.5;background-color:#f0f0f0;color:#223; font-size:14px;line-height:1.5;background-color:#f0f0f0;color:#223;
} }
#topbar button.primary{background-color:#3d97d4;color:#fff;} #topbar button.primary{background-color:#3d97d4;color:#fff;}
#topbar button:hover{background-color:#207ab7;color:#fff;} #topbar button:hover{background-color:#207ab7;color:#fff;}
#topbar button.removeall{float:left} #topbar button.removeall{float:left}
#file_list {display:grid;grid-gap:10px;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));padding-top:10px;} #file_list {display:grid;grid-gap:10px;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));padding-top:10px;}
#file_list:empty:after{content:'可以直接拖拽文件到这里';color:#777;font-size:0.8em;} #file_list:empty:after{content:'可以直接拖拽文件到这里';color:#777;font-size:0.8em;}
#file_list li{position:relative;display:block;vertical-align:top;padding:5px 5px;border-radius:5px;} #file_list li{position:relative;display:block;vertical-align:top;padding:5px 5px;border-radius:5px;}
#file_list li.up-over {} #file_list li.up-over {}
#file_list li.up-now {} #file_list li.up-now {}
#file_list li.up-now:after{content:'';position:absolute;top:0;left:0;display:block;width:100%;height:100%;background:rgba(255,255,255,0.8) url(loading.gif) center center no-repeat;border-radius:5px;z-index:999;} #file_list li.up-now:after{content:'';position:absolute;top:0;left:0;display:block;width:100%;height:100%;background:rgba(255,255,255,0.8) url(loading.gif) center center no-repeat;border-radius:5px;z-index:999;}
#file_list li:hover{background-color:#ddd;} #file_list li:hover{background-color:#ddd;}
#file_list li .picbox {display:flex;flex:0 0 auto;justify-content:center;overflow:hidden;position:relative;width:100%;padding-top:100%;align-items:center;} #file_list li .picbox {display:flex;flex:0 0 auto;justify-content:center;overflow:hidden;position:relative;width:100%;padding-top:100%;align-items:center;}
#file_list li .picbox img {display:block;max-width:100%;max-height:100%;position:absolute; #file_list li .picbox img {display:block;max-width:100%;max-height:100%;position:absolute;
top:50%;left:50%;transform:translateX(-50%) translateY(-50%);} top:50%;left:50%;transform:translateX(-50%) translateY(-50%);}
#file_list li.up-over .picbox:after{content:url('data:image/svg+xml;%20charset=utf8,%3Csvg%20viewBox%3D%220%200%201024%201024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20d%3D%22M512%200C229.376%200%200%20229.376%200%20512s229.376%20512%20512%20512%20512-229.376%20512-512S794.624%200%20512%200z%22%20fill%3D%22%234AC711%22%3E%3C%2Fpath%3E%3Cpath%20d%3D%22M855.552%20394.752l-358.4%20358.4a50.9952%2050.9952%200%200%201-72.192%200l-204.8-204.8c-18.944-19.968-18.944-51.2%200-71.168a50.5344%2050.5344%200%200%201%2072.192-1.024L460.8%20644.608l322.048-322.048c19.968-18.944%2051.2-18.944%2071.168%200%2020.48%2019.456%2020.992%2051.712%201.536%2072.192z%22%20fill%3D%22%23FFFFFF%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E');position:absolute;bottom:2px;right:2px;z-index:9;} #file_list li.up-over .picbox:after{content:url('data:image/svg+xml;%20charset=utf8,%3Csvg%20viewBox%3D%220%200%201024%201024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20d%3D%22M512%200C229.376%200%200%20229.376%200%20512s229.376%20512%20512%20512%20512-229.376%20512-512S794.624%200%20512%200z%22%20fill%3D%22%234AC711%22%3E%3C%2Fpath%3E%3Cpath%20d%3D%22M855.552%20394.752l-358.4%20358.4a50.9952%2050.9952%200%200%201-72.192%200l-204.8-204.8c-18.944-19.968-18.944-51.2%200-71.168a50.5344%2050.5344%200%200%201%2072.192-1.024L460.8%20644.608l322.048-322.048c19.968-18.944%2051.2-18.944%2071.168%200%2020.48%2019.456%2020.992%2051.712%201.536%2072.192z%22%20fill%3D%22%23FFFFFF%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E');position:absolute;bottom:2px;right:2px;z-index:9;}
#file_list li .tools {display:none;position:absolute;bottom:5px;right:5px;z-index:99;} #file_list li .tools {display:none;position:absolute;bottom:5px;right:5px;z-index:99;}
#file_list li:hover .tools {display:block;} #file_list li:hover .tools {display:block;}
#file_list li .tools .remove{cursor:pointer;} #file_list li .tools .remove{cursor:pointer;}
#file_list li .tools .remove:after{content:url('data:image/svg+xml;%20charset=utf8,%3Csvg%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%3E%3Cpath%20d=%22M17%206h3a1%201%200%200%201%200%202h-1v11a3%203%200%200%201-3%203H8a3%203%200%200%201-3-3V8H4a1%201%200%201%201%200-2h3V5a3%203%200%200%201%203-3h4a3%203%200%200%201%203%203v1zm-2%200V5a1%201%200%200%200-1-1h-4a1%201%200%200%200-1%201v1h6zm2%202H7v11a1%201%200%200%200%201%201h8a1%201%200%200%200%201-1V8zm-8%203a1%201%200%200%201%202%200v6a1%201%200%200%201-2%200v-6zm4%200a1%201%200%200%201%202%200v6a1%201%200%200%201-2%200v-6z%22%3E%3C/path%3E%3C/svg%3E');} #file_list li .tools .remove:after{content:url('data:image/svg+xml;%20charset=utf8,%3Csvg%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%3E%3Cpath%20d=%22M17%206h3a1%201%200%200%201%200%202h-1v11a3%203%200%200%201-3%203H8a3%203%200%200%201-3-3V8H4a1%201%200%201%201%200-2h3V5a3%203%200%200%201%203-3h4a3%203%200%200%201%203%203v1zm-2%200V5a1%201%200%200%200-1-1h-4a1%201%200%200%200-1%201v1h6zm2%202H7v11a1%201%200%200%200%201%201h8a1%201%200%200%200%201-1V8zm-8%203a1%201%200%200%201%202%200v6a1%201%200%200%201-2%200v-6zm4%200a1%201%200%200%201%202%200v6a1%201%200%200%201-2%200v-6z%22%3E%3C/path%3E%3C/svg%3E');}
#file_list li .namebox {font-size:14px;line-height:20px;max-height:40px;overflow:hidden;padding:5px 10px;text-align:center;display:flex;justify-content:center;align-items:flex-start;} #file_list li .namebox {font-size:14px;line-height:20px;max-height:40px;overflow:hidden;padding:5px 10px;text-align:center;display:flex;justify-content:center;align-items:flex-start;}
#file_list li .namebox span{word-break:break-all;vertical-align:top;} #file_list li .namebox span{word-break:break-all;vertical-align:top;}
</style> </style>
</head> </head>
<body> <body>
<div id="wrap"> <div id="wrap">
<div id="topbar"><button class="addfile primary">+ 添加文件</button><button class="removeall">清空列表</button></div> <div id="topbar"><button class="addfile primary">+ 添加文件</button><button class="removeall">清空列表</button></div>
<ul id="file_list"></ul> <ul id="file_list"></ul>
</div> </div>
<script> <script>
var editor=parent.tinymce.activeEditor; var editor=parent.tinymce.activeEditor;
var axupimgs=parent.axupimgs; var axupimgs=parent.axupimgs;
axupimgs.res = []; //存放本地文件的数组 axupimgs.res = []; //存放本地文件的数组
var blobInfo = {file:null} var blobInfo = {file:null}
blobInfo.blob = function(){return this.file;} blobInfo.blob = function(){return this.file;}
var upload_handler = axupimgs.images_upload_handler; var upload_handler = axupimgs.images_upload_handler;
var upload_base_path = axupimgs.images_upload_base_path; var upload_base_path = axupimgs.images_upload_base_path;
//为列表添加排序 //为列表添加排序
function reSort(){ function reSort(){
document.querySelectorAll('#file_list li').forEach((el,i)=>{ document.querySelectorAll('#file_list li').forEach((el,i)=>{
el.setAttribute('data-num',i); el.setAttribute('data-num',i);
}); });
} }
function addList(files){ function addList(files){
var files_sum = files.length; var files_sum = files.length;
var vDom = document.createDocumentFragment(); var vDom = document.createDocumentFragment();
for(let i=0;i<files_sum;i++){ for(let i=0;i<files_sum;i++){
let file = files[i]; let file = files[i];
let blobUrl = window.URL.createObjectURL(file) let blobUrl = window.URL.createObjectURL(file)
axupimgs.res.push({file:file,blobUrl:blobUrl,url:''}); axupimgs.res.push({file:file,blobUrl:blobUrl,url:''});
let li = document.createElement('li'); let li = document.createElement('li');
li.setAttribute('class','up-no'); li.setAttribute('class','up-no');
li.setAttribute('data-time',file.lastModified); li.setAttribute('data-time',file.lastModified);
li.innerHTML='<div class="picbox"><img src="'+blobUrl+'"></div><div class="namebox"><span>'+file.name+'</span></div><div class="tools"><a class="remove"></a></div>'; li.innerHTML='<div class="picbox"><img src="'+blobUrl+'"></div><div class="namebox"><span>'+file.name+'</span></div><div class="tools"><a class="remove"></a></div>';
vDom.appendChild(li); vDom.appendChild(li);
} }
document.querySelector('#file_list').appendChild(vDom); document.querySelector('#file_list').appendChild(vDom);
if(axupimgs.res.length>0){ if(axupimgs.res.length>0){
document.querySelectorAll('#file_list li.up-no').forEach((el,i)=>{ document.querySelectorAll('#file_list li.up-no').forEach((el,i)=>{
el.classList ? el.classList.add('up-now') : el.className+=' up-now'; el.classList ? el.classList.add('up-now') : el.className+=' up-now';
}); });
upAllFiles(0); upAllFiles(0);
} }
//reSort(); //reSort();
} }
//清空列表 //清空列表
document.querySelector('#topbar .removeall').addEventListener('click',()=>{ document.querySelector('#topbar .removeall').addEventListener('click',()=>{
axupimgs.res=[] axupimgs.res=[]
document.querySelectorAll('#file_list li').forEach((el,i)=>{ document.querySelectorAll('#file_list li').forEach((el,i)=>{
el.parentNode.removeChild(el) el.parentNode.removeChild(el)
}); });
}); });
//拖拽添加 //拖拽添加
document.addEventListener('dragover', (e)=>{ document.addEventListener('dragover', (e)=>{
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
e.dataTransfer.dropEffect = 'copy'; e.dataTransfer.dropEffect = 'copy';
}); });
document.addEventListener('drop', (e)=>{ document.addEventListener('drop', (e)=>{
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
if(!e.dataTransfer.files){return false;} if(!e.dataTransfer.files){return false;}
var dropfiles = e.dataTransfer.files; var dropfiles = e.dataTransfer.files;
if(!(dropfiles.length>0)){return false;} if(!(dropfiles.length>0)){return false;}
var exts=axupimgs.axupimgs_filetype.replace(/(\s)+/g,'').toLowerCase().split(','); var exts=axupimgs.axupimgs_filetype.replace(/(\s)+/g,'').toLowerCase().split(',');
var files=[]; var files=[];
for( let file of dropfiles ){ for( let file of dropfiles ){
ext = file.name.split('.'); ext = file.name.split('.');
ext = '.'+ext[ext.length-1]; ext = '.'+ext[ext.length-1];
for(let s of exts){ for(let s of exts){
if(s==ext){ if(s==ext){
files.push(file); files.push(file);
break; break;
} }
} }
} }
if(files.length>0){ addList(files) } if(files.length>0){ addList(files) }
}); });
//添加文件 //添加文件
document.querySelector('#topbar .addfile').addEventListener('click',()=>{ document.querySelector('#topbar .addfile').addEventListener('click',()=>{
var input = document.createElement('input'); var input = document.createElement('input');
input.setAttribute('type', 'file'); input.setAttribute('type', 'file');
input.setAttribute('multiple', 'multiple'); input.setAttribute('multiple', 'multiple');
input.setAttribute('accept', axupimgs.axupimgs_filetype); input.setAttribute('accept', axupimgs.axupimgs_filetype);
input.click(); input.click();
input.onchange = function() { input.onchange = function() {
var files = this.files; var files = this.files;
addList(files); addList(files);
} }
}); });
var file_i = 0; var file_i = 0;
function upAllFiles(n){ function upAllFiles(n){
var len = axupimgs.res.length; var len = axupimgs.res.length;
file_i = n; file_i = n;
if(len == n){ if(len == n){
file_i=0; file_i=0;
// document.querySelector('#topbar .upall').innerText='全部上传'; // document.querySelector('#topbar .upall').innerText='全部上传';
return true; return true;
} }
if( axupimgs.res[n].url!='' ){ if( axupimgs.res[n].url!='' ){
n++; n++;
upAllFiles(n) upAllFiles(n)
}else{ }else{
blobInfo.file=axupimgs.res[n].file; blobInfo.file=axupimgs.res[n].file;
upload_handler(blobInfo,function(url,name){ upload_handler(blobInfo,function(url,name){
if(upload_base_path){ if(upload_base_path){
if(upload_base_path.slice(-1)=='/' && url.substr(0,1)=='/' ){ if(upload_base_path.slice(-1)=='/' && url.substr(0,1)=='/' ){
url = upload_base_path + url.slice(1); url = upload_base_path + url.slice(1);
}else if(upload_base_path.slice(-1)!='/' && url.substr(0,1)!='/' ){ }else if(upload_base_path.slice(-1)!='/' && url.substr(0,1)!='/' ){
url = upload_base_path + '/' + url; url = upload_base_path + '/' + url;
}else{ }else{
url = upload_base_path + url; url = upload_base_path + url;
} }
} }
axupimgs.res[file_i].url = url; axupimgs.res[file_i].url = url;
// filename = url.split('/').pop(); // filename = url.split('/').pop();
filename = name filename = name
var li = document.querySelectorAll('#file_list li')[file_i]; var li = document.querySelectorAll('#file_list li')[file_i];
li.setAttribute('class','up-over'); li.setAttribute('class','up-over');
li.querySelector('.namebox span').innerText = filename; li.querySelector('.namebox span').innerText = filename;
n++ n++
upAllFiles(n); upAllFiles(n);
},function(err){ },function(err){
// document.querySelector('#topbar .upall').innerText='全部上传'; // document.querySelector('#topbar .upall').innerText='全部上传';
// document.querySelectorAll('#file_list li.up-now').forEach((el,i)=>{ // document.querySelectorAll('#file_list li.up-now').forEach((el,i)=>{
// el.setAttribute('class','up-no'); // el.setAttribute('class','up-no');
// }); // });
// alert(err); // alert(err);
}); });
} }
} }
// //
// document.querySelector('#topbar .upall').addEventListener('click',(e)=>{ // document.querySelector('#topbar .upall').addEventListener('click',(e)=>{
// if(e.target.innerText!='全部上传'){return false;} // if(e.target.innerText!='全部上传'){return false;}
// if(axupimgs.res.length>0){ // if(axupimgs.res.length>0){
// document.querySelectorAll('#file_list li.up-no').forEach((el,i)=>{ // document.querySelectorAll('#file_list li.up-no').forEach((el,i)=>{
// el.classList ? el.classList.add('up-now') : el.className+=' up-now'; // el.classList ? el.classList.add('up-now') : el.className+=' up-now';
// }); // });
// e.target.innerText='上传中...'; // e.target.innerText='上传中...';
// upAllFiles(0); // upAllFiles(0);
// } // }
// }); // });
var observ_flist = new MutationObserver( (muList,observe)=>{ var observ_flist = new MutationObserver( (muList,observe)=>{
if(muList[0].addedNodes.length>0){ if(muList[0].addedNodes.length>0){
muList[0].addedNodes.forEach((el)=>{ muList[0].addedNodes.forEach((el)=>{
el.querySelector('.remove').addEventListener('click',(e)=>{ el.querySelector('.remove').addEventListener('click',(e)=>{
var li = e.target.parentNode.parentNode; var li = e.target.parentNode.parentNode;
var n = li.getAttribute('data-num'); var n = li.getAttribute('data-num');
var el = document.querySelectorAll('#file_list li')[n]; var el = document.querySelectorAll('#file_list li')[n];
el.parentNode.removeChild(el); el.parentNode.removeChild(el);
axupimgs.res.splice(n,1); axupimgs.res.splice(n,1);
}); });
}); });
} }
reSort(); reSort();
}); });
observ_flist.observe(document.querySelector('#file_list'),{childList:true}); observ_flist.observe(document.querySelector('#file_list'),{childList:true});
</script> </script>
</body> </body>
</html> </html>

View File

@@ -1,13 +1,13 @@
<template> <template>
<RouterView /> <RouterView />
</template> </template>
<script setup> <script setup>
import {usePermisstionStroe} from '@/stores/permisstion.js' import {usePermisstionStroe} from '@/stores/permisstion.js'
window.addEventListener('beforeunload', e=>beforeunload(e)) window.addEventListener('beforeunload', e=>beforeunload(e))
const beforeunload = (()=>{ const beforeunload = (()=>{
const permisstionStore = usePermisstionStroe() const permisstionStore = usePermisstionStroe()
permisstionStore.setIsLoadRoutes(true) permisstionStore.setIsLoadRoutes(true)
permisstionStore.setIsSuccessReq() permisstionStore.setIsSuccessReq()
}) })
</script> </script>

View File

@@ -1,36 +1,36 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getArticle = (params) => { export const getArticle = (params) => {
return request({ return request({
url: '/workflow/mosr/article/list', url: '/workflow/mosr/article/list',
method: "get", method: "get",
params params
}); });
}; };
export const getArticleDetail = (articleId) => { export const getArticleDetail = (articleId) => {
return request({ return request({
url: `/workflow/mosr/article/${articleId}`, url: `/workflow/mosr/article/${articleId}`,
method: "get" method: "get"
}); });
}; };
export const addArticle= (data) => { export const addArticle= (data) => {
return request({ return request({
url: '/workflow/mosr/article/add', url: '/workflow/mosr/article/add',
method: "post", method: "post",
data data
}); });
}; };
export const editArticle= (data) => { export const editArticle= (data) => {
return request({ return request({
url: '/workflow/mosr/article/update', url: '/workflow/mosr/article/update',
method: "post", method: "post",
data data
}); });
}; };
export const deleteArticle = (articleIds) => { export const deleteArticle = (articleIds) => {
return request({ return request({
url: `/workflow/mosr/article/${articleIds}`, url: `/workflow/mosr/article/${articleIds}`,
method: "delete" method: "delete"
}); });
}; };

View File

@@ -1,31 +1,31 @@
import request from "@/utils/request.js"; import request from "@/utils/request.js";
export const initPassword=(data)=>{ export const initPassword=(data)=>{
return request({ return request({
url:'/admin/mosr/user/init/password', url:'/admin/mosr/user/init/password',
method:'post', method:'post',
data data
}) })
} }
export const editPassword=(data)=>{ export const editPassword=(data)=>{
return request({ return request({
url:'/admin/mosr/user/update/password', url:'/admin/mosr/user/update/password',
method:'post', method:'post',
data data
}) })
} }
export const getAgentInfo=()=>{ export const getAgentInfo=()=>{
return request({ return request({
url:'/admin/mosr/user/self/approval/agent', url:'/admin/mosr/user/self/approval/agent',
method:'get' method:'get'
}) })
} }
export const editAgentInfo=(data)=>{ export const editAgentInfo=(data)=>{
return request({ return request({
url:'/admin/mosr/user/self/approval/agent', url:'/admin/mosr/user/self/approval/agent',
method:'post', method:'post',
data data
}) })
} }

View File

@@ -1,15 +1,15 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getCacheOpt = (cacheKey) => { export const getCacheOpt = (cacheKey) => {
return request({ return request({
url: '/admin/dict/data/option/'+ cacheKey, url: '/admin/dict/data/option/'+ cacheKey,
method: 'get', method: 'get',
}) })
} }
export const getCacheType = (cacheKey) => { export const getCacheType = (cacheKey) => {
return request({ return request({
url: '/admin/dict/data/type/'+ cacheKey, url: '/admin/dict/data/type/'+ cacheKey,
method: 'get', method: 'get',
}) })
} }

View File

@@ -1,9 +1,9 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const requestList = ( api, params, method = 'get' ) => { export const requestList = ( api, params, method = 'get' ) => {
return request({ return request({
url: api, url: api,
method, method,
params params
}) })
} }

View File

@@ -1,54 +1,54 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
//获取部门信息 //获取部门信息
export const getDeptList = (params) => { export const getDeptList = (params) => {
return request({ return request({
url: '/admin/dept', url: '/admin/dept',
method: 'get', method: 'get',
params params
}) })
} }
//获取增加时的部门列表 //获取增加时的部门列表
export const getDeptOption = () => { export const getDeptOption = () => {
return request({ return request({
url: '/admin/dept/option', url: '/admin/dept/option',
method: 'get' method: 'get'
}) })
} }
//获取修改时的部门列表 //获取修改时的部门列表
export const getDeptExcludeOption = (deptId) => { export const getDeptExcludeOption = (deptId) => {
return request({ return request({
url: `/admin/dept/option/exclude/${deptId}`, url: `/admin/dept/option/exclude/${deptId}`,
method: 'get' method: 'get'
}) })
} }
//新增部门 //新增部门
export const addDept = (data) => { export const addDept = (data) => {
return request({ return request({
url: '/admin/dept', url: '/admin/dept',
method: 'post', method: 'post',
data data
}) })
} }
//编辑部门 //编辑部门
export const editDept = (data) => { export const editDept = (data) => {
return request({ return request({
url: '/admin/dept', url: '/admin/dept',
method: 'put', method: 'put',
data data
}) })
} }
//查询部门详情 //查询部门详情
export const getDeptDetail = (deptId) => { export const getDeptDetail = (deptId) => {
return request({ return request({
url: `/admin/dept/${deptId}`, url: `/admin/dept/${deptId}`,
method: "get" method: "get"
}); });
}; };
//删除部门 //删除部门
export const deleteDept = (deptId) => { export const deleteDept = (deptId) => {
return request({ return request({
url: `/admin/dept/${deptId}`, url: `/admin/dept/${deptId}`,
method: "delete" method: "delete"
}); });
}; };

View File

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

View File

@@ -1,31 +1,31 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getHomeTaskInfo = () => { export const getHomeTaskInfo = () => {
return request({ return request({
url: '/workflow/mosr/process/task', url: '/workflow/mosr/process/task',
method: "get" method: "get"
}); });
}; };
//获取已办数据 //获取已办数据
export const getDoneTaskInfo = () => { export const getDoneTaskInfo = () => {
return request({ return request({
url: '/workflow/mosr/process/task/about', url: '/workflow/mosr/process/task/about',
method: "get" method: "get"
}); });
}; };
//获取专项资金饼图数据 //获取专项资金饼图数据
export const getSpecialFundChart = () => { export const getSpecialFundChart = () => {
return request({ return request({
url: '/workflow/home/page/statistic', url: '/workflow/home/page/statistic',
method: "get" method: "get"
}); });
}; };
//获取首页四个统计数量 //获取首页四个统计数量
export const getHomeStatistics = () => { export const getHomeStatistics = () => {
return request({ return request({
url: '/workflow/mosr/process/task/statistics', url: '/workflow/mosr/process/task/statistics',
method: "get" method: "get"
}); });
}; };

View File

@@ -1,44 +1,44 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
// 获取list // 获取list
export const getIPBlackList = (params) => { export const getIPBlackList = (params) => {
return request({ return request({
url: '/admin/ip/back', url: '/admin/ip/back',
method: 'get', method: 'get',
params params
}) })
} }
// 新增 // 新增
export const addIPBlack = (data) => { export const addIPBlack = (data) => {
return request({ return request({
url: '/admin/ip/back', url: '/admin/ip/back',
method: 'post', method: 'post',
data data
}) })
} }
// 修改 // 修改
export const editIPBlack = (data) => { export const editIPBlack = (data) => {
return request({ return request({
url: '/admin/ip/back', url: '/admin/ip/back',
method: 'put', method: 'put',
data data
}) })
} }
// 删除 // 删除
export const delIPBlack = (ids) => { export const delIPBlack = (ids) => {
return request({ return request({
url: '/admin/ip/back/'+ids, url: '/admin/ip/back/'+ids,
method: 'delete' method: 'delete'
}) })
} }
// 详情 // 详情
export const getIPBlackDetail = (id) => { export const getIPBlackDetail = (id) => {
return request({ return request({
url: '/admin/ip/back/'+id, url: '/admin/ip/back/'+id,
method: 'get' method: 'get'
}) })
} }

View File

@@ -1,24 +1,24 @@
import request from "@/utils/request.js"; import request from "@/utils/request.js";
//查询登录日志 //查询登录日志
export const getLoginLogList = (params) => { export const getLoginLogList = (params) => {
return request({ return request({
url: "/log/login-info/list", url: "/log/login-info/list",
method: "get", method: "get",
params params
}); });
}; };
//查询登录日志详情 //查询登录日志详情
export const getLoginLogDetail = (infoId) => { export const getLoginLogDetail = (infoId) => {
return request({ return request({
url: `/log/login-info/${infoId}`, url: `/log/login-info/${infoId}`,
method: "get" method: "get"
}); });
}; };
//删除登录日志 //删除登录日志
export const deleteLoginLog = (infoIds) => { export const deleteLoginLog = (infoIds) => {
return request({ return request({
url: `/log/login-info/${infoIds}`, url: `/log/login-info/${infoIds}`,
method: "delete" method: "delete"
}); });
}; };

View File

@@ -1,24 +1,24 @@
import request from "@/utils/request.js"; import request from "@/utils/request.js";
//查询操作日志 //查询操作日志
export const getOperateLog = (params) => { export const getOperateLog = (params) => {
return request({ return request({
url: "/log/log/list", url: "/log/log/list",
method: "get", method: "get",
params params
}); });
}; };
//查询操作日志详情 //查询操作日志详情
export const getOperateLogDetail = (operId) => { export const getOperateLogDetail = (operId) => {
return request({ return request({
url: `/log/log/${operId}`, url: `/log/log/${operId}`,
method: "get" method: "get"
}); });
}; };
//删除操作日志 //删除操作日志
export const deleteOperateLog = (operIds) => { export const deleteOperateLog = (operIds) => {
return request({ return request({
url: `/log/log/${operIds}`, url: `/log/log/${operIds}`,
method: "delete" method: "delete"
}); });
}; };

View File

@@ -1,36 +1,36 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getCodeImg = () => { export const getCodeImg = () => {
return request({ return request({
url: '/auth/captchaImage', url: '/auth/captchaImage',
method: 'get' method: 'get'
}) })
} }
export const login = (data) => { export const login = (data) => {
return request({ return request({
url: '/auth/login', url: '/auth/login',
method: 'post', method: 'post',
data data
}) })
} }
export const switchAccount = (userId) => { export const switchAccount = (userId) => {
return request({ return request({
url: `/auth/switch/account/${userId}`, url: `/auth/switch/account/${userId}`,
method: 'post', method: 'post',
}) })
} }
export const getUserInfo = () => { export const getUserInfo = () => {
return request({ return request({
url: '/auth/info', url: '/auth/info',
method: 'get', method: 'get',
}) })
} }
export const getAuthInfo = () => { export const getAuthInfo = () => {
return request({ return request({
url: '/admin/mosr/user/detail/info', url: '/admin/mosr/user/detail/info',
method: 'get', method: 'get',
}) })
} }

View File

@@ -1,30 +1,30 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getNoticeList = (params) => { export const getNoticeList = (params) => {
return request({ return request({
url: '/notice/notice', url: '/notice/notice',
method: 'get', method: 'get',
params params
}) })
} }
export const getNoticeDetail = (noticeId) => { export const getNoticeDetail = (noticeId) => {
return request({ return request({
url: '/notice/notice/'+noticeId, url: '/notice/notice/'+noticeId,
method: "get" method: "get"
}); });
}; };
export const addNotice = (data) => { export const addNotice = (data) => {
return request({ return request({
url: '/notice/notice', url: '/notice/notice',
method: 'post', method: 'post',
data data
}) })
} }
export const deleteNotice = (noticeId) => { export const deleteNotice = (noticeId) => {
return request({ return request({
url: `/notice/notice/${noticeId}`, url: `/notice/notice/${noticeId}`,
method: "delete" method: "delete"
}); });
}; };

View File

@@ -1,43 +1,43 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getNotifyList = (params) => { export const getNotifyList = (params) => {
return request({ return request({
url: '/notice/notify', url: '/notice/notify',
method: 'get', method: 'get',
params params
}) })
} }
export const getNotifyDetail = (noticeId) => { export const getNotifyDetail = (noticeId) => {
return request({ return request({
url: '/notice/notify/'+noticeId, url: '/notice/notify/'+noticeId,
method: "get" method: "get"
}); });
}; };
//已读单个消息 //已读单个消息
export const readSingleNotify = (noticeId) => { export const readSingleNotify = (noticeId) => {
return request({ return request({
url: '/notice/notify/read/'+noticeId, url: '/notice/notify/read/'+noticeId,
method: 'put' method: 'put'
}) })
} }
//已读全部消息 //已读全部消息
export const readAllNotify = () => { export const readAllNotify = () => {
return request({ return request({
url: '/notice/notify/read/all', url: '/notice/notify/read/all',
method: 'put' method: 'put'
}) })
} }
//删除单个消息 //删除单个消息
export const deleteSingleNotify = (noticeId) => { export const deleteSingleNotify = (noticeId) => {
return request({ return request({
url: '/notice/notify/'+noticeId, url: '/notice/notify/'+noticeId,
method: "delete" method: "delete"
}); });
}; };
//删除多个消息 //删除多个消息
export const deleteMoreNotify = (noticeIds) => { export const deleteMoreNotify = (noticeIds) => {
return request({ return request({
url: '/notice/notify/batch/'+noticeIds, url: '/notice/notify/batch/'+noticeIds,
method: "delete" method: "delete"
}); });
}; };

View File

@@ -1,17 +1,17 @@
import request from "@/utils/request.js"; import request from "@/utils/request.js";
//查询在线用户 //查询在线用户
export const getOnlineList = (params) => { export const getOnlineList = (params) => {
return request({ return request({
url: "/admin/online/user", url: "/admin/online/user",
method: "get", method: "get",
params params
}); });
}; };
//强制退出用户 //强制退出用户
export const deleteOnlineUser= (tokenId) => { export const deleteOnlineUser= (tokenId) => {
return request({ return request({
url: '/admin/online/user/'+tokenId, url: '/admin/online/user/'+tokenId,
method: "delete" method: "delete"
}); });
}; };

View File

@@ -1,48 +1,48 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
//获取岗位信息 //获取岗位信息
export const getPostList = (params) => { export const getPostList = (params) => {
return request({ return request({
url: '/admin/post', url: '/admin/post',
method: 'get', method: 'get',
params params
}) })
} }
//查询岗位详情 //查询岗位详情
export const getPostDetail = (postId) => { export const getPostDetail = (postId) => {
return request({ return request({
url: `/admin/post/info/${postId}`, url: `/admin/post/info/${postId}`,
method: "get" method: "get"
}); });
}; };
//新增岗位 //新增岗位
export const addPost = (data) => { export const addPost = (data) => {
return request({ return request({
url: '/admin/post', url: '/admin/post',
method: 'post', method: 'post',
data data
}) })
} }
//编辑岗位 //编辑岗位
export const editPost = (data) => { export const editPost = (data) => {
return request({ return request({
url: '/admin/post', url: '/admin/post',
method: 'put', method: 'put',
data data
}) })
} }
//获取select下拉框数据 //获取select下拉框数据
export const getSelectOption = () => { export const getSelectOption = () => {
return request({ return request({
url: '/admin/post/option', url: '/admin/post/option',
method: 'get' method: 'get'
}) })
} }
//删除角色信息 //删除角色信息
export const deletePost = (postId) => { export const deletePost = (postId) => {
return request({ return request({
url: `/admin/post/${postId}`, url: `/admin/post/${postId}`,
method: "delete" method: "delete"
}); });
}; };

View File

@@ -1,128 +1,128 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
import axios from "axios"; import axios from "axios";
import {getToken} from "@/utils/auth"; import {getToken} from "@/utils/auth";
//需求征集 //需求征集
export const getDemandInfo = (param) => { export const getDemandInfo = (param) => {
return request({ return request({
url: '/workflow/mosr/requirement', url: '/workflow/mosr/requirement',
method: "get", method: "get",
params: param params: param
}); });
}; };
export const filterRequirementName = (requirementName) => { export const filterRequirementName = (requirementName) => {
return request({ return request({
url: `/workflow/mosr/requirement/match/${requirementName}`, url: `/workflow/mosr/requirement/match/${requirementName}`,
method: "get" method: "get"
}); });
}; };
export const getWorkflowInfo = () => { export const getWorkflowInfo = () => {
return request({ return request({
url: '/workflow/mosr/requirement/process', url: '/workflow/mosr/requirement/process',
method: "get" method: "get"
}); });
}; };
export const getInfo = (requirementId) => { export const getInfo = (requirementId) => {
return request({ return request({
url: `/workflow/mosr/requirement/info/${requirementId}`, url: `/workflow/mosr/requirement/info/${requirementId}`,
method: "get" method: "get"
}); });
}; };
export const getFormInfo = (requirementId) => { export const getFormInfo = (requirementId) => {
return request({ return request({
url: `/workflow/mosr/requirement/form/${requirementId}`, url: `/workflow/mosr/requirement/form/${requirementId}`,
method: "get" method: "get"
}); });
}; };
export const agreeTask = (data) => { export const agreeTask = (data) => {
return request({ return request({
url: `/workflow/mosr/process/task/agree`, url: `/workflow/mosr/process/task/agree`,
method: "post", method: "post",
data: data data: data
}); });
}; };
export const rejectTask = (data) => { export const rejectTask = (data) => {
return request({ return request({
url: `/workflow/mosr/process/task/reject`, url: `/workflow/mosr/process/task/reject`,
method: "post", method: "post",
data: data data: data
}); });
}; };
export const addRequirement = (data) => { export const addRequirement = (data) => {
return request({ return request({
url: '/workflow/mosr/requirement', url: '/workflow/mosr/requirement',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const resubmit = (data) => { export const resubmit = (data) => {
return request({ return request({
url: '/workflow/mosr/requirement/resubmit', url: '/workflow/mosr/requirement/resubmit',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const deleteFile = (fileId) => { export const deleteFile = (fileId) => {
return request({ return request({
url: `/workflow/process/file/delete/${fileId}`, url: `/workflow/process/file/delete/${fileId}`,
method: "delete" method: "delete"
}); });
}; };
export const downloadFile = (fileId) => { export const downloadFile = (fileId) => {
return request({ return request({
url: '/workflow/process/file/download', url: '/workflow/process/file/download',
method: "get", method: "get",
responseType:'blob', responseType:'blob',
params:{ params:{
fileId:fileId fileId:fileId
} }
}); });
}; };
export const getCompanyOption = () => { export const getCompanyOption = () => {
return request({ return request({
url: '/admin/mosr/sub/company/companyOption', url: '/admin/mosr/sub/company/companyOption',
method: "get" method: "get"
}); });
}; };
export const deleteDemand = (id) => { export const deleteDemand = (id) => {
return request({ return request({
url: `/workflow/mosr/requirement/${id}`, url: `/workflow/mosr/requirement/${id}`,
method: "delete" method: "delete"
}); });
}; };
export const getRequirementStatePerm = () => { export const getRequirementStatePerm = () => {
return request({ return request({
url: '/workflow/mosr/requirement/prem/state', url: '/workflow/mosr/requirement/prem/state',
method: "get" method: "get"
}); });
}; };
export const downloadTemplate = (type) => { export const downloadTemplate = (type) => {
return request({ return request({
url: '/workflow/mosr/attachment/download/template', url: '/workflow/mosr/attachment/download/template',
method: "get", method: "get",
responseType:'blob', responseType:'blob',
params:{ params:{
type:type type:type
} }
}); });
}; };
export const downloadTemplateZip = (typeList) => { export const downloadTemplateZip = (typeList) => {
return axios.get( return axios.get(
`${import.meta.env.VITE_BASE_URL}/workflow/mosr/attachment/download/pack?typeList=${typeList}`, `${import.meta.env.VITE_BASE_URL}/workflow/mosr/attachment/download/pack?typeList=${typeList}`,
{ {
responseType: 'blob', responseType: 'blob',
headers: { headers: {
Authorization: getToken() Authorization: getToken()
}, },
} }
); );
// return request({ // return request({
// url: '/workflow/mosr/attachment/download/pack', // url: '/workflow/mosr/attachment/download/pack',
// method: "get", // method: "get",
// responseType:'blob', // responseType:'blob',
// params:{ // params:{
// typeList:typeList // typeList:typeList
// } // }
// }); // });
}; };

View File

@@ -1,123 +1,185 @@
import request from '@/utils/request' import request from '@/utils/request'
export const fileUp = (url, data) => { export const fileUp = (url, data) => {
return request({ return request({
url, url,
method: 'post', method: 'post',
data, data,
headers: { headers: {
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
} }
}) })
} }
export const requirementReported = (data) => { export const requirementReported = (data) => {
return request({ return request({
url: '/workflow/mosr/requirement/reported', url: '/workflow/mosr/requirement/reported',
method: "post", method: "post",
data: data data: data
}); });
}; };
//需求汇总-征集名称关键词匹配 //需求汇总-征集名称关键词匹配
export const getRequirementName = (requirementName) => { export const getRequirementName = (requirementName) => {
return request({ return request({
url: `/workflow/mosr/requirement/collect/project/match/${requirementName}`, url: `/workflow/mosr/requirement/collect/project/match/${requirementName}`,
method: "get" method: "get"
}); });
}; };
//需求汇总-项目名称关键词匹配 //需求汇总-项目名称关键词匹配
export const getProjectName = (projectName) => { export const getProjectName = (projectName) => {
return request({ return request({
url: `workflow/mosr/requirement/collect`, url: `workflow/mosr/requirement/collect`,
method: "get", method: "get",
params:{ params:{
projectName:projectName projectName:projectName
} }
}); });
}; };
//获取需求上报 流程信息 //获取需求上报 流程信息
export const getProcessInfo = (specialFund) => { export const getProcessInfo = (specialFund) => {
return request({ return request({
url: `/workflow/mosr/requirement/collect/process/${specialFund}`, url: `/workflow/mosr/requirement/collect/process/${specialFund}`,
method: "get" method: "get"
}); });
}; };
export const getDetail = (projectId) => { export const getDetail = (projectId) => {
return request({ return request({
url: `/workflow/mosr/requirement/collect/info/${projectId}`, url: `/workflow/mosr/requirement/collect/info/${projectId}`,
method: "get" method: "get"
}); });
}; };
export const resubmitReported = (data) => { export const resubmitReported = (data) => {
return request({ return request({
url: '/workflow/mosr/requirement/collect/resubmit', url: '/workflow/mosr/requirement/collect/resubmit',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const getCollectAttachment = (params) => { export const getCollectAttachment = (params) => {
return request({ return request({
url: '/workflow/mosr/requirement/collect/attachments', url: '/workflow/mosr/requirement/collect/attachments',
method: "get", method: "get",
params:params params:params
}); });
}; };
export const uploadCollectAttachment= (data) => { export const uploadCollectAttachment= (data) => {
return request({ return request({
url: '/workflow/mosr/requirement/collect/upload', url: '/workflow/mosr/requirement/collect/upload',
method: "post", method: "post",
data: data data: data
}); });
}; };
// 年度计划 // 项目计划
export const addPlan= (data) => { export const addPlan= (data) => {
return request({ return request({
url: '/workflow/annual/plan', url: '/workflow/annual/plan',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const editPlan= (data) => { export const editPlan= (data) => {
return request({ return request({
url: '/workflow/annual/plan', url: '/workflow/annual/plan',
method: "put", method: "put",
data: data data: data
}); });
}; };
export const getPlan= (annualPlanId) => { export const getPlan= (annualPlanId) => {
return request({ return request({
url: `/workflow/annual/plan/info/${annualPlanId}`, url: `/workflow/annual/plan/info/${annualPlanId}`,
method: "get" method: "get"
}); });
}; };
export const deletePlan= (annualPlanId) => { export const deletePlan= (annualPlanId) => {
return request({ return request({
url: `/workflow/annual/plan/${annualPlanId}`, url: `/workflow/annual/plan/${annualPlanId}`,
method: "delete" method: "delete"
}); });
}; };
export const approvePlan= (data) => { export const approvePlan= (data) => {
return request({ return request({
url: '/workflow/annual/plan/approve', url: '/workflow/annual/plan/approve',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const getProjectOption = () => { export const getProjectOption = (projectName) => {
return request({ return request({
url: '/workflow/mosr/requirement/master', url: '/workflow/mosr/requirement/master',
method: "get" method: "get",
}); params:{
}; projectName:projectName
}
});
export const getRequirementOption = () => { };
return request({ export const getMasterProjectNameOption = (masterProjectName) => {
url: '/workflow/mosr/requirement/option', return request({
method: "get" url: '/workflow/mosr/payment/master/option',
}); method: "get",
}; params:{
masterProjectName:masterProjectName
}
});
};
export const getSubprojectNameOption = (subProjectName) => {
return request({
url: '/workflow/mosr/payment/sub/option',
method: "get",
params:{
subProjectName:subProjectName
}
});
};
export const getExpenseMasterProjectNameOption = (masterProjectName) => {
return request({
url: '/workflow/mosr/rd/expense/master/option',
method: "get",
params:{
masterProjectName:masterProjectName
}
});
};
export const getExpenseSubprojectNameOption = (subProjectName) => {
return request({
url: '/workflow/mosr/rd/expense/sub/option',
method: "get",
params:{
subProjectName:subProjectName
}
});
};
export const getCostMasterProjectNameOption = (masterProjectName) => {
return request({
url: '/workflow/mosr/cost/share/master/option',
method: "get",
params:{
masterProjectName:masterProjectName
}
});
};
export const getCostSubprojectNameOption = (subProjectName) => {
return request({
url: '/workflow/mosr/cost/share/sub/option',
method: "get",
params:{
subProjectName:subProjectName
}
});
};
export const getRequirementOption = () => {
return request({
url: '/workflow/mosr/requirement/option',
method: "get"
});
};

View File

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

View File

@@ -1,240 +1,240 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
import axios from "axios"; import axios from "axios";
import {getToken} from "@/utils/auth"; import {getToken} from "@/utils/auth";
//项目立项 //项目立项
export const getApplyProcess = (projectId) => { export const getApplyProcess = (projectId) => {
return request({ return request({
url: `/workflow/mosr/project/approval/initiation/process/${projectId}`, url: `/workflow/mosr/project/approval/initiation/process/${projectId}`,
method: "get" method: "get"
}); });
}; };
export const filterProjectName = (projectName,targetState) => { export const filterProjectName = (projectName,targetState) => {
return request({ return request({
url: `/workflow/mosr/project/approval/match/${projectName}/${targetState}`, url: `/workflow/mosr/project/approval/match/${projectName}/${targetState}`,
method: "get" method: "get"
}); });
}; };
export const projectApply = (data) => { export const projectApply = (data) => {
return request({ return request({
url: '/workflow/mosr/project/approval/initiation/apply', url: '/workflow/mosr/project/approval/initiation/apply',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const getApplyDetail = (ProjectId) => { export const getApplyDetail = (ProjectId) => {
return request({ return request({
url: `/workflow/mosr/project/approval/info/${ProjectId}`, url: `/workflow/mosr/project/approval/info/${ProjectId}`,
method: "get" method: "get"
}); });
}; };
export const resubmitApply = (data) => { export const resubmitApply = (data) => {
return request({ return request({
url: '/workflow/mosr/project/approval/initiation/resubmit', url: '/workflow/mosr/project/approval/initiation/resubmit',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const getInitiationAttachment = (params) => { export const getInitiationAttachment = (params) => {
return request({ return request({
url: '/workflow/mosr/project/approval/attachments', url: '/workflow/mosr/project/approval/attachments',
method: "get", method: "get",
params: params params: params
}); });
}; };
//项目实施 //项目实施
export const getCheckDetail = (projectId) => { export const getCheckDetail = (projectId) => {
return request({ return request({
url: `/workflow/mosr/project/implementation/info/${projectId}`, url: `/workflow/mosr/project/implementation/info/${projectId}`,
method: "get" method: "get"
}); });
}; };
export const resubmitCheck = (data) => { export const resubmitCheck = (data) => {
return request({ return request({
url: '/workflow/mosr/project/implementation/resubmit', url: '/workflow/mosr/project/implementation/resubmit',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const projectCheck = (data) => { export const projectCheck = (data) => {
return request({ return request({
url: '/workflow/mosr/project/implementation/initiation/check', url: '/workflow/mosr/project/implementation/initiation/check',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const getProjectCheckProcess = (projectId) => { export const getProjectCheckProcess = (projectId) => {
return request({ return request({
url: `/workflow/mosr/project/implementation/process/${projectId}`, url: `/workflow/mosr/project/implementation/process/${projectId}`,
method: "get" method: "get"
}); });
}; };
export const addLedger = (data) => { export const addLedger = (data) => {
return request({ return request({
url: '/workflow/mosr/expense/ledger', url: '/workflow/mosr/expense/ledger',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const getTags = (projectId) => { export const getTags = (projectId) => {
return request({ return request({
url: `/workflow/mosr/attachment/option/${projectId}`, url: `/workflow/mosr/attachment/option/${projectId}`,
method: "get" method: "get"
}); });
}; };
export const getTagList = (projectId) => { export const getTagList = (projectId) => {
return request({ return request({
url: `/workflow/mosr/file/tag/list`, url: `/workflow/mosr/file/tag/list`,
method: "get", method: "get",
params:{ params:{
projectId: projectId projectId: projectId
} }
}); });
}; };
export const addTag = (data) => { export const addTag = (data) => {
return request({ return request({
url: '/workflow/mosr/file/tag/add', url: '/workflow/mosr/file/tag/add',
method: "post", method: "post",
data:data data:data
}); });
}; };
export const updateTag = (data) => { export const updateTag = (data) => {
return request({ return request({
url: '/workflow/mosr/file/tag/update', url: '/workflow/mosr/file/tag/update',
method: "post", method: "post",
data:data data:data
}); });
}; };
export const delTag = (tageId) => { export const delTag = (tageId) => {
return request({ return request({
url: `/workflow/mosr/file/tag/${tageId}`, url: `/workflow/mosr/file/tag/${tageId}`,
method: "delete" method: "delete"
}); });
}; };
export const getPhaseProcess = () => { export const getPhaseProcess = () => {
return request({ return request({
url: '/workflow/phase/change/process', url: '/workflow/phase/change/process',
method: "get" method: "get"
}); });
}; };
export const submitPhaseChange = (data) => { export const submitPhaseChange = (data) => {
return request({ return request({
url: '/workflow/phase/change', url: '/workflow/phase/change',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const getPhaseDetail = (projectId) => { export const getPhaseDetail = (projectId) => {
return request({ return request({
url: `/workflow/phase/change/info/${projectId}`, url: `/workflow/phase/change/info/${projectId}`,
method: "get" method: "get"
}); });
}; };
export const getPhaseForm = (projectId) => { export const getPhaseForm = (projectId) => {
return request({ return request({
url: `/workflow/phase/change/from/${projectId}`, url: `/workflow/phase/change/from/${projectId}`,
method: "get" method: "get"
}); });
}; };
export const resubmitPhaseForm = (data) => { export const resubmitPhaseForm = (data) => {
return request({ return request({
url: '/workflow/phase/change/resubmit', url: '/workflow/phase/change/resubmit',
method: "post", method: "post",
data: data data: data
}); });
}; };
//项目归档 //项目归档
export const getConclusionDetail = (ProjectId) => { export const getConclusionDetail = (ProjectId) => {
return request({ return request({
url: `/workflow/mosr/project/filing/info/${ProjectId}`, url: `/workflow/mosr/project/filing/info/${ProjectId}`,
method: "get" method: "get"
}); });
}; };
export const resubmitConclusion = (data) => { export const resubmitConclusion = (data) => {
return request({ return request({
url: '/workflow/mosr/project/filing/resubmit', url: '/workflow/mosr/project/filing/resubmit',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const projectConclusion = (data) => { export const projectConclusion = (data) => {
return request({ return request({
url: '/workflow/mosr/project/filing/project/entry', url: '/workflow/mosr/project/filing/project/entry',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const getProjectConclusionProcess = () => { export const getProjectConclusionProcess = () => {
return request({ return request({
url: '/workflow/mosr/project/filing/process', url: '/workflow/mosr/project/filing/process',
method: "get" method: "get"
}); });
}; };
//获取前置流程 //获取前置流程
export const getPreProcess = () => { export const getPreProcess = () => {
return request({ return request({
url: '/workflow/details/pre/process', url: '/workflow/details/pre/process',
method: "get" method: "get"
}); });
}; };
export const updateLedger = (data) => { export const updateLedger = (data) => {
return request({ return request({
url: '/workflow/mosr/expense/ledger/replenishment', url: '/workflow/mosr/expense/ledger/replenishment',
method: "post", method: "post",
data: data data: data
}); });
}; };
export const searchUpdateLedgerData = (projectId) => { export const searchUpdateLedgerData = (projectId) => {
return request({ return request({
url: `/workflow/mosr/expense/ledger/${projectId}`, url: `/workflow/mosr/expense/ledger/${projectId}`,
method: "get" method: "get"
}); });
}; };
// //
// export const searchUpdateLedgerData = (projectId) => { // export const searchUpdateLedgerData = (projectId) => {
// return request({ // return request({
// url: '/workflow/mosr/expense/ledger/import', // url: '/workflow/mosr/expense/ledger/import',
// method: "get" // method: "get"
// }); // });
// }; // };
export const exportExcel = (data) => { export const exportExcel = (data) => {
return axios.post( return axios.post(
`${import.meta.env.VITE_BASE_URL}/workflow/mosr/project/implementation/export`, `${import.meta.env.VITE_BASE_URL}/workflow/mosr/project/implementation/export`,
data, { data, {
responseType: 'blob', responseType: 'blob',
headers: { headers: {
Authorization: getToken() Authorization: getToken()
} }
} }
); );
}; };
//台账模板下载 //台账模板下载
export const ledgerTemplateDownload = () => { export const ledgerTemplateDownload = () => {
return axios.get( return axios.get(
`${import.meta.env.VITE_BASE_URL}/workflow/mosr/project/implementation/download/template`, `${import.meta.env.VITE_BASE_URL}/workflow/mosr/project/implementation/download/template`,
{ {
responseType: 'blob', responseType: 'blob',
headers: { headers: {
Authorization: getToken() Authorization: getToken()
} }
} }
); );
}; };
//费用明细模板下载 //费用明细模板下载
export const costTemplateDownload = () => { export const costTemplateDownload = () => {
return axios.get( return axios.get(
`${import.meta.env.VITE_BASE_URL}/workflow/mosr/rd/expense/download/template`, `${import.meta.env.VITE_BASE_URL}/workflow/mosr/rd/expense/download/template`,
{ {
responseType: 'blob', responseType: 'blob',
headers: { headers: {
Authorization: getToken() Authorization: getToken()
} }
} }
); );
}; };

View File

@@ -1,68 +1,68 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getTableList = (params) => { export const getTableList = (params) => {
return request({ return request({
url: '/code-gen/table', url: '/code-gen/table',
method: 'get', method: 'get',
params params
}) })
} }
export const getDynamicTable = (params) => { export const getDynamicTable = (params) => {
return request({ return request({
url: '/code-gen/dynamic-table', url: '/code-gen/dynamic-table',
method: 'get', method: 'get',
params params
}) })
} }
export const getTableDetail = (tableId) => { export const getTableDetail = (tableId) => {
return request({ return request({
url: `/code-gen/table/${tableId}`, url: `/code-gen/table/${tableId}`,
method: 'get', method: 'get',
}) })
} }
export const previewCode = (tableId) => { export const previewCode = (tableId) => {
return request({ return request({
url: `/code-gen/table/preview/${tableId}`, url: `/code-gen/table/preview/${tableId}`,
method: 'get', method: 'get',
}) })
} }
export const deleteMoreTable = (params) => { export const deleteMoreTable = (params) => {
return request({ return request({
url: '/code-gen/table', url: '/code-gen/table',
method: 'delete', method: 'delete',
params params
}) })
} }
export const deleteTable = (tableId) => { export const deleteTable = (tableId) => {
return request({ return request({
url: `/code-gen/table/${tableId}`, url: `/code-gen/table/${tableId}`,
method: 'delete', method: 'delete',
}) })
} }
export const importTable = (data) => { export const importTable = (data) => {
return request({ return request({
url: "/code-gen/table/import-table", url: "/code-gen/table/import-table",
method: 'post', method: 'post',
data data
}) })
} }
export const editCodeGen = (data) => { export const editCodeGen = (data) => {
return request({ return request({
url: '/code-gen/table', url: '/code-gen/table',
method: 'put', method: 'put',
data data
}) })
} }
export const syncDatabase = (tableId) => { export const syncDatabase = (tableId) => {
return request({ return request({
url: '/code-gen/table/sync/'+tableId, url: '/code-gen/table/sync/'+tableId,
method: 'put' method: 'put'
}) })
} }

View File

@@ -1,54 +1,54 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getDataSourceList = (params) => { export const getDataSourceList = (params) => {
return request({ return request({
url: '/code-gen/data-source', url: '/code-gen/data-source',
method: 'get', method: 'get',
params params
}) })
} }
export const getDataSourceOption = () => { export const getDataSourceOption = () => {
return request({ return request({
url: '/code-gen/data-source/option', url: '/code-gen/data-source/option',
method: 'get' method: 'get'
}) })
} }
export const getDataSourceOptionType=()=>{ export const getDataSourceOptionType=()=>{
return request({ return request({
url:'/code-gen/data-source/option/type', url:'/code-gen/data-source/option/type',
method:'get' method:'get'
}) })
} }
export const getDataSource = (dsId) => { export const getDataSource = (dsId) => {
return request({ return request({
url: `/code-gen/data-source/${dsId}`, url: `/code-gen/data-source/${dsId}`,
method: 'get' method: 'get'
}) })
} }
export const addDataSource = (data) => { export const addDataSource = (data) => {
return request({ return request({
url: '/code-gen/data-source', url: '/code-gen/data-source',
method: 'post', method: 'post',
data data
}) })
} }
export const editDataSource = (data) => { export const editDataSource = (data) => {
return request({ return request({
url: '/code-gen/data-source', url: '/code-gen/data-source',
method: 'put', method: 'put',
data data
}) })
} }
export const deleteDataSource = (dsId) => { export const deleteDataSource = (dsId) => {
return request({ return request({
url: `/code-gen/data-source/${dsId}`, url: `/code-gen/data-source/${dsId}`,
method: 'delete' method: 'delete'
}) })
} }

View File

@@ -1,52 +1,52 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
// 请求校验规则表list // 请求校验规则表list
export const getRegularList = (params) => { export const getRegularList = (params) => {
return request({ return request({
url: '/code-gen/rapid/regular', url: '/code-gen/rapid/regular',
method: 'get', method: 'get',
params params
}) })
} }
// 获取校验规则表详情 // 获取校验规则表详情
export const getRegularDetails = (regularId) => { export const getRegularDetails = (regularId) => {
return request({ return request({
url: '/code-gen/rapid/regular/' + regularId, url: '/code-gen/rapid/regular/' + regularId,
method: 'get' method: 'get'
}) })
} }
// 获取校验规则选项列表 // 获取校验规则选项列表
export const getRegularOpt = (regularId) => { export const getRegularOpt = (regularId) => {
return request({ return request({
url: '/code-gen/rapid/regular/option', url: '/code-gen/rapid/regular/option',
method: 'get' method: 'get'
}) })
} }
// 新增校验规则表 // 新增校验规则表
export const addRegular = (data) => { export const addRegular = (data) => {
return request({ return request({
url: '/code-gen/rapid/regular', url: '/code-gen/rapid/regular',
method: 'post', method: 'post',
data data
}) })
} }
// 修改校验规则表 // 修改校验规则表
export const editRegular = (data) => { export const editRegular = (data) => {
return request({ return request({
url: '/code-gen/rapid/regular', url: '/code-gen/rapid/regular',
method: 'put', method: 'put',
data data
}) })
} }
// 删除校验规则表 // 删除校验规则表
export const delRegular =(regularId) => { export const delRegular =(regularId) => {
return request({ return request({
url: '/code-gen/rapid/regular/' + regularId, url: '/code-gen/rapid/regular/' + regularId,
method: 'delete' method: 'delete'
}) })
} }

View File

@@ -1,36 +1,36 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getResearchFundChart = (year) => { export const getResearchFundChart = (year) => {
return request({ return request({
url: '/workflow/mosr/rd/home', url: '/workflow/mosr/rd/home',
method: 'get', method: 'get',
params: {year:year} params: {year:year}
}) })
} }
export const getResearchFundDetail = (rdFundId) => { export const getResearchFundDetail = (rdFundId) => {
return request({ return request({
url: `/workflow/mosr/rd/${rdFundId}`, url: `/workflow/mosr/rd/${rdFundId}`,
method: "get" method: "get"
}); });
}; };
export const addResearchFund= (data) => { export const addResearchFund= (data) => {
return request({ return request({
url: '/workflow/mosr/rd/add', url: '/workflow/mosr/rd/add',
method: "post", method: "post",
data data
}); });
}; };
export const editResearchFund= (data) => { export const editResearchFund= (data) => {
return request({ return request({
url: '/workflow/mosr/rd/update', url: '/workflow/mosr/rd/update',
method: "post", method: "post",
data data
}); });
}; };
export const deleteResearchFund = (rdFundIds) => { export const deleteResearchFund = (rdFundIds) => {
return request({ return request({
url: `/workflow/mosr/rd/${rdFundIds}`, url: `/workflow/mosr/rd/${rdFundIds}`,
method: "delete" method: "delete"
}); });
}; };

View File

@@ -1,110 +1,110 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getRoleList = (params) => { export const getRoleList = (params) => {
return request({ return request({
url: '/admin/role', url: '/admin/role',
method: 'get', method: 'get',
params params
}) })
} }
//查询角色option //查询角色option
export const getRoleOption = () => { export const getRoleOption = () => {
return request({ return request({
url: '/admin/role/option', url: '/admin/role/option',
method: "get" method: "get"
}); });
}; };
export const getTemRoleOption = () => { export const getTemRoleOption = () => {
return request({ return request({
url: '/admin/role/option/template', url: '/admin/role/option/template',
method: "get" method: "get"
}); });
}; };
//查询角色信息 //查询角色信息
export const getRoleDetail = (roleId) => { export const getRoleDetail = (roleId) => {
return request({ return request({
url: `/admin/role/${roleId}`, url: `/admin/role/${roleId}`,
method: "get" method: "get"
}); });
}; };
//根据菜单id获取分配的角色信息 //根据菜单id获取分配的角色信息
export const getRoleInfoByMenuId = (params) => { export const getRoleInfoByMenuId = (params) => {
return request({ return request({
url: '/admin/role/menu', url: '/admin/role/menu',
method: 'get', method: 'get',
params params
}) })
} }
//获取排除在外的角色 //获取排除在外的角色
export const getRoleExcludeMenuId = (params) => { export const getRoleExcludeMenuId = (params) => {
return request({ return request({
url: '/admin/role/menu/list', url: '/admin/role/menu/list',
method: "get", method: "get",
params params
}); });
}; };
// 新增修改 // 新增修改
export const operate = (data) => { export const operate = (data) => {
if(data.roleId) return editRole(data) if(data.roleId) return editRole(data)
return addRole(data) return addRole(data)
} }
// 新增角色 // 新增角色
export const addRole = (data) => { export const addRole = (data) => {
return request({ return request({
url: '/admin/role', url: '/admin/role',
method: 'post', method: 'post',
data data
}) })
} }
// 修改角色 // 修改角色
export const editRole = (data) => { export const editRole = (data) => {
return request({ return request({
url: '/admin/role', url: '/admin/role',
method: 'put', method: 'put',
data data
}) })
} }
//解除当前角色对应的所有菜单的绑定关系 //解除当前角色对应的所有菜单的绑定关系
export const unbindAllRole = (menuId) => { export const unbindAllRole = (menuId) => {
return request({ return request({
url: '/admin/role/all/unbind/menu', url: '/admin/role/all/unbind/menu',
method: 'put', method: 'put',
data: { data: {
id: menuId id: menuId
} }
}) })
} }
// 解除角色与菜单之间的绑定状态 // 解除角色与菜单之间的绑定状态
export const cancelAuthorization = (menuId, roleIds) => { export const cancelAuthorization = (menuId, roleIds) => {
return request({ return request({
url: '/admin/role/unbind/menu', url: '/admin/role/unbind/menu',
method: 'put', method: 'put',
data: { data: {
id: menuId, id: menuId,
ids: roleIds ids: roleIds
} }
}) })
} }
//建立角色用户绑定关系 //建立角色用户绑定关系
export const bindRoleAndMenu = (menuId, roleIds) => { export const bindRoleAndMenu = (menuId, roleIds) => {
return request({ return request({
url: '/admin/role/bind/menu', url: '/admin/role/bind/menu',
method: 'put', method: 'put',
data: { data: {
id: menuId, id: menuId,
ids: roleIds ids: roleIds
} }
}) })
} }
//删除角色信息 //删除角色信息
export const deleteRole = (roleId) => { export const deleteRole = (roleId) => {
return request({ return request({
url: `/admin/role/${roleId}`, url: `/admin/role/${roleId}`,
method: "delete" method: "delete"
}); });
}; };

View File

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

View File

@@ -1,30 +1,30 @@
import request from "@/utils/request.js"; import request from "@/utils/request.js";
export const getSubCompanyList=(params)=>{ export const getSubCompanyList=(params)=>{
return request({ return request({
url:'/admin/mosr/sub/company', url:'/admin/mosr/sub/company',
method:'get', method:'get',
params params
}) })
} }
export const getDepartmentList=(params)=>{ export const getDepartmentList=(params)=>{
return request({ return request({
url:'/admin/mosr/department', url:'/admin/mosr/department',
method:'get', method:'get',
params params
}) })
} }
export const getCompanyDetail=(companyId)=>{ export const getCompanyDetail=(companyId)=>{
return request({ return request({
url:`/admin/mosr/sub/company/info/${companyId}`, url:`/admin/mosr/sub/company/info/${companyId}`,
method:'get' method:'get'
}) })
} }
export const setCompanyLeader=(data)=>{ export const setCompanyLeader=(data)=>{
return request({ return request({
url:'/admin/mosr/sub/company/leader', url:'/admin/mosr/sub/company/leader',
method:'post', method:'post',
data:data data:data
}) })
} }

View File

@@ -1,54 +1,54 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
// 请求参数配置表list // 请求参数配置表list
export const getConfigList = (params) => { export const getConfigList = (params) => {
return request({ return request({
url: '/admin/config', url: '/admin/config',
method: 'get', method: 'get',
params params
}) })
} }
//获取到option列表 //获取到option列表
// 获取参数配置表详情 // 获取参数配置表详情
export const getConfigDetails = (configId) => { export const getConfigDetails = (configId) => {
return request({ return request({
url: '/admin/config/' + configId, url: '/admin/config/' + configId,
method: 'get' method: 'get'
}) })
} }
// 获取参数配置表详情 // 获取参数配置表详情
export const getConfigByKey = (configKey) => { export const getConfigByKey = (configKey) => {
return request({ return request({
url: '/admin/config/key/' + configKey, url: '/admin/config/key/' + configKey,
method: 'get' method: 'get'
}) })
} }
// 新增参数配置表 // 新增参数配置表
export const addConfig = (data) => { export const addConfig = (data) => {
return request({ return request({
url: '/admin/config', url: '/admin/config',
method: 'post', method: 'post',
data data
}) })
} }
// 修改参数配置表 // 修改参数配置表
export const editConfig = (data) => { export const editConfig = (data) => {
return request({ return request({
url: '/admin/config', url: '/admin/config',
method: 'put', method: 'put',
data data
}) })
} }
// 删除参数配置表 // 删除参数配置表
export const delConfig =(configId) => { export const delConfig =(configId) => {
return request({ return request({
url: '/admin/config/' + configId, url: '/admin/config/' + configId,
method: 'delete' method: 'delete'
}) })
} }

View File

@@ -1,44 +1,44 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
// 请求字典类型表list // 请求字典类型表list
export const getDictDataList = (params) => { export const getDictDataList = (params) => {
return request({ return request({
url: '/admin/dict/data', url: '/admin/dict/data',
method: 'get', method: 'get',
params params
}) })
} }
// 获取字典数据表详情 // 获取字典数据表详情
export const getDictDataDetails = (dictCode) => { export const getDictDataDetails = (dictCode) => {
return request({ return request({
url: '/admin/dict/data/' + dictCode, url: '/admin/dict/data/' + dictCode,
method: 'get' method: 'get'
}) })
} }
// 新增字典数据表 // 新增字典数据表
export const addDictData = (data) => { export const addDictData = (data) => {
return request({ return request({
url: '/admin/dict/data', url: '/admin/dict/data',
method: 'post', method: 'post',
data data
}) })
} }
// 修改字典类型表 // 修改字典类型表
export const editDictData = (data) => { export const editDictData = (data) => {
return request({ return request({
url: '/admin/dict/data', url: '/admin/dict/data',
method: 'put', method: 'put',
data data
}) })
} }
// 删除字典类型表 // 删除字典类型表
export const delDictData = (dictCode) => { export const delDictData = (dictCode) => {
return request({ return request({
url: `/admin/dict/data/${dictCode}`, url: `/admin/dict/data/${dictCode}`,
method: 'delete' method: 'delete'
}) })
} }

View File

@@ -1,58 +1,58 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getDictOption = () => { export const getDictOption = () => {
return request({ return request({
url: '/admin/dict/type/option', url: '/admin/dict/type/option',
method: 'get' method: 'get'
}) })
} }
// 请求字典类型表list // 请求字典类型表list
export const getDictTypeList = (params) => { export const getDictTypeList = (params) => {
return request({ return request({
url: '/admin/dict/type', url: '/admin/dict/type',
method: 'get', method: 'get',
params params
}) })
} }
// 获取字典类型表详情 // 获取字典类型表详情
export const getDictTypeDetails = (dictTypeId) => { export const getDictTypeDetails = (dictTypeId) => {
return request({ return request({
url: '/admin/dict/type/' + dictTypeId, url: '/admin/dict/type/' + dictTypeId,
method: 'get' method: 'get'
}) })
} }
// 新增字典类型表 // 新增字典类型表
export const addDictType = (data) => { export const addDictType = (data) => {
return request({ return request({
url: '/admin/dict/type', url: '/admin/dict/type',
method: 'post', method: 'post',
data data
}) })
} }
// 修改字典类型表 // 修改字典类型表
export const editDictType = (data) => { export const editDictType = (data) => {
return request({ return request({
url: '/admin/dict/type', url: '/admin/dict/type',
method: 'put', method: 'put',
data data
}) })
} }
// 删除字典类型表 // 删除字典类型表
export const delDictType =(dictTypeId) => { export const delDictType =(dictTypeId) => {
return request({ return request({
url: '/admin/dict/type/' + dictTypeId, url: '/admin/dict/type/' + dictTypeId,
method: 'delete' method: 'delete'
}) })
} }
//字典刷新缓存 //字典刷新缓存
export const refreshDict =() => { export const refreshDict =() => {
return request({ return request({
url: 'admin/dict/type/refresh', url: 'admin/dict/type/refresh',
method: 'post' method: 'post'
}) })
} }

View File

@@ -1,16 +1,16 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getMappingList = (params) => { export const getMappingList = (params) => {
return request({ return request({
url: '/admin/mapping/switch', url: '/admin/mapping/switch',
method: 'get', method: 'get',
params params
}) })
} }
export const editMappingSwitch = (data) => { export const editMappingSwitch = (data) => {
return request({ return request({
url: '/admin/mapping/switch', url: '/admin/mapping/switch',
method: 'put', method: 'put',
data data
}) })
} }

View File

@@ -1,8 +1,8 @@
import request from '@/utils/request' import request from '@/utils/request'
export const getRouters = () => { export const getRouters = () => {
return request({ return request({
url: '/auth/router', url: '/auth/router',
method: 'get' method: 'get'
}) })
} }

View File

@@ -1,53 +1,53 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export const getMenuList = (params) => { export const getMenuList = (params) => {
return request({ return request({
url: '/admin/menu', url: '/admin/menu',
method: 'get', method: 'get',
params params
}) })
} }
export const editMenu = (data) => { export const editMenu = (data) => {
return request({ return request({
url: '/admin/menu', url: '/admin/menu',
method: 'put', method: 'put',
data data
}) })
} }
export const addMenu = (data) => { export const addMenu = (data) => {
return request({ return request({
url: '/admin/menu', url: '/admin/menu',
method: 'post', method: 'post',
data data
}) })
} }
export const delMenu = (menuId) => { export const delMenu = (menuId) => {
return request({ return request({
url: '/admin/menu/'+menuId, url: '/admin/menu/'+menuId,
method: 'delete' method: 'delete'
}) })
} }
export const getMenuInfo = (menuId) => { export const getMenuInfo = (menuId) => {
return request({ return request({
url: '/admin/menu/info/'+menuId, url: '/admin/menu/info/'+menuId,
method: 'get' method: 'get'
}) })
} }
export const getMenuOpt = (excludeId=0) => { export const getMenuOpt = (excludeId=0) => {
return request({ return request({
url: '/admin/menu/option/'+excludeId, url: '/admin/menu/option/'+excludeId,
method: 'get' method: 'get'
}) })
} }
export const getMenuOptRole = (roleId) => { export const getMenuOptRole = (roleId) => {
return request({ return request({
url: '/admin/menu/option/role/'+roleId, url: '/admin/menu/option/role/'+roleId,
method: 'get' method: 'get'
}) })
} }

View File

@@ -1,251 +1,251 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
// 根据角色或者部门id获取对应数据 // 根据角色或者部门id获取对应数据
export const getDeptOpt = (params = {}) => { export const getDeptOpt = (params = {}) => {
return request({ return request({
url: `/admin/mosr/department/option`, url: `/admin/mosr/department/option`,
method: 'get', method: 'get',
params params
}) })
} }
export const getSubCompOpt = () => { export const getSubCompOpt = () => {
return request({ return request({
url: `/admin/mosr/sub/company/option`, url: `/admin/mosr/sub/company/option`,
method: 'get' method: 'get'
}) })
} }
export const getUserAccount = () => { export const getUserAccount = () => {
return request({ return request({
url: `/admin/mosr/user/account/list`, url: `/admin/mosr/user/account/list`,
method: 'get' method: 'get'
}) })
} }
export const judgeIsSameRole = (userId) => { export const judgeIsSameRole = (userId) => {
return request({ return request({
url: `/admin/mosr/user/company/same/${userId}`, url: `/admin/mosr/user/company/same/${userId}`,
method: 'get' method: 'get'
}) })
} }
// 查询角色信息 // 查询角色信息
export const getRolesOpt = () => { export const getRolesOpt = () => {
return request({ return request({
url: '/admin/role/option', url: '/admin/role/option',
method: 'get', method: 'get',
}) })
} }
// 获取岗位下拉 // 获取岗位下拉
export const getJobOpt = () => { export const getJobOpt = () => {
return request({ return request({
url: '/admin/job/option', url: '/admin/job/option',
method: 'get', method: 'get',
}) })
} }
export const getMosrUserList = (params) => { export const getMosrUserList = (params) => {
return request({ return request({
url: '/admin/mosr/user', url: '/admin/mosr/user',
method: 'get', method: 'get',
params params
}) })
} }
export const getUserList = (params) => { export const getUserList = (params) => {
return request({ return request({
url: '/admin/user', url: '/admin/user',
method: 'get', method: 'get',
params params
}) })
} }
//获取用户详情 //获取用户详情
export const getUserDetail = (userId) => { export const getUserDetail = (userId) => {
return request({ return request({
url: `/admin/mosr/user/info/${userId}`, url: `/admin/mosr/user/info/${userId}`,
method: "get" method: "get"
}); });
}; };
// 操作 // 操作
export const operate = (data, type) => { export const operate = (data, type) => {
// console.log(type ,'type'); // console.log(type ,'type');
if (data.userId && type !== '0') return editUser(data) if (data.userId && type !== '0') return editUser(data)
else if (type == '0') return editUserOA(data) else if (type == '0') return editUserOA(data)
return addUser(data) return addUser(data)
} }
// 新增用户 // 新增用户
export const addUser = (data) => { export const addUser = (data) => {
return request({ return request({
url: '/admin/mosr/user', url: '/admin/mosr/user',
method: 'post', method: 'post',
data data
}) })
} }
// 修改用户 // 修改用户
export const editUser = (data) => { export const editUser = (data) => {
return request({ return request({
url: '/admin/mosr/user', url: '/admin/mosr/user',
method: 'put', method: 'put',
data data
}) })
} }
// 修改OA用户 // 修改OA用户
export const editUserOA = (data) => { export const editUserOA = (data) => {
return request({ return request({
url: '/admin/mosr/user/oa', url: '/admin/mosr/user/oa',
method: 'put', method: 'put',
data data
}) })
} }
//删除用户信息 //删除用户信息
export const deleteUser = (userId) => { export const deleteUser = (userId) => {
return request({ return request({
url: `/admin/user/${userId}`, url: `/admin/user/${userId}`,
method: "delete" method: "delete"
}); });
}; };
//根据roleId获取用户信息 //根据roleId获取用户信息
export const getUserByRoleId = (roleId, params) => { export const getUserByRoleId = (roleId, params) => {
return request({ return request({
url: `/admin/user/role/${roleId}`, url: `/admin/user/role/${roleId}`,
method: "get", method: "get",
params params
}); });
}; };
//排除角色id获取用户信息 //排除角色id获取用户信息
export const getUserExcludeRoleId = (roleId, params) => { export const getUserExcludeRoleId = (roleId, params) => {
return request({ return request({
url: `/admin/user/role/exclude/${roleId}`, url: `/admin/user/role/exclude/${roleId}`,
method: "get", method: "get",
params params
}); });
}; };
//建立角色用户绑定关系 //建立角色用户绑定关系
export const roleBindUser = (data) => { export const roleBindUser = (data) => {
return request({ return request({
url: '/admin/user/bind/role', url: '/admin/user/bind/role',
method: 'put', method: 'put',
data data
}) })
} }
// 解除角色与用户之间的绑定状态 // 解除角色与用户之间的绑定状态
export const cancelAuthorization = (data) => { export const cancelAuthorization = (data) => {
return request({ return request({
url: '/admin/user/unbind/role', url: '/admin/user/unbind/role',
method: 'put', method: 'put',
data data
}) })
} }
//解除当前角色对应的所有用户的绑定关系 //解除当前角色对应的所有用户的绑定关系
export const unbindAllUser = (roleId) => { export const unbindAllUser = (roleId) => {
return request({ return request({
url: '/admin/user/all/unbind/role', url: '/admin/user/all/unbind/role',
method: 'put', method: 'put',
data: { data: {
id: roleId id: roleId
} }
}) })
} }
//根据岗位id获取分配的用户信息 //根据岗位id获取分配的用户信息
export const getUserInfoByPostId = (postId, params) => { export const getUserInfoByPostId = (postId, params) => {
return request({ return request({
url: `/admin/user/post/${postId}`, url: `/admin/user/post/${postId}`,
method: 'get', method: 'get',
params params
}) })
} }
//排除岗位id获取用户信息 //排除岗位id获取用户信息
export const getUserExcludePostId = (postId, params) => { export const getUserExcludePostId = (postId, params) => {
return request({ return request({
url: `/admin/user/post/exclude/${postId}`, url: `/admin/user/post/exclude/${postId}`,
method: "get", method: "get",
params params
}); });
}; };
//建立岗位与用户绑定关系 //建立岗位与用户绑定关系
export const postBindUser = (userIds, postId) => { export const postBindUser = (userIds, postId) => {
return request({ return request({
url: '/admin/user/bind/post', url: '/admin/user/bind/post',
method: 'put', method: 'put',
data: { data: {
ids: userIds, ids: userIds,
id: postId id: postId
} }
}) })
} }
// 解除岗位与用户之间的绑定状态 // 解除岗位与用户之间的绑定状态
export const cancelPostAndUserAuthorization = (userIds, postId) => { export const cancelPostAndUserAuthorization = (userIds, postId) => {
return request({ return request({
url: '/admin/user/unbind/post', url: '/admin/user/unbind/post',
method: 'put', method: 'put',
data: { data: {
ids: userIds, ids: userIds,
id: postId id: postId
} }
}) })
} }
//解除当前岗位对应的所有用户的绑定关系 //解除当前岗位对应的所有用户的绑定关系
export const unbindAllUserByPost = (postId) => { export const unbindAllUserByPost = (postId) => {
return request({ return request({
url: '/admin/user/all/unbind/post', url: '/admin/user/all/unbind/post',
method: 'put', method: 'put',
data: { data: {
id: postId id: postId
} }
}) })
} }
export const bindAccount = (data) => { export const bindAccount = (data) => {
return request({ return request({
url: '/admin/mosr/user/bind/account', url: '/admin/mosr/user/bind/account',
method: 'post', method: 'post',
data data
}) })
} }
export const getBindAccount = (userId) => { export const getBindAccount = (userId) => {
return request({ return request({
url: `/admin/mosr/user/bind/account/info/${userId}`, url: `/admin/mosr/user/bind/account/info/${userId}`,
method: 'get' method: 'get'
}) })
} }
export const checkMatrix = (userId) => { export const checkMatrix = (userId) => {
return request({ return request({
url: `/admin/mosr/user/matrix?userId=` + userId, url: `/admin/mosr/user/matrix?userId=` + userId,
method: 'get' method: 'get'
}) })
} }
export const getAgentInfo=(userId)=>{ export const getAgentInfo=(userId)=>{
return request({ return request({
url: `/admin/mosr/user/approval/agent/${userId}`, url: `/admin/mosr/user/approval/agent/${userId}`,
method:'get' method:'get'
}) })
} }
export const editAgentInfo=(data)=>{ export const editAgentInfo=(data)=>{
return request({ return request({
url:'/admin/mosr/user/approval/agent', url:'/admin/mosr/user/approval/agent',
method:'post', method:'post',
data data
}) })
} }
export const addWhiteUser=(data)=>{ export const addWhiteUser=(data)=>{
return request({ return request({
url:'/admin/approve/white', url:'/admin/approve/white',
method:'post', method:'post',
data data
}) })
} }
export const delWhiteUser=(data)=>{ export const delWhiteUser=(data)=>{
return request({ return request({
url:'/admin/approve/white', url:'/admin/approve/white',
method:'delete', method:'delete',
data data
}) })
} }

View File

@@ -1,78 +1,78 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export function getProcessDefinitionList(param) { export function getProcessDefinitionList(param) {
return request({ return request({
url: "/workflow/process/definition", url: "/workflow/process/definition",
method: "get", method: "get",
params: param params: param
}) })
} }
export function getProcessDefinitionInfo(deploymentId) { export function getProcessDefinitionInfo(deploymentId) {
return request({ return request({
url: "/workflow/process/definition/" + deploymentId, url: "/workflow/process/definition/" + deploymentId,
method: "get", method: "get",
}) })
} }
export function getInitiateInfo(processDefinitionKey) { export function getInitiateInfo(processDefinitionKey) {
return request({ return request({
url: "/workflow/process/definition/key/" + processDefinitionKey, url: "/workflow/process/definition/key/" + processDefinitionKey,
method: "get", method: "get",
}) })
} }
export function getHistoryVersion(processDefinitionKey) { export function getHistoryVersion(processDefinitionKey) {
return request({ return request({
url: "/workflow/process/definition/history/" + processDefinitionKey, url: "/workflow/process/definition/history/" + processDefinitionKey,
method: "get", method: "get",
}) })
} }
export function deleteHistoryVersion(deploymentId) { export function deleteHistoryVersion(deploymentId) {
return request({ return request({
url: "/workflow/process/definition/" + deploymentId, url: "/workflow/process/definition/" + deploymentId,
method: "delete", method: "delete",
}) })
} }
export function suspendProcessDefinition(processDefinitionId) { export function suspendProcessDefinition(processDefinitionId) {
return request({ return request({
url: "/workflow/process/definition/suspend", url: "/workflow/process/definition/suspend",
method: "put", method: "put",
data: processDefinitionId data: processDefinitionId
}) })
} }
export function activateProcessDefinition(processDefinitionId) { export function activateProcessDefinition(processDefinitionId) {
return request({ return request({
url: "/workflow/process/definition/activate", url: "/workflow/process/definition/activate",
method: "put", method: "put",
data: processDefinitionId data: processDefinitionId
}) })
} }
export function addProcessDefinition(param) { export function addProcessDefinition(param) {
return request({ return request({
url: "/workflow/process/definition", url: "/workflow/process/definition",
method: "post", method: "post",
data: param data: param
}) })
} }
export function getTypeOption() { export function getTypeOption() {
return request({ return request({
url: "/workflow/process/definition/type/option", url: "/workflow/process/definition/type/option",
method: "get", method: "get",
}) })
} }
export function getFromPerm(processKey) { export function getFromPerm(processKey) {
return request({ return request({
url: "/workflow/process/definition/from/perm/"+processKey, url: "/workflow/process/definition/from/perm/"+processKey,
method: "get", method: "get",
}) })
} }

View File

@@ -1,9 +1,9 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export function deleteFile(fileId) { export function deleteFile(fileId) {
// 删除文件 // 删除文件
return request({ return request({
url: '/workflow/process/file/' + fileId, url: '/workflow/process/file/' + fileId,
method: 'delete', method: 'delete',
}) })
} }

View File

@@ -1,53 +1,53 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
/** /**
* 开始实例流程 * 开始实例流程
* @param param * @param param
* @returns {*} * @returns {*}
*/ */
export function startProcessInstance(param) { export function startProcessInstance(param) {
return request({ return request({
url: "/workflow/process/instance/start", url: "/workflow/process/instance/start",
method: "post", method: "post",
data: param data: param
}) })
} }
export function restartProcessInstance(param) { export function restartProcessInstance(param) {
return request({ return request({
url: "/workflow/process/instance/restart", url: "/workflow/process/instance/restart",
method: "post", method: "post",
data: param data: param
}) })
} }
export function getAboutInstanceList(param) { export function getAboutInstanceList(param) {
return request({ return request({
url: "/workflow/process/instance/about", url: "/workflow/process/instance/about",
method: "get", method: "get",
params: param params: param
}) })
} }
export function getInitiatedInstanceList(param) { export function getInitiatedInstanceList(param) {
return request({ return request({
url: "/workflow/process/instance/self", url: "/workflow/process/instance/self",
method: "get", method: "get",
params: param params: param
}) })
} }
export function getInitiatedInstanceInfo(processInstanceId) { export function getInitiatedInstanceInfo(processInstanceId) {
return request({ return request({
url: "/workflow/process/instance/info/"+processInstanceId, url: "/workflow/process/instance/info/"+processInstanceId,
method: "get", method: "get",
}) })
} }
export function getInitiatedInstanceReInfo(instanceId) { export function getInitiatedInstanceReInfo(instanceId) {
return request({ return request({
url: "/workflow/process/instance/re/info/"+instanceId, url: "/workflow/process/instance/re/info/"+instanceId,
method: "get", method: "get",
}) })
} }

View File

@@ -1,46 +1,46 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
// 请求系统内置监听器list // 请求系统内置监听器list
export const getProcessListenerList = (params) => { export const getProcessListenerList = (params) => {
return request({ return request({
url: '/workflow/process/listener', url: '/workflow/process/listener',
method: 'get', method: 'get',
params params
}) })
} }
//获取到option列表 //获取到option列表
// 获取系统内置监听器详情 // 获取系统内置监听器详情
export const getProcessListenerDetails = (processListenerId) => { export const getProcessListenerDetails = (processListenerId) => {
return request({ return request({
url: '/workflow/process/listener/' + processListenerId, url: '/workflow/process/listener/' + processListenerId,
method: 'get' method: 'get'
}) })
} }
// 新增系统内置监听器 // 新增系统内置监听器
export const addProcessListener = (data) => { export const addProcessListener = (data) => {
return request({ return request({
url: '/workflow/process/listener', url: '/workflow/process/listener',
method: 'post', method: 'post',
data data
}) })
} }
// 修改系统内置监听器 // 修改系统内置监听器
export const editProcessListener = (data) => { export const editProcessListener = (data) => {
return request({ return request({
url: '/workflow/process/listener', url: '/workflow/process/listener',
method: 'put', method: 'put',
data data
}) })
} }
// 删除系统内置监听器 // 删除系统内置监听器
export const delProcessListener =(processListenerId) => { export const delProcessListener =(processListenerId) => {
return request({ return request({
url: '/workflow/process/listener/' + processListenerId, url: '/workflow/process/listener/' + processListenerId,
method: 'delete' method: 'delete'
}) })
} }

View File

@@ -1,45 +1,45 @@
import request from '@/utils/request.js' import request from '@/utils/request.js'
export function getTaskList() { export function getTaskList() {
return request({ return request({
url: "/workflow/process/task", url: "/workflow/process/task",
method: "get", method: "get",
}) })
} }
export function getTaskInfo(taskId) { export function getTaskInfo(taskId) {
return request({ return request({
url: "/workflow/process/task/"+taskId, url: "/workflow/process/task/"+taskId,
method: "get", method: "get",
}) })
} }
export function completeTask(params) { export function completeTask(params) {
return request({ return request({
url: "/workflow/process/task/complete", url: "/workflow/process/task/complete",
method: "put", method: "put",
data: params data: params
}) })
} }
export function refuseTask(params) { export function refuseTask(params) {
return request({ return request({
url: "/workflow/process/task/refuse", url: "/workflow/process/task/refuse",
method: "put", method: "put",
data: params data: params
}) })
} }
export function rollBackTask(params) { export function rollBackTask(params) {
return request({ return request({
url: "/workflow/process/task/rollback", url: "/workflow/process/task/rollback",
method: "put", method: "put",
data: params data: params
}) })
} }
export function addComment(params) { export function addComment(params) {
return request({ return request({
url: "/workflow/process/task/comment", url: "/workflow/process/task/comment",
method: "post", method: "post",
data: params data: params
}) })
} }

View File

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

View File

@@ -1,77 +1,77 @@
tinymce.PluginManager.add('axupimgs', function (editor, url) { tinymce.PluginManager.add('axupimgs', function (editor, url) {
var pluginName = '多图片上传'; var pluginName = '多图片上传';
window.axupimgs = {}; //扔外部公共变量,也可以扔一个自定义的位置 window.axupimgs = {}; //扔外部公共变量,也可以扔一个自定义的位置
const baseURL = import.meta.env.VITE_BASE_URL const baseURL = import.meta.env.VITE_BASE_URL
// var baseURL=tinymce.baseURL; // var baseURL=tinymce.baseURL;
var iframe1 = '/upfiles.html'; var iframe1 = '/upfiles.html';
console.log('editor',editor) console.log('editor',editor)
axupimgs.images_upload_handler = editor.getParam('images_upload_handler_not_loading', undefined, 'function'); axupimgs.images_upload_handler = editor.getParam('images_upload_handler_not_loading', undefined, 'function');
axupimgs.images_upload_base_path = editor.getParam('images_upload_base_path', '', 'string'); axupimgs.images_upload_base_path = editor.getParam('images_upload_base_path', '', 'string');
axupimgs.axupimgs_filetype = editor.getParam('axupimgs_filetype', '.png,.gif,.jpg,.jpeg', 'string'); axupimgs.axupimgs_filetype = editor.getParam('axupimgs_filetype', '.png,.gif,.jpg,.jpeg', 'string');
axupimgs.res = []; axupimgs.res = [];
var openDialog = function () { var openDialog = function () {
return editor.windowManager.openUrl({ return editor.windowManager.openUrl({
title: pluginName, title: pluginName,
size: 'large', size: 'large',
url: iframe1, url: iframe1,
buttons: [ buttons: [
{ {
type: 'cancel', type: 'cancel',
text: 'Close' text: 'Close'
}, },
{ {
type: 'custom', type: 'custom',
text: 'Save', text: 'Save',
name: 'save', name: 'save',
primary: true primary: true
}, },
], ],
onAction: function (api, details) { onAction: function (api, details) {
switch (details.name) { switch (details.name) {
case 'save': case 'save':
var html = ''; var html = '';
var imgs = axupimgs.res; var imgs = axupimgs.res;
var len = imgs.length; var len = imgs.length;
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
if (imgs[i].url) { if (imgs[i].url) {
html += '<img src="' + imgs[i].url + '" />'; html += '<img src="' + imgs[i].url + '" />';
} }
} }
editor.insertContent(html); editor.insertContent(html);
axupimgs.res = []; axupimgs.res = [];
api.close(); api.close();
break; break;
default: default:
break; break;
} }
} }
}); });
}; };
editor.ui.registry.getAll().icons.axupimgs || editor.ui.registry.addIcon('axupimgs', '<svg viewBox="0 0 1280 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M1126.2,779.8V87.6c0-24-22.6-86.9-83.5-86.9H83.5C14.7,0.7,0,63.7,0,87.7v692c0,36.2,29.2,89.7,83.5,89.7l959.3-1.3c51.7,0,83.5-42.5,83.5-88.3zm-1044,4V86.3h961.6V783.7H82.2v0.1z" fill="#53565A"/><path d="M603,461.6L521.1,366.3,313,629.8,227.2,546.8,102.4,716.8H972.8v-170L768.2,235.2,603.1,461.6zM284.6,358.4a105.4,105.4,0,0,0,73.5-30c19.5-19.1,30.3-45,30.2-71.8,0-56.8-45.9-103-102.4-103-56.6,0-102.4,46.1-102.4,103C183.4,313.5,228,358.4,284.6,358.4z" fill="#9598A0"/><path d="M1197.7,153.6l-0.3,669.3s13.5,113.9-67.4,113.9H153.6c0,24.1,23.9,87.2,83.5,87.2h959.3c58.3,0,83.6-49.5,83.6-89.9V240.8c-0.1-41.8-44.9-87.2-82.3-87.2z" fill="#53565A"/></svg>'); editor.ui.registry.getAll().icons.axupimgs || editor.ui.registry.addIcon('axupimgs', '<svg viewBox="0 0 1280 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M1126.2,779.8V87.6c0-24-22.6-86.9-83.5-86.9H83.5C14.7,0.7,0,63.7,0,87.7v692c0,36.2,29.2,89.7,83.5,89.7l959.3-1.3c51.7,0,83.5-42.5,83.5-88.3zm-1044,4V86.3h961.6V783.7H82.2v0.1z" fill="#53565A"/><path d="M603,461.6L521.1,366.3,313,629.8,227.2,546.8,102.4,716.8H972.8v-170L768.2,235.2,603.1,461.6zM284.6,358.4a105.4,105.4,0,0,0,73.5-30c19.5-19.1,30.3-45,30.2-71.8,0-56.8-45.9-103-102.4-103-56.6,0-102.4,46.1-102.4,103C183.4,313.5,228,358.4,284.6,358.4z" fill="#9598A0"/><path d="M1197.7,153.6l-0.3,669.3s13.5,113.9-67.4,113.9H153.6c0,24.1,23.9,87.2,83.5,87.2h959.3c58.3,0,83.6-49.5,83.6-89.9V240.8c-0.1-41.8-44.9-87.2-82.3-87.2z" fill="#53565A"/></svg>');
editor.ui.registry.addButton('axupimgs', { editor.ui.registry.addButton('axupimgs', {
icon: 'axupimgs', icon: 'axupimgs',
tooltip: pluginName, tooltip: pluginName,
onAction: function () { onAction: function () {
openDialog(); openDialog();
} }
}); });
editor.ui.registry.addMenuItem('axupimgs', { editor.ui.registry.addMenuItem('axupimgs', {
icon: 'axupimgs', icon: 'axupimgs',
text: '图片批量上传...', text: '图片批量上传...',
onAction: function () { onAction: function () {
openDialog(); openDialog();
} }
}); });
return { return {
getMetadata: function () { getMetadata: function () {
return { return {
name: pluginName, name: pluginName,
url: "http://tinymce.ax-z.cn/more-plugins/axupimgs.php", url: "http://tinymce.ax-z.cn/more-plugins/axupimgs.php",
}; };
} }
}; };
}); });

View File

@@ -1,75 +1,75 @@
tinymce.PluginManager.add('axupimgs', function(editor, url) { tinymce.PluginManager.add('axupimgs', function(editor, url) {
var pluginName='Ax多图片上传'; var pluginName='Ax多图片上传';
window.axupimgs={}; //扔外部公共变量,也可以扔一个自定义的位置 window.axupimgs={}; //扔外部公共变量,也可以扔一个自定义的位置
var baseURL=tinymce.baseURL; var baseURL=tinymce.baseURL;
var iframe1 = baseURL+'/plugins/axupimgs/upfiles.html'; var iframe1 = baseURL+'/plugins/axupimgs/upfiles.html';
axupimgs.images_upload_handler = editor.getParam('images_upload_handler', undefined, 'function'); axupimgs.images_upload_handler = editor.getParam('images_upload_handler', undefined, 'function');
axupimgs.images_upload_base_path = editor.getParam('images_upload_base_path', '', 'string'); axupimgs.images_upload_base_path = editor.getParam('images_upload_base_path', '', 'string');
axupimgs.axupimgs_filetype = editor.getParam('axupimgs_filetype', '.png,.gif,.jpg,.jpeg', 'string'); axupimgs.axupimgs_filetype = editor.getParam('axupimgs_filetype', '.png,.gif,.jpg,.jpeg', 'string');
axupimgs.res=[]; axupimgs.res=[];
var openDialog = function() { var openDialog = function() {
return editor.windowManager.openUrl({ return editor.windowManager.openUrl({
title: pluginName, title: pluginName,
size: 'large', size: 'large',
url:iframe1, url:iframe1,
buttons: [ buttons: [
{ {
type: 'cancel', type: 'cancel',
text: 'Close' text: 'Close'
}, },
{ {
type: 'custom', type: 'custom',
text: 'Save', text: 'Save',
name: 'save', name: 'save',
primary: true primary: true
}, },
], ],
onAction: function (api, details) { onAction: function (api, details) {
switch (details.name) { switch (details.name) {
case 'save': case 'save':
var html = ''; var html = '';
var imgs = axupimgs.res; var imgs = axupimgs.res;
var len = imgs.length; var len = imgs.length;
for(let i=0;i<len;i++){ for(let i=0;i<len;i++){
if( imgs[i].url ){ if( imgs[i].url ){
html += '<img src="'+imgs[i].url+'" />'; html += '<img src="'+imgs[i].url+'" />';
} }
} }
editor.insertContent(html); editor.insertContent(html);
axupimgs.res=[]; axupimgs.res=[];
api.close(); api.close();
break; break;
default: default:
break; break;
} }
} }
}); });
}; };
editor.ui.registry.getAll().icons.axupimgs || editor.ui.registry.addIcon('axupimgs','<svg viewBox="0 0 1280 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M1126.2,779.8V87.6c0-24-22.6-86.9-83.5-86.9H83.5C14.7,0.7,0,63.7,0,87.7v692c0,36.2,29.2,89.7,83.5,89.7l959.3-1.3c51.7,0,83.5-42.5,83.5-88.3zm-1044,4V86.3h961.6V783.7H82.2v0.1z" fill="#53565A"/><path d="M603,461.6L521.1,366.3,313,629.8,227.2,546.8,102.4,716.8H972.8v-170L768.2,235.2,603.1,461.6zM284.6,358.4a105.4,105.4,0,0,0,73.5-30c19.5-19.1,30.3-45,30.2-71.8,0-56.8-45.9-103-102.4-103-56.6,0-102.4,46.1-102.4,103C183.4,313.5,228,358.4,284.6,358.4z" fill="#9598A0"/><path d="M1197.7,153.6l-0.3,669.3s13.5,113.9-67.4,113.9H153.6c0,24.1,23.9,87.2,83.5,87.2h959.3c58.3,0,83.6-49.5,83.6-89.9V240.8c-0.1-41.8-44.9-87.2-82.3-87.2z" fill="#53565A"/></svg>'); editor.ui.registry.getAll().icons.axupimgs || editor.ui.registry.addIcon('axupimgs','<svg viewBox="0 0 1280 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M1126.2,779.8V87.6c0-24-22.6-86.9-83.5-86.9H83.5C14.7,0.7,0,63.7,0,87.7v692c0,36.2,29.2,89.7,83.5,89.7l959.3-1.3c51.7,0,83.5-42.5,83.5-88.3zm-1044,4V86.3h961.6V783.7H82.2v0.1z" fill="#53565A"/><path d="M603,461.6L521.1,366.3,313,629.8,227.2,546.8,102.4,716.8H972.8v-170L768.2,235.2,603.1,461.6zM284.6,358.4a105.4,105.4,0,0,0,73.5-30c19.5-19.1,30.3-45,30.2-71.8,0-56.8-45.9-103-102.4-103-56.6,0-102.4,46.1-102.4,103C183.4,313.5,228,358.4,284.6,358.4z" fill="#9598A0"/><path d="M1197.7,153.6l-0.3,669.3s13.5,113.9-67.4,113.9H153.6c0,24.1,23.9,87.2,83.5,87.2h959.3c58.3,0,83.6-49.5,83.6-89.9V240.8c-0.1-41.8-44.9-87.2-82.3-87.2z" fill="#53565A"/></svg>');
editor.ui.registry.addButton('axupimgs', { editor.ui.registry.addButton('axupimgs', {
icon: 'axupimgs', icon: 'axupimgs',
tooltip: pluginName, tooltip: pluginName,
onAction: function() { onAction: function() {
openDialog(); openDialog();
} }
}); });
editor.ui.registry.addMenuItem('axupimgs', { editor.ui.registry.addMenuItem('axupimgs', {
icon: 'axupimgs', icon: 'axupimgs',
text: '图片批量上传...', text: '图片批量上传...',
onAction: function() { onAction: function() {
openDialog(); openDialog();
} }
}); });
return { return {
getMetadata: function() { getMetadata: function() {
return { return {
name: pluginName, name: pluginName,
url: "http://tinymce.ax-z.cn/more-plugins/axupimgs.php", url: "http://tinymce.ax-z.cn/more-plugins/axupimgs.php",
}; };
} }
}; };
}); });

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>

Before

Width:  |  Height:  |  Size: 276 B

After

Width:  |  Height:  |  Size: 277 B

View File

@@ -1,144 +1,144 @@
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
list-style: none; list-style: none;
box-sizing: border-box; box-sizing: border-box;
} }
/* ==============X轴/Y轴区域样式=============*/ /* ==============X轴/Y轴区域样式=============*/
.box-card-h { .box-card-h {
height: 390px !important; height: 390px !important;
} }
.box-card::-webkit-scrollbar { .box-card::-webkit-scrollbar {
width: 6px; width: 6px;
} }
// 滚动条轨道 // 滚动条轨道
.box-card::-webkit-scrollbar-track { .box-card::-webkit-scrollbar-track {
background: rgb(239, 239, 239); background: rgb(239, 239, 239);
border-radius: 2px; border-radius: 2px;
} }
// 小滑块 // 小滑块
.box-card::-webkit-scrollbar-thumb { .box-card::-webkit-scrollbar-thumb {
background: rgba(80, 81, 82, 0.29); background: rgba(80, 81, 82, 0.29);
border-radius: 10px; border-radius: 10px;
} }
.box-card { .box-card {
font-size: 15px; font-size: 15px;
height: 350px; height: 350px;
overflow-y: auto; overflow-y: auto;
.el-card__body { .el-card__body {
padding: 15px; padding: 15px;
} }
.x-y-axis { .x-y-axis {
margin-bottom: 10px; margin-bottom: 10px;
} }
.list-group { .list-group {
height: 100%; height: 100%;
} }
.cards { .cards {
margin-bottom: 10px; margin-bottom: 10px;
span:last-child { span:last-child {
color: #2a99ff; color: #2a99ff;
} }
.update-color { .update-color {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-around; justify-content: space-around;
> span{ > span{
white-space: pre white-space: pre
} }
} }
} }
.card-active { .card-active {
outline: none; /* 隐藏默认的蓝色外边框 */ outline: none; /* 隐藏默认的蓝色外边框 */
box-shadow: 0 0 5px blue; /* 添加阴影效果,颜色为蓝色 */ box-shadow: 0 0 5px blue; /* 添加阴影效果,颜色为蓝色 */
} }
.x-y-cards { .x-y-cards {
.el-card__body { .el-card__body {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
height: 50px; height: 50px;
} }
.cards-right { .cards-right {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
> span:first-child { > span:first-child {
color: #2a99ff; color: #2a99ff;
} }
} }
} }
} }
//扩大拖拽区域 //扩大拖拽区域
.drag-block { .drag-block {
height: 329px; height: 329px;
} }
.red-bgc { .red-bgc {
background-color: red; background-color: red;
} }
.yellow-bgc { .yellow-bgc {
background-color: yellow; background-color: yellow;
} }
/* ==============基础设置样式=============*/ /* ==============基础设置样式=============*/
.basic-setup { .basic-setup {
font-weight: bold; font-weight: bold;
font-size: 18px; font-size: 18px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.setting { .setting {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-bottom: 10px; margin-bottom: 10px;
.setting-title { .setting-title {
font-weight: bold; font-weight: bold;
font-size: 16px; font-size: 16px;
margin-bottom: 5px; margin-bottom: 5px;
} }
.setting-item { .setting-item {
margin-bottom: 10px; margin-bottom: 10px;
} }
} }
/* ==============高级设置样式=============*/ /* ==============高级设置样式=============*/
.advanced-setting{ .advanced-setting{
.el-form-item { .el-form-item {
display: block; display: block;
.el-form-item__label { .el-form-item__label {
font-weight: bold; font-weight: bold;
font-size: 18px; font-size: 18px;
} }
.el-form-item__content { .el-form-item__content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
font-size: 15px; font-size: 15px;
} }
} }
} }
/* ==============echarts样式=============*/ /* ==============echarts样式=============*/
#container { #container {
box-sizing: border-box; box-sizing: border-box;
height: 450px; height: 450px;
width: 80%; width: 80%;
margin: 0 auto; margin: 0 auto;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,53 +1,53 @@
.el-side { .el-side {
border-radius: 10px; border-radius: 10px;
} }
.logo { .logo {
height: 65px; height: 65px;
background-color: #BEA266; background-color: #BEA266;
color: #ffffff; color: #ffffff;
font-weight: bold; font-weight: bold;
font-size: 26px; font-size: 26px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
padding: 10px; padding: 10px;
& > img { & > img {
object-fit: scale-down; object-fit: scale-down;
width: 100%; width: 100%;
height: 40px; height: 40px;
} }
} }
.port-link{ .port-link{
display: block; display: block;
width: 200px; width: 200px;
height: 50px; height: 50px;
margin-left: -40px; margin-left: -40px;
padding-left: 40px; padding-left: 40px;
} }
.el-menu { .el-menu {
border: none !important; border: none !important;
.el-sub-menu { .el-sub-menu {
.el-sub-menu__title { .el-sub-menu__title {
display: block; display: block;
font-size: 14px; font-size: 14px;
&:hover{ &:hover{
//background-color: #1F315F; //background-color: #1F315F;
} }
} }
.el-menu-item { .el-menu-item {
font-size: 14px; font-size: 14px;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
&:hover { &:hover {
//background-color: #373350 !important; //background-color: #373350 !important;
//color: #EDC49A; //color: #EDC49A;
} }
} }
.el-menu-item.is-active { .el-menu-item.is-active {
background: rgba(190,162,102,0.5); background: rgba(190,162,102,0.5);
//background-color: #373350 !important; //background-color: #373350 !important;
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@@ -1,212 +1,212 @@
<template> <template>
<el-form :label-position="labelAlign"> <el-form :label-position="labelAlign">
<el-form-item :label="title" v-if="fileListShow === 'READ' || fileListShow === 'EDIT'" :label-position="labelAlign" :style="{marginTop: '10px',marginLeft: tag!=='需求上报'?'15px':'0'}"> <el-form-item :label="title" v-if="fileListShow === 'READ' || fileListShow === 'EDIT'" :label-position="labelAlign" :style="{marginTop: '10px',marginLeft: tag!=='需求上报'?'15px':'0'}">
<file-upload @getFile="getOtherFile" v-if="fileListShow === 'EDIT'"/> <file-upload @getFile="getOtherFile" v-if="fileListShow === 'EDIT'"/>
<!-- :style="{width:isOpenPrint?'610px': '100%'}" table-layout="auto" id="printTable"--> <!-- :style="{width:isOpenPrint?'610px': '100%'}" table-layout="auto" id="printTable"-->
<fvTable style="width:100%;" :height="tag=='项目立项'?'160':'160'" :style="{maxHeight:tag=='项目立项'?'160px':'160px',height:tag=='项目立项'?'160px':'160px'}" v-if="processViewer" :scrollbar-always-on="true" :tableConfig="tableConfig" <fvTable style="width:100%;" :height="tag=='项目立项'?'160':'160'" :style="{maxHeight:tag=='项目立项'?'160px':'160px',height:tag=='项目立项'?'160px':'160px'}" v-if="processViewer" :scrollbar-always-on="true" :tableConfig="tableConfig"
:data="_value" :isSettingCol="false" :pagination="false"> :data="_value" :isSettingCol="false" :pagination="false">
<template #empty> <template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/> <el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template> </template>
</fvTable> </fvTable>
</el-form-item> </el-form-item>
</el-form> </el-form>
<file-preview ref="filePreviewRef" :fullscreen="fullscreen" v-if="filePreviewShow" :fileName="filePreviewParam.fileName" :fileUrl="filePreviewParam.fileUrl" <file-preview ref="filePreviewRef" :fullscreen="fullscreen" v-if="filePreviewShow" :fileName="filePreviewParam.fileName" :fileUrl="filePreviewParam.fileUrl"
:fileType="filePreviewParam.fileType"/> :fileType="filePreviewParam.fileType"/>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import {downloadFile, deleteFile} from "@/api/project-demand"; import {downloadFile, deleteFile} from "@/api/project-demand";
import {ElNotification} from "element-plus"; import {ElNotification} from "element-plus";
import FilePreview from "../filePreview/index.vue"; import FilePreview from "../filePreview/index.vue";
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
default: '' default: ''
}, },
tag: { tag: {
type: String, type: String,
default: '' default: ''
}, },
fileNameTableWidth: { fileNameTableWidth: {
type: String, type: String,
default: '400' default: '400'
}, },
fileListShow: { fileListShow: {
type: String, type: String,
default: 'READ' default: 'READ'
}, },
value: { value: {
type: Array, type: Array,
default: [] default: []
}, },
processViewer: { processViewer: {
type: Boolean, type: Boolean,
default: false default: false
}, },
labelAlign: { labelAlign: {
type: String, type: String,
default: 'right' default: 'right'
}, },
//弹窗是否铺满全屏 //弹窗是否铺满全屏
fullscreen: { fullscreen: {
type: Boolean, type: Boolean,
default: false default: false
}, },
//是否开始打印 //是否开始打印
isOpenPrint: { isOpenPrint: {
type: Boolean, type: Boolean,
default: false default: false
}, },
}) })
const emit = defineEmits(['update:value']) const emit = defineEmits(['update:value'])
const tableConfig = reactive({ const tableConfig = reactive({
columns: [ columns: [
{ {
prop: 'index', prop: 'index',
type: 'index', type: 'index',
label: '序号', label: '序号',
align: 'center', align: 'center',
width: 85, width: 85,
}, },
{ {
prop: 'originalFileName', prop: 'originalFileName',
label: '文件名', label: '文件名',
align: 'center', align: 'center',
width: props.fileNameTableWidth, width: props.fileNameTableWidth,
showOverflowTooltip: false, showOverflowTooltip: false,
currentRender: ({row, index}) => (<div style="color: #2a99ff;cursor: pointer;" onClick={()=>clickToPreview(row)}>{row.originalFileName}</div>) currentRender: ({row, index}) => (<div style="color: #2a99ff;cursor: pointer;" onClick={()=>clickToPreview(row)}>{row.originalFileName}</div>)
}, },
{ {
prop: 'tag', prop: 'tag',
label: '标签', label: '标签',
align: 'center', align: 'center',
showOverflowTooltip: false, showOverflowTooltip: false,
minWidth: props.fileNameTableWidth, minWidth: props.fileNameTableWidth,
}, },
{ {
prop: 'size', prop: 'size',
label: '文件大小', label: '文件大小',
align: 'center', align: 'center',
width: 150, width: 150,
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB') currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
}, },
{ {
prop: 'oper', prop: 'oper',
label: '操作', label: '操作',
align: 'center', align: 'center',
showOverflowTooltip: false, showOverflowTooltip: false,
currentRender: ({row, index}) => { currentRender: ({row, index}) => {
let btn = [] let btn = []
btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'}) btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'})
// if (row.newFile) { // if (row.newFile) {
// btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'}) // btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'})
// } // }
return ( return (
<div style={{width: '100%'}}> <div style={{width: '100%'}}>
{ {
btn.map(item => ( btn.map(item => (
<el-button <el-button
type={item.type} type={item.type}
onClick={() => item.func()} onClick={() => item.func()}
link> link>
{item.label} {item.label}
</el-button> </el-button>
)) ))
} }
{ {
row.newFile ? <popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'} row.newFile ? <popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
onDelete={() => handleDelete(row)}/> onDelete={() => handleDelete(row)}/>
: '' : ''
} }
</div> </div>
) )
} }
} }
] ]
}) })
const filePreviewParam = ref({ const filePreviewParam = ref({
fileUrl: '', fileUrl: '',
fileName: '', fileName: '',
fileType: 'pdf' fileType: 'pdf'
}) })
const filePreviewShow = ref(false) const filePreviewShow = ref(false)
const _value = computed({ const _value = computed({
get() { get() {
return props.value; return props.value;
}, },
set(val) { set(val) {
emit("update:value", val); emit("update:value", val);
} }
}) })
const clickToPreview=(row)=>{ const clickToPreview=(row)=>{
filePreviewShow.value = false filePreviewShow.value = false
filePreviewParam.value = { filePreviewParam.value = {
fileUrl: row.url, fileUrl: row.url,
fileName: row.originalFileName, fileName: row.originalFileName,
fileType: row.fileType fileType: row.fileType
} }
nextTick(()=>{ nextTick(()=>{
filePreviewShow.value = true filePreviewShow.value = true
}) })
} }
const getOtherFile = (val) => { const getOtherFile = (val) => {
props.processViewer = false props.processViewer = false
let fileObj = compositeParam(val) let fileObj = compositeParam(val)
_value.value.push(fileObj) _value.value.push(fileObj)
nextTick(() => { nextTick(() => {
props.processViewer = true props.processViewer = true
}) })
} }
const compositeParam = (item, type) => { const compositeParam = (item, type) => {
return { return {
fileId: item.id, fileId: item.id,
size: item.size, size: item.size,
originalFileName: item.originalFilename, originalFileName: item.originalFilename,
fileType: item.fileType, fileType: item.fileType,
url: item.url, url: item.url,
newFile: true, newFile: true,
tag: props.tag tag: props.tag
} }
} }
const handleDownload = (row) => { const handleDownload = (row) => {
downloadFile(row.fileId).then(res => { downloadFile(row.fileId).then(res => {
const blob = new Blob([res]) const blob = new Blob([res])
let a = document.createElement('a') let a = document.createElement('a')
a.href = URL.createObjectURL(blob) a.href = URL.createObjectURL(blob)
a.download = row.originalFileName a.download = row.originalFileName
a.click() a.click()
}) })
} }
const handleDelete = (row) => { const handleDelete = (row) => {
deleteFile(row.fileId).then(res => { deleteFile(row.fileId).then(res => {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.msg, message: res.msg,
type: res.code === 1000 ? 'success' : 'error' type: res.code === 1000 ? 'success' : 'error'
}) })
if (res.code === 1000) { if (res.code === 1000) {
_value.value.splice(_value.value.findIndex((item) => item.fileId === row.fileId), 1); _value.value.splice(_value.value.findIndex((item) => item.fileId === row.fileId), 1);
} }
}); });
} }
watch(() => props.processViewer, (newVal) => { watch(() => props.processViewer, (newVal) => {
props.processViewer = newVal props.processViewer = newVal
}, {deep: true}) }, {deep: true})
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
:deep(.el-table--fit ) { :deep(.el-table--fit ) {
height: 160px !important; height: 160px !important;
} }
@media print { @media print {
//#printTable{ //#printTable{
// width: 400px!important; // width: 400px!important;
//} //}
} }
</style> </style>

View File

@@ -1,242 +1,242 @@
<template> <template>
<!-- <baseTitle title="审核意见"></baseTitle>--> <!-- <baseTitle title="审核意见"></baseTitle>-->
<!-- <fvForm :schema="schema" @getInstance="(e)=>form = e"></fvForm>--> <!-- <fvForm :schema="schema" @getInstance="(e)=>form = e"></fvForm>-->
<div class="oper-page-btn" style="display: flex"> <div class="oper-page-btn" style="display: flex">
<el-button type="danger" @click="handleReject">驳回</el-button> <el-button type="danger" @click="handleReject">驳回</el-button>
<el-button color="#DED0B2" @click="handleAgree">同意</el-button> <el-button color="#DED0B2" @click="handleAgree">同意</el-button>
</div> </div>
<div class="opinion-dialog"> <div class="opinion-dialog">
<el-dialog v-model="showBackNode" title="请选择退回节点" width="400"> <el-dialog v-model="showBackNode" title="请选择退回节点" width="400">
<el-table :data="taskUserOptionList" style="width: 100%" <el-table :data="taskUserOptionList" style="width: 100%"
:header-cell-style="{background:'#f5f7fa'}"> :header-cell-style="{background:'#f5f7fa'}">
<el-table-column width="55"> <el-table-column width="55">
<template #default="scope"> <template #default="scope">
<el-radio <el-radio
class="radio" class="radio"
:label="scope.row" :label="scope.row"
v-model="backNode" v-model="backNode"
>&emsp;&emsp;&emsp; >&emsp;&emsp;&emsp;
</el-radio> </el-radio>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="nodeName" prop="nodeName"
label="节点名称"> label="节点名称">
<!-- <template #default="scope">--> <!-- <template #default="scope">-->
<!-- {{scope.row.nodeId==-1?'发起节点':scope.row.nodeName}}--> <!-- {{scope.row.nodeId==-1?'发起节点':scope.row.nodeName}}-->
<!-- </template>--> <!-- </template>-->
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="name" prop="name"
label="操作者"> label="操作者">
<template #default="scope"> <template #default="scope">
<el-tag v-if="scope.row.userInfo" type="success">{{ scope.row.userInfo.name }}</el-tag> <el-tag v-if="scope.row.userInfo" type="success">{{ scope.row.userInfo.name }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="oper" style="display: flex;justify-content: flex-end;margin-top: 10px"> <div class="oper" style="display: flex;justify-content: flex-end;margin-top: 10px">
<el-button type="danger" @click="rollbackHandler">确定</el-button> <el-button type="danger" @click="rollbackHandler">确定</el-button>
<el-button @click="showBackNode=false">取消</el-button> <el-button @click="showBackNode=false">取消</el-button>
</div> </div>
<!-- <el-select v-if="taskUserOptionList?.length>0" v-model="backNode" placeholder="请选择退回节点" clearable>--> <!-- <el-select v-if="taskUserOptionList?.length>0" v-model="backNode" placeholder="请选择退回节点" clearable>-->
<!-- <el-option--> <!-- <el-option-->
<!-- v-for="item in taskUserOptionList"--> <!-- v-for="item in taskUserOptionList"-->
<!-- :key="item.nodeId"--> <!-- :key="item.nodeId"-->
<!-- :label="item.nodeName + (item.userInfo ? ':' + item.userInfo.name : '')"--> <!-- :label="item.nodeName + (item.userInfo ? ':' + item.userInfo.name : '')"-->
<!-- :value="item.nodeId">--> <!-- :value="item.nodeId">-->
<!-- </el-option>--> <!-- </el-option>-->
<!-- </el-select>--> <!-- </el-select>-->
<!-- <el-button type="danger" @click="rollbackHandler">确认</el-button>--> <!-- <el-button type="danger" @click="rollbackHandler">确认</el-button>-->
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import {ElNotification} from 'element-plus'; import {ElNotification} from 'element-plus';
import {agreeTask, rejectTask} from "@/api/project-demand/index.js"; import {agreeTask, rejectTask} from "@/api/project-demand/index.js";
import {useTagsView} from '@/stores/tagsview.js' import {useTagsView} from '@/stores/tagsview.js'
const tagsViewStore = useTagsView() const tagsViewStore = useTagsView()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const props = defineProps({ const props = defineProps({
taskId: { taskId: {
type: String, type: String,
default: '' default: ''
}, },
formData: { formData: {
type: Object, type: Object,
default: {} default: {}
}, },
value: { value: {
type: String, type: String,
default: '' default: ''
}, },
//退回节点选择框数据 //退回节点选择框数据
taskUserOptionList: { taskUserOptionList: {
type: Array, type: Array,
default: [] default: []
} }
}) })
const form = ref() const form = ref()
const backNode = ref({}) const backNode = ref({})
const showBackNode = ref(false) const showBackNode = ref(false)
const schema = computed(() => { const schema = computed(() => {
return [ return [
{ {
label: '', label: '',
prop: 'auditOpinion', prop: 'auditOpinion',
component: 'el-input', component: 'el-input',
colProps: { colProps: {
span: 24 span: 24
}, },
props: { props: {
placeholder: '请输入审核意见', placeholder: '请输入审核意见',
type: 'textarea', type: 'textarea',
rows: 3 rows: 3
} }
} }
] ]
}) })
const _value = computed({ const _value = computed({
get() { get() {
return props.value; return props.value;
}, },
set(val) { set(val) {
emit("update:value", val); emit("update:value", val);
} }
}) })
const back = () => { const back = () => {
switch (route.name) { switch (route.name) {
case 'Initiation/detail': case 'Initiation/detail':
router.push({name: 'Initiation'}) router.push({name: 'Initiation'})
break; break;
case 'Filing/detail': case 'Filing/detail':
router.push({name: 'Filing'}) router.push({name: 'Filing'})
break; break;
case 'Implementation/detail': case 'Implementation/detail':
if (route.query.source === 'home') { if (route.query.source === 'home') {
router.push('/home') router.push('/home')
} else { } else {
if (route.query.step === '10') { if (route.query.step === '10') {
router.push({name: 'Summary'}) router.push({name: 'Summary'})
} else if (route.query.step === '20') { } else if (route.query.step === '20') {
router.push({name: 'Initiation'}) router.push({name: 'Initiation'})
} else if (route.query.step === '40') { } else if (route.query.step === '40') {
router.push({name: 'Implementation'}) router.push({name: 'Implementation'})
} else if (route.query.step === '50') { } else if (route.query.step === '50') {
router.push({name: 'Filing'}) router.push({name: 'Filing'})
} else if (route.query.step === '00') { } else if (route.query.step === '00') {
router.push({name: 'Requirement'}) router.push({name: 'Requirement'})
} }
} }
break; break;
// case 'Summary/detail': // case 'Summary/detail':
// if (route.query.source === 'home') { // if (route.query.source === 'home') {
// router.push('/home') // router.push('/home')
// } else { // } else {
// router.push({name: 'Summary'}) // router.push({name: 'Summary'})
// } // }
// break; // break;
case 'Requirement/detail': case 'Requirement/detail':
if (route.query.source === 'home') { if (route.query.source === 'home') {
router.push('/home') router.push('/home')
} else { } else {
router.push({name: 'Requirement'}) router.push({name: 'Requirement'})
} }
break; break;
case 'Fund/detail': case 'Fund/detail':
if (route.query.source === 'home') { if (route.query.source === 'home') {
router.push('/home') router.push('/home')
} else { } else {
router.push({name: 'Fund'}) router.push({name: 'Fund'})
} }
break; break;
case 'Share/detail': case 'Share/detail':
if (route.query.source === 'home') { if (route.query.source === 'home') {
router.push('/home') router.push('/home')
} else { } else {
router.push({name: 'Expense/share'}) router.push({name: 'Expense/share'})
} }
break; break;
case 'Phase/detail': case 'Phase/detail':
if (route.query.source === 'home') { if (route.query.source === 'home') {
router.push('/home') router.push('/home')
} else { } else {
router.push({name: 'Implementation'}) router.push({name: 'Implementation'})
} }
break; break;
} }
} }
// 驳回 // 驳回
const handleReject = async () => { const handleReject = async () => {
if (!_value.value) { if (!_value.value) {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: '请填写审核意见', message: '请填写审核意见',
type: 'warning' type: 'warning'
}) })
return return
} }
showBackNode.value = true showBackNode.value = true
backNode.value = {} backNode.value = {}
} }
//回退节点 //回退节点
const rollbackHandler = async () => { const rollbackHandler = async () => {
// const values = form.value.getValues() // const values = form.value.getValues()
const params = { const params = {
taskId: props.taskId, taskId: props.taskId,
// ...values // ...values
auditOpinion: _value.value, auditOpinion: _value.value,
rollBackId: backNode.value.nodeId rollBackId: backNode.value.nodeId
} }
// console.log('params', params) // console.log('params', params)
const res = await rejectTask(params) const res = await rejectTask(params)
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.msg, message: res.msg,
type: res.code === 1000 ? 'success' : 'error' type: res.code === 1000 ? 'success' : 'error'
}) })
if (res.code === 1000) { if (res.code === 1000) {
tagsViewStore.delVisitedViews(router.currentRoute.value.path) tagsViewStore.delVisitedViews(router.currentRoute.value.path)
back() back()
} }
} }
const handleAgree = async () => { const handleAgree = async () => {
if (!_value.value) { if (!_value.value) {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: '请填写审核意见', message: '请填写审核意见',
type: 'warning' type: 'warning'
}) })
return return
} }
// const values = form.value.getValues() // const values = form.value.getValues()
const params = { const params = {
taskId: props.taskId, taskId: props.taskId,
formData: props.formData, formData: props.formData,
auditOpinion: _value.value auditOpinion: _value.value
} }
const res = await agreeTask(params) const res = await agreeTask(params)
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.msg, message: res.msg,
type: res.code === 1000 ? 'success' : 'error' type: res.code === 1000 ? 'success' : 'error'
}) })
if (res.code === 1000) { if (res.code === 1000) {
tagsViewStore.delVisitedViews(router.currentRoute.value.path) tagsViewStore.delVisitedViews(router.currentRoute.value.path)
back() back()
} }
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.opinion-dialog { .opinion-dialog {
.el-dialog__body { .el-dialog__body {
padding: 0 !important; padding: 0 !important;
} }
} }
</style> </style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,442 +1,442 @@
<template> <template>
<div class="detail-block" v-loading="loading"> <div class="detail-block" v-loading="loading">
<el-form :model="localFormData" ref="summaryForm" :rules="rules"> <el-form :model="localFormData" ref="summaryForm" :rules="rules">
<baseTitle title="预期知识产权"></baseTitle> <baseTitle title="预期知识产权"></baseTitle>
<el-row gutter="20" style="margin-bottom: -18px;margin-left: 5px"> <el-row gutter="20" style="margin-bottom: -18px;margin-left: 5px">
<!-- <el-col :span="6">--> <!-- <el-col :span="6">-->
<!-- <el-form-item label="预期成果形式" prop="resultForm">--> <!-- <el-form-item label="预期成果形式" prop="resultForm">-->
<!-- <span>{{ filterDict(cacheStore.getDict('result_form'), localFormData.resultForm) }}</span>--> <!-- <span>{{ filterDict(cacheStore.getDict('result_form'), localFormData.resultForm) }}</span>-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<!-- </el-col>--> <!-- </el-col>-->
<el-col :span="6"> <el-col :span="6">
<el-form-item label="知识产权归属" prop="intellectualProperty"> <el-form-item label="知识产权归属" prop="intellectualProperty">
<span>{{ <span>{{
filterDict(cacheStore.getDict('intellectual_property'), localFormData.intellectualProperty) filterDict(cacheStore.getDict('intellectual_property'), localFormData.intellectualProperty)
}}</span> }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估专利(项)" prop="newPatent"> <el-form-item label="预估专利(项)" prop="newPatent">
<span>{{ localFormData.newPatent }}</span> <span>{{ localFormData.newPatent }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估软件著作权(项)" prop="softwareCopyright"> <el-form-item label="预估软件著作权(项)" prop="softwareCopyright">
<span>{{ localFormData.softwareCopyright }}</span> <span>{{ localFormData.softwareCopyright }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估技术标准(项)" prop="technicalNorms"> <el-form-item label="预估技术标准(项)" prop="technicalNorms">
<span>{{ localFormData.technicalNorms }}</span> <span>{{ localFormData.technicalNorms }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估新产品(项)" prop="newProduct"> <el-form-item label="预估新产品(项)" prop="newProduct">
<span>{{ localFormData.newProduct }}</span> <span>{{ localFormData.newProduct }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估新工艺(项)" prop="newProcess"> <el-form-item label="预估新工艺(项)" prop="newProcess">
<span>{{ localFormData.newProcess }}</span> <span>{{ localFormData.newProcess }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估新装置(项)" prop="newDevice"> <el-form-item label="预估新装置(项)" prop="newDevice">
<span>{{ localFormData.newDevice }}</span> <span>{{ localFormData.newDevice }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估新材料(项)" prop="newMaterials"> <el-form-item label="预估新材料(项)" prop="newMaterials">
<span>{{ localFormData.newMaterials }}</span> <span>{{ localFormData.newMaterials }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估计算机软件(项)" prop="computerSoftware"> <el-form-item label="预估计算机软件(项)" prop="computerSoftware">
<span>{{ localFormData.computerSoftware }}</span> <span>{{ localFormData.computerSoftware }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估论文论著(项)" prop="thesis"> <el-form-item label="预估论文论著(项)" prop="thesis">
<span>{{ localFormData.thesis }}</span> <span>{{ localFormData.thesis }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估研究报告(项)" prop="researchReport"> <el-form-item label="预估研究报告(项)" prop="researchReport">
<span>{{ localFormData.researchReport }}</span> <span>{{ localFormData.researchReport }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估商标(项)" prop="trademark"> <el-form-item label="预估商标(项)" prop="trademark">
<span>{{ localFormData.trademark }}</span> <span>{{ localFormData.trademark }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="预估其他(项)" prop="other"> <el-form-item label="预估其他(项)" prop="other">
<span style="white-space: pre-wrap">{{ localFormData.other }}</span> <span style="white-space: pre-wrap">{{ localFormData.other }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<baseTitle title="项目描述"></baseTitle> <baseTitle title="项目描述"></baseTitle>
<el-row gutter="20" style="margin-left: 5px;margin-bottom: -18px;"> <el-row gutter="20" style="margin-left: 5px;margin-bottom: -18px;">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="现有业务描述" prop="serviceDescription"> <el-form-item label="现有业务描述" prop="serviceDescription">
<span style="white-space: pre-wrap">{{ localFormData.serviceDescription }}</span> <span style="white-space: pre-wrap">{{ localFormData.serviceDescription }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="建设目标描述" prop="contentDescription"> <el-form-item label="建设目标描述" prop="contentDescription">
<span style="white-space: pre-wrap">{{ localFormData.contentDescription }}</span> <span style="white-space: pre-wrap">{{ localFormData.contentDescription }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<baseTitle title="需求上报申请书" style="margin-bottom: -3px;"></baseTitle> <baseTitle title="需求上报申请书" style="margin-bottom: -3px;"></baseTitle>
<!-- <el-row gutter="20" style="margin-bottom: -15px;">--> <!-- <el-row gutter="20" style="margin-bottom: -15px;">-->
<!-- <el-col :span="24">--> <!-- <el-col :span="24">-->
<!-- <single-file-component tag="需求上报" v-model:value="localFormData.singleFile" :processViewer="processViewer"/>--> <!-- <single-file-component tag="需求上报" v-model:value="localFormData.singleFile" :processViewer="processViewer"/>-->
<!-- &lt;!&ndash; <el-form-item>&ndash;&gt;--> <!-- &lt;!&ndash; <el-form-item>&ndash;&gt;-->
<!-- &lt;!&ndash; {{localFormData.singleFile}}&ndash;&gt;--> <!-- &lt;!&ndash; {{localFormData.singleFile}}&ndash;&gt;-->
<!-- &lt;!&ndash; <el-button type="primary" link @click="handleDownload(localFormData.singleFile)" style="font-size: 16px">&ndash;&gt;--> <!-- &lt;!&ndash; <el-button type="primary" link @click="handleDownload(localFormData.singleFile)" style="font-size: 16px">&ndash;&gt;-->
<!-- &lt;!&ndash; {{ localFormData.singleFile?.originalFileName }}&ndash;&gt;--> <!-- &lt;!&ndash; {{ localFormData.singleFile?.originalFileName }}&ndash;&gt;-->
<!-- &lt;!&ndash; </el-button>&ndash;&gt;--> <!-- &lt;!&ndash; </el-button>&ndash;&gt;-->
<!-- &lt;!&ndash; </el-form-item>&ndash;&gt;--> <!-- &lt;!&ndash; </el-form-item>&ndash;&gt;-->
<!-- </el-col>--> <!-- </el-col>-->
<!-- </el-row>--> <!-- </el-row>-->
<!--/* <baseTitle title="附件文件" style="margin-bottom: 0"></baseTitle>*/--> <!--/* <baseTitle title="附件文件" style="margin-bottom: 0"></baseTitle>*/-->
<el-row gutter="20" style="margin-bottom: -18px;"> <el-row gutter="20" style="margin-bottom: -18px;">
<el-col :span="24" class="file-table-style"> <el-col :span="24" class="file-table-style">
<file-component tag="需求上报" <file-component tag="需求上报"
v-model:value="localFormData.fileList" :processViewer="processViewer" v-model:value="localFormData.fileList" :processViewer="processViewer"
:file-list-show="fileListShow"/> :file-list-show="fileListShow"/>
</el-col> </el-col>
<el-col :span="24" style="margin-top: -15px"> <el-col :span="24" style="margin-top: -15px">
<div v-if="data.taskId"> <div v-if="data.taskId">
<baseTitle title="审核意见"></baseTitle> <baseTitle title="审核意见"></baseTitle>
<el-form-item prop="_value"> <el-form-item prop="_value">
<el-input <el-input
v-model="_value" v-model="_value"
:rows="3" :rows="3"
type="textarea" type="textarea"
placeholder="请输入审核意见" placeholder="请输入审核意见"
/> />
</el-form-item> </el-form-item>
</div> </div>
<div v-if="data.state==='5'" style="margin-bottom: 15px"> <div v-if="data.state==='5'" style="margin-bottom: 15px">
<baseTitle title="前置流程" v-if="localFormData.preProcess"></baseTitle> <baseTitle title="前置流程" v-if="localFormData.preProcess"></baseTitle>
<div style="display: flex;align-items: center;flex-wrap: wrap;"> <div style="display: flex;align-items: center;flex-wrap: wrap;">
<div v-for="(item,index) in localFormData.preProcess" :key="item.requestId"> <div v-for="(item,index) in localFormData.preProcess" :key="item.requestId">
<a :href="item.baseUrl" target="_blank" <a :href="item.baseUrl" target="_blank"
style="color: #2a99ff;cursor: pointer">{{ item.requestName }}<span style="color: #2a99ff;cursor: pointer">{{ item.requestName }}<span
v-if="index != localFormData.preProcess.length -1"></span> v-if="index != localFormData.preProcess.length -1"></span>
</a> </a>
</div> </div>
</div> </div>
</div> </div>
<div v-perm="['annual:plan:approve']" v-if="data.state==='4'"> <div v-perm="['annual:plan:approve']" v-if="data.state==='4'">
<!-- <baseTitle title="前置流程"></baseTitle>--> <!-- <baseTitle title="前置流程"></baseTitle>-->
<!-- <select-pre-process :formData="localFormData"/>--> <!-- <select-pre-process :formData="localFormData"/>-->
<baseTitle title="审核意见"></baseTitle> <baseTitle title="审核意见"></baseTitle>
<el-form-item prop="_value"> <el-form-item prop="_value">
<el-input <el-input
v-model="_value" v-model="_value"
:rows="3" :rows="3"
type="textarea" type="textarea"
placeholder="请输入审核意见" placeholder="请输入审核意见"
/> />
</el-form-item> </el-form-item>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<div class="approval-record"> <div class="approval-record">
<div class="approval-title" style="margin-top: -12px"> <div class="approval-title" style="margin-top: -12px">
<baseTitle title="审批记录"></baseTitle> <baseTitle title="审批记录"></baseTitle>
<div class="diagram"> <div class="diagram">
<div class="base-title">流程图</div> <div class="base-title">流程图</div>
<el-switch <el-switch
v-model="changeDiagram" v-model="changeDiagram"
style="--el-switch-on-color:#BEA266 ; --el-switch-off-color:#cecdcd" style="--el-switch-on-color:#BEA266 ; --el-switch-off-color:#cecdcd"
/> />
</div> </div>
<el-button color="#DED0B2" style="margin-left: 10px" <el-button color="#DED0B2" style="margin-left: 10px"
@click="handleCarbonCopy()">立即抄送 @click="handleCarbonCopy()">立即抄送
</el-button> </el-button>
</div> </div>
<div class="process"> <div class="process">
<operation-render v-if="processViewer && data.operationList && data.operationList.length > 0&&!changeDiagram" <operation-render v-if="processViewer && data.operationList && data.operationList.length > 0&&!changeDiagram"
:operation-list="data.operationList" :operation-list="data.operationList"
:step="'report'" :step="'report'"
:state="data.state"/> :state="data.state"/>
<process-diagram-viewer v-if="processViewer&&changeDiagram" id-name="summaryProcess"/> <process-diagram-viewer v-if="processViewer&&changeDiagram" id-name="summaryProcess"/>
</div> </div>
</div> </div>
</el-form> </el-form>
<user-picker :multiple="true" ref="carbonCopyUserRef" title="请选择抄送人员" <user-picker :multiple="true" ref="carbonCopyUserRef" title="请选择抄送人员"
v-model:value="carbonCopyUserList" @ok="carbonCopyUserPickerOk" v-model:value="carbonCopyUserList" @ok="carbonCopyUserPickerOk"
@cancelOrClear="carbonCopyUserPickerOk"/> @cancelOrClear="carbonCopyUserPickerOk"/>
<div class="oper-page-btn" v-perm="['annual:plan:approve']" v-if="data.state==='4'"> <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 type="danger" @click="handleRejectPlan">驳回项目计划</el-button>
<el-button color="#DED0B2" @click="handleAgreePlan">通过年度计划</el-button> <el-button color="#DED0B2" @click="handleAgreePlan">通过项目计划</el-button>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import {toThousands} from '@/utils/changePrice.js' import {toThousands} from '@/utils/changePrice.js'
import {downloadFile, deleteFile} from "@/api/project-demand"; import {downloadFile, deleteFile} from "@/api/project-demand";
import OperationRender from '@/views/workflow/common/OperationRender.vue' import OperationRender from '@/views/workflow/common/OperationRender.vue'
import ProcessDiagramViewer from '@/views/workflow/common/ProcessDiagramViewer.vue' import ProcessDiagramViewer from '@/views/workflow/common/ProcessDiagramViewer.vue'
import {useTagsView} from '@/stores/tagsview.js' import {useTagsView} from '@/stores/tagsview.js'
import {getFundOption} from "@/api/special-fund"; import {getFundOption} from "@/api/special-fund";
import {useCacheStore} from '@/stores/cache.js' import {useCacheStore} from '@/stores/cache.js'
import {getSubCompOpt} from "@/api/user/user"; import {getSubCompOpt} from "@/api/user/user";
import FileComponent from "./FileComponent.vue"; import FileComponent from "./FileComponent.vue";
import {ElNotification} from "element-plus"; import {ElNotification} from "element-plus";
import {approvePlan} from "@/api/project-demand/summary"; import {approvePlan} from "@/api/project-demand/summary";
import SelectPreProcess from "@/components/SelectPreProcess.vue"; import SelectPreProcess from "@/components/SelectPreProcess.vue";
import {applyCcSend} from "@/api/expense-manage"; import {applyCcSend} from "@/api/expense-manage";
import UserPicker from "@/views/workflow/process/common/UserPicker.vue"; import UserPicker from "@/views/workflow/process/common/UserPicker.vue";
const emit = defineEmits(['update:value','ccSend']) const emit = defineEmits(['update:value','ccSend'])
const tagsViewStore = useTagsView() const tagsViewStore = useTagsView()
const cacheStore = useCacheStore() const cacheStore = useCacheStore()
const props = defineProps({ const props = defineProps({
formData: { formData: {
type: Object, type: Object,
default: {} default: {}
}, },
data: { data: {
type: Object, type: Object,
default: { default: {
state: '1' state: '1'
} }
}, },
processViewer: { processViewer: {
type: Boolean, type: Boolean,
default: false default: false
}, },
fileListShow: { fileListShow: {
type: String, type: String,
default: 'READ' default: 'READ'
}, },
loading: { loading: {
type: Boolean, type: Boolean,
default: false default: false
}, },
value: { value: {
type: String, type: String,
default: '' default: ''
} }
}) })
const changeDiagram = ref(false) const changeDiagram = ref(false)
const localFormData = ref({}) const localFormData = ref({})
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const fundOption = ref([]) const fundOption = ref([])
const companyOption = ref([]) const companyOption = ref([])
const dictName = ref({}) const dictName = ref({})
const carbonCopyUserList = ref([]) const carbonCopyUserList = ref([])
const carbonCopyUserRef = ref() const carbonCopyUserRef = ref()
const rules = reactive({ const rules = reactive({
auditOpinion: [{required: true, message: '请输入审核意见', trigger: 'blur'}], auditOpinion: [{required: true, message: '请输入审核意见', trigger: 'blur'}],
}) })
const _value = computed({ const _value = computed({
get() { get() {
return props.value; return props.value;
}, },
set(val) { set(val) {
emit("update:value", val); emit("update:value", val);
} }
}) })
const handleCarbonCopy = () => { const handleCarbonCopy = () => {
carbonCopyUserRef.value.showUserPicker() carbonCopyUserRef.value.showUserPicker()
} }
const carbonCopyUserPickerOk = (userList) => { const carbonCopyUserPickerOk = (userList) => {
carbonCopyUserList.value = userList.map(item => item.id) carbonCopyUserList.value = userList.map(item => item.id)
console.log('localFormData.value', props.data) console.log('localFormData.value', props.data)
console.log("🚀 ~ file:'carbonCopyUserList.value ", carbonCopyUserList.value) console.log("🚀 ~ file:'carbonCopyUserList.value ", carbonCopyUserList.value)
addUser() addUser()
} }
const addUser = async () => { const addUser = async () => {
const res = await applyCcSend({ const res = await applyCcSend({
instanceId: props.data.processInstanceId, instanceId: props.data.processInstanceId,
projectId: route.query.projectId, projectId: route.query.projectId,
state: route.query.step, state: route.query.step,
userIds: carbonCopyUserList.value userIds: carbonCopyUserList.value
}) })
console.log('res', res) console.log('res', res)
if (res.code === 1000) { if (res.code === 1000) {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: '抄送成功', message: '抄送成功',
type: 'success' type: 'success'
}) })
emit('ccSend') emit('ccSend')
} else { } else {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.msg, message: res.msg,
type: 'error' type: 'error'
}) })
} }
} }
const handleRejectPlan = async () => { const handleRejectPlan = async () => {
// const values = form.value.getValues() // const values = form.value.getValues()
// console.log('route',route.query.projectId) // console.log('route',route.query.projectId)
if (!_value.value) { if (!_value.value) {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: '请填写审核意见', message: '请填写审核意见',
type: 'warning' type: 'warning'
}) })
return return
} }
const params = { const params = {
auditOpinion: _value.value, auditOpinion: _value.value,
projectId: parseInt(route.query.projectId), projectId: parseInt(route.query.projectId),
state: false state: false
} }
// console.log('params', params) // console.log('params', params)
const res = await approvePlan(params) const res = await approvePlan(params)
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.msg, message: res.msg,
type: res.code === 1000 ? 'success' : 'error' type: res.code === 1000 ? 'success' : 'error'
}) })
tagsViewStore.delVisitedViews(router.currentRoute.value.path) tagsViewStore.delVisitedViews(router.currentRoute.value.path)
router.push({ router.push({
name: 'Summary' name: 'Summary'
}) })
} }
const handleAgreePlan = async () => { const handleAgreePlan = async () => {
if (!_value.value) { if (!_value.value) {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: '请填写审核意见', message: '请填写审核意见',
type: 'warning' type: 'warning'
}) })
return return
} }
const params = { const params = {
auditOpinion: _value.value, auditOpinion: _value.value,
projectId: parseInt(route.query.projectId), projectId: parseInt(route.query.projectId),
preProcess: JSON.stringify(localFormData.value.preProcess), preProcess: JSON.stringify(localFormData.value.preProcess),
state: true state: true
} }
const res = await approvePlan(params) const res = await approvePlan(params)
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.msg, message: res.msg,
type: res.code === 1000 ? 'success' : 'error' type: res.code === 1000 ? 'success' : 'error'
}) })
tagsViewStore.delVisitedViews(router.currentRoute.value.path) tagsViewStore.delVisitedViews(router.currentRoute.value.path)
router.push({ router.push({
name: 'Summary' name: 'Summary'
}) })
} }
const filterDict = (data, value) => { const filterDict = (data, value) => {
if (data === undefined || value === undefined) return; if (data === undefined || value === undefined) return;
let label = '' let label = ''
let result = [] let result = []
if (value instanceof Array) { if (value instanceof Array) {
value.forEach(item1 => { value.forEach(item1 => {
data.find(item => { data.find(item => {
if (item.value == item1) { if (item.value == item1) {
result.push(item.label) result.push(item.label)
} }
}) })
}) })
label = result.map(item => item).join('') label = result.map(item => item).join('')
} else { } else {
if (data instanceof Array) { if (data instanceof Array) {
data.find(item => { data.find(item => {
if (item.value == value) { if (item.value == value) {
label = item.label label = item.label
} }
}) })
} }
} }
return label return label
} }
const getFundOptions = async () => { const getFundOptions = async () => {
const resFund = await getFundOption() const resFund = await getFundOption()
fundOption.value = resFund.data fundOption.value = resFund.data
const res = await getSubCompOpt() const res = await getSubCompOpt()
companyOption.value = res.data companyOption.value = res.data
} }
const changeName = (option, value) => { const changeName = (option, value) => {
let name = '' let name = ''
option.forEach(item => { option.forEach(item => {
if (item.value == value) { if (item.value == value) {
name = item.label name = item.label
} }
}) })
return name return name
} }
const handleDownload = (row) => { const handleDownload = (row) => {
downloadFile(row.fileId).then(res => { downloadFile(row.fileId).then(res => {
const blob = new Blob([res]) const blob = new Blob([res])
let a = document.createElement('a') let a = document.createElement('a')
a.href = URL.createObjectURL(blob) a.href = URL.createObjectURL(blob)
a.download = row.originalFileName a.download = row.originalFileName
a.click() a.click()
}) })
} }
watch(() => props.processViewer, (newVal) => { watch(() => props.processViewer, (newVal) => {
props.processViewer = newVal props.processViewer = newVal
}, {deep: true}) }, {deep: true})
watch(() => props.loading, (newVal) => { watch(() => props.loading, (newVal) => {
props.loading = newVal props.loading = newVal
}, {deep: true}) }, {deep: true})
watchEffect(() => { watchEffect(() => {
props.formData.singleFile = [props.formData.singleFile] props.formData.singleFile = [props.formData.singleFile]
return Object.keys(props.formData).length && (localFormData.value = props.formData) return Object.keys(props.formData).length && (localFormData.value = props.formData)
}) })
getFundOptions() getFundOptions()
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.detail-block { .detail-block {
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
padding-bottom: 0 !important; padding-bottom: 0 !important;
} }
.file-table-style { .file-table-style {
:deep(.el-table__header) { :deep(.el-table__header) {
.is-leaf:first-child { .is-leaf:first-child {
.cell { .cell {
margin-left: -25px !important; margin-left: -25px !important;
} }
} }
} }
:deep(.el-table__body) { :deep(.el-table__body) {
.el-table__cell:first-child { .el-table__cell:first-child {
.cell { .cell {
margin-left: -13px !important; margin-left: -13px !important;
} }
} }
} }
} }
</style> </style>

View File

@@ -1,209 +1,209 @@
<template> <template>
<el-form :label-position="labelAlign"> <el-form :label-position="labelAlign">
<el-form-item :label="title?'其他文件':''" :label-position="labelAlign" :label-width="title?95:''"> <el-form-item :label="title?'其他文件':''" :label-position="labelAlign" :label-width="title?95:''">
<fvTable style="width: 100%;max-height: 80px;" v-if="processViewer" height="80" :tableConfig="tableConfig" <fvTable style="width: 100%;max-height: 80px;" v-if="processViewer" height="80" :tableConfig="tableConfig"
:data="_value" :isSettingCol="false" :pagination="false"> :data="_value" :isSettingCol="false" :pagination="false">
<template #empty> <template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/> <el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template> </template>
</fvTable> </fvTable>
</el-form-item> </el-form-item>
</el-form> </el-form>
<file-preview ref="filePreviewRef" :fullscreen="fullscreen" v-if="filePreviewShow" :fileName="filePreviewParam.fileName" :fileUrl="filePreviewParam.fileUrl" <file-preview ref="filePreviewRef" :fullscreen="fullscreen" v-if="filePreviewShow" :fileName="filePreviewParam.fileName" :fileUrl="filePreviewParam.fileUrl"
:fileType="filePreviewParam.fileType"/> :fileType="filePreviewParam.fileType"/>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import {downloadFile, deleteFile} from "@/api/project-demand"; import {downloadFile, deleteFile} from "@/api/project-demand";
import {ElNotification} from "element-plus"; import {ElNotification} from "element-plus";
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
default: '' default: ''
}, },
tag: { tag: {
type: String, type: String,
default: '' default: ''
}, },
fileNameTableWidth: { fileNameTableWidth: {
type: String, type: String,
default: '400' default: '400'
}, },
value: { value: {
type: Array, type: Array,
default: [] default: []
}, },
processViewer: { processViewer: {
type: Boolean, type: Boolean,
default: false default: false
}, },
labelAlign: { labelAlign: {
type: String, type: String,
default: 'right' default: 'right'
}, },
//弹窗是否铺满全屏 //弹窗是否铺满全屏
fullscreen: { fullscreen: {
type: Boolean, type: Boolean,
default: false default: false
} }
}) })
const emit = defineEmits(['update:value']) const emit = defineEmits(['update:value'])
const tableConfig = reactive({ const tableConfig = reactive({
columns: [ columns: [
{ {
prop: 'index', prop: 'index',
type: 'index', type: 'index',
label: '序号', label: '序号',
align: 'center', align: 'center',
width: 85, width: 85,
}, },
{ {
prop: 'originalFileName', prop: 'originalFileName',
label: '文件名', label: '文件名',
align: 'center', align: 'center',
width: props.fileNameTableWidth, width: props.fileNameTableWidth,
showOverflowTooltip: false, showOverflowTooltip: false,
currentRender: ({row, index}) => (<div style="color: #2a99ff;cursor: pointer;" onClick={()=>clickToPreview(row)}>{row.originalFileName}</div>) currentRender: ({row, index}) => (<div style="color: #2a99ff;cursor: pointer;" onClick={()=>clickToPreview(row)}>{row.originalFileName}</div>)
}, },
{ {
prop: 'tag', prop: 'tag',
label: '标签', label: '标签',
align: 'center' align: 'center'
}, },
{ {
prop: 'size', prop: 'size',
label: '文件大小', label: '文件大小',
align: 'center', align: 'center',
width: 150, width: 150,
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB') currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
}, },
{ {
prop: 'oper', prop: 'oper',
label: '操作', label: '操作',
align: 'center', align: 'center',
showOverflowTooltip: false, showOverflowTooltip: false,
currentRender: ({row, index}) => { currentRender: ({row, index}) => {
let btn = [] let btn = []
btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'}) btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'})
// if (row.newFile) { // if (row.newFile) {
// btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'}) // btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'})
// } // }
return ( return (
<div style={{width: '100%'}}> <div style={{width: '100%'}}>
{ {
btn.map(item => ( btn.map(item => (
<el-button <el-button
type={item.type} type={item.type}
onClick={() => item.func()} onClick={() => item.func()}
link> link>
{item.label} {item.label}
</el-button> </el-button>
)) ))
} }
{ {
row.newFile ? <popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'} row.newFile ? <popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
onDelete={() => handleDelete(row)}/> onDelete={() => handleDelete(row)}/>
: '' : ''
} }
</div> </div>
) )
} }
} }
] ]
}) })
const filePreviewParam = ref({ const filePreviewParam = ref({
fileUrl: '', fileUrl: '',
fileName: '', fileName: '',
fileType: 'pdf' fileType: 'pdf'
}) })
const filePreviewShow = ref(false) const filePreviewShow = ref(false)
const clickToPreview=(row)=>{ const clickToPreview=(row)=>{
filePreviewShow.value = false filePreviewShow.value = false
filePreviewParam.value = { filePreviewParam.value = {
fileUrl: row.url, fileUrl: row.url,
fileName: row.originalFileName, fileName: row.originalFileName,
fileType: row.fileType fileType: row.fileType
} }
nextTick(()=>{ nextTick(()=>{
filePreviewShow.value = true filePreviewShow.value = true
}) })
} }
const _value = computed({ const _value = computed({
get() { get() {
return props.value; return props.value;
}, },
set(val) { set(val) {
emit("update:value", val); emit("update:value", val);
} }
}) })
const getOtherFile = (val) => { const getOtherFile = (val) => {
props.processViewer = false props.processViewer = false
let fileObj = compositeParam(val) let fileObj = compositeParam(val)
_value.value.push(fileObj) _value.value.push(fileObj)
nextTick(() => { nextTick(() => {
props.processViewer = true props.processViewer = true
}) })
} }
const compositeParam = (item, type) => { const compositeParam = (item, type) => {
return { return {
fileId: item.id, fileId: item.id,
size: item.size, size: item.size,
originalFileName: item.originalFilename, originalFileName: item.originalFilename,
fileType: item.fileType, fileType: item.fileType,
url: item.url, url: item.url,
newFile: true, newFile: true,
tag: props.tag tag: props.tag
} }
} }
const handleDownload = (row) => { const handleDownload = (row) => {
downloadFile(row.fileId).then(res => { downloadFile(row.fileId).then(res => {
const blob = new Blob([res]) const blob = new Blob([res])
let a = document.createElement('a') let a = document.createElement('a')
a.href = URL.createObjectURL(blob) a.href = URL.createObjectURL(blob)
a.download = row.originalFileName a.download = row.originalFileName
a.click() a.click()
}) })
} }
const handleDelete = (row) => { const handleDelete = (row) => {
deleteFile(row.fileId).then(res => { deleteFile(row.fileId).then(res => {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.msg, message: res.msg,
type: res.code === 1000 ? 'success' : 'error' type: res.code === 1000 ? 'success' : 'error'
}) })
if (res.code === 1000) { if (res.code === 1000) {
_value.value.splice(_value.value.findIndex((item) => item.fileId === row.fileId), 1); _value.value.splice(_value.value.findIndex((item) => item.fileId === row.fileId), 1);
} }
}); });
} }
watch(() => props.processViewer, (newVal) => { watch(() => props.processViewer, (newVal) => {
props.processViewer = newVal props.processViewer = newVal
}, {deep: true}) }, {deep: true})
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
:deep(.el-table--fit ) { :deep(.el-table--fit ) {
height: 80px !important; height: 80px !important;
} }
:deep(.el-table__header) { :deep(.el-table__header) {
.is-leaf:first-child { .is-leaf:first-child {
.cell { .cell {
margin-left: -25px !important; margin-left: -25px !important;
} }
} }
} }
:deep(.el-table__body) { :deep(.el-table__body) {
.el-table__cell:first-child { .el-table__cell:first-child {
.cell { .cell {
margin-left: -13px !important; margin-left: -13px !important;
} }
} }
} }
</style> </style>

View File

@@ -1,193 +1,210 @@
<template> <template>
<el-upload :file-list="_value" ref="uploadRef" <el-upload :file-list="_value" ref="uploadRef"
action="#" action="#"
:headers="headers" :headers="headers"
:limit="maxSize" :limit="maxSize"
with-credentials with-credentials
:multiple="multiple" :multiple="multiple"
:data="uploadParams" :on-change="handleChange" :data="uploadParams" :on-change="handleChange"
:http-request="customUpload" :http-request="customUpload"
:show-file-list="showFileList" :show-file-list="showFileList"
:auto-upload="false" :auto-upload="false"
:before-upload="beforeUpload" :before-upload="beforeUpload"
:on-success="handleUploadSuccess" :on-error="uploadError"
:on-error="uploadError" :before-remove="beforeRemove"
:before-remove="beforeRemove" :on-remove="handleRemove"
:on-remove="handleRemove" >
> <!-- :on-success="handleUploadSuccess"-->
<el-button color="#DED0B2" :loading="loading" :disabled="disabled">上传文件</el-button> <el-button color="#DED0B2" :loading="loading" :disabled="disabled">上传文件</el-button>
</el-upload> </el-upload>
</template> </template>
<script setup> <script setup>
import {ElLoading, ElMessage, ElMessageBox, ElNotification} from "element-plus"; import {ElLoading, ElMessage, ElMessageBox, ElNotification} from "element-plus";
import {getToken} from '@/utils/auth' import {getToken} from '@/utils/auth'
import {nextTick} from "vue"; import {nextTick} from "vue";
import axios from "axios"; import axios from "axios";
const baseURL = import.meta.env.VITE_BASE_URL const baseURL = import.meta.env.VITE_BASE_URL
const uploadFileUrl = ref(baseURL + "/workflow/process/file/upload") const uploadFileUrl = ref(baseURL + "/workflow/process/file/upload")
const headers = reactive({ const headers = reactive({
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
authorization: getToken() authorization: getToken()
}) })
const loading = ref(false) const loading = ref(false)
const showTable = ref(false) const showTable = ref(false)
const uploadIndex = ref(0) const uploadIndex = ref(0)
const uploadParams = ref({}) const uploadParams = ref({})
const props = defineProps({ const props = defineProps({
value: { value: {
type: Array, type: Array,
default: () => { default: () => {
return [] return []
} }
}, },
maxSize: { maxSize: {
type: Number, type: Number,
default: 999999 default: 999999
}, },
showFileList: { showFileList: {
type: Boolean, type: Boolean,
default: false default: false
}, },
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false default: false
}, },
multiple: { multiple: {
type: Boolean, type: Boolean,
default: true default: true
} }
}) })
const uploadRef = ref(null); // el-upload 的 ref const uploadRef = ref(null); // el-upload 的 ref
const uploadPromises = ref([]); // 跟踪每个文件的上传状态 const uploadPromises = ref([]); // 跟踪每个文件的上传状态
const emit = defineEmits(["input", "beforeUpload","getFile", "delete"]) const emit = defineEmits(["input", "beforeUpload", "getFile", "delete"])
const fileList = ref([]) const fileList = ref([])
const _value = computed({ const _value = computed({
get() { get() {
return props.value; return props.value;
}, },
set(val) { set(val) {
emit("input", val); emit("input", val);
} }
}) })
const beforeRemove = (file) => { const beforeRemove = (file) => {
return ElMessageBox.confirm(`确认删除名称为${file.name}的文件吗?`, '系统提示', { return ElMessageBox.confirm(`确认删除名称为${file.name}的文件吗?`, '系统提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => true) }).then(() => true)
} }
const uploadLoading = ref(false) const uploadLoading = ref(false)
const uploadFile = ref([]) const uploadFile = ref([])
const handleRemove = (file) => { const handleRemove = (file) => {
emit("delete", file.response.data.id) emit("delete", file.response.data.id)
} }
// 文件选择变化时触发 // 文件选择变化时触发
const handleChange = (file, files) => { const handleChange = (file, files) => {
console.log(file, files,'files') const deleteFileRow = JSON.parse(localStorage.getItem('deleteFileRow'));
uploadIndex.value++ console.log("🚀 ~ file:deleteFileRow ", deleteFileRow, uploadFile.value)
uploadFile.value.push(file) let deleteIndex = null
}; if (deleteFileRow) {
watch(() => uploadIndex.value, (newVal) => { deleteIndex = uploadFile.value.findIndex((item) => item.name === deleteFileRow.originalFileName && item.size === deleteFileRow.size)
console.log('newVal',newVal) console.log("🚀 ~ file:deleteIndex ", deleteIndex)
startUpload(uploadFile.value); // 自动触发上传
},{ if (deleteIndex != -1) {
deep: true uploadFile.value.splice(deleteIndex, 1);
}) }
// 自定义上传逻辑 }
const customUpload = async (options) => {
const formData = new FormData();
formData.append('file', options.raw); console.log(file, files, 'files')
try { uploadIndex.value++
const response = await axios.post(uploadFileUrl.value, formData, { uploadFile.value.push(file)
headers: headers, console.log("🚀 ~ file:uploadFile.value ", uploadFile.value)
}); localStorage.removeItem('deleteFileRow')
};
fileList.value.push(response.data.data) watch(() => uploadIndex.value, (newVal) => {
console.log('newVal', newVal)
emit("getFile", response.data.data) startUpload(uploadFile.value); // 自动触发上传
return response.data; // 成功时返回响应 }, {
} catch (error) { deep: true
throw new Error('上传失败'); // 失败时抛出错误 })
} // 自定义上传逻辑
}; const customUpload = async (options) => {
const formData = new FormData();
// 触发所有文件上传 formData.append('file', options.raw);
const startUpload = (files) => { try {
uploadLoading.value= ElLoading.service({ const response = await axios.post(uploadFileUrl.value, formData, {
fullscreen: true, headers: headers,
text: '文件上传中...', });
})
if (files.length === 0) { fileList.value.push(response.data.data)
return; // 没有文件时直接返回
} emit("getFile", response.data.data)
uploadPromises.value = []; // 重置 Promise 数组 return response.data; // 成功时返回响应
files.forEach((file) => { } catch (error) {
// 触发每个文件的上传 throw new Error('上传失败'); // 失败时抛出错误
const promise = new Promise((resolve, reject) => { }
customUpload(file).then(resolve) };
.catch(reject);
}); // 触发所有文件上传
uploadPromises.value.push(promise); const startUpload = (files) => {
}); uploadLoading.value = ElLoading.service({
fullscreen: true,
// 使用 Promise.all 监听所有文件上传完成 text: '文件上传中...',
Promise.all(uploadPromises.value) })
.then(() => { if (files.length === 0) {
ElNotification({ return; // 没有文件时直接返回
title: '提示', }
message: '所有文件上传完成!', uploadPromises.value = []; // 重置 Promise 数组
type: 'success' files.forEach((file) => {
}) // 触发每个文件的上传
files = []; // 清空文件列表 const promise = new Promise((resolve, reject) => {
uploadRef.value.clearFiles(); // 清空上传组件 customUpload(file).then(resolve)
nextTick(() => { .catch(reject);
uploadLoading.value.close() });
uploadLoading.value=null uploadPromises.value.push(promise);
}) });
})
// 使用 Promise.all 监听所有文件上传完成
}; Promise.all(uploadPromises.value)
.then(() => {
const beforeUpload = () => { ElNotification({
loading.value = true title: '提示',
return true message: '所有文件上传完成!',
} type: 'success'
const handleUploadSuccess = (res) => { })
ElNotification({ files = []; // 清空文件列表
title: '提示', uploadRef.value.clearFiles(); // 清空上传组件
message: res.code === 1000 ? '上传成功' : '上传失败', uploadFile.value = [] // 清空文件列表
type: res.code === 1000 ? 'success' : 'error' nextTick(() => {
}) uploadLoading.value.close()
loading.value = false uploadLoading.value = null
showTable.value = true })
let data = res.data })
fileList.value.push(data)
emit("getFile", res.data) };
}
const uploadError = () => { const beforeUpload = () => {
loading.value = false loading.value = true
ElNotification({ return true
title: '提示', }
message: "上传失败,请稍后再试!", const handleUploadSuccess = (res) => {
type: 'error'
}) ElNotification({
} title: '提示',
defineExpose({ message: res.code === 1000 ? '上传成功' : '上传失败',
handleRemove type: res.code === 1000 ? 'success' : 'error'
}) })
</script> loading.value = false
showTable.value = true
<style lang="scss" scoped> let data = res.data
a { fileList.value.push(data)
font-size: 14px; // emit("getFile", res.data)
color: #2a99ff; }
} const uploadError = () => {
loading.value = false
:deep(.el-upload-list) { ElNotification({
width: 400px; title: '提示',
} message: "上传失败,请稍后再试!",
</style> type: 'error'
})
}
defineExpose({
handleRemove
})
</script>
<style lang="scss" scoped>
a {
font-size: 14px;
color: #2a99ff;
}
:deep(.el-upload-list) {
width: 400px;
}
</style>

View File

@@ -1,43 +1,43 @@
<script setup> <script setup>
defineProps({ defineProps({
msg: { msg: {
type: String, type: String,
required: true required: true
} }
}) })
</script> </script>
<template> <template>
<div class="greetings"> <div class="greetings">
<h1 class="green">{{ msg }}</h1> <h1 class="green">{{ msg }}</h1>
<h3> <h3>
Youve successfully created a project with Youve successfully created a project with
<a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> + <a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> +
<a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>. <a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>.
</h3> </h3>
</div> </div>
</template> </template>
<style scoped> <style scoped>
h1 { h1 {
font-weight: 500; font-weight: 500;
font-size: 2.6rem; font-size: 2.6rem;
top: -10px; top: -10px;
} }
h3 { h3 {
font-size: 1.2rem; font-size: 1.2rem;
} }
.greetings h1, .greetings h1,
.greetings h3 { .greetings h3 {
text-align: center; text-align: center;
} }
@media (min-width: 1024px) { @media (min-width: 1024px) {
.greetings h1, .greetings h1,
.greetings h3 { .greetings h3 {
text-align: left; text-align: left;
} }
} }
</style> </style>

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,3 @@
<template> <template>
<router-view></router-view> <router-view></router-view>
</template> </template>

View File

@@ -1,101 +1,101 @@
<template> <template>
<div style="display: flex;justify-content: center"> <div style="display: flex;justify-content: center">
<span class="stateIcon" :style="{backgroundColor: filterDictClass(cacheStore.getDict(dictType), value)}"></span> <span class="stateIcon" :style="{backgroundColor: filterDictClass(cacheStore.getDict(dictType), value)}"></span>
<span>{{tagConfig.label}}</span> <span>{{tagConfig.label}}</span>
<span> {{ filterDict(cacheStore.getDict(dictType), value) }}</span> <span> {{ filterDict(cacheStore.getDict(dictType), value) }}</span>
</div> </div>
</template> </template>
<script setup> <script setup>
import {defineProps} from "vue"; import {defineProps} from "vue";
import {useCacheStore} from "@/stores/cache.js"; import {useCacheStore} from "@/stores/cache.js";
const cacheStore = useCacheStore(); const cacheStore = useCacheStore();
const props = defineProps({ const props = defineProps({
dictType: { dictType: {
type: String, type: String,
default: "" default: ""
}, },
value: { value: {
type: Object, type: Object,
default: null default: null
} }
}); });
const tagConfig = reactive({ const tagConfig = reactive({
listClass: "green", listClass: "green",
isType: true, isType: true,
label: "" label: ""
}); });
const filterDictClass = (data, value) => { const filterDictClass = (data, value) => {
if (!data|| value == null) return 'gray' if (!data|| value == null) return 'gray'
if (data instanceof Array) { if (data instanceof Array) {
tagConfig.value = data.find(item => item.value == value) tagConfig.value = data.find(item => item.value == value)
if (!tagConfig.value) { if (!tagConfig.value) {
return '#409EFF' return '#409EFF'
} else { } else {
if (tagConfig.value?.isType) { if (tagConfig.value?.isType) {
return changeParams(tagConfig.value.listClass) return changeParams(tagConfig.value.listClass)
} else { } else {
return tagConfig.value.listClass return tagConfig.value.listClass
} }
} }
} }
} }
const filterDict = (data, value) => { const filterDict = (data, value) => {
if (!data || value == null) return '未知' if (!data || value == null) return '未知'
if (data instanceof Array) { if (data instanceof Array) {
if (value == true || value == false) { if (value == true || value == false) {
tagConfig.value = data.find(item => item.value == value.toString()) tagConfig.value = data.find(item => item.value == value.toString())
} else if (typeof value === "object") { } else if (typeof value === "object") {
if (value !== null) { if (value !== null) {
tagConfig.value = data.find(item => item.value == value[0]) tagConfig.value = data.find(item => item.value == value[0])
} else { } else {
tagConfig.value = {} tagConfig.value = {}
} }
} else { } else {
tagConfig.value = data.find(item => item.value == value) tagConfig.value = data.find(item => item.value == value)
} }
} }
return tagConfig.value?.label || '未知' return tagConfig.value?.label || '未知'
} }
/** /**
* 根据接口返回的listClass切换成对应的颜色 * 根据接口返回的listClass切换成对应的颜色
* @param listClass 后端返回的listClass字段 * @param listClass 后端返回的listClass字段
* @returns {string} * @returns {string}
*/ */
const changeParams = (listClass) => { const changeParams = (listClass) => {
switch (listClass) { switch (listClass) {
case 'danger': case 'danger':
return 'red' return 'red'
case 'success': case 'success':
return '#67C23A' return '#67C23A'
case 'info': case 'info':
return '#909399' return '#909399'
case 'primary': case 'primary':
return '#409EFF' return '#409EFF'
case 'warning': case 'warning':
return '#E6A23C' return '#E6A23C'
default: default:
return listClass return listClass
} }
} }
// dictFormat() // dictFormat()
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
//.dot{ //.dot{
// width:8px; // width:8px;
// height: 20px; // height: 20px;
// margin-left: -5px; // margin-left: -5px;
// background-color: green; // background-color: green;
// z-index: 99999; // z-index: 99999;
//} //}
:deep(.el-tag){ :deep(.el-tag){
position: relative; position: relative;
margin-top: 9px; margin-top: 9px;
margin-right: 7px; margin-right: 7px;
height: 8px; height: 8px;
} }
</style> </style>

View File

@@ -1,81 +1,81 @@
<template> <template>
<el-popconfirm <el-popconfirm
confirm-button-text="确认" confirm-button-text="确认"
cancel-button-text="取消" cancel-button-text="取消"
icon="WarningFilled" icon="WarningFilled"
icon-color="#E6A23C" icon-color="#E6A23C"
:title="title" :title="title"
@confirm="handleDelete" @confirm="handleDelete"
@cancel="handleCancel" @cancel="handleCancel"
> >
<template #reference> <template #reference>
<el-button :type="btnType" size="mini" :disabled="isDisabled" v-if="perm" v-perm="perm" :icon="btnIcon" :plain="isPlain" :link="link"> <el-button :type="btnType" size="mini" :disabled="isDisabled" v-if="perm" v-perm="perm" :icon="btnIcon" :plain="isPlain" :link="link">
{{ btnText }} {{ btnText }}
</el-button> </el-button>
<el-button :type="btnType" size="mini" :disabled="isDisabled" v-else :icon="btnIcon" :plain="isPlain" :link="link"> <el-button :type="btnType" size="mini" :disabled="isDisabled" v-else :icon="btnIcon" :plain="isPlain" :link="link">
{{ btnText }} {{ btnText }}
</el-button> </el-button>
</template> </template>
</el-popconfirm> </el-popconfirm>
</template> </template>
<script setup> <script setup>
const props = defineProps({ const props = defineProps({
name: { name: {
type: Object, type: Object,
default: null default: null
}, },
btnType: { btnType: {
type: String, type: String,
default: 'danger' default: 'danger'
}, },
type: { type: {
type: String, type: String,
default: '' default: ''
}, },
link: { link: {
type: Boolean, type: Boolean,
default: true default: true
}, },
btnIcon: { btnIcon: {
type: String, type: String,
default: '' default: ''
}, },
btnText: { btnText: {
type: String, type: String,
default: '删除' default: '删除'
}, },
perm: { perm: {
type: Array, type: Array,
default: null default: null
}, },
isDisabled: { isDisabled: {
type: Boolean, type: Boolean,
default: false default: false
}, },
isPlain: { isPlain: {
type: Boolean, type: Boolean,
default: false default: false
}, },
}) })
const emit = defineEmits() const emit = defineEmits()
const title = ref(`确认${props.btnText}名称为"${props.name}"的${props.type}吗!`) const title = ref(`确认${props.btnText}名称为"${props.name}"的${props.type}吗!`)
const visible = ref(false) const visible = ref(false)
watch(() => props.name, (newVal) => { watch(() => props.name, (newVal) => {
title.value = "确认" + props.btnText + "名称为" + '"' + props.name + '"' + "的" + props.type + "吗!" title.value = "确认" + props.btnText + "名称为" + '"' + props.name + '"' + "的" + props.type + "吗!"
}) })
const handleCancel = () => { const handleCancel = () => {
visible.value = false visible.value = false
} }
const handleDelete = () => { const handleDelete = () => {
emit("delete") emit("delete")
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.el-popconfirm__main { .el-popconfirm__main {
display: flex; display: flex;
word-break: break-all; word-break: break-all;
align-items: center; align-items: center;
} }
</style> </style>

View File

@@ -1,275 +1,275 @@
<template> <template>
<div v-loading="_value"> <div v-loading="_value">
<el-form :model="attachment" inline style="margin-left: 15px" @submit.prevent="handleSearch"> <el-form :model="attachment" inline style="margin-left: 15px" @submit.prevent="handleSearch">
<el-form-item label="名称" prop="fileName"> <el-form-item label="名称" prop="fileName">
<el-input v-model="attachment.fileName" placeholder="请输入文件名查询" clearable filterable style="width: 300px"/> <el-input v-model="attachment.fileName" placeholder="请输入文件名查询" clearable filterable style="width: 300px"/>
</el-form-item> </el-form-item>
<el-form-item label="项目阶段" prop="targetState" v-if="allFile"> <el-form-item label="项目阶段" prop="targetState" v-if="allFile">
<el-select v-model="attachment.targetState" placeholder="请选择项目阶段" clearable filterable style="width: 300px"> <el-select v-model="attachment.targetState" placeholder="请选择项目阶段" clearable filterable style="width: 300px">
<el-option <el-option
v-for="item in cacheStore.getDict('archive_file_type')" v-for="item in cacheStore.getDict('archive_file_type')"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="标签" prop="tag" v-if="type==='30'"> <el-form-item label="标签" prop="tag" v-if="type==='30'">
<el-select v-model="attachment.tag" placeholder="请选择标签" clearable filterable style="width: 300px"> <el-select v-model="attachment.tag" placeholder="请选择标签" clearable filterable style="width: 300px">
<el-option <el-option
v-for="item in tagsOption" v-for="item in tagsOption"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="handleSearch" color="#DED0B2">搜索</el-button> <el-button @click="handleSearch" color="#DED0B2">搜索</el-button>
<el-button @click="handleReset">重置</el-button> <el-button @click="handleReset">重置</el-button>
<el-button v-if="uploadState&&!allFile" color="#DED0B2" @click="handleUpload">上传附件</el-button> <el-button v-if="uploadState&&!allFile" color="#DED0B2" @click="handleUpload">上传附件</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-card style="width: 100%;overflow-y: hidden"> <el-card style="width: 100%;overflow-y: hidden">
<fvTable style="width: 100%;max-height: 318px" v-if="showTable" height="318" :tableConfig="allFile?tableConfigAll:tableConfig" <fvTable style="width: 100%;max-height: 318px" v-if="showTable" height="318" :tableConfig="allFile?tableConfigAll:tableConfig"
:data="fileList" :isSettingCol="false" :pagination="false"> :data="fileList" :isSettingCol="false" :pagination="false">
<template #empty> <template #empty>
<el-empty :image-size="99" description="暂无数据" style="padding: 0"/> <el-empty :image-size="99" description="暂无数据" style="padding: 0"/>
</template> </template>
</fvTable> </fvTable>
</el-card> </el-card>
<file-preview ref="filePreviewRef" v-if="filePreviewShow" :fileName="filePreviewParam.fileName" :fileUrl="filePreviewParam.fileUrl" <file-preview ref="filePreviewRef" v-if="filePreviewShow" :fileName="filePreviewParam.fileName" :fileUrl="filePreviewParam.fileUrl"
:fileType="filePreviewParam.fileType"/> :fileType="filePreviewParam.fileType"/>
</div> </div>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import {downloadFile} from "@/api/project-demand"; import {downloadFile} from "@/api/project-demand";
import {ElNotification} from "element-plus"; import {ElNotification} from "element-plus";
import {getTags} from "@/api/project-manage"; import {getTags} from "@/api/project-manage";
import {computed, ref} from "vue"; import {computed, ref} from "vue";
import {useCacheStore} from '@/stores/cache.js' import {useCacheStore} from '@/stores/cache.js'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const cacheStore = useCacheStore() const cacheStore = useCacheStore()
const attachment = reactive({}) const attachment = reactive({})
const emit = defineEmits(['search','update:modelValue']) const emit = defineEmits(['search','update:modelValue'])
const props = defineProps({ const props = defineProps({
fileList: { fileList: {
type: Array, type: Array,
default: [] default: []
}, },
type: { type: {
type: String, type: String,
default: '00' default: '00'
}, },
uploadState: { uploadState: {
type: Boolean, type: Boolean,
default: false default: false
}, },
loading: { loading: {
type: Boolean, type: Boolean,
default: true default: true
}, },
allFile: { allFile: {
type: Boolean, type: Boolean,
default: false default: false
} }
}) })
const tagsOption = ref([]) const tagsOption = ref([])
const tableConfig = reactive({ const tableConfig = reactive({
columns: [ columns: [
{ {
prop: 'index', prop: 'index',
type: 'index', type: 'index',
label: '序号', label: '序号',
align: 'center', align: 'center',
width:85, width:85,
}, },
{ {
prop: 'originalFileName', prop: 'originalFileName',
label: '文件名', label: '文件名',
align: 'center', align: 'center',
currentRender: ({row, index}) => (<div style="color: #2a99ff;cursor: pointer;" onClick={()=>clickToPreview(row)}>{row.originalFileName}</div>) currentRender: ({row, index}) => (<div style="color: #2a99ff;cursor: pointer;" onClick={()=>clickToPreview(row)}>{row.originalFileName}</div>)
}, },
{ {
prop: 'tag', prop: 'tag',
label:'标签', label:'标签',
align: 'center' align: 'center'
}, },
{ {
prop: 'size', prop: 'size',
label: '文件大小', label: '文件大小',
align: 'center', align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB') currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
}, },
{ {
prop: 'createTime', prop: 'createTime',
label: '上传时间', label: '上传时间',
align: 'center', align: 'center',
}, },
{ {
prop: 'oper', prop: 'oper',
label: '操作', label: '操作',
align: 'center', align: 'center',
showOverflowTooltip: false, showOverflowTooltip: false,
currentRender: ({row, index}) => { currentRender: ({row, index}) => {
return ( return (
<div> <div>
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button> <el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
</div> </div>
) )
} }
} }
] ]
}) })
const tableConfigAll = reactive({ const tableConfigAll = reactive({
columns: [ columns: [
{ {
prop: 'index', prop: 'index',
type: 'index', type: 'index',
label: '序号', label: '序号',
align: 'center', align: 'center',
width:85, width:85,
}, },
{ {
prop: 'originalFileName', prop: 'originalFileName',
label: '文件名', label: '文件名',
align: 'center', align: 'center',
currentRender: ({row, index}) => (<div style="color: #2a99ff;cursor: pointer;" onClick={()=>clickToPreview(row)}>{row.originalFileName}</div>) currentRender: ({row, index}) => (<div style="color: #2a99ff;cursor: pointer;" onClick={()=>clickToPreview(row)}>{row.originalFileName}</div>)
}, },
{ {
prop: 'targetState', prop: 'targetState',
label:'项目阶段', label:'项目阶段',
align: 'center', align: 'center',
showOverflowTooltip: false, showOverflowTooltip: false,
currentRender: ({row, index}) => { currentRender: ({row, index}) => {
if (row.targetState&&row.targetState !== null&&row.targetState!==undefined) { if (row.targetState&&row.targetState !== null&&row.targetState!==undefined) {
return (<Tag dictType={'archive_file_type'} value={row.targetState}/>) return (<Tag dictType={'archive_file_type'} value={row.targetState}/>)
} else { } else {
return '--' return '--'
} }
} }
}, },
{ {
prop: 'tag', prop: 'tag',
label:'标签', label:'标签',
align: 'center' align: 'center'
}, },
{ {
prop: 'size', prop: 'size',
label: '文件大小', label: '文件大小',
align: 'center', align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB') currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
}, },
{ {
prop: 'createTime', prop: 'createTime',
label: '上传时间', label: '上传时间',
align: 'center', align: 'center',
}, },
{ {
prop: 'oper', prop: 'oper',
label: '操作', label: '操作',
align: 'center', align: 'center',
showOverflowTooltip: false, showOverflowTooltip: false,
currentRender: ({row, index}) => { currentRender: ({row, index}) => {
return ( return (
<div> <div>
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button> <el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
</div> </div>
) )
} }
} }
] ]
}) })
const showTable = ref(true) const showTable = ref(true)
const _value = computed({ const _value = computed({
get() { get() {
return props.loading || "" return props.loading || ""
}, },
set(value) { set(value) {
emit('update:modelValue', value) emit('update:modelValue', value)
} }
}) })
const filePreviewParam = ref({ const filePreviewParam = ref({
fileUrl: '', fileUrl: '',
fileName: '', fileName: '',
fileType: 'pdf' fileType: 'pdf'
}) })
const filePreviewShow = ref(false) const filePreviewShow = ref(false)
const clickToPreview=(row)=>{ const clickToPreview=(row)=>{
filePreviewShow.value = false filePreviewShow.value = false
filePreviewParam.value = { filePreviewParam.value = {
fileUrl: row.url, fileUrl: row.url,
fileName: row.originalFileName, fileName: row.originalFileName,
fileType: row.fileType fileType: row.fileType
} }
nextTick(()=>{ nextTick(()=>{
filePreviewShow.value = true filePreviewShow.value = true
}) })
} }
const getTagsOption = () => { const getTagsOption = () => {
if (!route.query.id) return if (!route.query.id) return
getTags(route.query.id).then(res => { getTags(route.query.id).then(res => {
if (res.code === 1000) { if (res.code === 1000) {
tagsOption.value = res.data tagsOption.value = res.data
} else { } else {
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.msg, message: res.msg,
type: 'error' type: 'error'
}) })
} }
}) })
} }
const handleSearch = () => { const handleSearch = () => {
emit('search', attachment) emit('search', attachment)
} }
const handleReset=()=>{ const handleReset=()=>{
attachment.fileName='' attachment.fileName=''
attachment.targetState='' attachment.targetState=''
attachment.tag=null attachment.tag=null
emit('search', {}) emit('search', {})
} }
const handleUpload = () => { const handleUpload = () => {
emit('upload') emit('upload')
} }
const handleDownload = (row) => { const handleDownload = (row) => {
downloadFile(row.fileId).then(res => { downloadFile(row.fileId).then(res => {
const blob = new Blob([res]) const blob = new Blob([res])
let a = document.createElement('a') let a = document.createElement('a')
a.href = URL.createObjectURL(blob) a.href = URL.createObjectURL(blob)
a.download = row.originalFileName a.download = row.originalFileName
a.click() a.click()
}) })
} }
watch(() => props.type, (val) => { watch(() => props.type, (val) => {
props.type = val props.type = val
}) })
watch(() => props.fileList, (val) => { watch(() => props.fileList, (val) => {
showTable.value = false showTable.value = false
nextTick(() => { nextTick(() => {
showTable.value = true showTable.value = true
}) })
props.fileList = val props.fileList = val
}) })
if (props.type === '30') { if (props.type === '30') {
getTagsOption() getTagsOption()
} }
onActivated(()=>{ onActivated(()=>{
if (props.type === '30') { if (props.type === '30') {
getTagsOption() getTagsOption()
} }
handleSearch() handleSearch()
}) })
</script> </script>
<style scoped> <style scoped>
:deep(.el-table--fit ) { :deep(.el-table--fit ) {
height: 318px !important; height: 318px !important;
} }
</style> </style>

View File

@@ -1,226 +1,226 @@
<template> <template>
<div style="display: flex;align-items: center;flex-wrap: wrap;"> <div style="display: flex;align-items: center;flex-wrap: wrap;">
<el-button color="#DED0B2" @click="handleShowPreTable" style="margin-right: 10px"> <el-button color="#DED0B2" @click="handleShowPreTable" style="margin-right: 10px">
{{ {{
localFormData.preProcess && localFormData.preProcess.length > 0 ? '更改' : '请选择前置流程' localFormData.preProcess && localFormData.preProcess.length > 0 ? '更改' : '请选择前置流程'
}} }}
</el-button> </el-button>
<div v-for="(item,index) in localFormData.preProcess" :key="item.requestId"> <div v-for="(item,index) in localFormData.preProcess" :key="item.requestId">
<a :href="item.baseUrl" target="_blank" <a :href="item.baseUrl" target="_blank"
style="color: #2a99ff;cursor: pointer">{{ item.requestName }}<span style="color: #2a99ff;cursor: pointer">{{ item.requestName }}<span
v-if="index != localFormData.preProcess.length -1"></span> v-if="index != localFormData.preProcess.length -1"></span>
</a> </a>
</div> </div>
</div> </div>
<el-dialog v-if="showPreTable" title="前置流程" v-model="showPreTable" width="80%"> <el-dialog v-if="showPreTable" title="前置流程" v-model="showPreTable" width="80%">
<el-form :model="preProcessForm" inline @submit.prevent="getPreProcessList"> <el-form :model="preProcessForm" inline @submit.prevent="getPreProcessList">
<el-form-item label="请求名称"> <el-form-item label="请求名称">
<el-input v-model="preProcessForm.requestName" placeholder="请输入请求名称" clearable> <el-input v-model="preProcessForm.requestName" placeholder="请输入请求名称" clearable>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button color="#DED0B2" @click="getPreProcessList">搜索</el-button> <el-button color="#DED0B2" @click="getPreProcessList">搜索</el-button>
<el-button @click="handleReset">重置</el-button> <el-button @click="handleReset">重置</el-button>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-tag type="danger" style="font-size: 16px;color: red;" >特别提示{{ getPreProcessTag(localFormData.projectImpact,basicData.projectImpact) }}</el-tag> <el-tag type="danger" style="font-size: 16px;color: red;" >特别提示{{ getPreProcessTag(localFormData.projectImpact,basicData.projectImpact) }}</el-tag>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-table :data="preProcessList" v-loading="loading" <el-table :data="preProcessList" v-loading="loading"
@select="handleSelect" @select-all="handleSelect" row-key="requestId" ref="preProcessTable"> @select="handleSelect" @select-all="handleSelect" row-key="requestId" ref="preProcessTable">
<el-table-column type="selection" width="55" :reserve-selection="true" <el-table-column type="selection" width="55" :reserve-selection="true"
:selectable="checkSelectable"/> :selectable="checkSelectable"/>
<el-table-column prop="requestId" label="请求id"></el-table-column> <el-table-column prop="requestId" label="请求id"></el-table-column>
<el-table-column prop="requestName" label="请求名称"></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="lastOperatorName" label="最后操作人名称"></el-table-column>
<el-table-column prop="lastOperateTime" 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="currentNodeName" label="当前节点"></el-table-column>
<el-table-column prop="creatorName" 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 prop="createTime" label="创建时间"></el-table-column>
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template #default="scope"> <template #default="scope">
<a :href="scope.row.baseUrl" target="_blank" style="color: #2a99ff;margin-left: 10px">查看流程</a> <a :href="scope.row.baseUrl" target="_blank" style="color: #2a99ff;margin-left: 10px">查看流程</a>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<paging :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :page-sizes="[10, 20, 30, 40,50]" <paging :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :page-sizes="[10, 20, 30, 40,50]"
:total="total" @changeSize="handleSizeChange" @goPage="handleCurrentChange"/> :total="total" @changeSize="handleSizeChange" @goPage="handleCurrentChange"/>
<div class="oper"> <div class="oper">
<el-button color="#DED0B2" @click="choosePreProcess">确定</el-button> <el-button color="#DED0B2" @click="choosePreProcess">确定</el-button>
<el-button @click="handleCancel">取消</el-button> <el-button @click="handleCancel">取消</el-button>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import { import {
getPreProcess getPreProcess
} from "@/api/project-manage"; } from "@/api/project-manage";
import Paging from "@/components/pagination/index.vue"; import Paging from "@/components/pagination/index.vue";
const props = defineProps({ const props = defineProps({
formData: { formData: {
type: Object, type: Object,
default: {} default: {}
}, },
basicData: { basicData: {
type: Object, type: Object,
default: {} default: {}
}, },
}) })
const loading = ref(false) const loading = ref(false)
//暂存数据 //暂存数据
const originalProcess = ref([]) const originalProcess = ref([])
const currentList = ref([]) const currentList = ref([])
const showPreTable = ref(false) const showPreTable = ref(false)
const selectRows = ref([]) const selectRows = ref([])
const preProcessList = ref([]) const preProcessList = ref([])
const total = ref(0) const total = ref(0)
const preProcessTable = ref() const preProcessTable = ref()
const localFormData = ref({ const localFormData = ref({
projectPersonIds: [], projectPersonIds: [],
projectChargePerson: null, projectChargePerson: null,
preProcess: [ preProcess: [
// { // {
// requestId: null, // requestId: null,
// requestName: '', // requestName: '',
// baseUrl: '' // baseUrl: ''
// } // }
] ]
}) })
const preProcessForm = reactive({ const preProcessForm = reactive({
requestName: '' requestName: ''
}) })
const pageInfo = reactive({ const pageInfo = reactive({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
}) })
const getPreProcessTag = (impact,basicImpact) => { const getPreProcessTag = (impact,basicImpact) => {
let data='' let data=''
if(impact){ if(impact){
data= impact data= impact
}else if(basicImpact){ }else if(basicImpact){
data= basicImpact data= basicImpact
} }
if (data == 1) { if (data == 1) {
//一般项目 //一般项目
return '研发费用20万元以下科技创新项目报总经理审批' return '研发费用20万元以下科技创新项目报总经理审批'
} else if (data == 2) { } else if (data == 2) {
//重大项目 //重大项目
return '重大项目20万元到500万元之间要总办会审批' return '重大项目20万元到500万元之间要总办会审批'
} else if (data == 3) { } else if (data == 3) {
//特别重大项目 //特别重大项目
return '特别重大项目500万元以上要董事会审批' return '特别重大项目500万元以上要董事会审批'
} }
} }
const handleReset = () => { const handleReset = () => {
preProcessForm.requestName = '' preProcessForm.requestName = ''
getPreProcessList() getPreProcessList()
} }
const handleSelect = async (selection) => { const handleSelect = async (selection) => {
selectRows.value = selection selectRows.value = selection
} }
const checkSelectable=(row)=>{ const checkSelectable=(row)=>{
const detailProcessStr = localStorage.getItem('detailProcess'); const detailProcessStr = localStorage.getItem('detailProcess');
let preProcessArray = [] let preProcessArray = []
if (detailProcessStr) { if (detailProcessStr) {
try { try {
preProcessArray = JSON.parse(detailProcessStr) preProcessArray = JSON.parse(detailProcessStr)
} catch (e) { } catch (e) {
preProcessArray=[] preProcessArray=[]
} }
if (preProcessArray&&preProcessArray.length > 0) { if (preProcessArray&&preProcessArray.length > 0) {
for (let i = 0; i < preProcessArray.length; i++) { for (let i = 0; i < preProcessArray.length; i++) {
return preProcessArray[i].requestId !== row.requestId; return preProcessArray[i].requestId !== row.requestId;
} }
}else{ }else{
return true return true
} }
} }
} }
const handleShowPreTable = () => { const handleShowPreTable = () => {
showPreTable.value = true showPreTable.value = true
nextTick(() => { nextTick(() => {
localFormData.value.preProcess?.forEach((item) => { localFormData.value.preProcess?.forEach((item) => {
if (preProcessTable.value) { if (preProcessTable.value) {
preProcessTable.value.toggleRowSelection(item, true) preProcessTable.value.toggleRowSelection(item, true)
} }
}) })
}) })
getPreProcessList() getPreProcessList()
} }
const handleCancel = () => { const handleCancel = () => {
showPreTable.value = false showPreTable.value = false
} }
const choosePreProcess = () => { const choosePreProcess = () => {
let preProcessObj = {} let preProcessObj = {}
let preProcessArray = [] let preProcessArray = []
const detailProcessStr = localStorage.getItem('detailProcess'); const detailProcessStr = localStorage.getItem('detailProcess');
try { try {
originalProcess.value = JSON.parse(detailProcessStr) originalProcess.value = JSON.parse(detailProcessStr)
} catch (e) { } catch (e) {
originalProcess.value=[] originalProcess.value=[]
} }
selectRows.value.forEach((item) => { selectRows.value.forEach((item) => {
const exists = originalProcess.value?.some(dp => dp.requestId === item.requestId) const exists = originalProcess.value?.some(dp => dp.requestId === item.requestId)
if (!exists) { if (!exists) {
preProcessObj = { preProcessObj = {
requestId: item.requestId, requestId: item.requestId,
requestName: item.requestName, requestName: item.requestName,
baseUrl: item.baseUrl baseUrl: item.baseUrl
} }
preProcessArray.push(preProcessObj) preProcessArray.push(preProcessObj)
} }
}) })
if(props.formData.mode === 'view'||props.formData.mode === 'resubmit'){ if(props.formData.mode === 'view'||props.formData.mode === 'resubmit'){
localFormData.value.preProcess = [...originalProcess.value,...preProcessArray] localFormData.value.preProcess = [...originalProcess.value,...preProcessArray]
}else{ }else{
localFormData.value.preProcess = preProcessArray localFormData.value.preProcess = preProcessArray
} }
localStorage.setItem('preProcess', JSON.stringify(preProcessArray)) localStorage.setItem('preProcess', JSON.stringify(preProcessArray))
showPreTable.value = false showPreTable.value = false
} }
const getPreProcessList = () => { const getPreProcessList = () => {
loading.value = true loading.value = true
getPreProcess().then(res => { getPreProcess().then(res => {
loading.value = false loading.value = false
let searchArray = [] let searchArray = []
let regexPattern = ("%" + preProcessForm.requestName + "%").replace(/%/g, '.*').replace(/_/g, '.'); let regexPattern = ("%" + preProcessForm.requestName + "%").replace(/%/g, '.*').replace(/_/g, '.');
let regex = new RegExp('^' + regexPattern + '$'); let regex = new RegExp('^' + regexPattern + '$');
res.data.filter((item) => { res.data.filter((item) => {
if (regex.test(item.requestName)) { if (regex.test(item.requestName)) {
searchArray.push(item) searchArray.push(item)
} }
}) })
total.value = searchArray.length total.value = searchArray.length
currentList.value = searchArray currentList.value = searchArray
preProcessList.value = currentList.value.slice(0, 10) preProcessList.value = currentList.value.slice(0, 10)
}) })
} }
//切换每页显示条数 //切换每页显示条数
const handleSizeChange = (val) => { const handleSizeChange = (val) => {
pageInfo.pageSize = val; pageInfo.pageSize = val;
preProcessList.value = currentList.value.slice((pageInfo.pageNum - 1) * val, pageInfo.pageNum * val) preProcessList.value = currentList.value.slice((pageInfo.pageNum - 1) * val, pageInfo.pageNum * val)
}; };
//点击页码进行分页功能 //点击页码进行分页功能
const handleCurrentChange = (val) => { const handleCurrentChange = (val) => {
pageInfo.pageNum = val; pageInfo.pageNum = val;
preProcessList.value = currentList.value.slice((val - 1) * pageInfo.pageSize, val * pageInfo.pageSize) preProcessList.value = currentList.value.slice((val - 1) * pageInfo.pageSize, val * pageInfo.pageSize)
}; };
watchEffect(() => { watchEffect(() => {
return Object.keys(props.formData).length && (localFormData.value = props.formData) return Object.keys(props.formData).length && (localFormData.value = props.formData)
}) })
</script> </script>
<style scoped> <style scoped>
.oper { .oper {
margin-top: 20px; margin-top: 20px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
} }
</style> </style>

View File

@@ -1,63 +1,63 @@
<template> <template>
<div class="tag-style"> <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) }} {{ filterDict(cacheStore.getDict(dictType), value) }}
</el-tag> </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}"> :class="{'null-tag':filterDict(cacheStore.getDict(dictType), value)===undefined}">
{{ filterDict(cacheStore.getDict(dictType), value) }} {{ filterDict(cacheStore.getDict(dictType), value) }}
</el-tag> </el-tag>
</div> </div>
</template> </template>
<script setup> <script setup>
import {useCacheStore} from "@/stores/cache.js"; import {useCacheStore} from "@/stores/cache.js";
import {defineProps, nextTick} from "vue"; import {defineProps, nextTick} from "vue";
const cacheStore = useCacheStore(); const cacheStore = useCacheStore();
const props = defineProps({ const props = defineProps({
dictType: { dictType: {
type: String, type: String,
default: "", default: "",
required: true required: true
}, },
value: { value: {
type: String || Number, type: String || Number,
default: null default: null
} }
}); });
const tagConfig = ref({}) const tagConfig = ref({})
const filterDict = (data, value) => { const filterDict = (data, value) => {
if (!data || value == null) return if (!data || value == null) return
if (data instanceof Array) { if (data instanceof Array) {
if (value == true || value == false) { if (value == true || value == false) {
tagConfig.value = data.find(item => item.value == value.toString()) tagConfig.value = data.find(item => item.value == value.toString())
} else if (typeof value === "object") { } else if (typeof value === "object") {
if (value !== null) { if (value !== null) {
tagConfig.value = data.find(item => item.value == value[0]) tagConfig.value = data.find(item => item.value == value[0])
} else { } else {
tagConfig.value = {} tagConfig.value = {}
} }
} else { } else {
tagConfig.value = data.find(item => item.value == value) tagConfig.value = data.find(item => item.value == value)
} }
} }
return tagConfig.value?.label || '未知' return tagConfig.value?.label || '未知'
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.tag-style { .tag-style {
:deep(.el-tag.el-tag--dark) { :deep(.el-tag.el-tag--dark) {
border-color: transparent !important; border-color: transparent !important;
} }
.null-tag { .null-tag {
border-color: transparent; border-color: transparent;
background-color: transparent; background-color: transparent;
} }
} }
</style> </style>

View File

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

View File

@@ -1,86 +1,86 @@
<script setup> <script setup>
import WelcomeItem from './WelcomeItem.vue' import WelcomeItem from './WelcomeItem.vue'
import DocumentationIcon from './icons/IconDocumentation.vue' import DocumentationIcon from './icons/IconDocumentation.vue'
import ToolingIcon from './icons/IconTooling.vue' import ToolingIcon from './icons/IconTooling.vue'
import EcosystemIcon from './icons/IconEcosystem.vue' import EcosystemIcon from './icons/IconEcosystem.vue'
import CommunityIcon from './icons/IconCommunity.vue' import CommunityIcon from './icons/IconCommunity.vue'
import SupportIcon from './icons/IconSupport.vue' import SupportIcon from './icons/IconSupport.vue'
</script> </script>
<template> <template>
<WelcomeItem> <WelcomeItem>
<template #icon> <template #icon>
<DocumentationIcon /> <DocumentationIcon />
</template> </template>
<template #heading>Documentation</template> <template #heading>Documentation</template>
Vues Vues
<a href="https://vuejs.org/" target="_blank" rel="noopener">official documentation</a> <a href="https://vuejs.org/" target="_blank" rel="noopener">official documentation</a>
provides you with all information you need to get started. provides you with all information you need to get started.
</WelcomeItem> </WelcomeItem>
<WelcomeItem> <WelcomeItem>
<template #icon> <template #icon>
<ToolingIcon /> <ToolingIcon />
</template> </template>
<template #heading>Tooling</template> <template #heading>Tooling</template>
This project is served and bundled with This project is served and bundled with
<a href="https://vitejs.dev/guide/features.html" target="_blank" rel="noopener">Vite</a>. The <a href="https://vitejs.dev/guide/features.html" target="_blank" rel="noopener">Vite</a>. The
recommended IDE setup is recommended IDE setup is
<a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VSCode</a> + <a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VSCode</a> +
<a href="https://github.com/johnsoncodehk/volar" target="_blank" rel="noopener">Volar</a>. If <a href="https://github.com/johnsoncodehk/volar" target="_blank" rel="noopener">Volar</a>. If
you need to test your components and web pages, check out you need to test your components and web pages, check out
<a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a> and <a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a> and
<a href="https://on.cypress.io/component" target="_blank">Cypress Component Testing</a>. <a href="https://on.cypress.io/component" target="_blank">Cypress Component Testing</a>.
<br /> <br />
More instructions are available in <code>README.md</code>. More instructions are available in <code>README.md</code>.
</WelcomeItem> </WelcomeItem>
<WelcomeItem> <WelcomeItem>
<template #icon> <template #icon>
<EcosystemIcon /> <EcosystemIcon />
</template> </template>
<template #heading>Ecosystem</template> <template #heading>Ecosystem</template>
Get official tools and libraries for your project: Get official tools and libraries for your project:
<a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>, <a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>,
<a href="https://router.vuejs.org/" target="_blank" rel="noopener">Vue Router</a>, <a href="https://router.vuejs.org/" target="_blank" rel="noopener">Vue Router</a>,
<a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener">Vue Test Utils</a>, and <a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener">Vue Test Utils</a>, and
<a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener">Vue Dev Tools</a>. If <a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener">Vue Dev Tools</a>. If
you need more resources, we suggest paying you need more resources, we suggest paying
<a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">Awesome Vue</a> <a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">Awesome Vue</a>
a visit. a visit.
</WelcomeItem> </WelcomeItem>
<WelcomeItem> <WelcomeItem>
<template #icon> <template #icon>
<CommunityIcon /> <CommunityIcon />
</template> </template>
<template #heading>Community</template> <template #heading>Community</template>
Got stuck? Ask your question on Got stuck? Ask your question on
<a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a>, our official <a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a>, our official
Discord server, or Discord server, or
<a href="https://stackoverflow.com/questions/tagged/vue.js" target="_blank" rel="noopener" <a href="https://stackoverflow.com/questions/tagged/vue.js" target="_blank" rel="noopener"
>StackOverflow</a >StackOverflow</a
>. You should also subscribe to >. You should also subscribe to
<a href="https://news.vuejs.org" target="_blank" rel="noopener">our mailing list</a> and follow <a href="https://news.vuejs.org" target="_blank" rel="noopener">our mailing list</a> and follow
the official the official
<a href="https://twitter.com/vuejs" target="_blank" rel="noopener">@vuejs</a> <a href="https://twitter.com/vuejs" target="_blank" rel="noopener">@vuejs</a>
twitter account for latest news in the Vue world. twitter account for latest news in the Vue world.
</WelcomeItem> </WelcomeItem>
<WelcomeItem> <WelcomeItem>
<template #icon> <template #icon>
<SupportIcon /> <SupportIcon />
</template> </template>
<template #heading>Support Vue</template> <template #heading>Support Vue</template>
As an independent project, Vue relies on community backing for its sustainability. You can help As an independent project, Vue relies on community backing for its sustainability. You can help
us by us by
<a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener">becoming a sponsor</a>. <a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener">becoming a sponsor</a>.
</WelcomeItem> </WelcomeItem>
</template> </template>

View File

@@ -1,286 +1,286 @@
<template> <template>
<div class="tinymce-boxz" style="width: 100%"> <div class="tinymce-boxz" style="width: 100%">
<Editor v-model="content" :init="init"/> <Editor v-model="content" :init="init"/>
</div> </div>
</template> </template>
<script setup> <script setup>
import tinymce from 'tinymce' import tinymce from 'tinymce'
import Editor from "@tinymce/tinymce-vue"; import Editor from "@tinymce/tinymce-vue";
import {defineProps} from "vue"; import {defineProps} from "vue";
import {ElLoading, ElMessage, ElNotification} from "element-plus"; import {ElLoading, ElMessage, ElNotification} from "element-plus";
import {getToken} from '@/utils/auth' import {getToken} from '@/utils/auth'
import axios from "axios"; import axios from "axios";
import 'tinymce/themes/silver' import 'tinymce/themes/silver'
import 'tinymce/icons/default/icons' import 'tinymce/icons/default/icons'
import 'tinymce/plugins/preview' import 'tinymce/plugins/preview'
import 'tinymce/plugins/searchreplace' import 'tinymce/plugins/searchreplace'
import 'tinymce/plugins/autolink' import 'tinymce/plugins/autolink'
import 'tinymce/plugins/directionality' import 'tinymce/plugins/directionality'
import 'tinymce/plugins/visualblocks' import 'tinymce/plugins/visualblocks'
import 'tinymce/plugins/visualchars' import 'tinymce/plugins/visualchars'
import 'tinymce/plugins/advlist' import 'tinymce/plugins/advlist'
import 'tinymce/plugins/fullscreen' import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/image' import 'tinymce/plugins/image'
import 'tinymce/plugins/link' import 'tinymce/plugins/link'
import 'tinymce/plugins/media' import 'tinymce/plugins/media'
import 'tinymce/plugins/template' import 'tinymce/plugins/template'
import 'tinymce/plugins/code' import 'tinymce/plugins/code'
import 'tinymce/plugins/codesample' import 'tinymce/plugins/codesample'
import 'tinymce/plugins/table' import 'tinymce/plugins/table'
import 'tinymce/plugins/pagebreak' import 'tinymce/plugins/pagebreak'
import 'tinymce/plugins/nonbreaking' import 'tinymce/plugins/nonbreaking'
import 'tinymce/plugins/anchor' import 'tinymce/plugins/anchor'
import 'tinymce/plugins/insertdatetime' import 'tinymce/plugins/insertdatetime'
import 'tinymce/plugins/lists' import 'tinymce/plugins/lists'
import 'tinymce/plugins/wordcount' import 'tinymce/plugins/wordcount'
import 'tinymce/plugins/autosave' import 'tinymce/plugins/autosave'
import '@/assets/axupimgs/plugin.js'//多图上传插件 import '@/assets/axupimgs/plugin.js'//多图上传插件
const emit = defineEmits(['update:value','getFiles']) const emit = defineEmits(['update:value','getFiles'])
const props = defineProps({ const props = defineProps({
//默认值 //默认值
value: { value: {
type: String, type: String,
default: "", default: "",
}, },
imageUrl: { imageUrl: {
type: String, type: String,
default: "", default: "",
}, },
fileUrl: { fileUrl: {
type: String, type: String,
default: "", default: "",
}, },
plugins: { plugins: {
type: [String, Array], type: [String, Array],
default: default:
"preview searchreplace autolink directionality visualblocks visualchars fullscreen image axupimgs link media template code codesample table pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave", "preview searchreplace autolink directionality visualblocks visualchars fullscreen image axupimgs link media template code codesample table pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave",
}, },
toolbar: { toolbar: {
type: [String, Array], type: [String, Array],
default: [ default: [
"fullscreen undo redo | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | bullist numlist | blockquote subscript superscript removeformat ", "fullscreen undo redo | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | bullist numlist | blockquote subscript superscript removeformat ",
"styleselect formatselect fontselect fontsizeselect | table image axupimgs media pagebreak insertdatetime selectall visualblocks searchreplace | code preview | indent2em lineheight formatpainter", "styleselect formatselect fontselect fontsizeselect | table image axupimgs media pagebreak insertdatetime selectall visualblocks searchreplace | code preview | indent2em lineheight formatpainter",
], ],
}, },
fontFormats: { fontFormats: {
type: [String, Array], type: [String, Array],
default: "微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;" default: "微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;"
}, },
width: { width: {
type: String, type: String,
default: 'auto' default: 'auto'
}, },
height: { height: {
type: Number, type: Number,
default: 500 default: 500
} }
}) })
const fileLists=ref([]) const fileLists=ref([])
const content = ref(props.value); const content = ref(props.value);
const imgUrl = ref(); const imgUrl = ref();
// const apiKey = reactive("v4zo4n22oanvco29ws5drh0pecuf3gh53clx53cccj3grjwg"); // const apiKey = reactive("v4zo4n22oanvco29ws5drh0pecuf3gh53clx53cccj3grjwg");
const init = reactive({ const init = reactive({
language_url: '/langs/zh_CN.js', //汉化路径是自定义的 language_url: '/langs/zh_CN.js', //汉化路径是自定义的
skin_url: '/skins/ui/oxide', //皮肤 skin_url: '/skins/ui/oxide', //皮肤
content_css: '/skins/content/default/content.css', content_css: '/skins/content/default/content.css',
language: 'zh_CN', language: 'zh_CN',
placeholder: "在这里输入文字", //textarea中的提示信息 placeholder: "在这里输入文字", //textarea中的提示信息
min_width: 300, min_width: 300,
min_height: 200, min_height: 200,
width: props.width, width: props.width,
height: props.height, //注引入autoresize插件时此属性失效 height: props.height, //注引入autoresize插件时此属性失效
resize: "both", //编辑器宽高是否可变false-否,true-高可变,'both'-宽高均可,注意引号 resize: "both", //编辑器宽高是否可变false-否,true-高可变,'both'-宽高均可,注意引号
promotion: false, promotion: false,
branding: false, //tiny技术支持信息是否显示 branding: false, //tiny技术支持信息是否显示
statusbar: false, //最下方的元素路径和字数统计那一栏是否显示 statusbar: false, //最下方的元素路径和字数统计那一栏是否显示
elementpath: false, //元素路径是否显示 elementpath: false, //元素路径是否显示
font_formats: props.fontFormats, //字体样式 font_formats: props.fontFormats, //字体样式
plugins: props.plugins, //插件配置 axupimgs indent2em plugins: props.plugins, //插件配置 axupimgs indent2em
toolbar: props.toolbar, //工具栏配置设为false则隐藏 toolbar: props.toolbar, //工具栏配置设为false则隐藏
menubar: "file edit view format table tools", //菜单栏配置设为false则隐藏不配置则默认显示全部菜单也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单” menubar: "file edit view format table tools", //菜单栏配置设为false则隐藏不配置则默认显示全部菜单也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单”
images_upload_url: '/workflow/process/file/upload', //后端处理程序的url建议直接自定义上传函数image_upload_handler这个就可以不用了 images_upload_url: '/workflow/process/file/upload', //后端处理程序的url建议直接自定义上传函数image_upload_handler这个就可以不用了
// images_upload_base_path: '/demo', //相对基本路径--关于图片上传建议查看--http://tinymce.ax-z.cn/general/upload-images.php // images_upload_base_path: '/demo', //相对基本路径--关于图片上传建议查看--http://tinymce.ax-z.cn/general/upload-images.php
paste_data_images: true, //图片是否可粘贴 paste_data_images: true, //图片是否可粘贴
file_picker_types: "file image", //file image media分别对应三个类型文件的上传link插件image和axupimgs插件media插件。想屏蔽某个插件的上传就去掉对应的参数 file_picker_types: "file image", //file image media分别对应三个类型文件的上传link插件image和axupimgs插件media插件。想屏蔽某个插件的上传就去掉对应的参数
// 文件上传处理函数 // 文件上传处理函数
setup: function (editor) { setup: function (editor) {
editor.on('change', function (e) { editor.on('change', function (e) {
tinymce.activeEditor.save();//执行自动保存 tinymce.activeEditor.save();//执行自动保存
}); });
}, },
//此处为图片上传处理函数 //此处为图片上传处理函数
images_upload_handler: (blobInfo, success) => { images_upload_handler: (blobInfo, success) => {
// new Promise((resolve, reject) => { // new Promise((resolve, reject) => {
let formData = new FormData() let formData = new FormData()
formData.append('file', blobInfo.blob()) formData.append('file', blobInfo.blob())
//上传图片接口 上传成功后返回图片地址,用于显示在富文本中 //上传图片接口 上传成功后返回图片地址,用于显示在富文本中
uploadFile(formData, props.imageUrl, success, true) uploadFile(formData, props.imageUrl, success, true)
// }), // }),
}, },
images_upload_handler_not_loading: (blobInfo, success) => { images_upload_handler_not_loading: (blobInfo, success) => {
let formData = new FormData() let formData = new FormData()
formData.append('file', blobInfo.blob()) formData.append('file', blobInfo.blob())
//上传图片接口 //上传图片接口
uploadFile(formData, props.imageUrl, success, false) uploadFile(formData, props.imageUrl, success, false)
}, },
file_picker_callback: (callback, value, meta) => { file_picker_callback: (callback, value, meta) => {
// 使用案例http://tinymce.ax-z.cn/general/upload-images.php // 使用案例http://tinymce.ax-z.cn/general/upload-images.php
// meta.filetype //根据这个判断点击的是什么file image media // meta.filetype //根据这个判断点击的是什么file image media
let filetype; //限制文件的上传类型,需要什么就添加什么的后缀 let filetype; //限制文件的上传类型,需要什么就添加什么的后缀
if (meta.filetype == "image") { if (meta.filetype == "image") {
filetype = ".jpg, .jpeg, .png, .gif, .ico, .svg"; filetype = ".jpg, .jpeg, .png, .gif, .ico, .svg";
} else if (meta.filetype == "media") { } else if (meta.filetype == "media") {
filetype = ".mp3, .mp4, .avi, .mov"; filetype = ".mp3, .mp4, .avi, .mov";
} else { } else {
filetype = filetype =
".pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4, .jpg, .jpeg, .png, .gif, .ico, .svg"; ".pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4, .jpg, .jpeg, .png, .gif, .ico, .svg";
} }
let inputElem = document.createElement("input"); //创建文件选择 let inputElem = document.createElement("input"); //创建文件选择
inputElem.setAttribute("type", "file"); inputElem.setAttribute("type", "file");
inputElem.setAttribute("accept", filetype); inputElem.setAttribute("accept", filetype);
inputElem.click(); inputElem.click();
inputElem.onchange = () => { inputElem.onchange = () => {
let file = inputElem.files[0]; //获取文件信息 let file = inputElem.files[0]; //获取文件信息
let xhr, formData; let xhr, formData;
xhr = new XMLHttpRequest(); xhr = new XMLHttpRequest();
xhr.withCredentials = false; xhr.withCredentials = false;
xhr.open('POST', import.meta.env.VITE_BASE_URL + props.imageUrl); xhr.open('POST', import.meta.env.VITE_BASE_URL + props.imageUrl);
xhr.setRequestHeader( xhr.setRequestHeader(
'Authorization', getToken() 'Authorization', getToken()
) )
let loading = ElLoading.service({ let loading = ElLoading.service({
lock: true, lock: true,
text: '文件上传中...', text: '文件上传中...',
background: 'rgba(0, 0, 0, 0.7)', background: 'rgba(0, 0, 0, 0.7)',
}) })
xhr.onload = function () { xhr.onload = function () {
let res; let res;
// if (xhr.status != 200) { // if (xhr.status != 200) {
// failure('HTTP Error: ' + xhr.status); // failure('HTTP Error: ' + xhr.status);
// return; // return;
// } // }
res = JSON.parse(xhr.responseText); res = JSON.parse(xhr.responseText);
ElNotification({ ElNotification({
title: '提示', title: '提示',
message: res.code === 1000 ? '上传成功' : '上传失败', message: res.code === 1000 ? '上传成功' : '上传失败',
type: res.code === 1000 ? 'success' : 'error' type: res.code === 1000 ? 'success' : 'error'
}) })
loading.close() loading.close()
console.log("🚀 ~ file:res.data ", res.data) console.log("🚀 ~ file:res.data ", res.data)
res.data.originalFileName=res.data.originalFilename res.data.originalFileName=res.data.originalFilename
console.log("🚀 ~ file:'meta.filetype ",meta.filetype ) console.log("🚀 ~ file:'meta.filetype ",meta.filetype )
if (res && res.data && res.data.fileType && if (res && res.data && res.data.fileType &&
!["png", "jpg", "jpeg","gif", "svg","ico"].includes(res.data.fileType.toLowerCase())){ !["png", "jpg", "jpeg","gif", "svg","ico"].includes(res.data.fileType.toLowerCase())){
fileLists.value.push(res.data) fileLists.value.push(res.data)
emit('getFiles',fileLists.value) emit('getFiles',fileLists.value)
} }
const fileUrl = res.data.url; const fileUrl = res.data.url;
// '?fileId='+res.data.id+ // '?fileId='+res.data.id+
callback(fileUrl + '?fileName=' + res.data.originalFilename, {text: file.name, title: file.name}); callback(fileUrl + '?fileName=' + res.data.originalFilename, {text: file.name, title: file.name});
}; };
formData = new FormData(); formData = new FormData();
formData.append('file', file, file.name); formData.append('file', file, file.name);
xhr.send(formData); xhr.send(formData);
// //
// let reader = new FileReader(); // let reader = new FileReader();
// reader.readAsDataURL(file); // reader.readAsDataURL(file);
// reader.onload = function () { // reader.onload = function () {
// let formData; // let formData;
// let id = "blobid" + new Date().getTime(); // let id = "blobid" + new Date().getTime();
// let blobCache = tinymce.activeEditor.editorUpload.blobCache; // let blobCache = tinymce.activeEditor.editorUpload.blobCache;
// let base64 = reader.result.split(",")[1]; // let base64 = reader.result.split(",")[1];
// let blobInfo = blobCache.create(id, file, base64); // let blobInfo = blobCache.create(id, file, base64);
// blobCache.add(blobInfo); // blobCache.add(blobInfo);
// // callback(blobInfo.blobUri(), {alt: file.name}); // // callback(blobInfo.blobUri(), {alt: file.name});
// formData = new FormData(); // formData = new FormData();
// formData.append('file', file, file.name ); // formData.append('file', file, file.name );
// uploadFile(formData, props.imageUrl,callback) // uploadFile(formData, props.imageUrl,callback)
// }; // };
}; };
}, },
}); });
//内容有变化,就更新内容,将值返回给父组件 //内容有变化,就更新内容,将值返回给父组件
watch(() => { watch(() => {
emit("update:value", content.value); emit("update:value", content.value);
}); });
const uploadFile = (formData, url, success, isLoading) => { const uploadFile = (formData, url, success, isLoading) => {
let loading = null let loading = null
if (isLoading) { if (isLoading) {
loading = ElLoading.service({ loading = ElLoading.service({
lock: true, lock: true,
text: '图片上传中...', text: '图片上传中...',
background: 'rgba(0, 0, 0, 0.7)', background: 'rgba(0, 0, 0, 0.7)',
}) })
} }
axios.post( axios.post(
import.meta.env.VITE_BASE_URL + url, import.meta.env.VITE_BASE_URL + url,
formData, formData,
{ {
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
Authorization: getToken() Authorization: getToken()
} }
} }
).then(res => { ).then(res => {
// if (res.status !== 200) { // if (res.status !== 200) {
// ElMessage.error("上传失败!") // ElMessage.error("上传失败!")
// } // }
let data = res.data let data = res.data
if (data.code !== 1000) { if (data.code !== 1000) {
ElMessage.error(data.msg) ElMessage.error(data.msg)
if (loading) { if (loading) {
loading.close() loading.close()
} }
} else { } else {
if (isLoading) { if (isLoading) {
success(data.data.url) success(data.data.url)
} else { } else {
success(data.data.url, data.data.originalFilename) success(data.data.url, data.data.originalFilename)
} }
if (loading) { if (loading) {
loading.close() loading.close()
} }
} }
}) })
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.tox-sidebar-wrap { .tox-sidebar-wrap {
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 6px; width: 6px;
} }
// 滚动条轨道 // 滚动条轨道
&::-webkit-scrollbar-track { &::-webkit-scrollbar-track {
background: rgb(239, 239, 239); background: rgb(239, 239, 239);
border-radius: 2px; border-radius: 2px;
} }
// 小滑块 // 小滑块
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background: rgba(80, 81, 82, 0.29); background: rgba(80, 81, 82, 0.29);
border-radius: 10px; border-radius: 10px;
} }
} }
.tinymce-boxz > textarea { .tinymce-boxz > textarea {
display: none; display: none;
} }
</style> </style>
<style lang="scss"> <style lang="scss">
/* 隐藏apikey没有绑定当前域名的提示 */ /* 隐藏apikey没有绑定当前域名的提示 */
.tox-notifications-container .tox-notification--warning { .tox-notifications-container .tox-notification--warning {
display: none !important; display: none !important;
} }
.tox.tox-tinymce { .tox.tox-tinymce {
max-width: 100%; max-width: 100%;
} }
</style> </style>

View File

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

View File

@@ -1,85 +1,85 @@
<template> <template>
<div class="item"> <div class="item">
<i> <i>
<slot name="icon"></slot> <slot name="icon"></slot>
</i> </i>
<div class="details"> <div class="details">
<h3> <h3>
<slot name="heading"></slot> <slot name="heading"></slot>
</h3> </h3>
<slot></slot> <slot></slot>
</div> </div>
</div> </div>
</template> </template>
<style scoped> <style scoped>
.item { .item {
margin-top: 2rem; margin-top: 2rem;
display: flex; display: flex;
} }
.details { .details {
flex: 1; flex: 1;
margin-left: 1rem; margin-left: 1rem;
} }
i { i {
display: flex; display: flex;
place-items: center; place-items: center;
place-content: center; place-content: center;
width: 32px; width: 32px;
height: 32px; height: 32px;
color: var(--color-text); color: var(--color-text);
} }
h3 { h3 {
font-size: 1.2rem; font-size: 1.2rem;
font-weight: 500; font-weight: 500;
margin-bottom: 0.4rem; margin-bottom: 0.4rem;
color: var(--color-heading); color: var(--color-heading);
} }
@media (min-width: 1024px) { @media (min-width: 1024px) {
.item { .item {
margin-top: 0; margin-top: 0;
padding: 0.4rem 0 1rem calc(var(--section-gap) / 2); padding: 0.4rem 0 1rem calc(var(--section-gap) / 2);
} }
i { i {
top: calc(50% - 25px); top: calc(50% - 25px);
left: -26px; left: -26px;
position: absolute; position: absolute;
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
background: var(--color-background); background: var(--color-background);
border-radius: 8px; border-radius: 8px;
width: 50px; width: 50px;
height: 50px; height: 50px;
} }
.item:before { .item:before {
content: ' '; content: ' ';
border-left: 1px solid var(--color-border); border-left: 1px solid var(--color-border);
position: absolute; position: absolute;
left: 0; left: 0;
bottom: calc(50% + 25px); bottom: calc(50% + 25px);
height: calc(50% - 25px); height: calc(50% - 25px);
} }
.item:after { .item:after {
content: ' '; content: ' ';
border-left: 1px solid var(--color-border); border-left: 1px solid var(--color-border);
position: absolute; position: absolute;
left: 0; left: 0;
top: calc(50% + 25px); top: calc(50% + 25px);
height: calc(50% - 25px); height: calc(50% - 25px);
} }
.item:first-of-type:before { .item:first-of-type:before {
display: none; display: none;
} }
.item:last-of-type:after { .item:last-of-type:after {
display: none; display: none;
} }
} }
</style> </style>

View File

@@ -1,33 +1,33 @@
<template> <template>
<div class="base-title"> <div class="base-title">
<span></span> <span></span>
<span>{{ title }}</span> <span>{{ title }}</span>
</div> </div>
</template> </template>
<script setup> <script setup>
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
default: '' default: ''
} }
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.base-title { .base-title {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
margin: 15px 0; margin: 15px 0;
font-weight: bold; font-weight: bold;
>span:first-child { >span:first-child {
display: inline-block; display: inline-block;
width: 10px; width: 10px;
height: 20px; height: 20px;
background: #BEA266; background: #BEA266;
margin-right: 5px; margin-right: 5px;
} }
} }
</style> </style>

View File

@@ -1,69 +1,69 @@
<template> <template>
<codemirror <codemirror
v-model="javaCode" v-model="javaCode"
:placeholder="editorPlaceholder" :placeholder="editorPlaceholder"
:style="{ height: editorHeight+'px' }" :style="{ height: editorHeight+'px' }"
:autofocus="true" :autofocus="true"
:indent-with-tab="true" :indent-with-tab="true"
:tabSize="tabSize" :tabSize="tabSize"
:extensions="extensions" :extensions="extensions"
:scrollbarStyle="null" :scrollbarStyle="null"
/> />
</template> </template>
<script setup> <script setup>
import {Codemirror} from "vue-codemirror"; import {Codemirror} from "vue-codemirror";
import {java, javaLanguage} from "@codemirror/lang-java"; import {java, javaLanguage} from "@codemirror/lang-java";
const emit = defineEmits() const emit = defineEmits()
const props = defineProps({ const props = defineProps({
value: { value: {
type: String, type: String,
default: "", default: "",
}, },
editorPlaceholder: { editorPlaceholder: {
type: String, type: String,
default: "请输入代码", default: "请输入代码",
}, },
editorHeight: { editorHeight: {
type: String, type: String,
default: "300", default: "300",
}, },
tabSize: { tabSize: {
type: Number, type: Number,
default: 2, default: 2,
} }
}) })
const _value = computed({ const _value = computed({
get() { get() {
return props.value || "" return props.value || ""
}, },
set(value) { set(value) {
emit('update:value', value) emit('update:value', value)
} }
}) })
const javaCode = ref(); const javaCode = ref();
const customJavaCodeTips = (context) => { const customJavaCodeTips = (context) => {
let word = context.matchBefore(/\w*/) let word = context.matchBefore(/\w*/)
if (word.from == word.to && !context.explicit) return null; if (word.from == word.to && !context.explicit) return null;
return { return {
from: word.from?word.from:context.pos, from: word.from?word.from:context.pos,
options: [ options: [
{label: "function", type: "keyword",apply:"function name(params) {\n\t\n}",detail: "definition"}, {label: "function", type: "keyword",apply:"function name(params) {\n\t\n}",detail: "definition"},
// {label: "hello", type: "variable", info: "(World)"}, // {label: "hello", type: "variable", info: "(World)"},
{label: "fori", type: "keyword",apply:"for (let i = 0; i < list.length; i++) {\n\n}", detail: "loop"}, {label: "fori", type: "keyword",apply:"for (let i = 0; i < list.length; i++) {\n\n}", detail: "loop"},
{label: "for", type: "keyword",apply:"for (let name of list) {\n\n}", detail: "of loop"}, {label: "for", type: "keyword",apply:"for (let name of list) {\n\n}", detail: "of loop"},
{label: "psf", type: "keyword",apply:"public static final ", detail: "public static final"}, {label: "psf", type: "keyword",apply:"public static final ", detail: "public static final"},
{label: "psv", type: "keyword",apply:"public static void name(){\n\n}", detail: "public static void"}, {label: "psv", type: "keyword",apply:"public static void name(){\n\n}", detail: "public static void"},
{label: "psfi", type: "keyword",apply:"public static final int ", detail: "public static final int"}, {label: "psfi", type: "keyword",apply:"public static final int ", detail: "public static final int"},
{label: "psfs", type: "keyword",apply:"public static final String ", detail: "public static final String"}, {label: "psfs", type: "keyword",apply:"public static final String ", detail: "public static final String"},
{label: "psvm", type: "keyword", apply: "public static void main(String[] args){\n\t\n}", detail: "main() 方法声明"} {label: "psvm", type: "keyword", apply: "public static void main(String[] args){\n\t\n}", detail: "main() 方法声明"}
] ]
} }
} }
const javaSnippets = javaLanguage.data.of({ const javaSnippets = javaLanguage.data.of({
autocomplete: customJavaCodeTips, autocomplete: customJavaCodeTips,
}) })
const extensions = ref([java(), javaSnippets]); const extensions = ref([java(), javaSnippets]);
</script> </script>

View File

@@ -1,48 +1,48 @@
<template> <template>
<codemirror <codemirror
v-model="jsCode" v-model="jsCode"
:placeholder="editorPlaceholder" :placeholder="editorPlaceholder"
:style="{ height: editorHeight+'px' }" :style="{ height: editorHeight+'px' }"
:autofocus="true" :autofocus="true"
:indent-with-tab="true" :indent-with-tab="true"
:tabSize="tabSize" :tabSize="tabSize"
:extensions="extensions" :extensions="extensions"
:scrollbarStyle="null" :scrollbarStyle="null"
/> />
</template> </template>
<script setup> <script setup>
import {Codemirror} from "vue-codemirror"; import {Codemirror} from "vue-codemirror";
import {javascript} from "@codemirror/lang-javascript"; import {javascript} from "@codemirror/lang-javascript";
import {defineEmits, ref, defineProps, computed} from "vue"; import {defineEmits, ref, defineProps, computed} from "vue";
const emit = defineEmits() const emit = defineEmits()
const props = defineProps({ const props = defineProps({
value: { value: {
type: String, type: String,
default: "", default: "",
}, },
editorPlaceholder: { editorPlaceholder: {
type: String, type: String,
default: "请输入代码", default: "请输入代码",
}, },
editorHeight: { editorHeight: {
type: String, type: String,
default: "300", default: "300",
}, },
tabSize: { tabSize: {
type: Number, type: Number,
default: 2, default: 2,
} }
}) })
const _value = computed({ const _value = computed({
get() { get() {
return props.value || "" return props.value || ""
}, },
set(value) { set(value) {
emit('update:value', value) emit('update:value', value)
} }
}) })
const jsCode = ref(); const jsCode = ref();
const extensions = ref([javascript()]); const extensions = ref([javascript()]);
</script> </script>

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