Commit 3670dbbf1d1ae0093da3731079e8219c280869c4
1 parent
592bca7b
Jeecg-Boot 2.1.4 版本发布 | 重构较大,较多新功能
Showing
270 changed files
with
15817 additions
and
24938 deletions
Too many changes to show.
To preserve performance only 65 of 270 files are displayed.
README.md
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | Jeecg-Boot 快速开发平台(前后端分离版本) |
8 | 8 | =============== |
9 | 9 | |
10 | -当前最新版本: 2.1.3(发布日期:20191226) | |
10 | +当前最新版本: 2.1.4(发布日期:2020-02-24) | |
11 | 11 | |
12 | 12 | |
13 | 13 | [](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE) |
... | ... | @@ -43,7 +43,7 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤 |
43 | 43 | |
44 | 44 | - 技术官网: [http://www.jeecg.com](http://www.jeecg.com) |
45 | 45 | |
46 | -- 开发文档: [http://doc.jeecg.com/1273753](http://doc.jeecg.com/1273753) | |
46 | +- 开发文档: [http://doc.jeecg.com](http://doc.jeecg.com/1273753) | |
47 | 47 | |
48 | 48 | - 视频教程 :[JeecgBoot入门系列视频](https://space.bilibili.com/454617261/channel/detail?cid=84186) |
49 | 49 | |
... | ... | @@ -67,7 +67,7 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤 |
67 | 67 | |
68 | 68 | 为什么选择JEECG-BOOT? |
69 | 69 | ----------------------------------- |
70 | -* 1.采用最新主流前后分离框架(Springboot2+Mybatis+antd),容易上手; 代码生成器依赖性低,灵活的扩展能力,可灵活实现二次开发; | |
70 | +* 1.采用最新主流前后分离框架(Springboot+Mybatis+antd),容易上手; 代码生成器依赖性低,灵活的扩展能力,可灵活实现二次开发; | |
71 | 71 | * 2.开发效率很高,采用代码生成器,单表数据模型和一对多(父子表)数据模型,增删改查功能自动生成,菜单配置直接使用; |
72 | 72 | * 3.代码生成器提供强大模板机制,支持自定义模板风格。目前提供四套风格模板(单表两套、一对多两套) |
73 | 73 | * 4.封装完善的用户、角色、菜单、组织机构、数据字典、在线定时任务等基础功能,支持访问授权、按钮权限、数据权限等功能 |
... | ... |
ant-design-vue-jeecg/README.md
ant-design-vue-jeecg/package.json
1 | 1 | { |
2 | 2 | "name": "vue-antd-jeecg", |
3 | - "version": "2.1.3", | |
3 | + "version": "2.1.4", | |
4 | 4 | "private": true, |
5 | 5 | "scripts": { |
6 | 6 | "pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ", |
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | }, |
11 | 11 | "dependencies": { |
12 | 12 | "@antv/data-set": "^0.10.2", |
13 | - "@jeecg/antd-online-re": "2.1.3", | |
13 | + "@jeecg/antd-online-214": "^2.1.4", | |
14 | 14 | "@tinymce/tinymce-vue": "^2.0.0", |
15 | 15 | "ant-design-vue": "^1.4.0", |
16 | 16 | "apexcharts": "^3.6.5", |
... | ... | @@ -24,7 +24,7 @@ |
24 | 24 | "lodash.pick": "^4.4.0", |
25 | 25 | "md5": "^2.2.1", |
26 | 26 | "nprogress": "^0.2.0", |
27 | - "tinymce": "^5.0.2", | |
27 | + "tinymce": "^5.1.4", | |
28 | 28 | "viser-vue": "^2.4.4", |
29 | 29 | "vue": "^2.6.10", |
30 | 30 | "vue-apexcharts": "^1.3.2", |
... | ... | @@ -51,12 +51,12 @@ |
51 | 51 | "babel-eslint": "^10.0.1", |
52 | 52 | "eslint": "^5.16.0", |
53 | 53 | "eslint-plugin-vue": "^5.1.0", |
54 | + "html-webpack-plugin": "^4.0.0-beta.11", | |
54 | 55 | "less": "^3.9.0", |
55 | 56 | "less-loader": "^4.1.0", |
56 | 57 | "node-sass": "^4.11.0", |
57 | 58 | "sass-loader": "^7.0.1", |
58 | - "vue-template-compiler": "^2.6.10", | |
59 | - "html-webpack-plugin": "^4.0.0-beta.11" | |
59 | + "vue-template-compiler": "^2.6.10" | |
60 | 60 | }, |
61 | 61 | "eslintConfig": { |
62 | 62 | "root": true, |
... | ... |
ant-design-vue-jeecg/public/index.html
... | ... | @@ -5,9 +5,9 @@ |
5 | 5 | <meta charset="utf-8"> |
6 | 6 | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
7 | 7 | <meta name="viewport" content="width=device-width,initial-scale=1.0"> |
8 | - <title>Jeecg-Boot 快速开发平台</title> | |
8 | + <title>Jeecg-Boot 企业级快速开发平台</title> | |
9 | 9 | <link rel="icon" href="<%= BASE_URL %>logo.png"> |
10 | - <script src="https://cdn.bootcss.com/babel-polyfill/7.6.0/polyfill.js"></script> | |
10 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.2.5/polyfill.js"></script> | |
11 | 11 | <style> |
12 | 12 | html, |
13 | 13 | body, |
... | ... | @@ -244,8 +244,8 @@ |
244 | 244 | window._CONFIG = {}; |
245 | 245 | window._CONFIG['domianURL'] = 'http://127.0.0.1:8080/jeecg-boot'; |
246 | 246 | window._CONFIG['casPrefixUrl'] = 'http://cas.example.org:8443/cas'; |
247 | - window._CONFIG['imgDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/view'; | |
248 | - window._CONFIG['downloadUrl'] = window._CONFIG['domianURL'] + '/sys/common/download'; | |
247 | + window._CONFIG['onlinePreviewDomainURL'] = 'http://fileview.jeecg.com/onlinePreview' | |
248 | + window._CONFIG['staticDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/static'; | |
249 | 249 | window._CONFIG['pdfDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/pdf/pdfPreviewIframe'; |
250 | 250 | </script> |
251 | 251 | </head> |
... | ... |
ant-design-vue-jeecg/src/api/api.js
... | ... | @@ -25,7 +25,7 @@ const frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params); |
25 | 25 | //验证用户是否存在 |
26 | 26 | const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params); |
27 | 27 | //改变密码 |
28 | -const changPassword = (params)=>putAction("/sys/user/changPassword",params); | |
28 | +const changePassword = (params)=>putAction("/sys/user/changePassword",params); | |
29 | 29 | |
30 | 30 | //权限管理 |
31 | 31 | const addPermission= (params)=>postAction("/sys/permission/add",params); |
... | ... | @@ -34,6 +34,7 @@ const getPermissionList = (params)=>getAction("/sys/permission/list",params); |
34 | 34 | /*update_begin author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */ |
35 | 35 | const getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params); |
36 | 36 | const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params); |
37 | +const getSystemSubmenuBatch = (params) => getAction('/sys/permission/getSystemSubmenuBatch', params) | |
37 | 38 | /*update_end author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */ |
38 | 39 | |
39 | 40 | // const deletePermission = (params)=>deleteAction("/sys/permission/delete",params); |
... | ... | @@ -56,6 +57,14 @@ const queryParentName = (params)=>getAction("/sys/sysDepart/queryParentName",p |
56 | 57 | const searchByKeywords = (params)=>getAction("/sys/sysDepart/searchBy",params); |
57 | 58 | const deleteByDepartId = (params)=>deleteAction("/sys/sysDepart/delete",params); |
58 | 59 | |
60 | +//二级部门管理 | |
61 | +const queryDepartPermission = (params)=>getAction("/sys/permission/queryDepartPermission",params); | |
62 | +const saveDepartPermission = (params)=>postAction("/sys/permission/saveDepartPermission",params); | |
63 | +const queryTreeListForDeptRole = (params)=>getAction("/sys/sysDepartPermission/queryTreeListForDeptRole",params); | |
64 | +const queryDeptRolePermission = (params)=>getAction("/sys/sysDepartPermission/queryDeptRolePermission",params); | |
65 | +const saveDeptRolePermission = (params)=>postAction("/sys/sysDepartPermission/saveDeptRolePermission",params); | |
66 | +const queryMyDepartTreeList = (params)=>getAction("/sys/sysDepart/queryMyDeptTreeList",params); | |
67 | + | |
59 | 68 | //日志管理 |
60 | 69 | //const getLogList = (params)=>getAction("/sys/log/list",params); |
61 | 70 | const deleteLog = (params)=>deleteAction("/sys/log/delete",params); |
... | ... | @@ -94,6 +103,7 @@ const queryUserRoleMap = (params)=>getAction("/sys/user/queryUserRoleMap",params |
94 | 103 | const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params); |
95 | 104 | // 加载分类字典 |
96 | 105 | const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params); |
106 | +const checkRuleByCode = (params) => getAction('/sys/checkRule/checkByCode', params) | |
97 | 107 | |
98 | 108 | export { |
99 | 109 | // imgView, |
... | ... | @@ -108,7 +118,7 @@ export { |
108 | 118 | queryall, |
109 | 119 | frozenBatch, |
110 | 120 | checkOnlyUser, |
111 | - changPassword, | |
121 | + changePassword, | |
112 | 122 | getPermissionList, |
113 | 123 | addPermission, |
114 | 124 | editPermission, |
... | ... | @@ -142,7 +152,15 @@ export { |
142 | 152 | queryTreeListForRole, |
143 | 153 | getSystemMenuList, |
144 | 154 | getSystemSubmenu, |
145 | - loadCategoryData | |
155 | + getSystemSubmenuBatch, | |
156 | + loadCategoryData, | |
157 | + checkRuleByCode, | |
158 | + queryDepartPermission, | |
159 | + saveDepartPermission, | |
160 | + queryTreeListForDeptRole, | |
161 | + queryDeptRolePermission, | |
162 | + saveDeptRolePermission, | |
163 | + queryMyDepartTreeList | |
146 | 164 | } |
147 | 165 | |
148 | 166 | |
... | ... |
ant-design-vue-jeecg/src/api/manage.js
... | ... | @@ -112,3 +112,17 @@ export function downFile(url,parameter){ |
112 | 112 | }) |
113 | 113 | } |
114 | 114 | |
115 | +/** | |
116 | + * 获取文件访问路径 | |
117 | + * @param avatar | |
118 | + * @param imgerver | |
119 | + * @param str | |
120 | + * @returns {*} | |
121 | + */ | |
122 | +export function getFileAccessHttpUrl(avatar,imgerver,subStr) { | |
123 | + if(avatar && avatar.indexOf(subStr) != -1 ){ | |
124 | + return avatar; | |
125 | + }else{ | |
126 | + return imgerver + "/" + avatar; | |
127 | + } | |
128 | +} | |
... | ... |
ant-design-vue-jeecg/src/assets/less/common.less
ant-design-vue-jeecg/src/components/chart/BarAndLine.vue
1 | 1 | <template> |
2 | 2 | <div :style="{ padding: '0 50px 32px 0' }"> |
3 | 3 | <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> |
4 | - <v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :padding=" padding"> | |
4 | + <v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :padding=" padding" :onClick="handleClick"> | |
5 | 5 | <v-tooltip/> |
6 | 6 | <v-legend/> |
7 | 7 | <v-axis/> |
... | ... | @@ -12,9 +12,11 @@ |
12 | 12 | </template> |
13 | 13 | |
14 | 14 | <script> |
15 | + import { ChartEventMixins } from './mixins/ChartMixins' | |
15 | 16 | |
16 | 17 | export default { |
17 | - name: 'BarMultid', | |
18 | + name: 'BarAndLine', | |
19 | + mixins: [ChartEventMixins], | |
18 | 20 | props: { |
19 | 21 | title: { |
20 | 22 | type: String, |
... | ... |
ant-design-vue-jeecg/src/components/chart/BarMultid.vue
1 | 1 | <template> |
2 | 2 | <div :style="{ padding: '0 0 32px 32px' }"> |
3 | 3 | <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> |
4 | - <v-chart :forceFit="true" :height="254" :data="chartData" :padding="['auto', 'auto', '40', '50']"> | |
5 | - <v-tooltip /> | |
6 | - <v-axis /> | |
7 | - <v-legend /> | |
8 | - <v-bar position="x*y" color="type" :adjust="adjust" /> | |
4 | + <v-chart :data="data" :height="height" :force-fit="true" :onClick="handleClick"> | |
5 | + <v-tooltip/> | |
6 | + <v-axis/> | |
7 | + <v-legend/> | |
8 | + <v-bar position="x*y" color="type" :adjust="adjust"/> | |
9 | 9 | </v-chart> |
10 | 10 | </div> |
11 | 11 | </template> |
12 | 12 | |
13 | 13 | <script> |
14 | 14 | import { DataSet } from '@antv/data-set' |
15 | + import { ChartEventMixins } from './mixins/ChartMixins' | |
15 | 16 | |
16 | - const sourceDataConst = [ | |
17 | - { type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 }, | |
18 | - { type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 }, | |
19 | - ]; | |
20 | - const fieldsConst = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.']; | |
21 | 17 | export default { |
22 | 18 | name: 'BarMultid', |
19 | + mixins: [ChartEventMixins], | |
23 | 20 | props: { |
24 | 21 | title: { |
25 | 22 | type: String, |
26 | 23 | default: '' |
27 | 24 | }, |
28 | - sourceData:{ | |
29 | - type:Array, | |
30 | - default:()=>[] | |
25 | + dataSource: { | |
26 | + type: Array, | |
27 | + default: () => [ | |
28 | + { type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 }, | |
29 | + { type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 } | |
30 | + ] | |
31 | 31 | }, |
32 | - fields:{ | |
33 | - type:Array, | |
34 | - default:()=>[] | |
32 | + fields: { | |
33 | + type: Array, | |
34 | + default: () => ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.'] | |
35 | + }, | |
36 | + // 别名,需要的格式:[{field:'name',alias:'姓名'}, {field:'sex',alias:'性别'}] | |
37 | + aliases: { | |
38 | + type: Array, | |
39 | + default: () => [] | |
40 | + }, | |
41 | + height: { | |
42 | + type: Number, | |
43 | + default: 254 | |
35 | 44 | } |
36 | 45 | }, |
37 | 46 | data() { |
38 | 47 | return { |
39 | - chartData:"", | |
40 | - height: 400, | |
41 | 48 | adjust: [{ |
42 | 49 | type: 'dodge', |
43 | - marginRatio: 1 / 32, | |
44 | - }], | |
45 | - }; | |
46 | - }, | |
47 | - watch: { | |
48 | - 'sourceData': function () { | |
49 | - this.drawChart(); | |
50 | + marginRatio: 1 / 32 | |
51 | + }] | |
50 | 52 | } |
51 | 53 | }, |
52 | - mounted(){ | |
53 | - this.drawChart() | |
54 | - }, | |
55 | - methods:{ | |
56 | - drawChart(){ | |
57 | - let temp = sourceDataConst; | |
58 | - if(this.sourceData && this.sourceData.length>0){ | |
59 | - temp = this.sourceData | |
60 | - } | |
61 | - const dv = new DataSet.View().source(temp); | |
54 | + computed: { | |
55 | + data() { | |
56 | + const dv = new DataSet.View().source(this.dataSource) | |
62 | 57 | dv.transform({ |
63 | 58 | type: 'fold', |
64 | - fields:(!this.fields||this.fields.length==0)?fieldsConst:this.fields, | |
59 | + fields: this.fields, | |
65 | 60 | key: 'x', |
66 | - value: 'y', | |
67 | - }); | |
68 | - this.chartData=dv.rows; | |
61 | + value: 'y' | |
62 | + }) | |
63 | + | |
64 | + // bar 使用不了 - 和 / 所以替换下 | |
65 | + let rows = dv.rows.map(row => { | |
66 | + if (typeof row.x === 'string') { | |
67 | + row.x = row.x.replace(/[-/]/g, '_') | |
68 | + } | |
69 | + return row | |
70 | + }) | |
71 | + // 替换别名 | |
72 | + rows.forEach(row => { | |
73 | + for (let item of this.aliases) { | |
74 | + if (item.field === row.type) { | |
75 | + row.type = item.alias | |
76 | + break | |
77 | + } | |
78 | + } | |
79 | + }) | |
80 | + return rows | |
69 | 81 | } |
70 | 82 | } |
71 | 83 | } |
... | ... |
ant-design-vue-jeecg/src/components/chart/LineChartMultid.vue
1 | 1 | <template> |
2 | 2 | <div :style="{ padding: '0 0 32px 32px' }"> |
3 | 3 | <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> |
4 | - <v-chart :force-fit="true" :height="height" :data="data" :scale="scale"> | |
4 | + <v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :onClick="handleClick"> | |
5 | 5 | <v-tooltip/> |
6 | 6 | <v-axis/> |
7 | 7 | <v-legend/> |
... | ... | @@ -13,9 +13,11 @@ |
13 | 13 | |
14 | 14 | <script> |
15 | 15 | import { DataSet } from '@antv/data-set' |
16 | + import { ChartEventMixins } from './mixins/ChartMixins' | |
16 | 17 | |
17 | 18 | export default { |
18 | 19 | name: 'LineChartMultid', |
20 | + mixins: [ChartEventMixins], | |
19 | 21 | props: { |
20 | 22 | title: { |
21 | 23 | type: String, |
... | ... |
ant-design-vue-jeecg/src/components/chart/Pie.vue
1 | 1 | <template> |
2 | - <v-chart :forceFit="true" :height="height" :data="data" :scale="scale"> | |
2 | + <v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :onClick="handleClick"> | |
3 | 3 | <v-tooltip :showTitle="false" dataKey="item*percent"/> |
4 | 4 | <v-axis/> |
5 | 5 | <v-legend dataKey="item"/> |
... | ... | @@ -10,8 +10,11 @@ |
10 | 10 | |
11 | 11 | <script> |
12 | 12 | const DataSet = require('@antv/data-set') |
13 | + import { ChartEventMixins } from './mixins/ChartMixins' | |
13 | 14 | |
14 | 15 | export default { |
16 | + name: 'Pie', | |
17 | + mixins: [ChartEventMixins], | |
15 | 18 | props: { |
16 | 19 | title: { |
17 | 20 | type: String, |
... | ... |
ant-design-vue-jeecg/src/components/chart/mixins/ChartMixins.js
0 → 100644
ant-design-vue-jeecg/src/components/dict/JDictSelectTag.vue
1 | 1 | <template> |
2 | - <a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="value" :disabled="disabled"> | |
2 | + <a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="getValueSting" :disabled="disabled"> | |
3 | 3 | <a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio> |
4 | 4 | </a-radio-group> |
5 | 5 | |
6 | - <a-select v-else-if="tagType=='select'" :getPopupContainer = "(target) => target.parentNode" :placeholder="placeholder" :disabled="disabled" :value="value" @change="handleInput"> | |
7 | - <a-select-option value="">请选择</a-select-option> | |
6 | + <a-select v-else-if="tagType=='select'" :getPopupContainer = "(target) => target.parentNode" :placeholder="placeholder" :disabled="disabled" :value="getValueSting" @change="handleInput"> | |
7 | + <a-select-option :value="undefined">请选择</a-select-option> | |
8 | 8 | <a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value"> |
9 | 9 | <span style="display: inline-block;width: 100%" :title=" item.text || item.label "> |
10 | 10 | {{ item.text || item.label }} |
... | ... | @@ -23,7 +23,7 @@ |
23 | 23 | placeholder: String, |
24 | 24 | triggerChange: Boolean, |
25 | 25 | disabled: Boolean, |
26 | - value: String, | |
26 | + value: [String, Number], | |
27 | 27 | type: String |
28 | 28 | }, |
29 | 29 | data() { |
... | ... | @@ -50,6 +50,11 @@ |
50 | 50 | //获取字典数据 |
51 | 51 | // this.initDictData(); |
52 | 52 | }, |
53 | + computed: { | |
54 | + getValueSting(){ | |
55 | + return this.value ? this.value.toString() : null; | |
56 | + }, | |
57 | + }, | |
53 | 58 | methods: { |
54 | 59 | initDictData() { |
55 | 60 | //根据字典Code, 初始化字典数组 |
... | ... |
ant-design-vue-jeecg/src/components/dict/JDictSelectUtil.js
... | ... | @@ -47,10 +47,20 @@ export function filterDictText(dictOptions, text) { |
47 | 47 | * @return String |
48 | 48 | */ |
49 | 49 | export function filterMultiDictText(dictOptions, text) { |
50 | + //js “!text” 认为0为空,所以做提前处理 | |
51 | + if(text === 0 || text === '0'){ | |
52 | + for (let dictItem of dictOptions) { | |
53 | + if (text == dictItem.value) { | |
54 | + return dictItem.text | |
55 | + } | |
56 | + } | |
57 | + } | |
58 | + | |
50 | 59 | if(!text || !dictOptions || dictOptions.length==0){ |
51 | 60 | return "" |
52 | 61 | } |
53 | 62 | let re = ""; |
63 | + text = text.toString() | |
54 | 64 | let arr = text.split(",") |
55 | 65 | dictOptions.forEach(function (option) { |
56 | 66 | for(let i=0;i<arr.length;i++){ |
... | ... |
ant-design-vue-jeecg/src/components/jeecg/JEditableTable.vue
... | ... | @@ -32,6 +32,8 @@ |
32 | 32 | </a-col> |
33 | 33 | </a-row> |
34 | 34 | |
35 | + <slot name="actionButtonAfter" :target="getVM()"/> | |
36 | + | |
35 | 37 | <div :id="`${caseId}inputTable`" class="input-table"> |
36 | 38 | <!-- 渲染表头 --> |
37 | 39 | <div class="thead" ref="thead"> |
... | ... | @@ -142,7 +144,9 @@ |
142 | 144 | placement="top" |
143 | 145 | :title="(tooltips[id] || {}).title" |
144 | 146 | :visible="(tooltips[id] || {}).visible || false" |
145 | - :autoAdjustOverflow="true"> | |
147 | + :autoAdjustOverflow="true" | |
148 | + :getPopupContainer="getParentContainer" | |
149 | + > | |
146 | 150 | |
147 | 151 | <input |
148 | 152 | :id="id" |
... | ... | @@ -175,7 +179,9 @@ |
175 | 179 | placement="top" |
176 | 180 | :title="(tooltips[id] || {}).title" |
177 | 181 | :visible="(tooltips[id] || {}).visible || false" |
178 | - :autoAdjustOverflow="true"> | |
182 | + :autoAdjustOverflow="true" | |
183 | + :getPopupContainer="getParentContainer" | |
184 | + > | |
179 | 185 | |
180 | 186 | <span |
181 | 187 | @mouseover="()=>{handleMouseoverCommono(row,col)}" |
... | ... | @@ -211,7 +217,9 @@ |
211 | 217 | placement="top" |
212 | 218 | :title="(tooltips[id] || {}).title" |
213 | 219 | :visible="(tooltips[id] || {}).visible || false" |
214 | - :autoAdjustOverflow="true"> | |
220 | + :autoAdjustOverflow="true" | |
221 | + :getPopupContainer="getParentContainer" | |
222 | + > | |
215 | 223 | |
216 | 224 | <span |
217 | 225 | @mouseover="()=>{handleMouseoverCommono(row,col)}" |
... | ... | @@ -278,19 +286,33 @@ |
278 | 286 | </template> |
279 | 287 | |
280 | 288 | <div :hidden="uploadValues[id] != null"> |
281 | - | |
282 | - <a-upload | |
283 | - name="file" | |
284 | - :data="{'isup':1}" | |
285 | - :multiple="false" | |
286 | - :action="col.action" | |
287 | - :headers="uploadGetHeaders(row,col)" | |
288 | - :showUploadList="false" | |
289 | - v-bind="buildProps(row,col)" | |
290 | - @change="(v)=>handleChangeUpload(v,id,row,col)" | |
289 | + <a-tooltip | |
290 | + :key="i" | |
291 | + :id="id" | |
292 | + placement="top" | |
293 | + :title="(tooltips[id] || {}).title" | |
294 | + :visible="(tooltips[id] || {}).visible || false" | |
295 | + :autoAdjustOverflow="true" | |
296 | + :getPopupContainer="getParentContainer" | |
291 | 297 | > |
292 | - <a-button icon="upload">{{ col.placeholder }}</a-button> | |
293 | - </a-upload> | |
298 | + | |
299 | + <span | |
300 | + @mouseover="()=>{handleMouseoverCommono(row,col)}" | |
301 | + @mouseout="()=>{handleMouseoutCommono(row,col)}"> | |
302 | + <a-upload | |
303 | + name="file" | |
304 | + :data="{'isup':1}" | |
305 | + :multiple="false" | |
306 | + :action="col.action" | |
307 | + :headers="uploadGetHeaders(row,col)" | |
308 | + :showUploadList="false" | |
309 | + v-bind="buildProps(row,col)" | |
310 | + @change="(v)=>handleChangeUpload(v,id,row,col)" | |
311 | + > | |
312 | + <a-button icon="upload">{{ col.placeholder }}</a-button> | |
313 | + </a-upload> | |
314 | + </span> | |
315 | + </a-tooltip> | |
294 | 316 | </div> |
295 | 317 | |
296 | 318 | </div> |
... | ... | @@ -303,7 +325,10 @@ |
303 | 325 | placement="top" |
304 | 326 | :title="(tooltips[id] || {}).title" |
305 | 327 | :visible="(tooltips[id] || {}).visible || false" |
306 | - :autoAdjustOverflow="true"> | |
328 | + :autoAdjustOverflow="true" | |
329 | + :getPopupContainer="getParentContainer" | |
330 | + > | |
331 | + | |
307 | 332 | <span |
308 | 333 | @mouseover="()=>{handleMouseoverCommono(row,col)}" |
309 | 334 | @mouseout="()=>{handleMouseoutCommono(row,col)}"> |
... | ... | @@ -359,19 +384,33 @@ |
359 | 384 | </template> |
360 | 385 | |
361 | 386 | <div :hidden="uploadValues[id] != null"> |
362 | - | |
363 | - <a-upload | |
364 | - name="file" | |
365 | - :data="{'isup':1}" | |
366 | - :multiple="false" | |
367 | - :action="getUploadAction(col.action)" | |
368 | - :headers="uploadGetHeaders(row,col)" | |
369 | - :showUploadList="false" | |
370 | - v-bind="buildProps(row,col)" | |
371 | - @change="(v)=>handleChangeUpload(v,id,row,col)" | |
387 | + <a-tooltip | |
388 | + :key="i" | |
389 | + :id="id" | |
390 | + placement="top" | |
391 | + :title="(tooltips[id] || {}).title" | |
392 | + :visible="(tooltips[id] || {}).visible || false" | |
393 | + :autoAdjustOverflow="true" | |
394 | + :getPopupContainer="getParentContainer" | |
372 | 395 | > |
373 | - <a-button icon="upload">{{ col.placeholder }}</a-button> | |
374 | - </a-upload> | |
396 | + | |
397 | + <span | |
398 | + @mouseover="()=>{handleMouseoverCommono(row,col)}" | |
399 | + @mouseout="()=>{handleMouseoutCommono(row,col)}"> | |
400 | + <a-upload | |
401 | + name="file" | |
402 | + :data="{'isup':1}" | |
403 | + :multiple="false" | |
404 | + :action="getUploadAction(col.action)" | |
405 | + :headers="uploadGetHeaders(row,col)" | |
406 | + :showUploadList="false" | |
407 | + v-bind="buildProps(row,col)" | |
408 | + @change="(v)=>handleChangeUpload(v,id,row,col)" | |
409 | + > | |
410 | + <a-button icon="upload">{{ col.placeholder }}</a-button> | |
411 | + </a-upload> | |
412 | + </span> | |
413 | + </a-tooltip> | |
375 | 414 | </div> |
376 | 415 | |
377 | 416 | </div> |
... | ... | @@ -406,19 +445,33 @@ |
406 | 445 | </template> |
407 | 446 | |
408 | 447 | <div :hidden="uploadValues[id] != null"> |
409 | - | |
410 | - <a-upload | |
411 | - name="file" | |
412 | - :data="{'isup':1}" | |
413 | - :multiple="false" | |
414 | - :action="getUploadAction(col.action)" | |
415 | - :headers="uploadGetHeaders(row,col)" | |
416 | - :showUploadList="false" | |
417 | - v-bind="buildProps(row,col)" | |
418 | - @change="(v)=>handleChangeUpload(v,id,row,col)" | |
448 | + <a-tooltip | |
449 | + :key="i" | |
450 | + :id="id" | |
451 | + placement="top" | |
452 | + :title="(tooltips[id] || {}).title" | |
453 | + :visible="(tooltips[id] || {}).visible || false" | |
454 | + :autoAdjustOverflow="true" | |
455 | + :getPopupContainer="getParentContainer" | |
419 | 456 | > |
420 | - <a-button icon="upload">请上传图片</a-button> | |
421 | - </a-upload> | |
457 | + | |
458 | + <span | |
459 | + @mouseover="()=>{handleMouseoverCommono(row,col)}" | |
460 | + @mouseout="()=>{handleMouseoutCommono(row,col)}"> | |
461 | + <a-upload | |
462 | + name="file" | |
463 | + :data="{'isup':1}" | |
464 | + :multiple="false" | |
465 | + :action="getUploadAction(col.action)" | |
466 | + :headers="uploadGetHeaders(row,col)" | |
467 | + :showUploadList="false" | |
468 | + v-bind="buildProps(row,col)" | |
469 | + @change="(v)=>handleChangeUpload(v,id,row,col)" | |
470 | + > | |
471 | + <a-button icon="upload">请上传图片</a-button> | |
472 | + </a-upload> | |
473 | + </span> | |
474 | + </a-tooltip> | |
422 | 475 | </div> |
423 | 476 | |
424 | 477 | </div> |
... | ... | @@ -433,7 +486,10 @@ |
433 | 486 | placement="top" |
434 | 487 | :title="(tooltips[id] || {}).title" |
435 | 488 | :visible="(tooltips[id] || {}).visible || false" |
436 | - :autoAdjustOverflow="true"> | |
489 | + :autoAdjustOverflow="true" | |
490 | + :getPopupContainer="getParentContainer" | |
491 | + > | |
492 | + | |
437 | 493 | <span |
438 | 494 | @mouseover="()=>{handleMouseoverCommono(row,col)}" |
439 | 495 | @mouseout="()=>{handleMouseoutCommono(row,col)}"> |
... | ... | @@ -459,7 +515,9 @@ |
459 | 515 | placement="top" |
460 | 516 | :title="(tooltips[id] || {}).title" |
461 | 517 | :visible="(tooltips[id] || {}).visible || false" |
462 | - :autoAdjustOverflow="true"> | |
518 | + :autoAdjustOverflow="true" | |
519 | + :getPopupContainer="getParentContainer" | |
520 | + > | |
463 | 521 | |
464 | 522 | <span |
465 | 523 | @mouseover="()=>{handleMouseoverCommono(row,col)}" |
... | ... | @@ -492,7 +550,9 @@ |
492 | 550 | placement="top" |
493 | 551 | :title="(tooltips[id] || {}).title" |
494 | 552 | :visible="(tooltips[id] || {}).visible || false" |
495 | - :autoAdjustOverflow="true"> | |
553 | + :autoAdjustOverflow="true" | |
554 | + :getPopupContainer="getParentContainer" | |
555 | + > | |
496 | 556 | |
497 | 557 | <span |
498 | 558 | @mouseover="()=>{handleMouseoverCommono(row,col)}" |
... | ... | @@ -526,7 +586,9 @@ |
526 | 586 | placement="top" |
527 | 587 | :title="(tooltips[id] || {}).title" |
528 | 588 | :visible="(tooltips[id] || {}).visible || false" |
529 | - :autoAdjustOverflow="true"> | |
589 | + :autoAdjustOverflow="true" | |
590 | + :getPopupContainer="getParentContainer" | |
591 | + > | |
530 | 592 | |
531 | 593 | <span |
532 | 594 | @mouseover="()=>{handleMouseoverCommono(row,col)}" |
... | ... | @@ -693,6 +755,7 @@ |
693 | 755 | } |
694 | 756 | }, |
695 | 757 | created() { |
758 | + this.inputValues = [] | |
696 | 759 | // 当前显示的tr |
697 | 760 | this.visibleTrEls = [] |
698 | 761 | this.disabledRowIds = (this.disabledRowIds || []) |
... | ... | @@ -771,149 +834,155 @@ |
771 | 834 | dataSource: { |
772 | 835 | immediate: true, |
773 | 836 | handler: function (newValue) { |
774 | - this.initialize() | |
775 | - | |
776 | - let rows = [] | |
777 | - let checkboxValues = {} | |
778 | - let selectValues = {} | |
779 | - let jdateValues = {} | |
780 | - let slotValues = {} | |
781 | - let uploadValues = {} | |
782 | - let popupValues = {} | |
783 | - let radioValues = {} | |
784 | - let multiSelectValues = {} | |
785 | - let searchSelectValues = {} | |
786 | - | |
787 | - // 禁用行的id | |
788 | - let disabledRowIds = (this.disabledRowIds || []) | |
789 | - newValue.forEach((data, newValueIndex) => { | |
790 | - // 判断源数据是否带有id | |
791 | - if (data.id == null || data.id === '') { | |
792 | - data.id = this.removeCaseId(this.generateId() + newValueIndex) | |
793 | - } | |
837 | + // 兼容IE | |
838 | + this.getElementPromise('tbody').then(() => { | |
839 | + | |
840 | + this.initialize() | |
841 | + | |
842 | + let rows = [] | |
843 | + let checkboxValues = {} | |
844 | + let selectValues = {} | |
845 | + let jdateValues = {} | |
846 | + let slotValues = {} | |
847 | + let uploadValues = {} | |
848 | + let popupValues = {} | |
849 | + let radioValues = {} | |
850 | + let multiSelectValues = {} | |
851 | + let searchSelectValues = {} | |
852 | + | |
853 | + // 禁用行的id | |
854 | + let disabledRowIds = (this.disabledRowIds || []) | |
855 | + newValue.forEach((data, newValueIndex) => { | |
856 | + // 判断源数据是否带有id | |
857 | + if (data.id == null || data.id === '') { | |
858 | + data.id = this.removeCaseId(this.generateId() + newValueIndex) | |
859 | + } | |
794 | 860 | |
795 | - let value = { id: this.caseId + data.id } | |
796 | - let row = { id: value.id } | |
797 | - let disabled = false | |
798 | - this.columns.forEach(column => { | |
799 | - let inputId = column.key + value.id | |
800 | - let sourceValue = (data[column.key] == null ? '' : data[column.key]).toString() | |
801 | - if (column.type === FormTypes.checkbox) { | |
802 | - | |
803 | - // 判断是否设定了customValue(自定义值) | |
804 | - if (column.customValue instanceof Array) { | |
805 | - let customValue = (column.customValue[0] || '').toString() | |
806 | - checkboxValues[inputId] = (sourceValue === customValue) | |
807 | - } else { | |
808 | - checkboxValues[inputId] = sourceValue | |
809 | - } | |
861 | + let value = { id: this.caseId + data.id } | |
862 | + let row = { id: value.id } | |
863 | + let disabled = false | |
864 | + this.columns.forEach(column => { | |
865 | + let inputId = column.key + value.id | |
866 | + let sourceValue = (data[column.key] == null ? '' : data[column.key]).toString() | |
867 | + if (column.type === FormTypes.checkbox) { | |
868 | + | |
869 | + // 判断是否设定了customValue(自定义值) | |
870 | + if (column.customValue instanceof Array) { | |
871 | + let customValue = (column.customValue[0] || '').toString() | |
872 | + checkboxValues[inputId] = (sourceValue === customValue) | |
873 | + } else { | |
874 | + checkboxValues[inputId] = sourceValue | |
875 | + } | |
810 | 876 | |
811 | - } else if (column.type === FormTypes.select) { | |
812 | - if (sourceValue) { | |
813 | - // 判断是否是多选 | |
814 | - selectValues[inputId] = (column.props || {})['mode'] === 'multiple' ? sourceValue.split(',') : sourceValue | |
815 | - } else { | |
816 | - selectValues[inputId] = undefined | |
817 | - } | |
877 | + } else if (column.type === FormTypes.select) { | |
878 | + if (sourceValue) { | |
879 | + // 判断是否是多选 | |
880 | + selectValues[inputId] = (column.props || {})['mode'] === 'multiple' ? sourceValue.split(',') : sourceValue | |
881 | + } else { | |
882 | + selectValues[inputId] = undefined | |
883 | + } | |
818 | 884 | |
819 | - } else if (column.type === FormTypes.date || column.type === FormTypes.datetime) { | |
820 | - jdateValues[inputId] = sourceValue | |
885 | + } else if (column.type === FormTypes.date || column.type === FormTypes.datetime) { | |
886 | + jdateValues[inputId] = sourceValue | |
821 | 887 | |
822 | - } else if (column.type === FormTypes.slot) { | |
823 | - if (sourceValue !== 0 && !sourceValue) { | |
824 | - slotValues[inputId] = column.defaultValue | |
825 | - } else { | |
826 | - slotValues[inputId] = sourceValue | |
827 | - } | |
888 | + } else if (column.type === FormTypes.slot) { | |
889 | + if (sourceValue !== 0 && !sourceValue) { | |
890 | + slotValues[inputId] = column.defaultValue | |
891 | + } else { | |
892 | + slotValues[inputId] = sourceValue | |
893 | + } | |
828 | 894 | |
829 | - } else if (column.type === FormTypes.popup) { | |
830 | - popupValues[inputId] = sourceValue | |
831 | - } else if (column.type === FormTypes.radio) { | |
832 | - radioValues[inputId] = sourceValue | |
833 | - } else if (column.type === FormTypes.sel_search) { | |
834 | - searchSelectValues[inputId] = sourceValue | |
835 | - } else if (column.type === FormTypes.list_multi) { | |
836 | - if (sourceValue.length > 0) { | |
837 | - multiSelectValues[inputId] = sourceValue.split(',') | |
838 | - } else { | |
839 | - multiSelectValues[inputId] = [] | |
840 | - } | |
841 | - } else if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) { | |
842 | - if (sourceValue) { | |
843 | - let fileName = sourceValue.substring(sourceValue.lastIndexOf('/') + 1) | |
844 | - uploadValues[inputId] = { | |
845 | - name: fileName, | |
846 | - status: 'done', | |
847 | - path: sourceValue | |
895 | + } else if (column.type === FormTypes.popup) { | |
896 | + popupValues[inputId] = sourceValue | |
897 | + } else if (column.type === FormTypes.radio) { | |
898 | + radioValues[inputId] = sourceValue | |
899 | + } else if (column.type === FormTypes.sel_search) { | |
900 | + searchSelectValues[inputId] = sourceValue | |
901 | + } else if (column.type === FormTypes.list_multi) { | |
902 | + if (sourceValue.length > 0) { | |
903 | + multiSelectValues[inputId] = sourceValue.split(',') | |
904 | + } else { | |
905 | + multiSelectValues[inputId] = [] | |
848 | 906 | } |
907 | + } else if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) { | |
908 | + if (sourceValue) { | |
909 | + let fileName = sourceValue.substring(sourceValue.lastIndexOf('/') + 1) | |
910 | + uploadValues[inputId] = { | |
911 | + name: fileName, | |
912 | + status: 'done', | |
913 | + path: sourceValue | |
914 | + } | |
915 | + } | |
916 | + } else { | |
917 | + value[column.key] = sourceValue | |
849 | 918 | } |
850 | - } else { | |
851 | - value[column.key] = sourceValue | |
852 | - } | |
853 | 919 | |
854 | - // 解析disabledRows | |
855 | - for (let columnKey in this.disabledRows) { | |
856 | - // 判断是否有该属性 | |
857 | - if (this.disabledRows.hasOwnProperty(columnKey) && data.hasOwnProperty(columnKey)) { | |
858 | - if (disabled !== true) { | |
859 | - let temp = this.disabledRows[columnKey] | |
860 | - // 禁用规则可以是一个数组 | |
861 | - if (temp instanceof Array) { | |
862 | - disabled = temp.includes(data[columnKey]) | |
863 | - } else { | |
864 | - disabled = (temp === data[columnKey]) | |
865 | - } | |
866 | - if (disabled) { | |
867 | - disabledRowIds.push(row.id) | |
920 | + // 解析disabledRows | |
921 | + for (let columnKey in this.disabledRows) { | |
922 | + // 判断是否有该属性 | |
923 | + if (this.disabledRows.hasOwnProperty(columnKey) && data.hasOwnProperty(columnKey)) { | |
924 | + if (disabled !== true) { | |
925 | + let temp = this.disabledRows[columnKey] | |
926 | + // 禁用规则可以是一个数组 | |
927 | + if (temp instanceof Array) { | |
928 | + disabled = temp.includes(data[columnKey]) | |
929 | + } else { | |
930 | + disabled = (temp === data[columnKey]) | |
931 | + } | |
932 | + if (disabled) { | |
933 | + disabledRowIds.push(row.id) | |
934 | + } | |
868 | 935 | } |
869 | 936 | } |
870 | 937 | } |
871 | - } | |
938 | + }) | |
939 | + this.inputValues.push(value) | |
940 | + rows.push(row) | |
941 | + }) | |
942 | + this.disabledRowIds = disabledRowIds | |
943 | + this.checkboxValues = checkboxValues | |
944 | + this.selectValues = selectValues | |
945 | + this.jdateValues = jdateValues | |
946 | + this.slotValues = slotValues | |
947 | + this.rows = rows | |
948 | + this.uploadValues = uploadValues | |
949 | + this.popupValues = popupValues | |
950 | + this.radioValues = radioValues | |
951 | + this.multiSelectValues = multiSelectValues | |
952 | + this.searchSelectValues = searchSelectValues | |
953 | + | |
954 | + // 更新form表单的值 | |
955 | + this.$nextTick(() => { | |
956 | + this.updateFormValues() | |
872 | 957 | }) |
873 | - this.inputValues.push(value) | |
874 | - rows.push(row) | |
875 | - }) | |
876 | - this.disabledRowIds = disabledRowIds | |
877 | - this.checkboxValues = checkboxValues | |
878 | - this.selectValues = selectValues | |
879 | - this.jdateValues = jdateValues | |
880 | - this.slotValues = slotValues | |
881 | - this.rows = rows | |
882 | - this.uploadValues = uploadValues | |
883 | - this.popupValues = popupValues | |
884 | - this.radioValues = radioValues | |
885 | - this.multiSelectValues = multiSelectValues | |
886 | - this.searchSelectValues = searchSelectValues | |
887 | - | |
888 | - // 更新form表单的值 | |
889 | - this.$nextTick(() => { | |
890 | - this.updateFormValues() | |
891 | 958 | }) |
892 | - | |
893 | 959 | } |
894 | 960 | }, |
895 | 961 | columns: { |
896 | 962 | immediate: true, |
897 | 963 | handler(columns) { |
898 | - columns.forEach(column => { | |
899 | - if (column.type === FormTypes.select || column.type === FormTypes.list_multi || column.type === FormTypes.sel_search) { | |
900 | - // 兼容 旧版本 options | |
901 | - if (column.options instanceof Array) { | |
902 | - column.options = column.options.map(item => { | |
903 | - if (item) { | |
904 | - return { | |
905 | - ...item, | |
906 | - text: item.text || item.title, | |
907 | - title: item.text || item.title | |
964 | + // 兼容IE | |
965 | + this.getElementPromise('tbody').then(() => { | |
966 | + columns.forEach(column => { | |
967 | + if (column.type === FormTypes.select || column.type === FormTypes.list_multi || column.type === FormTypes.sel_search) { | |
968 | + // 兼容 旧版本 options | |
969 | + if (column.options instanceof Array) { | |
970 | + column.options = column.options.map(item => { | |
971 | + if (item) { | |
972 | + return { | |
973 | + ...item, | |
974 | + text: item.text || item.title, | |
975 | + title: item.text || item.title | |
976 | + } | |
908 | 977 | } |
909 | - } | |
910 | - return {} | |
911 | - }) | |
912 | - } | |
913 | - if (column.dictCode) { | |
914 | - this._loadDictConcatToOptions(column) | |
978 | + return {} | |
979 | + }) | |
980 | + } | |
981 | + if (column.dictCode) { | |
982 | + this._loadDictConcatToOptions(column) | |
983 | + } | |
915 | 984 | } |
916 | - } | |
985 | + }) | |
917 | 986 | }) |
918 | 987 | } |
919 | 988 | }, |
... | ... | @@ -923,19 +992,12 @@ |
923 | 992 | } |
924 | 993 | }, |
925 | 994 | mounted() { |
926 | - // 获取document element对象 | |
927 | - let elements = {}; | |
928 | - ['inputTable', 'tbody'].forEach(id => { | |
929 | - elements[id] = document.getElementById(this.caseId + id) | |
930 | - }) | |
931 | - this.el = elements | |
932 | - | |
933 | 995 | let vm = this |
934 | 996 | /** 监听滚动条事件 */ |
935 | - this.el.inputTable.onscroll = function (event) { | |
997 | + this.getElement('inputTable').onscroll = function (event) { | |
936 | 998 | vm.syncScrollBar(event.target.scrollLeft) |
937 | 999 | } |
938 | - this.el.tbody.onscroll = function (event) { | |
1000 | + this.getElement('tbody').onscroll = function (event) { | |
939 | 1001 | // vm.recalcTrHiddenItem(event.target.scrollTop) |
940 | 1002 | } |
941 | 1003 | |
... | ... | @@ -955,6 +1017,25 @@ |
955 | 1017 | }, |
956 | 1018 | methods: { |
957 | 1019 | |
1020 | + getElement(id, noCaseId = false) { | |
1021 | + if (!this.el[id]) { | |
1022 | + this.el[id] = document.getElementById((noCaseId ? '' : this.caseId) + id) | |
1023 | + } | |
1024 | + return this.el[id] | |
1025 | + }, | |
1026 | + | |
1027 | + getElementPromise(id, noCaseId = false) { | |
1028 | + return new Promise((resolve) => { | |
1029 | + let timer = setInterval(() => { | |
1030 | + let element = this.getElement(id, noCaseId) | |
1031 | + if (element) { | |
1032 | + clearInterval(timer) | |
1033 | + resolve(element) | |
1034 | + } | |
1035 | + }, 10) | |
1036 | + }) | |
1037 | + }, | |
1038 | + | |
958 | 1039 | /** 初始化列表 */ |
959 | 1040 | initialize() { |
960 | 1041 | // inputValues:用来存储input表单的值 |
... | ... | @@ -985,14 +1066,14 @@ |
985 | 1066 | this.searchSelectValues = [] |
986 | 1067 | this.scrollTop = 0 |
987 | 1068 | this.$nextTick(() => { |
988 | - this.el.tbody.scrollTop = 0 | |
1069 | + this.getElement('tbody').scrollTop = 0 | |
989 | 1070 | }) |
990 | 1071 | }, |
991 | 1072 | |
992 | 1073 | /** 同步滚动条状态 */ |
993 | 1074 | syncScrollBar(scrollLeft) { |
994 | 1075 | // this.style.tbody.left = `${scrollLeft}px` |
995 | - // this.el.tbody.scrollLeft = scrollLeft | |
1076 | + // this.getElement('tbody').scrollLeft = scrollLeft | |
996 | 1077 | }, |
997 | 1078 | /** 重置滚动条位置,参数留空则滚动到上次记录的位置 */ |
998 | 1079 | resetScrollTop(top) { |
... | ... | @@ -1157,7 +1238,7 @@ |
1157 | 1238 | target: this |
1158 | 1239 | }) |
1159 | 1240 | // 设置滚动条位置 |
1160 | - let tbody = this.el.tbody | |
1241 | + let tbody = this.getElement('tbody') | |
1161 | 1242 | let offsetHeight = tbody.offsetHeight |
1162 | 1243 | let realScrollTop = tbody.scrollTop + offsetHeight |
1163 | 1244 | if (forceScrollToBottom === false) { |
... | ... | @@ -1245,13 +1326,14 @@ |
1245 | 1326 | return true |
1246 | 1327 | }, |
1247 | 1328 | |
1248 | - /** 获取表格表单里的值(同步版) */ | |
1249 | - getValuesSync(options = {}) { | |
1329 | + /** 获取表格表单里的值(异步版) */ | |
1330 | + getValuesAsync(options = {}, callback) { | |
1250 | 1331 | let { validate, rowIds } = options |
1251 | 1332 | if (typeof validate !== 'boolean') validate = true |
1252 | 1333 | if (!(rowIds instanceof Array)) rowIds = null |
1253 | 1334 | // console.log('options:', { validate, rowIds }) |
1254 | 1335 | |
1336 | + let asyncCount = 0 | |
1255 | 1337 | let error = 0 |
1256 | 1338 | let inputValues = cloneObject(this.inputValues) |
1257 | 1339 | let tooltips = Object.assign({}, this.tooltips) |
... | ... | @@ -1314,7 +1396,7 @@ |
1314 | 1396 | } else if (column.type === FormTypes.sel_search) { |
1315 | 1397 | value[column.key] = this.searchSelectValues[inputId] |
1316 | 1398 | } else if (column.type === FormTypes.list_multi) { |
1317 | - if (!this.multiSelectValues[inputId] || this.multiSelectValues[inputId].length == 0) { | |
1399 | + if (!this.multiSelectValues[inputId] || this.multiSelectValues[inputId].length === 0) { | |
1318 | 1400 | value[column.key] = '' |
1319 | 1401 | } else { |
1320 | 1402 | value[column.key] = this.multiSelectValues[inputId].join(',') |
... | ... | @@ -1326,20 +1408,27 @@ |
1326 | 1408 | |
1327 | 1409 | // 检查表单验证 |
1328 | 1410 | if (validate === true) { |
1329 | - let results = this.validateOneInput(value[column.key], value, column, notPassedIds, false, 'getValues') | |
1330 | - tooltips[inputId] = results[0] | |
1331 | - if (tooltips[inputId].passed === false) { | |
1332 | - error++ | |
1333 | - // if (error++ === 0) { | |
1334 | - // let element = document.getElementById(inputId) | |
1335 | - // while (element.className !== 'tr') { | |
1336 | - // element = element.parentElement | |
1337 | - // } | |
1338 | - // this.jumpToId(inputId, element) | |
1339 | - // } | |
1411 | + const handleValidateOneInput = (results) => { | |
1412 | + tooltips[inputId] = results[0] | |
1413 | + if (tooltips[inputId].passed === false) { | |
1414 | + error++ | |
1415 | + // if (error++ === 0) { | |
1416 | + // let element = document.getElementById(inputId) | |
1417 | + // while (element.className !== 'tr') { | |
1418 | + // element = element.parentElement | |
1419 | + // } | |
1420 | + // this.jumpToId(inputId, element) | |
1421 | + // } | |
1422 | + } | |
1423 | + tooltips[inputId].visible = false | |
1424 | + notPassedIds = results[1] | |
1340 | 1425 | } |
1341 | - tooltips[inputId].visible = false | |
1342 | - notPassedIds = results[1] | |
1426 | + asyncCount++ | |
1427 | + let results = this.validateOneInputAsync(value[column.key], value, column, notPassedIds, false, 'getValues', (results) => { | |
1428 | + handleValidateOneInput(results) | |
1429 | + asyncCount-- | |
1430 | + }) | |
1431 | + handleValidateOneInput(results) | |
1343 | 1432 | } |
1344 | 1433 | }) |
1345 | 1434 | // 将caseId去除 |
... | ... | @@ -1352,25 +1441,42 @@ |
1352 | 1441 | this.tooltips = tooltips |
1353 | 1442 | this.notPassedIds = notPassedIds |
1354 | 1443 | } |
1444 | + | |
1445 | + const timer = setInterval(() => { | |
1446 | + if (asyncCount === 0) { | |
1447 | + clearInterval(timer) | |
1448 | + if (typeof callback === 'function') { | |
1449 | + callback({ error, values }) | |
1450 | + } | |
1451 | + } | |
1452 | + }, 50) | |
1453 | + | |
1355 | 1454 | return { error, values } |
1356 | 1455 | }, |
1357 | 1456 | |
1457 | + /** 获取表格表单里的值(同步版) */ | |
1458 | + getValuesSync(options = {}) { | |
1459 | + return this.getValuesAsync(options) | |
1460 | + }, | |
1461 | + | |
1358 | 1462 | /** 获取表格表单里的值 */ |
1359 | 1463 | getValues(callback, validate = true, rowIds) { |
1360 | - let result = this.getValuesSync({ validate, rowIds }) | |
1361 | - if (typeof callback === 'function') { | |
1362 | - callback(result.error, result.values) | |
1363 | - } | |
1464 | + this.getValuesAsync({ validate, rowIds }, ({ error, values }) => { | |
1465 | + if (typeof callback === 'function') { | |
1466 | + callback(error, values) | |
1467 | + } | |
1468 | + }) | |
1364 | 1469 | }, |
1365 | 1470 | /** getValues的Promise版 */ |
1366 | 1471 | getValuesPromise(validate = true, rowIds) { |
1367 | 1472 | return new Promise((resolve, reject) => { |
1368 | - let { error, values } = this.getValuesSync({ validate, rowIds }) | |
1369 | - if (error === 0) { | |
1370 | - resolve(values) | |
1371 | - } else { | |
1372 | - reject(VALIDATE_NO_PASSED) | |
1373 | - } | |
1473 | + this.getValuesAsync({ validate, rowIds }, ({ error, values }) => { | |
1474 | + if (error === 0) { | |
1475 | + resolve(values) | |
1476 | + } else { | |
1477 | + reject(VALIDATE_NO_PASSED) | |
1478 | + } | |
1479 | + }) | |
1374 | 1480 | }) |
1375 | 1481 | }, |
1376 | 1482 | /** 获取被删除项的id */ |
... | ... | @@ -1468,14 +1574,24 @@ |
1468 | 1574 | // element = document.getElementById(id) |
1469 | 1575 | // } |
1470 | 1576 | // if (element != null) { |
1471 | - // console.log(this.el.tbody.scrollTop, element.offsetTop) | |
1472 | - // this.el.tbody.scrollTop = element.offsetTop | |
1473 | - // console.log(this.el.tbody.scrollTop, element.offsetTop) | |
1577 | + // console.log(this.getElement('tbody').scrollTop, element.offsetTop) | |
1578 | + // this.getElement('tbody').scrollTop = element.offsetTop | |
1579 | + // console.log(this.getElement('tbody').scrollTop, element.offsetTop) | |
1474 | 1580 | // } |
1475 | 1581 | // }, |
1476 | 1582 | |
1477 | - /** 验证单个表单 */ | |
1478 | - validateOneInput(value, row, column, notPassedIds, update = false, validType = 'input') { | |
1583 | + /** | |
1584 | + * 验证单个表单,异步版 | |
1585 | + * | |
1586 | + * @param value 校验的值 | |
1587 | + * @param row 校验的行 | |
1588 | + * @param column 校验的列 | |
1589 | + * @param notPassedIds 没有通过校验的 id | |
1590 | + * @param update 是否更新到vue中 | |
1591 | + * @param validType 校验触发的方式(input、blur等) | |
1592 | + * @param callback | |
1593 | + */ | |
1594 | + validateOneInputAsync(value, row, column, notPassedIds, update = false, validType = 'input', callback) { | |
1479 | 1595 | let tooltips = Object.assign({}, this.tooltips) |
1480 | 1596 | // let notPassedIds = cloneObject(this.notPassedIds) |
1481 | 1597 | let inputId = column.key + row.id |
... | ... | @@ -1515,6 +1631,10 @@ |
1515 | 1631 | if (column.type === FormTypes.date || column.type === FormTypes.datetime) { |
1516 | 1632 | element = element.getElementsByTagName('input')[0] |
1517 | 1633 | } |
1634 | + // upload 在 .ant-upload .ant-btn 上设置 border-color | |
1635 | + if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) { | |
1636 | + element = element.getElementsByClassName('ant-upload')[0].getElementsByClassName('ant-btn')[0] | |
1637 | + } | |
1518 | 1638 | element.style.borderColor = borderColor |
1519 | 1639 | element.style.boxShadow = boxShadow |
1520 | 1640 | if (element.tagName === 'SPAN') { |
... | ... | @@ -1527,6 +1647,10 @@ |
1527 | 1647 | this.notPassedIds = notPassedIds |
1528 | 1648 | } |
1529 | 1649 | |
1650 | + if (typeof callback === 'function') { | |
1651 | + callback([tooltips[inputId], notPassedIds]) | |
1652 | + } | |
1653 | + | |
1530 | 1654 | } |
1531 | 1655 | |
1532 | 1656 | if (typeof passed === 'function') { |
... | ... | @@ -1547,9 +1671,13 @@ |
1547 | 1671 | nextThen([passed, message]) |
1548 | 1672 | } |
1549 | 1673 | |
1550 | - | |
1551 | 1674 | return [tooltips[inputId], notPassedIds] |
1552 | 1675 | }, |
1676 | + | |
1677 | + /** 验证单个表单 */ | |
1678 | + validateOneInput(value, row, column, notPassedIds, update = false, validType = 'input') { | |
1679 | + return this.validateOneInputAsync(value, row, column, notPassedIds, update, validType) | |
1680 | + }, | |
1553 | 1681 | /** 通过规则验证值是否正确 */ |
1554 | 1682 | validateValue(column, value) { |
1555 | 1683 | let rules = column.validateRules |
... | ... | @@ -1620,7 +1748,7 @@ |
1620 | 1748 | |
1621 | 1749 | /** 动态更新表单的值 */ |
1622 | 1750 | updateFormValues() { |
1623 | - let trs = this.el.tbody.getElementsByClassName('tr') | |
1751 | + let trs = this.getElement('tbody').getElementsByClassName('tr') | |
1624 | 1752 | let trEls = [] |
1625 | 1753 | for (let tr of trs) { |
1626 | 1754 | trEls.push(tr) |
... | ... | @@ -1959,7 +2087,7 @@ |
1959 | 2087 | handleClickDownloadFile(id) { |
1960 | 2088 | let { path } = this.uploadValues[id] || {} |
1961 | 2089 | if (path) { |
1962 | - let url = window._CONFIG['downloadUrl'] + '/' + path | |
2090 | + let url = window._CONFIG['staticDomainURL'] + '/' + path | |
1963 | 2091 | window.open(url) |
1964 | 2092 | } |
1965 | 2093 | }, |
... | ... | @@ -2130,7 +2258,7 @@ |
2130 | 2258 | getCellImageView(id) { |
2131 | 2259 | let currUploadObj = this.uploadValues[id] || null |
2132 | 2260 | if (currUploadObj && currUploadObj['path']) { |
2133 | - return window._CONFIG['domianURL'] + '/sys/common/view/' + currUploadObj['path'] | |
2261 | + return window._CONFIG['staticDomainURL'] + '/' + currUploadObj['path'] | |
2134 | 2262 | } else { |
2135 | 2263 | return '' |
2136 | 2264 | } |
... | ... | @@ -2340,7 +2468,7 @@ |
2340 | 2468 | |
2341 | 2469 | .td { |
2342 | 2470 | /*flex: 1;*/ |
2343 | - padding: 14px 0 14px @spacing; | |
2471 | + padding: 14px @spacing 14px 0; | |
2344 | 2472 | justify-content: center; |
2345 | 2473 | |
2346 | 2474 | &:last-child { |
... | ... |
ant-design-vue-jeecg/src/components/jeecg/JGraphicCode.vue
ant-design-vue-jeecg/src/components/jeecg/JImageUpload.vue
0 → 100644
1 | +<template> | |
2 | + <a-upload | |
3 | + name="file" | |
4 | + listType="picture-card" | |
5 | + :multiple="isMultiple" | |
6 | + :action="uploadAction" | |
7 | + :headers="headers" | |
8 | + :data="{biz:bizPath}" | |
9 | + :fileList="fileList" | |
10 | + :beforeUpload="beforeUpload" | |
11 | + :disabled="disabled" | |
12 | + :isMultiple="isMultiple" | |
13 | + :showUploadList="isMultiple" | |
14 | + @change="handleChange" | |
15 | + @preview="handlePreview"> | |
16 | + <img v-if="!isMultiple && picUrl" :src="getAvatarView()" style="height:104px;max-width:300px"/> | |
17 | + <div v-else > | |
18 | + <a-icon :type="uploadLoading ? 'loading' : 'plus'" /> | |
19 | + <div class="ant-upload-text">{{ text }}</div> | |
20 | + </div> | |
21 | + <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel()"> | |
22 | + <img alt="example" style="width: 100%" :src="previewImage"/> | |
23 | + </a-modal> | |
24 | + </a-upload> | |
25 | +</template> | |
26 | + | |
27 | +<script> | |
28 | + import Vue from 'vue' | |
29 | + import { ACCESS_TOKEN } from "@/store/mutation-types" | |
30 | + import { getFileAccessHttpUrl } from '@/api/manage' | |
31 | + | |
32 | + const uidGenerator=()=>{ | |
33 | + return '-'+parseInt(Math.random()*10000+1,10); | |
34 | + } | |
35 | + const getFileName=(path)=>{ | |
36 | + if(path.lastIndexOf("\\")>=0){ | |
37 | + let reg=new RegExp("\\\\","g"); | |
38 | + path = path.replace(reg,"/"); | |
39 | + } | |
40 | + return path.substring(path.lastIndexOf("/")+1); | |
41 | + } | |
42 | + export default { | |
43 | + name: 'JImageUpload', | |
44 | + data(){ | |
45 | + return { | |
46 | + uploadAction:window._CONFIG['domianURL']+"/sys/common/upload", | |
47 | + urlView:window._CONFIG['staticDomainURL'], | |
48 | + uploadLoading:false, | |
49 | + picUrl:false, | |
50 | + headers:{}, | |
51 | + fileList: [], | |
52 | + previewImage:"", | |
53 | + previewVisible: false, | |
54 | + } | |
55 | + }, | |
56 | + props:{ | |
57 | + text:{ | |
58 | + type:String, | |
59 | + required:false, | |
60 | + default:"上传" | |
61 | + }, | |
62 | + /*这个属性用于控制文件上传的业务路径*/ | |
63 | + bizPath:{ | |
64 | + type:String, | |
65 | + required:false, | |
66 | + default:"temp" | |
67 | + }, | |
68 | + value:{ | |
69 | + type:[String,Array], | |
70 | + required:false | |
71 | + }, | |
72 | + disabled:{ | |
73 | + type:Boolean, | |
74 | + required:false, | |
75 | + default: false | |
76 | + }, | |
77 | + isMultiple:{ | |
78 | + type:Boolean, | |
79 | + required:false, | |
80 | + default: false | |
81 | + } | |
82 | + }, | |
83 | + watch:{ | |
84 | + value(val){ | |
85 | + if (val instanceof Array) { | |
86 | + this.initFileList(val.join(',')) | |
87 | + } else { | |
88 | + this.initFileList(val) | |
89 | + } | |
90 | + } | |
91 | + }, | |
92 | + created(){ | |
93 | + const token = Vue.ls.get(ACCESS_TOKEN); | |
94 | + this.headers = {"X-Access-Token":token} | |
95 | + }, | |
96 | + methods:{ | |
97 | + initFileList(paths){ | |
98 | + if(!paths || paths.length==0){ | |
99 | + this.fileList = []; | |
100 | + return; | |
101 | + } | |
102 | + this.picUrl = true; | |
103 | + let fileList = []; | |
104 | + let arr = paths.split(",") | |
105 | + for(var a=0;a<arr.length;a++){ | |
106 | + let url = getFileAccessHttpUrl(arr[a],this.urlView,"http"); | |
107 | + fileList.push({ | |
108 | + uid: uidGenerator(), | |
109 | + name: getFileName(arr[a]), | |
110 | + status: 'done', | |
111 | + url: url, | |
112 | + response:{ | |
113 | + status:"history", | |
114 | + message:arr[a] | |
115 | + } | |
116 | + }) | |
117 | + } | |
118 | + this.fileList = fileList | |
119 | + }, | |
120 | + beforeUpload: function(file){ | |
121 | + var fileType = file.type; | |
122 | + if(fileType.indexOf('image')<0){ | |
123 | + this.$message.warning('请上传图片'); | |
124 | + return false; | |
125 | + } | |
126 | + }, | |
127 | + handleChange(info) { | |
128 | + this.picUrl = false; | |
129 | + let fileList = info.fileList | |
130 | + if(info.file.status==='done'){ | |
131 | + if(info.file.response.success){ | |
132 | + this.picUrl = true; | |
133 | + fileList = fileList.map((file) => { | |
134 | + if (file.response) { | |
135 | + file.url = file.response.message; | |
136 | + } | |
137 | + return file; | |
138 | + }); | |
139 | + } | |
140 | + //this.$message.success(`${info.file.name} 上传成功!`); | |
141 | + }else if (info.file.status === 'error') { | |
142 | + this.$message.error(`${info.file.name} 上传失败.`); | |
143 | + }else if(info.file.status === 'removed'){ | |
144 | + this.handleDelete(info.file) | |
145 | + } | |
146 | + this.fileList = fileList | |
147 | + if(info.file.status==='done' || info.file.status === 'removed'){ | |
148 | + this.handlePathChange() | |
149 | + } | |
150 | + }, | |
151 | + // 预览 | |
152 | + handlePreview (file) { | |
153 | + this.previewImage = file.url || file.thumbUrl | |
154 | + this.previewVisible = true | |
155 | + }, | |
156 | + getAvatarView(){ | |
157 | + if(this.fileList.length>0){ | |
158 | + let url = this.fileList[0].url | |
159 | + return getFileAccessHttpUrl(url,this.urlView,"http") | |
160 | + } | |
161 | + }, | |
162 | + handlePathChange(){ | |
163 | + let uploadFiles = this.fileList | |
164 | + let path = '' | |
165 | + if(!uploadFiles || uploadFiles.length==0){ | |
166 | + path = '' | |
167 | + } | |
168 | + let arr = []; | |
169 | + if(!this.isMultiple){ | |
170 | + arr.push(uploadFiles[uploadFiles.length-1].response.message) | |
171 | + }else{ | |
172 | + for(var a=0;a<uploadFiles.length;a++){ | |
173 | + arr.push(uploadFiles[a].response.message) | |
174 | + } | |
175 | + } | |
176 | + if(arr.length>0){ | |
177 | + path = arr.join(",") | |
178 | + } | |
179 | + this.$emit('change', path); | |
180 | + }, | |
181 | + handleDelete(file){ | |
182 | + //如有需要新增 删除逻辑 | |
183 | + console.log(file) | |
184 | + }, | |
185 | + handleCancel() { | |
186 | + this.close(); | |
187 | + this.previewVisible = false; | |
188 | + }, | |
189 | + close () { | |
190 | + | |
191 | + }, | |
192 | + }, | |
193 | + model: { | |
194 | + prop: 'value', | |
195 | + event: 'change' | |
196 | + } | |
197 | + } | |
198 | +</script> | |
199 | + | |
200 | +<style scoped> | |
201 | + | |
202 | +</style> | |
0 | 203 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/components/jeecg/JImportModal.vue
... | ... | @@ -42,6 +42,11 @@ |
42 | 42 | type: String, |
43 | 43 | default: '', |
44 | 44 | required: false |
45 | + }, | |
46 | + biz:{ | |
47 | + type: String, | |
48 | + default: '', | |
49 | + required: false | |
45 | 50 | } |
46 | 51 | }, |
47 | 52 | data(){ |
... | ... | @@ -49,7 +54,8 @@ |
49 | 54 | visible:false, |
50 | 55 | uploading:false, |
51 | 56 | fileList:[], |
52 | - uploadAction:'' | |
57 | + uploadAction:'', | |
58 | + foreignKeys:'' | |
53 | 59 | } |
54 | 60 | }, |
55 | 61 | watch: { |
... | ... | @@ -67,10 +73,11 @@ |
67 | 73 | handleClose(){ |
68 | 74 | this.visible=false |
69 | 75 | }, |
70 | - show(){ | |
76 | + show(arg){ | |
71 | 77 | this.fileList = [] |
72 | 78 | this.uploading = false |
73 | 79 | this.visible = true |
80 | + this.foreignKeys = arg; | |
74 | 81 | }, |
75 | 82 | handleRemove(file) { |
76 | 83 | const index = this.fileList.indexOf(file); |
... | ... | @@ -85,6 +92,12 @@ |
85 | 92 | handleImport() { |
86 | 93 | const { fileList } = this; |
87 | 94 | const formData = new FormData(); |
95 | + if(this.biz){ | |
96 | + formData.append('isSingleTableImport',this.biz); | |
97 | + } | |
98 | + if(this.foreignKeys && this.foreignKeys.length>0){ | |
99 | + formData.append('foreignKeys',this.foreignKeys); | |
100 | + } | |
88 | 101 | fileList.forEach((file) => { |
89 | 102 | formData.append('files[]', file); |
90 | 103 | }); |
... | ... |
ant-design-vue-jeecg/src/components/jeecg/JModal/index.vue
0 → 100644
1 | +<template> | |
2 | + <a-modal | |
3 | + ref="modal" | |
4 | + class="j-modal-box" | |
5 | + :class="{'fullscreen':innerFullscreen,'no-title':isNoTitle,'no-footer':isNoFooter,}" | |
6 | + :visible="visible" | |
7 | + v-bind="_attrs" | |
8 | + v-on="$listeners" | |
9 | + @ok="handleOk" | |
10 | + @cancel="handleCancel" | |
11 | + > | |
12 | + | |
13 | + <slot></slot> | |
14 | + | |
15 | + <template v-if="!isNoTitle" slot="title"> | |
16 | + <a-row class="j-modal-title-row" type="flex"> | |
17 | + <a-col class="left"> | |
18 | + <slot name="title">{{ title }}</slot> | |
19 | + </a-col> | |
20 | + <a-col v-if="switchFullscreen" class="right" @click="toggleFullscreen"> | |
21 | + <a-button class="ant-modal-close ant-modal-close-x" ghost type="link" :icon="fullscreenButtonIcon"/> | |
22 | + </a-col> | |
23 | + </a-row> | |
24 | + </template> | |
25 | + | |
26 | + <!-- 处理 scopedSlots --> | |
27 | + <template v-for="slotName of scopedSlotsKeys" :slot="slotName"> | |
28 | + <slot :name="slotName"></slot> | |
29 | + </template> | |
30 | + | |
31 | + <!-- 处理 slots --> | |
32 | + <template v-for="slotName of slotsKeys" v-slot:[slotName]> | |
33 | + <slot :name="slotName"></slot> | |
34 | + </template> | |
35 | + | |
36 | + </a-modal> | |
37 | +</template> | |
38 | + | |
39 | +<script> | |
40 | + import ACol from 'ant-design-vue/es/grid/Col' | |
41 | + | |
42 | + export default { | |
43 | + name: 'JModal', | |
44 | + components: { ACol }, | |
45 | + props: { | |
46 | + title: String, | |
47 | + // 可使用 .sync 修饰符 | |
48 | + visible: Boolean, | |
49 | + // 是否在弹出时禁止 body 滚动 | |
50 | + lockScroll: { | |
51 | + type: Boolean, | |
52 | + default: true | |
53 | + }, | |
54 | + // 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符 | |
55 | + fullscreen: { | |
56 | + type: Boolean, | |
57 | + default: true | |
58 | + }, | |
59 | + // 是否允许切换全屏(允许后右上角会出现一个按钮) | |
60 | + switchFullscreen: { | |
61 | + type: Boolean, | |
62 | + default: false | |
63 | + }, | |
64 | + }, | |
65 | + data() { | |
66 | + return { | |
67 | + // 内部使用的 slots ,不再处理 | |
68 | + usedSlots: ['title'], | |
69 | + | |
70 | + // 缓存 body 的 overflow | |
71 | + bodyOverflowCache: '', | |
72 | + innerFullscreen: this.fullscreen, | |
73 | + fullscreenButtonIcon: 'fullscreen-exit', | |
74 | + } | |
75 | + }, | |
76 | + computed: { | |
77 | + // 一些未处理的参数或特殊处理的参数绑定到 a-modal 上 | |
78 | + _attrs() { | |
79 | + let attrs = { ...this.$attrs } | |
80 | + // 如果全屏就将宽度设为 100% | |
81 | + if (this.innerFullscreen) { | |
82 | + attrs['width'] = '100%' | |
83 | + } | |
84 | + return attrs | |
85 | + }, | |
86 | + isNoTitle() { | |
87 | + return !this.title && !this.allSlotsKeys.includes('title') | |
88 | + }, | |
89 | + isNoFooter() { | |
90 | + return this._attrs['footer'] === null | |
91 | + }, | |
92 | + slotsKeys() { | |
93 | + return Object.keys(this.$slots).filter(key => !this.usedSlots.includes(key)) | |
94 | + }, | |
95 | + scopedSlotsKeys() { | |
96 | + return Object.keys(this.$scopedSlots).filter(key => !this.usedSlots.includes(key)) | |
97 | + }, | |
98 | + allSlotsKeys() { | |
99 | + return this.slotsKeys.concat(this.scopedSlotsKeys) | |
100 | + }, | |
101 | + // 是否锁定body滚动 | |
102 | + lockBodyScroll() { | |
103 | + return this.lockScroll || this.innerFullscreen | |
104 | + } | |
105 | + }, | |
106 | + watch: { | |
107 | + visible() { | |
108 | + if (this.visible) { | |
109 | + this.innerFullscreen = this.fullscreen | |
110 | + } | |
111 | + if (this.lockBodyScroll) { | |
112 | + if (this.visible) { | |
113 | + this.bodyOverflowCache = document.body.style.overflow | |
114 | + document.body.style.overflow = 'hidden' | |
115 | + } else { | |
116 | + document.body.style.overflow = this.bodyOverflowCache | |
117 | + } | |
118 | + } | |
119 | + }, | |
120 | + innerFullscreen(val) { | |
121 | + this.$emit('update:fullscreen', val) | |
122 | + }, | |
123 | + }, | |
124 | + methods: { | |
125 | + | |
126 | + close() { | |
127 | + this.$emit('update:visible', false) | |
128 | + }, | |
129 | + | |
130 | + handleOk() { | |
131 | + this.close() | |
132 | + }, | |
133 | + handleCancel() { | |
134 | + this.close() | |
135 | + }, | |
136 | + | |
137 | + toggleFullscreen() { | |
138 | + if (this.innerFullscreen) { | |
139 | + this.fullscreenButtonIcon = 'fullscreen' | |
140 | + } else { | |
141 | + this.fullscreenButtonIcon = 'fullscreen-exit' | |
142 | + } | |
143 | + this.innerFullscreen = !this.innerFullscreen | |
144 | + }, | |
145 | + | |
146 | + } | |
147 | + } | |
148 | +</script> | |
149 | + | |
150 | +<style lang="scss"> | |
151 | + .j-modal-box { | |
152 | + | |
153 | + &.fullscreen { | |
154 | + top: 0; | |
155 | + left: 0; | |
156 | + padding: 0; | |
157 | + | |
158 | + height: 100vh; | |
159 | + | |
160 | + & .ant-modal-content { | |
161 | + height: 100vh; | |
162 | + border-radius: 0; | |
163 | + | |
164 | + & .ant-modal-body { | |
165 | + /* title 和 footer 各占 55px */ | |
166 | + height: calc(100% - 55px - 55px); | |
167 | + overflow: auto; | |
168 | + } | |
169 | + } | |
170 | + | |
171 | + &.no-title, &.no-footer { | |
172 | + .ant-modal-body { | |
173 | + height: calc(100% - 55px); | |
174 | + } | |
175 | + } | |
176 | + | |
177 | + &.no-title.no-footer { | |
178 | + .ant-modal-body { | |
179 | + height: 100%; | |
180 | + } | |
181 | + } | |
182 | + | |
183 | + } | |
184 | + | |
185 | + .j-modal-title-row { | |
186 | + .left { | |
187 | + width: calc(100% - 56px - 56px); | |
188 | + } | |
189 | + | |
190 | + .right { | |
191 | + width: 56px; | |
192 | + | |
193 | + .ant-modal-close { | |
194 | + right: 56px; | |
195 | + color: rgba(0, 0, 0, 0.45); | |
196 | + | |
197 | + &:hover { | |
198 | + color: rgba(0, 0, 0, 0.75); | |
199 | + } | |
200 | + | |
201 | + } | |
202 | + } | |
203 | + } | |
204 | + | |
205 | + /deep/ { | |
206 | + | |
207 | + } | |
208 | + } | |
209 | +</style> | |
0 | 210 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/components/jeecg/JSuperQuery.vue
1 | 1 | <template> |
2 | 2 | <div class="j-super-query-box"> |
3 | 3 | |
4 | - <slot> | |
5 | - <a-tooltip v-if="superQueryFlag" title="已有高级查询条件生效"> | |
6 | - <a-button type="primary" @click="visible=true"> | |
7 | - <a-icon type="appstore" theme="twoTone" :spin="true"></a-icon> | |
8 | - <span>高级查询</span> | |
9 | - </a-button> | |
10 | - </a-tooltip> | |
11 | - <a-button v-else type="primary" icon="filter" @click="visible=true">高级查询</a-button> | |
12 | - </slot> | |
4 | + <div @click="visible=true"> | |
5 | + <slot> | |
6 | + <a-tooltip v-if="superQueryFlag" :mouseLeaveDelay="0.2"> | |
7 | + <template slot="title"> | |
8 | + <span>已有高级查询条件生效</span> | |
9 | + <a-divider type="vertical"/> | |
10 | + <a @click="handleReset">清空</a> | |
11 | + </template> | |
12 | + <a-button type="primary"> | |
13 | + <a-icon type="appstore" theme="twoTone" :spin="true"></a-icon> | |
14 | + <span>高级查询</span> | |
15 | + </a-button> | |
16 | + </a-tooltip> | |
17 | + <a-button v-else type="primary" icon="filter" @click="visible=true">高级查询</a-button> | |
18 | + </slot> | |
19 | + </div> | |
13 | 20 | |
14 | 21 | <a-modal |
15 | 22 | title="高级查询构造器" |
... | ... |
ant-design-vue-jeecg/src/components/jeecg/JUpload.vue
... | ... | @@ -4,11 +4,12 @@ |
4 | 4 | :multiple="true" |
5 | 5 | :action="uploadAction" |
6 | 6 | :headers="headers" |
7 | - :data="{'isup':1,'bizPath':bizPath}" | |
7 | + :data="{'biz':bizPath}" | |
8 | 8 | :fileList="fileList" |
9 | 9 | :beforeUpload="beforeUpload" |
10 | 10 | @change="handleChange" |
11 | - :disabled="disabled"> | |
11 | + :disabled="disabled" | |
12 | + :returnUrl="returnUrl"> | |
12 | 13 | <a-button> |
13 | 14 | <a-icon type="upload" />{{ text }} |
14 | 15 | </a-button> |
... | ... | @@ -19,6 +20,7 @@ |
19 | 20 | |
20 | 21 | import Vue from 'vue' |
21 | 22 | import { ACCESS_TOKEN } from "@/store/mutation-types" |
23 | + import { getFileAccessHttpUrl } from '@/api/manage'; | |
22 | 24 | |
23 | 25 | const FILE_TYPE_ALL = "all" |
24 | 26 | const FILE_TYPE_IMG = "image" |
... | ... | @@ -38,9 +40,10 @@ |
38 | 40 | data(){ |
39 | 41 | return { |
40 | 42 | uploadAction:window._CONFIG['domianURL']+"/sys/common/upload", |
41 | - urlDownload:window._CONFIG['domianURL'] + "/sys/common/download/", | |
43 | + urlDownload:window._CONFIG['staticDomainURL'], | |
42 | 44 | headers:{}, |
43 | - fileList: [] | |
45 | + fileList: [], | |
46 | + newFileList: [], | |
44 | 47 | } |
45 | 48 | }, |
46 | 49 | props:{ |
... | ... | @@ -77,11 +80,25 @@ |
77 | 80 | required: false, |
78 | 81 | default: false |
79 | 82 | }, |
83 | + /** | |
84 | + * update -- author:lvdandan -- date:20190219 -- for:Jupload组件增加是否返回url, | |
85 | + * true:仅返回url | |
86 | + * false:返回fileName filePath fileSize | |
87 | + */ | |
88 | + returnUrl:{ | |
89 | + type:Boolean, | |
90 | + required:false, | |
91 | + default: true | |
92 | + }, | |
80 | 93 | }, |
81 | 94 | watch:{ |
82 | 95 | value(val){ |
83 | 96 | if (val instanceof Array) { |
84 | - this.initFileList(val.join(',')) | |
97 | + if(this.returnUrl){ | |
98 | + this.initFileList(val.join(',')) | |
99 | + }else{ | |
100 | + this.initFileListArr(val); | |
101 | + } | |
85 | 102 | } else { |
86 | 103 | this.initFileList(val) |
87 | 104 | } |
... | ... | @@ -93,6 +110,26 @@ |
93 | 110 | }, |
94 | 111 | |
95 | 112 | methods:{ |
113 | + initFileListArr(val){ | |
114 | + if(!val || val.length==0){ | |
115 | + this.fileList = []; | |
116 | + return; | |
117 | + } | |
118 | + let fileList = []; | |
119 | + for(var a=0;a<val.length;a++){ | |
120 | + fileList.push({ | |
121 | + uid:uidGenerator(), | |
122 | + name:val[a].fileName, | |
123 | + status: 'done', | |
124 | + url: val[a].filePath, | |
125 | + response:{ | |
126 | + status:"history", | |
127 | + message:val[a].filePath | |
128 | + } | |
129 | + }) | |
130 | + } | |
131 | + this.fileList = fileList | |
132 | + }, | |
96 | 133 | initFileList(paths){ |
97 | 134 | if(!paths || paths.length==0){ |
98 | 135 | //return []; |
... | ... | @@ -104,11 +141,12 @@ |
104 | 141 | let fileList = []; |
105 | 142 | let arr = paths.split(",") |
106 | 143 | for(var a=0;a<arr.length;a++){ |
144 | + let url = getFileAccessHttpUrl(arr[a],this.urlDownload,"http"); | |
107 | 145 | fileList.push({ |
108 | 146 | uid:uidGenerator(), |
109 | 147 | name:getFileName(arr[a]), |
110 | 148 | status: 'done', |
111 | - url: this.urlDownload+arr[a], | |
149 | + url: url, | |
112 | 150 | response:{ |
113 | 151 | status:"history", |
114 | 152 | message:arr[a] |
... | ... | @@ -156,12 +194,13 @@ |
156 | 194 | if(info.file.response.success){ |
157 | 195 | fileList = fileList.map((file) => { |
158 | 196 | if (file.response) { |
159 | - file.url = this.urlDownload+file.response.message; | |
197 | + let reUrl = file.response.message; | |
198 | + file.url = getFileAccessHttpUrl(reUrl,this.urlDownload,"http"); | |
160 | 199 | } |
161 | 200 | return file; |
162 | 201 | }); |
163 | 202 | } |
164 | - this.$message.success(`${info.file.name} 上传成功!`); | |
203 | + //this.$message.success(`${info.file.name} 上传成功!`); | |
165 | 204 | }else if (info.file.status === 'error') { |
166 | 205 | this.$message.error(`${info.file.name} 上传失败.`); |
167 | 206 | }else if(info.file.status === 'removed'){ |
... | ... | @@ -169,7 +208,26 @@ |
169 | 208 | } |
170 | 209 | this.fileList = fileList |
171 | 210 | if(info.file.status==='done' || info.file.status === 'removed'){ |
172 | - this.handlePathChange() | |
211 | + //returnUrl为true时仅返回文件路径 | |
212 | + if(this.returnUrl){ | |
213 | + this.handlePathChange() | |
214 | + }else{ | |
215 | + //returnUrl为false时返回文件名称、文件路径及文件大小 | |
216 | + fileList = fileList.filter((file) => { | |
217 | + if (file.response) { | |
218 | + return file.response.success === true; | |
219 | + } | |
220 | + return false; | |
221 | + }).map((file) => { | |
222 | + var fileJson = { | |
223 | + fileName:file.name, | |
224 | + filePath:file.url, | |
225 | + fileSize:file.size | |
226 | + }; | |
227 | + this.newFileList.push(fileJson); | |
228 | + this.$emit('change', this.newFileList); | |
229 | + }); | |
230 | + } | |
173 | 231 | } |
174 | 232 | }, |
175 | 233 | handleDelete(file){ |
... | ... |
ant-design-vue-jeecg/src/components/jeecg/index.js
1 | -import T from './JFormContainer.vue' | |
2 | -let install = function (Vue) { | |
3 | - Vue.component('JFormContainer',T); | |
4 | -} | |
5 | -export default { install }; | |
6 | 1 | \ No newline at end of file |
2 | +import JModal from './JModal' | |
3 | +import JFormContainer from './JFormContainer.vue' | |
4 | + | |
5 | +export default { | |
6 | + install(Vue) { | |
7 | + Vue.component('JFormContainer', JFormContainer) | |
8 | + Vue.component(JModal.name, JModal) | |
9 | + } | |
10 | +} | |
7 | 11 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/components/jeecgbiz/modal/JSelectUserByDepModal.vue
... | ... | @@ -17,9 +17,11 @@ |
17 | 17 | selectable |
18 | 18 | :selectedKeys="selectedDepIds" |
19 | 19 | :checkStrictly="true" |
20 | - @select="onDepSelect" | |
21 | 20 | :dropdownStyle="{maxHeight:'200px',overflow:'auto'}" |
22 | 21 | :treeData="departTree" |
22 | + :expandAction="false" | |
23 | + :expandedKeys.sync="expandedKeys" | |
24 | + @select="onDepSelect" | |
23 | 25 | /> |
24 | 26 | </a-card> |
25 | 27 | </a-col> |
... | ... | @@ -28,7 +30,7 @@ |
28 | 30 | 用户账号: |
29 | 31 | <a-input-search |
30 | 32 | :style="{width:'150px',marginBottom:'15px'}" |
31 | - placeholder="请输入用户账号" | |
33 | + placeholder="请输入账号" | |
32 | 34 | v-model="queryParam.username" |
33 | 35 | @search="onSearch" |
34 | 36 | ></a-input-search> |
... | ... | @@ -43,6 +45,7 @@ |
43 | 45 | :dataSource="dataSource" |
44 | 46 | :pagination="ipagination" |
45 | 47 | :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}" |
48 | + :loading="loading" | |
46 | 49 | @change="handleTableChange"> |
47 | 50 | </a-table> |
48 | 51 | </a-card> |
... | ... | @@ -71,7 +74,7 @@ |
71 | 74 | dataIndex: 'username' |
72 | 75 | }, |
73 | 76 | { |
74 | - title: '真实姓名', | |
77 | + title: '用户姓名', | |
75 | 78 | align: 'center', |
76 | 79 | dataIndex: 'realname' |
77 | 80 | }, |
... | ... | @@ -90,14 +93,14 @@ |
90 | 93 | } |
91 | 94 | }, |
92 | 95 | { |
93 | - title: '手机号码', | |
96 | + title: '手机', | |
94 | 97 | align: 'center', |
95 | 98 | dataIndex: 'phone' |
96 | 99 | }, |
97 | 100 | { |
98 | - title: '邮箱', | |
101 | + title: '部门', | |
99 | 102 | align: 'center', |
100 | - dataIndex: 'email' | |
103 | + dataIndex: 'orgCode' | |
101 | 104 | } |
102 | 105 | ], |
103 | 106 | scrollTrigger: {}, |
... | ... | @@ -124,60 +127,74 @@ |
124 | 127 | selectedDepIds: [], |
125 | 128 | departTree: [], |
126 | 129 | visible: false, |
127 | - form: this.$form.createForm(this) | |
130 | + form: this.$form.createForm(this), | |
131 | + loading: false, | |
132 | + expandedKeys: [], | |
128 | 133 | } |
129 | 134 | }, |
130 | 135 | computed: { |
131 | 136 | // 计算属性的 getter |
132 | 137 | getType: function () { |
133 | - console.log("multi: ", this.multi); | |
134 | 138 | return this.multi == true ? 'checkbox' : 'radio'; |
135 | 139 | } |
136 | 140 | }, |
137 | 141 | watch: { |
138 | - userIds() { | |
139 | - this.initUserNames() | |
140 | - } | |
142 | + userIds: { | |
143 | + immediate: true, | |
144 | + handler() { | |
145 | + this.initUserNames() | |
146 | + } | |
147 | + }, | |
141 | 148 | }, |
142 | 149 | created() { |
143 | 150 | // 该方法触发屏幕自适应 |
144 | 151 | this.resetScreenSize(); |
145 | - this.loadData().then((res) => { | |
146 | - this.initUserNames(); | |
147 | - }) | |
152 | + this.loadData() | |
148 | 153 | }, |
149 | 154 | methods: { |
150 | 155 | initUserNames() { |
151 | - let names = '' | |
152 | - console.log("props userIds: ", this.userIds) | |
153 | 156 | if (this.userIds) { |
154 | - let currUserIds = this.userIds | |
155 | - let userIdsArr = currUserIds.split(','); | |
156 | - for (let item of this.dataSource) { | |
157 | - if (userIdsArr.includes(item.username)) { | |
158 | - names += "," + item.realname | |
157 | + // 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确 | |
158 | + let values = this.userIds.split(',') + ',' | |
159 | + getUserList({ | |
160 | + username: values, | |
161 | + pageNo: 1, | |
162 | + pageSize: values.length | |
163 | + }).then((res) => { | |
164 | + if (res.success) { | |
165 | + let selectedRowKeys = [] | |
166 | + let realNames = [] | |
167 | + res.result.records.forEach(user => { | |
168 | + realNames.push(user['realname']) | |
169 | + selectedRowKeys.push(user['id']) | |
170 | + }) | |
171 | + this.selectedRowKeys = selectedRowKeys | |
172 | + this.$emit('initComp', realNames.join(',')) | |
159 | 173 | } |
160 | - } | |
161 | - if (names) { | |
162 | - names = names.substring(1) | |
163 | - } | |
164 | - this.$emit("initComp", names) | |
165 | - }else{ | |
174 | + }) | |
175 | + } else { | |
166 | 176 | // JSelectUserByDep组件bug issues/I16634 |
167 | - this.$emit("initComp", "") | |
177 | + this.$emit('initComp', '') | |
168 | 178 | } |
169 | 179 | }, |
170 | 180 | async loadData(arg) { |
171 | 181 | if (arg === 1) { |
172 | 182 | this.ipagination.current = 1; |
173 | 183 | } |
174 | - let params = this.getQueryParams();//查询条件 | |
175 | - await getUserList(params).then((res) => { | |
176 | - if (res.success) { | |
177 | - this.dataSource = res.result.records; | |
178 | - this.ipagination.total = res.result.total; | |
179 | - } | |
180 | - }) | |
184 | + if (this.selectedDepIds && this.selectedDepIds.length > 0) { | |
185 | + await this.initQueryUserByDepId(this.selectedDepIds) | |
186 | + } else { | |
187 | + this.loading = true | |
188 | + let params = this.getQueryParams()//查询条件 | |
189 | + await getUserList(params).then((res) => { | |
190 | + if (res.success) { | |
191 | + this.dataSource = res.result.records | |
192 | + this.ipagination.total = res.result.total | |
193 | + } | |
194 | + }).finally(() => { | |
195 | + this.loading = false | |
196 | + }) | |
197 | + } | |
181 | 198 | }, |
182 | 199 | // 触发屏幕自适应 |
183 | 200 | resetScreenSize() { |
... | ... | @@ -191,6 +208,7 @@ |
191 | 208 | showModal() { |
192 | 209 | this.visible = true; |
193 | 210 | this.queryDepartTree(); |
211 | + this.initUserNames() | |
194 | 212 | this.loadData(); |
195 | 213 | this.form.resetFields(); |
196 | 214 | }, |
... | ... | @@ -234,7 +252,6 @@ |
234 | 252 | handleSubmit() { |
235 | 253 | let that = this; |
236 | 254 | this.getSelectUserRows(); |
237 | - console.log(that.selectUserRows) | |
238 | 255 | that.$emit('ok', that.selectUserRows, that.selectUserIds); |
239 | 256 | that.searchReset(0) |
240 | 257 | that.close(); |
... | ... | @@ -270,17 +287,22 @@ |
270 | 287 | }, |
271 | 288 | // 根据选择的id来查询用户信息 |
272 | 289 | initQueryUserByDepId(selectedDepIds) { |
273 | - queryUserByDepId({id: selectedDepIds.toString()}).then((res) => { | |
290 | + this.loading = true | |
291 | + return queryUserByDepId({id: selectedDepIds.toString()}).then((res) => { | |
274 | 292 | if (res.success) { |
275 | 293 | this.dataSource = res.result; |
276 | 294 | this.ipagination.total = res.result.length; |
277 | 295 | } |
296 | + }).finally(() => { | |
297 | + this.loading = false | |
278 | 298 | }) |
279 | 299 | }, |
280 | 300 | queryDepartTree() { |
281 | 301 | queryDepartTreeList().then((res) => { |
282 | 302 | if (res.success) { |
283 | 303 | this.departTree = res.result; |
304 | + // 默认展开父节点 | |
305 | + this.expandedKeys = this.departTree.map(item => item.id) | |
284 | 306 | } |
285 | 307 | }) |
286 | 308 | }, |
... | ... |
ant-design-vue-jeecg/src/components/jeecgbiz/modal/SelectUserListModal.vue
ant-design-vue-jeecg/src/components/layouts/IframePageView.vue
... | ... | @@ -5,6 +5,8 @@ |
5 | 5 | </template> |
6 | 6 | |
7 | 7 | <script> |
8 | + import Vue from 'vue' | |
9 | + import { ACCESS_TOKEN } from "@/store/mutation-types" | |
8 | 10 | import PageLayout from '../page/PageLayout' |
9 | 11 | import RouteView from './RouteView' |
10 | 12 | |
... | ... | @@ -40,6 +42,12 @@ |
40 | 42 | /*update_begin author:wuxianquan date:20190908 for:判断打开方式,新窗口打开时this.$route.meta.internalOrExternal==true */ |
41 | 43 | if(this.$route.meta.internalOrExternal != undefined && this.$route.meta.internalOrExternal==true){ |
42 | 44 | this.closeCurrent(); |
45 | + //外部url加入token | |
46 | + let tokenStr = "${token}"; | |
47 | + if(url.indexOf(tokenStr)!=-1){ | |
48 | + let token = Vue.ls.get(ACCESS_TOKEN); | |
49 | + this.url = url.replace(tokenStr,token); | |
50 | + } | |
43 | 51 | window.open(this.url); |
44 | 52 | } |
45 | 53 | /*update_end author:wuxianquan date:20190908 for:判断打开方式,新窗口打开时this.$route.meta.internalOrExternal==true */ |
... | ... |
ant-design-vue-jeecg/src/components/layouts/TabLayout.vue
... | ... | @@ -80,30 +80,41 @@ |
80 | 80 | }, |
81 | 81 | created() { |
82 | 82 | if (this.$route.path != indexKey) { |
83 | - this.pageList.push({ | |
84 | - name: 'dashboard-analysis', | |
85 | - path: indexKey, | |
86 | - fullPath: indexKey, | |
87 | - meta: { | |
88 | - icon: 'dashboard', | |
89 | - title: '首页' | |
90 | - } | |
91 | - }) | |
92 | - this.linkList.push(indexKey) | |
83 | + this.addIndexToFirst() | |
93 | 84 | } |
85 | + // update-begin-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常 | |
86 | + let storeKey = 'route:title:' + this.$route.fullPath | |
87 | + let routeTitle = this.$ls.get(storeKey) | |
88 | + if (routeTitle) { | |
89 | + this.$route.meta.title = routeTitle | |
90 | + } | |
91 | + // update-end-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常 | |
94 | 92 | this.pageList.push(this.$route) |
95 | 93 | this.linkList.push(this.$route.fullPath) |
96 | 94 | this.activePage = this.$route.fullPath |
97 | 95 | }, |
98 | 96 | watch: { |
99 | 97 | '$route': function(newRoute) { |
98 | + //console.log("新的路由",newRoute) | |
100 | 99 | this.activePage = newRoute.fullPath |
101 | 100 | if (!this.multipage) { |
102 | 101 | this.linkList = [newRoute.fullPath] |
103 | 102 | this.pageList = [Object.assign({},newRoute)] |
104 | - } else if (this.linkList.indexOf(newRoute.fullPath) < 0) { | |
103 | + // update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存 | |
104 | + } else if(indexKey==newRoute.fullPath) { | |
105 | + //首页时 判断是否缓存 没有缓存 刷新之 | |
106 | + if (newRoute.meta.keepAlive === false) { | |
107 | + this.routeReload() | |
108 | + } | |
109 | + // update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存 | |
110 | + }else if (this.linkList.indexOf(newRoute.fullPath) < 0) { | |
105 | 111 | this.linkList.push(newRoute.fullPath) |
106 | 112 | this.pageList.push(Object.assign({},newRoute)) |
113 | + // update-begin-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍 | |
114 | + if (newRoute.meta.keepAlive) { | |
115 | + this.routeReload() | |
116 | + } | |
117 | + // update-end-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍 | |
107 | 118 | } else if (this.linkList.indexOf(newRoute.fullPath) >= 0) { |
108 | 119 | let oldIndex = this.linkList.indexOf(newRoute.fullPath) |
109 | 120 | let oldPositionRoute = this.pageList[oldIndex] |
... | ... | @@ -114,6 +125,7 @@ |
114 | 125 | let index = this.linkList.lastIndexOf(key) |
115 | 126 | let waitRouter = this.pageList[index] |
116 | 127 | this.$router.push(Object.assign({},waitRouter)); |
128 | + this.changeTitle(waitRouter.meta.title) | |
117 | 129 | }, |
118 | 130 | 'multipage': function(newVal) { |
119 | 131 | if(this.reloadFlag){ |
... | ... | @@ -122,9 +134,44 @@ |
122 | 134 | this.pageList = [this.$route] |
123 | 135 | } |
124 | 136 | } |
125 | - } | |
137 | + }, | |
138 | + // update-begin-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG | |
139 | + device() { | |
140 | + if (this.multipage && this.linkList.indexOf(indexKey) === -1) { | |
141 | + this.addIndexToFirst() | |
142 | + } | |
143 | + }, | |
144 | + // update-end-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG | |
126 | 145 | }, |
127 | 146 | methods: { |
147 | + // update-begin-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG | |
148 | + // 将首页添加到第一位 | |
149 | + addIndexToFirst() { | |
150 | + this.pageList.splice(0, 0, { | |
151 | + name: 'dashboard-analysis', | |
152 | + path: indexKey, | |
153 | + fullPath: indexKey, | |
154 | + meta: { | |
155 | + icon: 'dashboard', | |
156 | + title: '首页' | |
157 | + } | |
158 | + }) | |
159 | + this.linkList.splice(0, 0, indexKey) | |
160 | + }, | |
161 | + // update-end-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG | |
162 | + | |
163 | + // update-begin-author:sunjianlei date:20200120 for: 动态更改页面标题 | |
164 | + changeTitle(title) { | |
165 | + let projectTitle = "Jeecg-Boot 企业级快速开发平台" | |
166 | + // 首页特殊处理 | |
167 | + if (this.$route.path === indexKey) { | |
168 | + document.title = projectTitle | |
169 | + } else { | |
170 | + document.title = title + ' · ' + projectTitle | |
171 | + } | |
172 | + }, | |
173 | + // update-end-author:sunjianlei date:20200120 for: 动态更改页面标题 | |
174 | + | |
128 | 175 | changePage(key) { |
129 | 176 | this.activePage = key |
130 | 177 | }, |
... | ... | @@ -236,6 +283,9 @@ |
236 | 283 | let currRouter = this.pageList[keyIndex] |
237 | 284 | let meta = Object.assign({},currRouter.meta,{title:title}) |
238 | 285 | this.pageList.splice(keyIndex, 1, Object.assign({},currRouter,{meta:meta})) |
286 | + if (key === this.activePage) { | |
287 | + this.changeTitle(title) | |
288 | + } | |
239 | 289 | } |
240 | 290 | }, |
241 | 291 | //update-end-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title |
... | ... |
ant-design-vue-jeecg/src/components/layouts/UserLayout.vue
... | ... | @@ -17,12 +17,12 @@ |
17 | 17 | |
18 | 18 | <div class="footer"> |
19 | 19 | <div class="links"> |
20 | - <a href="http://jeecg-boot.mydoc.io" target="_blank">帮助</a> | |
20 | + <a href="http://doc.jeecg.com" target="_blank">帮助</a> | |
21 | 21 | <a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank">隐私</a> |
22 | - <a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank">条款</a> | |
22 | + <a href="https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE" target="_blank">条款</a> | |
23 | 23 | </div> |
24 | 24 | <div class="copyright"> |
25 | - Copyright © 2019 <a href="http://www.jeecg.org" target="_blank">JEECG开源社区</a> 出品 | |
25 | + Copyright © 2019 <a href="http://www.jeecg.com" target="_blank">JEECG开源社区</a> 出品 | |
26 | 26 | </div> |
27 | 27 | </div> |
28 | 28 | </div> |
... | ... |
ant-design-vue-jeecg/src/components/page/GlobalFooter.vue
1 | 1 | <template> |
2 | 2 | <div class="footer"> |
3 | 3 | <div class="links"> |
4 | - <a href="http://www.jeecg.org" target="_blank">JEECG 首页</a> | |
4 | + <a href="http://www.jeecg.com" target="_blank">JEECG 首页</a> | |
5 | 5 | <a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank"> |
6 | 6 | <a-icon type="github"/> |
7 | 7 | </a> |
... | ... |
ant-design-vue-jeecg/src/components/page/GlobalHeader.vue
ant-design-vue-jeecg/src/components/page/GlobalLayout.vue
... | ... | @@ -154,6 +154,10 @@ |
154 | 154 | //此处触发动态路由被点击事件 |
155 | 155 | this.findMenuBykey(this.menus,value.key) |
156 | 156 | this.$emit("dynamicRouterShow",value.key,this.activeMenu.meta.title) |
157 | + // update-begin-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常 | |
158 | + let storeKey = 'route:title:' + this.activeMenu.path | |
159 | + this.$ls.set(storeKey, this.activeMenu.meta.title) | |
160 | + // update-end-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常 | |
157 | 161 | }, |
158 | 162 | findMenuBykey(menus,key){ |
159 | 163 | for(let i of menus){ |
... | ... | @@ -337,6 +341,10 @@ |
337 | 341 | font-size: 16px; |
338 | 342 | padding: 4px; |
339 | 343 | } |
344 | + | |
345 | + .anticon { | |
346 | + color: white; | |
347 | + } | |
340 | 348 | } |
341 | 349 | } |
342 | 350 | |
... | ... | @@ -349,6 +357,10 @@ |
349 | 357 | &:hover { |
350 | 358 | background: rgba(0, 0, 0, 0.05); |
351 | 359 | } |
360 | + | |
361 | + .anticon { | |
362 | + color: black; | |
363 | + } | |
352 | 364 | } |
353 | 365 | } |
354 | 366 | } |
... | ... |
ant-design-vue-jeecg/src/components/tools/DynamicNotice.vue
0 → 100644
1 | +<template> | |
2 | + <component | |
3 | + :is="comp" | |
4 | + :formData="formData" | |
5 | + ref="compModel" | |
6 | + v-if="comp"> | |
7 | + </component> | |
8 | +</template> | |
9 | +<script> | |
10 | + export default { | |
11 | + name: 'DynamicNotice', | |
12 | + data () { | |
13 | + return { | |
14 | + compName: this.path | |
15 | + } | |
16 | + }, | |
17 | + computed: { | |
18 | + comp: function () { | |
19 | + if(!this.path){ | |
20 | + return null; | |
21 | + } | |
22 | + return () => import(`@/views/${this.path}.vue`) | |
23 | + } | |
24 | + }, | |
25 | + props: ['path','formData'], | |
26 | + methods: { | |
27 | + detail () { | |
28 | + setTimeout(() => { | |
29 | + if(this.path){ | |
30 | + this.$refs.compModel.view(this.formData); | |
31 | + } | |
32 | + }, 200) | |
33 | + }, | |
34 | + } | |
35 | + } | |
36 | +</script> | |
0 | 37 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/components/tools/HeaderNotice.vue
... | ... | @@ -72,6 +72,7 @@ |
72 | 72 | </a-badge> |
73 | 73 | </span> |
74 | 74 | <show-announcement ref="ShowAnnouncement" @ok="modalFormOk"></show-announcement> |
75 | + <dynamic-notice ref="showDynamNotice" :path="openPath" :formData="formData"/> | |
75 | 76 | </a-popover> |
76 | 77 | </template> |
77 | 78 | |
... | ... | @@ -79,11 +80,13 @@ |
79 | 80 | import { getAction,putAction } from '@/api/manage' |
80 | 81 | import ShowAnnouncement from './ShowAnnouncement' |
81 | 82 | import store from '@/store/' |
83 | + import DynamicNotice from './DynamicNotice' | |
82 | 84 | |
83 | 85 | |
84 | 86 | export default { |
85 | 87 | name: "HeaderNotice", |
86 | 88 | components: { |
89 | + DynamicNotice, | |
87 | 90 | ShowAnnouncement, |
88 | 91 | }, |
89 | 92 | data () { |
... | ... | @@ -105,6 +108,8 @@ |
105 | 108 | websock: null, |
106 | 109 | lockReconnect:false, |
107 | 110 | heartCheck:null, |
111 | + formData:{}, | |
112 | + openPath:'' | |
108 | 113 | } |
109 | 114 | }, |
110 | 115 | computed:{ |
... | ... | @@ -172,7 +177,13 @@ |
172 | 177 | } |
173 | 178 | }); |
174 | 179 | this.hovered = false; |
175 | - this.$refs.ShowAnnouncement.detail(record); | |
180 | + if(record.openType==='component'){ | |
181 | + this.openPath = record.openPage; | |
182 | + this.formData = {id:record.busId}; | |
183 | + this.$refs.showDynamNotice.detail(record.openPage); | |
184 | + }else{ | |
185 | + this.$refs.ShowAnnouncement.detail(record); | |
186 | + } | |
176 | 187 | }, |
177 | 188 | toMyAnnouncement(){ |
178 | 189 | |
... | ... |
ant-design-vue-jeecg/src/components/tools/ShowAnnouncement.vue
... | ... | @@ -5,11 +5,14 @@ |
5 | 5 | :visible="visible" |
6 | 6 | :bodyStyle ="bodyStyle" |
7 | 7 | @cancel="handleCancel" |
8 | - destroyOnClose | |
9 | - :footer="null"> | |
8 | + destroyOnClose> | |
10 | 9 | <template slot="title"> |
11 | 10 | <a-button icon="fullscreen" class="custom-btn" @click="handleClickToggleFullScreen"/> |
12 | 11 | </template> |
12 | + <template slot="footer"> | |
13 | + <a-button key="back" @click="handleCancel">关闭</a-button> | |
14 | + <a-button v-if="record.openType==='url'&&record.readFlag!=='1'" type="primary" @click="toHandle">去处理</a-button> | |
15 | + </template> | |
13 | 16 | <a-card class="daily-article" :loading="loading"> |
14 | 17 | <a-card-meta |
15 | 18 | :title="record.titile" |
... | ... | @@ -74,7 +77,14 @@ |
74 | 77 | this.modelStyle.style.top = '50px' |
75 | 78 | } |
76 | 79 | this.modelStyle.fullScreen = mode |
77 | - } | |
80 | + }, | |
81 | + toHandle(){ | |
82 | + if(this.record.openType==='url'&&this.record.readFlag!== '1'){ | |
83 | + this.visible = false; | |
84 | + //链接跳转 | |
85 | + this.$router.push({path: this.record.openPage}) | |
86 | + } | |
87 | + }, | |
78 | 88 | } |
79 | 89 | } |
80 | 90 | </script> |
... | ... |
ant-design-vue-jeecg/src/components/tools/UserMenu.vue
... | ... | @@ -5,7 +5,8 @@ |
5 | 5 | <span class="action" @click="showClick"> |
6 | 6 | <a-icon type="search"></a-icon> |
7 | 7 | </span> |
8 | - <span v-show="shows" class="borders"> | |
8 | + <!-- update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 --> | |
9 | + <component :is="searchMenuComp" v-show="searchMenuVisible || isMobile()" class="borders" :visible="searchMenuVisible" title="搜索菜单" :footer="null" @cancel="searchMenuVisible=false"> | |
9 | 10 | <a-select |
10 | 11 | class="search-input" |
11 | 12 | showSearch |
... | ... | @@ -13,16 +14,20 @@ |
13 | 14 | placeholder="搜索菜单" |
14 | 15 | optionFilterProp="children" |
15 | 16 | :filterOption="filterOption" |
17 | + :open="isMobile()?true:null" | |
18 | + :getPopupContainer="(node) => node.parentNode" | |
19 | + :style="isMobile()?{width: '100%',marginBottom:'50px'}:{}" | |
16 | 20 | @change="searchMethods" |
17 | 21 | @blur="hiddenClick" |
18 | 22 | > |
19 | - <a-select-option v-for="site in search " :value="site.id">{{site.meta.title}}</a-select-option> | |
23 | + <a-select-option v-for="site in searchMenuOptions" :value="site.id">{{site.meta.title}}</a-select-option> | |
20 | 24 | </a-select> |
21 | - </span> | |
22 | - <!-- update-end author:sunjianlei date:20191@20 for: 解决全局样式冲突的问题 --> | |
25 | + </component> | |
26 | + <!-- update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 --> | |
27 | + <!-- update-end author:sunjianlei date:20191220 for: 解决全局样式冲突的问题 --> | |
23 | 28 | <!-- update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航 --> |
24 | 29 | <span class="action"> |
25 | - <a class="logout_title" target="_blank" href="http://jeecg-boot.mydoc.io"> | |
30 | + <a class="logout_title" target="_blank" href="http://doc.jeecg.com"> | |
26 | 31 | <a-icon type="question-circle-o"></a-icon> |
27 | 32 | </a> |
28 | 33 | </span> |
... | ... | @@ -95,9 +100,11 @@ |
95 | 100 | mixins: [mixinDevice], |
96 | 101 | data(){ |
97 | 102 | return{ |
98 | - //菜单搜索 | |
99 | - search:[], | |
100 | - shows:false | |
103 | + // update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 -------------- | |
104 | + searchMenuOptions:[], | |
105 | + searchMenuComp: 'span', | |
106 | + searchMenuVisible: false, | |
107 | + // update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 -------------- | |
101 | 108 | } |
102 | 109 | }, |
103 | 110 | components: { |
... | ... | @@ -116,10 +123,8 @@ |
116 | 123 | /* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/ |
117 | 124 | created() { |
118 | 125 | let lists = [] |
119 | - console.log("permissionMenuList: ",this.permissionMenuList) | |
120 | 126 | this.searchMenus(lists,this.permissionMenuList) |
121 | - this.search=[...lists] | |
122 | - console.log(this.search) | |
127 | + this.searchMenuOptions=[...lists] | |
123 | 128 | }, |
124 | 129 | computed: { |
125 | 130 | ...mapState({ |
... | ... | @@ -129,10 +134,21 @@ |
129 | 134 | }) |
130 | 135 | }, |
131 | 136 | /* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/ |
137 | + watch: { | |
138 | + // update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 | |
139 | + device: { | |
140 | + immediate: true, | |
141 | + handler() { | |
142 | + this.searchMenuVisible = false | |
143 | + this.searchMenuComp = this.isMobile() ? 'a-modal' : 'span' | |
144 | + }, | |
145 | + }, | |
146 | + // update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 | |
147 | + }, | |
132 | 148 | methods: { |
133 | 149 | /* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/ |
134 | - showClick(){ | |
135 | - this.shows = !this.shows | |
150 | + showClick() { | |
151 | + this.searchMenuVisible = true | |
136 | 152 | }, |
137 | 153 | hiddenClick(){ |
138 | 154 | this.shows = false |
... | ... | @@ -141,8 +157,8 @@ |
141 | 157 | ...mapActions(["Logout"]), |
142 | 158 | ...mapGetters(["nickname", "avatar","userInfo"]), |
143 | 159 | getAvatar(){ |
144 | - console.log('url = '+ window._CONFIG['imgDomainURL']+"/"+this.avatar()) | |
145 | - return window._CONFIG['imgDomainURL']+"/"+this.avatar() | |
160 | + console.log('url = '+ window._CONFIG['staticDomainURL']+"/"+this.avatar()) | |
161 | + return window._CONFIG['staticDomainURL']+"/"+this.avatar() | |
146 | 162 | }, |
147 | 163 | handleLogout() { |
148 | 164 | const that = this |
... | ... | @@ -189,10 +205,17 @@ |
189 | 205 | filterOption(input, option) { |
190 | 206 | return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0 |
191 | 207 | }, |
192 | - searchMethods(value){ | |
193 | - let jump = this.search.filter(item=>item.id==value) | |
194 | - this.$router.push({ path:jump[0].path}) | |
208 | + // update_begin author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题 | |
209 | + searchMethods(value) { | |
210 | + let route = this.searchMenuOptions.filter(item => item.id === value)[0] | |
211 | + if (route.meta.internalOrExternal === true || route.component.includes('layouts/IframePageView')) { | |
212 | + window.open(route.meta.url, '_blank') | |
213 | + } else { | |
214 | + this.$router.push({ path: route.path }) | |
215 | + } | |
216 | + this.searchMenuVisible = false | |
195 | 217 | } |
218 | + // update_end author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题 | |
196 | 219 | /*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/ |
197 | 220 | } |
198 | 221 | } |
... | ... | @@ -203,7 +226,7 @@ |
203 | 226 | /* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */ |
204 | 227 | .user-wrapper .search-input { |
205 | 228 | width: 180px; |
206 | - color: white; | |
229 | + color: inherit; | |
207 | 230 | |
208 | 231 | /deep/ { |
209 | 232 | .ant-select-selection { |
... | ... |
ant-design-vue-jeecg/src/main.js
... | ... | @@ -18,8 +18,8 @@ import VueApexCharts from 'vue-apexcharts' |
18 | 18 | |
19 | 19 | import preview from 'vue-photo-preview' |
20 | 20 | import 'vue-photo-preview/dist/skin.css' |
21 | -import "@jeecg/antd-online-re" | |
22 | -import '@jeecg/antd-online-re/dist/OnlineForm.css' | |
21 | +import "@jeecg/antd-online-214" | |
22 | +import '@jeecg/antd-online-214/dist/OnlineForm.css' | |
23 | 23 | |
24 | 24 | import { |
25 | 25 | ACCESS_TOKEN, |
... | ... |
ant-design-vue-jeecg/src/mixins/JeecgListMixin.js
... | ... | @@ -236,9 +236,9 @@ export const JeecgListMixin = { |
236 | 236 | return |
237 | 237 | } |
238 | 238 | if (typeof window.navigator.msSaveBlob !== 'undefined') { |
239 | - window.navigator.msSaveBlob(new Blob([data]), fileName+'.xls') | |
239 | + window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.ms-excel'}), fileName+'.xls') | |
240 | 240 | }else{ |
241 | - let url = window.URL.createObjectURL(new Blob([data])) | |
241 | + let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.ms-excel'})) | |
242 | 242 | let link = document.createElement('a') |
243 | 243 | link.style.display = 'none' |
244 | 244 | link.href = url |
... | ... | @@ -286,7 +286,7 @@ export const JeecgListMixin = { |
286 | 286 | if(text && text.indexOf(",")>0){ |
287 | 287 | text = text.substring(0,text.indexOf(",")) |
288 | 288 | } |
289 | - return window._CONFIG['imgDomainURL']+"/"+text | |
289 | + return window._CONFIG['staticDomainURL']+"/"+text | |
290 | 290 | }, |
291 | 291 | /* 文件下载 */ |
292 | 292 | uploadFile(text){ |
... | ... | @@ -297,7 +297,7 @@ export const JeecgListMixin = { |
297 | 297 | if(text.indexOf(",")>0){ |
298 | 298 | text = text.substring(0,text.indexOf(",")) |
299 | 299 | } |
300 | - window.open(window._CONFIG['domianURL'] + "/sys/common/download/"+text); | |
300 | + window.open(window._CONFIG['staticDomainURL']+ "/"+text); | |
301 | 301 | }, |
302 | 302 | } |
303 | 303 | |
... | ... |
ant-design-vue-jeecg/src/mixins/OnlAutoListMixin.js
0 → 100644
1 | +export const HrefJump = { | |
2 | + data() { | |
3 | + return { | |
4 | + fieldHrefSlots: [], | |
5 | + hrefComponent: { | |
6 | + model: { | |
7 | + title: '', | |
8 | + width: '100%', | |
9 | + visible: false, | |
10 | + destroyOnClose: true, | |
11 | + style: { | |
12 | + top: 0, | |
13 | + left: 0, | |
14 | + height: '100%', | |
15 | + margin: 0, | |
16 | + padding: 0 | |
17 | + }, | |
18 | + bodyStyle: { padding: '8px', height: 'calc(100vh - 108px)', overflow: 'auto', overflowX: 'hidden' }, | |
19 | + // 隐藏掉取消按钮 | |
20 | + cancelButtonProps: { style: { display: 'none' } }, | |
21 | + afterClose: () => { | |
22 | + // 恢复body的滚动 | |
23 | + document.body.style.overflow = null | |
24 | + } | |
25 | + }, | |
26 | + on: { | |
27 | + ok: () => this.hrefComponent.model.visible = false, | |
28 | + cancel: () => this.hrefComponent.model.visible = false | |
29 | + }, | |
30 | + is: null, | |
31 | + params: {}, | |
32 | + } | |
33 | + } | |
34 | + }, | |
35 | + methods: { | |
36 | + //支持链接href跳转 | |
37 | + handleClickFieldHref(field, record) { | |
38 | + let href = field.href | |
39 | + let urlPattern = /(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?/ | |
40 | + let compPattern = /\.vue(\?.*)?$/ | |
41 | + if (typeof href === 'string') { | |
42 | + href = href.trim().replace(/\${([^}]+)?}/g, (s1, s2) => record[s2]) | |
43 | + if (urlPattern.test(href)) { | |
44 | + window.open(href, '_blank') | |
45 | + } else if (compPattern.test(href)) { | |
46 | + this.openHrefCompModal(href) | |
47 | + } else { | |
48 | + this.$router.push(href) | |
49 | + } | |
50 | + } | |
51 | + }, | |
52 | + openHrefCompModal(href) { | |
53 | + // 解析 href 参数 | |
54 | + let index = href.indexOf('?') | |
55 | + let path = href | |
56 | + if (index !== -1) { | |
57 | + path = href.substring(0, index) | |
58 | + let paramString = href.substring(index + 1, href.length) | |
59 | + let paramArray = paramString.split('&') | |
60 | + let params = {} | |
61 | + paramArray.forEach(paramObject => { | |
62 | + let paramItem = paramObject.split('=') | |
63 | + params[paramItem[0]] = paramItem[1] | |
64 | + }) | |
65 | + this.hrefComponent.params = params | |
66 | + } else { | |
67 | + this.hrefComponent.params = {} | |
68 | + } | |
69 | + this.hrefComponent.model.visible = true | |
70 | + this.hrefComponent.model.title = '@/views/' + path | |
71 | + this.hrefComponent.is = () => import('@/views/' + (path.startsWith('/')?path.slice(1):path)) | |
72 | + // 禁止body滚动,防止滚动穿透 | |
73 | + setTimeout(() => { | |
74 | + document.body.style.overflow = 'hidden' | |
75 | + }, 300) | |
76 | + }, | |
77 | + } | |
78 | +} | |
0 | 79 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/store/modules/user.js
... | ... | @@ -120,6 +120,19 @@ const user = { |
120 | 120 | sessionStorage.setItem(USER_AUTH,JSON.stringify(authData)); |
121 | 121 | sessionStorage.setItem(SYS_BUTTON_AUTH,JSON.stringify(allAuthData)); |
122 | 122 | if (menuData && menuData.length > 0) { |
123 | + //update--begin--autor:qinfeng-----date:20200109------for:JEECG-63 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示------ | |
124 | + menuData.forEach((item, index) => { | |
125 | + if (item["children"]) { | |
126 | + let hasChildrenMenu = item["children"].filter((i) => { | |
127 | + return !i.hidden || i.hidden == false | |
128 | + }) | |
129 | + if (hasChildrenMenu == null || hasChildrenMenu.length == 0) { | |
130 | + item["hidden"] = true | |
131 | + } | |
132 | + } | |
133 | + }) | |
134 | + console.log(" menu show json ", menuData) | |
135 | + //update--end--autor:qinfeng-----date:20200109------for:JEECG-63 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示------ | |
123 | 136 | commit('SET_PERMISSIONLIST', menuData) |
124 | 137 | } else { |
125 | 138 | reject('getPermissionList: permissions must be a non-null array !') |
... | ... |
ant-design-vue-jeecg/src/utils/authFilter.js
1 | - | |
2 | 1 | import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types" |
3 | 2 | |
4 | 3 | export function disabledAuthFilter(code,formData) { |
... | ... | @@ -10,27 +9,30 @@ export function disabledAuthFilter(code,formData) { |
10 | 9 | } |
11 | 10 | |
12 | 11 | function nodeDisabledAuth(code,formData){ |
13 | - console.log("页面权限禁用--NODE--开始"); | |
14 | - var permissionList = []; | |
12 | + let permissionList = []; | |
15 | 13 | try { |
16 | - var obj = formData; | |
17 | 14 | //console.log("页面权限禁用--NODE--开始",obj); |
18 | - if (obj) { | |
19 | - let bpmList = obj.permissionList; | |
20 | - for (var bpm of bpmList) { | |
21 | - if(bpm.type == '2') { | |
22 | - permissionList.push(bpm); | |
23 | - } | |
24 | - } | |
15 | + if (formData) { | |
16 | + let bpmList = formData.permissionList; | |
17 | + permissionList = bpmList.filter(item=>item.type=='2') | |
18 | + // for (let bpm of bpmList) { | |
19 | + // if(bpm.type == '2') { | |
20 | + // permissionList.push(bpm); | |
21 | + // } | |
22 | + // } | |
23 | + }else{ | |
24 | + return false; | |
25 | 25 | } |
26 | 26 | } catch (e) { |
27 | 27 | //console.log("页面权限异常----", e); |
28 | 28 | } |
29 | - if (permissionList === null || permissionList === "" || permissionList === undefined||permissionList.length<=0) { | |
29 | + if (permissionList.length == 0) { | |
30 | 30 | return false; |
31 | 31 | } |
32 | + | |
33 | + console.log("流程节点页面权限禁用--NODE--开始"); | |
32 | 34 | let permissions = []; |
33 | - for (var item of permissionList) { | |
35 | + for (let item of permissionList) { | |
34 | 36 | if(item.type == '2') { |
35 | 37 | permissions.push(item.action); |
36 | 38 | } |
... | ... | @@ -39,9 +41,9 @@ function nodeDisabledAuth(code,formData){ |
39 | 41 | if (!permissions.includes(code)) { |
40 | 42 | return false; |
41 | 43 | }else{ |
42 | - for (var item2 of permissionList) { | |
44 | + for (let item2 of permissionList) { | |
43 | 45 | if(code === item2.action){ |
44 | - console.log("页面权限禁用--NODE--生效"); | |
46 | + console.log("流程节点页面权限禁用--NODE--生效"); | |
45 | 47 | return true; |
46 | 48 | } |
47 | 49 | } |
... | ... | @@ -50,21 +52,21 @@ function nodeDisabledAuth(code,formData){ |
50 | 52 | } |
51 | 53 | |
52 | 54 | function globalDisabledAuth(code){ |
53 | - console.log("页面禁用权限--Global--开始"); | |
55 | + //console.log("全局页面禁用权限--Global--开始"); | |
54 | 56 | |
55 | 57 | var permissionList = []; |
56 | 58 | var allPermissionList = []; |
57 | 59 | |
58 | 60 | //let authList = Vue.ls.get(USER_AUTH); |
59 | 61 | let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]"); |
60 | - for (var auth of authList) { | |
62 | + for (let auth of authList) { | |
61 | 63 | if(auth.type == '2') { |
62 | 64 | permissionList.push(auth); |
63 | 65 | } |
64 | 66 | } |
65 | 67 | //console.log("页面禁用权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH)); |
66 | 68 | let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]"); |
67 | - for (var gauth of allAuthList) { | |
69 | + for (let gauth of allAuthList) { | |
68 | 70 | if(gauth.type == '2') { |
69 | 71 | allPermissionList.push(gauth); |
70 | 72 | } |
... | ... | @@ -73,7 +75,7 @@ function globalDisabledAuth(code){ |
73 | 75 | var gFlag = false;//禁用命中 |
74 | 76 | var invalidFlag = false;//无效命中 |
75 | 77 | if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){ |
76 | - for (var itemG of allPermissionList) { | |
78 | + for (let itemG of allPermissionList) { | |
77 | 79 | if(code === itemG.action){ |
78 | 80 | if(itemG.status == '0'){ |
79 | 81 | invalidFlag = true; |
... | ... | @@ -92,7 +94,7 @@ function globalDisabledAuth(code){ |
92 | 94 | return gFlag; |
93 | 95 | } |
94 | 96 | let permissions = []; |
95 | - for (var item of permissionList) { | |
97 | + for (let item of permissionList) { | |
96 | 98 | if(item.type == '2') { |
97 | 99 | permissions.push(item.action); |
98 | 100 | } |
... | ... | @@ -101,9 +103,9 @@ function globalDisabledAuth(code){ |
101 | 103 | if (!permissions.includes(code)) { |
102 | 104 | return gFlag; |
103 | 105 | }else{ |
104 | - for (var item2 of permissionList) { | |
106 | + for (let item2 of permissionList) { | |
105 | 107 | if(code === item2.action){ |
106 | - console.log("页面权限解除禁用--Global--生效"); | |
108 | + console.log("全局页面权限解除禁用--Global--生效"); | |
107 | 109 | gFlag = false; |
108 | 110 | } |
109 | 111 | } |
... | ... | @@ -134,12 +136,12 @@ function hasColoum(item,authList){ |
134 | 136 | //权限无效时不做控制,有效时控制,只能控制 显示不显示 |
135 | 137 | //根据授权码前缀获取未授权的列信息 |
136 | 138 | function getNoAuthCols(pre){ |
137 | - var permissionList = []; | |
138 | - var allPermissionList = []; | |
139 | + let permissionList = []; | |
140 | + let allPermissionList = []; | |
139 | 141 | |
140 | 142 | //let authList = Vue.ls.get(USER_AUTH); |
141 | 143 | let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]"); |
142 | - for (var auth of authList) { | |
144 | + for (let auth of authList) { | |
143 | 145 | //显示策略,有效状态 |
144 | 146 | if(auth.type == '1'&&startWith(auth.action,pre)) { |
145 | 147 | permissionList.push(substrPre(auth.action,pre)); |
... | ... | @@ -147,7 +149,7 @@ function getNoAuthCols(pre){ |
147 | 149 | } |
148 | 150 | //console.log("页面禁用权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH)); |
149 | 151 | let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]"); |
150 | - for (var gauth of allAuthList) { | |
152 | + for (let gauth of allAuthList) { | |
151 | 153 | //显示策略,有效状态 |
152 | 154 | if(gauth.type == '1'&&gauth.status == '1'&&startWith(gauth.action,pre)) { |
153 | 155 | allPermissionList.push(substrPre(gauth.action,pre)); |
... | ... |
ant-design-vue-jeecg/src/utils/commonUploadFile.js
... | ... | @@ -38,7 +38,7 @@ const getUploadFileList=(paths)=>{ |
38 | 38 | uid:uidGenerator(), |
39 | 39 | name:getFileName(arr[a]), |
40 | 40 | status: 'done', |
41 | - url: window._CONFIG['domianURL']+"/sys/common/view/"+arr[a], | |
41 | + url: window._CONFIG['staticDomainURL']+"/"+arr[a], | |
42 | 42 | response:{ |
43 | 43 | status:"history", |
44 | 44 | message:arr[a] |
... | ... |
ant-design-vue-jeecg/src/utils/hasPermission.js
... | ... | @@ -2,35 +2,37 @@ import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types" |
2 | 2 | |
3 | 3 | const hasPermission = { |
4 | 4 | install (Vue, options) { |
5 | - console.log(options); | |
5 | + //console.log(options); | |
6 | 6 | Vue.directive('has', { |
7 | 7 | inserted: (el, binding, vnode)=>{ |
8 | - console.log("页面权限控制----"); | |
8 | + //console.log("页面权限控制----"); | |
9 | + console.time() | |
9 | 10 | //节点权限处理,如果命中则不进行全局权限处理 |
10 | 11 | if(!filterNodePermission(el, binding, vnode)){ |
11 | 12 | filterGlobalPermission(el, binding, vnode); |
12 | 13 | } |
14 | + console.timeEnd() //计时结束并输出时长 | |
13 | 15 | } |
14 | 16 | }); |
15 | 17 | } |
16 | 18 | }; |
17 | 19 | |
18 | 20 | /** |
19 | - * 全局权限控制 | |
21 | + * 流程节点权限控制 | |
20 | 22 | */ |
21 | 23 | export function filterNodePermission(el, binding, vnode) { |
22 | - console.log("页面权限--NODE--"); | |
23 | - | |
24 | - var permissionList = []; | |
24 | + let permissionList = []; | |
25 | 25 | try { |
26 | - var obj = vnode.context.$props.formData; | |
26 | + let obj = vnode.context.$props.formData; | |
27 | 27 | if (obj) { |
28 | 28 | let bpmList = obj.permissionList; |
29 | - for (var bpm of bpmList) { | |
29 | + for (let bpm of bpmList) { | |
30 | 30 | if(bpm.type != '2') { |
31 | 31 | permissionList.push(bpm); |
32 | 32 | } |
33 | 33 | } |
34 | + }else{ | |
35 | + return false; | |
34 | 36 | } |
35 | 37 | } catch (e) { |
36 | 38 | //console.log("页面权限异常----", e); |
... | ... | @@ -39,8 +41,10 @@ export function filterNodePermission(el, binding, vnode) { |
39 | 41 | //el.parentNode.removeChild(el) |
40 | 42 | return false; |
41 | 43 | } |
44 | + | |
45 | + console.log("流程节点页面权限--NODE--"); | |
42 | 46 | let permissions = []; |
43 | - for (var item of permissionList) { | |
47 | + for (let item of permissionList) { | |
44 | 48 | if(item.type != '2') { |
45 | 49 | permissions.push(item.action); |
46 | 50 | } |
... | ... | @@ -51,7 +55,7 @@ export function filterNodePermission(el, binding, vnode) { |
51 | 55 | //el.parentNode.removeChild(el) |
52 | 56 | return false; |
53 | 57 | }else{ |
54 | - for (var item2 of permissionList) { | |
58 | + for (let item2 of permissionList) { | |
55 | 59 | if(binding.value === item2.action){ |
56 | 60 | return true; |
57 | 61 | } |
... | ... | @@ -64,29 +68,29 @@ export function filterNodePermission(el, binding, vnode) { |
64 | 68 | * 全局权限控制 |
65 | 69 | */ |
66 | 70 | export function filterGlobalPermission(el, binding, vnode) { |
67 | - console.log("页面权限--Global--"); | |
71 | + console.log("全局页面权限--Global--"); | |
68 | 72 | |
69 | - var permissionList = []; | |
70 | - var allPermissionList = []; | |
73 | + let permissionList = []; | |
74 | + let allPermissionList = []; | |
71 | 75 | |
72 | 76 | //let authList = Vue.ls.get(USER_AUTH); |
73 | 77 | let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]"); |
74 | - for (var auth of authList) { | |
78 | + for (let auth of authList) { | |
75 | 79 | if(auth.type != '2') { |
76 | 80 | permissionList.push(auth); |
77 | 81 | } |
78 | 82 | } |
79 | 83 | //console.log("页面权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH)); |
80 | 84 | let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]"); |
81 | - for (var gauth of allAuthList) { | |
85 | + for (let gauth of allAuthList) { | |
82 | 86 | if(gauth.type != '2') { |
83 | 87 | allPermissionList.push(gauth); |
84 | 88 | } |
85 | 89 | } |
86 | 90 | //设置全局配置是否有命中 |
87 | - var invalidFlag = false;//无效命中 | |
91 | + let invalidFlag = false;//无效命中 | |
88 | 92 | if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){ |
89 | - for (var itemG of allPermissionList) { | |
93 | + for (let itemG of allPermissionList) { | |
90 | 94 | if(binding.value === itemG.action){ |
91 | 95 | if(itemG.status == '0'){ |
92 | 96 | invalidFlag = true; |
... | ... | @@ -103,7 +107,7 @@ export function filterGlobalPermission(el, binding, vnode) { |
103 | 107 | return; |
104 | 108 | } |
105 | 109 | let permissions = []; |
106 | - for (var item of permissionList) { | |
110 | + for (let item of permissionList) { | |
107 | 111 | if(item.type != '2'){ |
108 | 112 | permissions.push(item.action); |
109 | 113 | } |
... | ... |
ant-design-vue-jeecg/src/utils/request.js
... | ... | @@ -5,9 +5,16 @@ import { VueAxios } from './axios' |
5 | 5 | import {Modal, notification} from 'ant-design-vue' |
6 | 6 | import { ACCESS_TOKEN } from "@/store/mutation-types" |
7 | 7 | |
8 | +//自动设置后台服务 baseURL (也可以手工指定写死项目名字) | |
9 | +let baseDomain = window._CONFIG['domianURL']; | |
10 | +let baseProject = baseDomain.substring(baseDomain.lastIndexOf("/")); | |
11 | +console.log("baseDomain= ",baseDomain) | |
12 | +console.log("baseProject= ",baseProject) | |
13 | + | |
8 | 14 | // 创建 axios 实例 |
9 | 15 | const service = axios.create({ |
10 | - baseURL: '/jeecg-boot', // api base_url | |
16 | + //baseURL: '/jeecg-boot', | |
17 | + baseURL: baseProject, // api base_url | |
11 | 18 | timeout: 9000 // 请求超时时间 |
12 | 19 | }) |
13 | 20 | |
... | ... |
ant-design-vue-jeecg/src/utils/util.js
... | ... | @@ -257,6 +257,62 @@ export function cssExpand(css, id) { |
257 | 257 | document.head.appendChild(style) |
258 | 258 | } |
259 | 259 | |
260 | + | |
261 | +/** 用于js增强事件,运行JS代码,可以传参 */ | |
262 | +// options 所需参数: | |
263 | +// 参数名 类型 说明 | |
264 | +// vm VueComponent vue实例 | |
265 | +// event Object event对象 | |
266 | +// jsCode String 待执行的js代码 | |
267 | +// errorMessage String 执行出错后的提示(控制台) | |
268 | +export function jsExpand(options = {}) { | |
269 | + | |
270 | + // 绑定到window上的keyName | |
271 | + let windowKeyName = 'J_CLICK_EVENT_OPTIONS' | |
272 | + if (typeof window[windowKeyName] != 'object') { | |
273 | + window[windowKeyName] = {} | |
274 | + } | |
275 | + | |
276 | + // 随机生成JS增强的执行id,防止冲突 | |
277 | + let id = randomString(16, 'qwertyuioplkjhgfdsazxcvbnm'.toUpperCase()) | |
278 | + // 封装按钮点击事件 | |
279 | + let code = ` | |
280 | + (function (o_${id}) { | |
281 | + try { | |
282 | + (function (globalEvent, vm) { | |
283 | + ${options.jsCode} | |
284 | + })(o_${id}.event, o_${id}.vm) | |
285 | + } catch (e) { | |
286 | + o_${id}.error(e) | |
287 | + } | |
288 | + o_${id}.done() | |
289 | + })(window['${windowKeyName}']['EVENT_${id}']) | |
290 | + ` | |
291 | + // 创建script标签 | |
292 | + const script = document.createElement('script') | |
293 | + // 将需要传递的参数挂载到window对象上 | |
294 | + window[windowKeyName]['EVENT_' + id] = { | |
295 | + vm: options.vm, | |
296 | + event: options.event, | |
297 | + // 当执行完成时,无论如何都会调用的回调事件 | |
298 | + done() { | |
299 | + // 执行完后删除新增的 script 标签不会撤销执行结果(已产生的结果不会被撤销) | |
300 | + script.outerHTML = '' | |
301 | + delete window[windowKeyName]['EVENT_' + id] | |
302 | + }, | |
303 | + // 当js运行出错的时候调用的事件 | |
304 | + error(e) { | |
305 | + console.group(`${options.errorMessage || '用户自定义JS增强代码运行出错'}(${new Date()})`) | |
306 | + console.error(e) | |
307 | + console.groupEnd() | |
308 | + } | |
309 | + } | |
310 | + // 将事件挂载到document中 | |
311 | + script.innerHTML = code | |
312 | + document.body.appendChild(script) | |
313 | +} | |
314 | + | |
315 | + | |
260 | 316 | /** |
261 | 317 | * 重复值验证工具方法 |
262 | 318 | * |
... | ... | @@ -270,12 +326,39 @@ export function cssExpand(css, id) { |
270 | 326 | * @param callback |
271 | 327 | */ |
272 | 328 | export function validateDuplicateValue(tableName, fieldName, fieldVal, dataId, callback) { |
273 | - let params = { tableName, fieldName, fieldVal, dataId } | |
274 | - api.duplicateCheck(params).then(res => { | |
275 | - res['success'] ? callback() : callback(res['message']) | |
276 | - }).catch(err => { | |
277 | - callback(err.message || err) | |
278 | - }) | |
329 | + if (fieldVal) { | |
330 | + let params = { tableName, fieldName, fieldVal, dataId } | |
331 | + api.duplicateCheck(params).then(res => { | |
332 | + res['success'] ? callback() : callback(res['message']) | |
333 | + }).catch(err => { | |
334 | + callback(err.message || err) | |
335 | + }) | |
336 | + } else { | |
337 | + callback() | |
338 | + } | |
339 | +} | |
340 | + | |
341 | +/** | |
342 | + * 根据编码校验规则code,校验传入的值是否合法 | |
343 | + * | |
344 | + * 使用示例: | |
345 | + * { validator: (rule, value, callback) => validateCheckRule('common', value, callback) } | |
346 | + * | |
347 | + * @param ruleCode 编码校验规则 code | |
348 | + * @param value 被验证的值 | |
349 | + * @param callback | |
350 | + */ | |
351 | +export function validateCheckRule(ruleCode, value, callback) { | |
352 | + if (ruleCode && value) { | |
353 | + value = encodeURIComponent(value) | |
354 | + api.checkRuleByCode({ ruleCode, value }).then(res => { | |
355 | + res['success'] ? callback() : callback(res['message']) | |
356 | + }).catch(err => { | |
357 | + callback(err.message || err) | |
358 | + }) | |
359 | + } else { | |
360 | + callback() | |
361 | + } | |
279 | 362 | } |
280 | 363 | |
281 | 364 | /** |
... | ... | @@ -295,4 +378,40 @@ export function pushIfNotExist(array, value, key) { |
295 | 378 | } |
296 | 379 | array.push(value) |
297 | 380 | return true |
381 | +} | |
382 | + | |
383 | +/** | |
384 | + * 可用于判断是否成功 | |
385 | + * @type {symbol} | |
386 | + */ | |
387 | +export const succeedSymbol = Symbol() | |
388 | +/** | |
389 | + * 可用于判断是否失败 | |
390 | + * @type {symbol} | |
391 | + */ | |
392 | +export const failedSymbol = Symbol() | |
393 | + | |
394 | +/** | |
395 | + * 使 promise 无论如何都会 resolve,除非传入的参数不是一个Promise对象或返回Promise对象的方法 | |
396 | + * 一般用在 Promise.all 中 | |
397 | + * | |
398 | + * @param promise 可传Promise对象或返回Promise对象的方法 | |
399 | + * @returns {Promise<any>} | |
400 | + */ | |
401 | +export function alwaysResolve(promise) { | |
402 | + return new Promise((resolve, reject) => { | |
403 | + let p = promise | |
404 | + if (typeof promise === 'function') { | |
405 | + p = promise() | |
406 | + } | |
407 | + if (p instanceof Promise) { | |
408 | + p.then(data => { | |
409 | + resolve({ type: succeedSymbol, data }) | |
410 | + }).catch(error => { | |
411 | + resolve({ type: failedSymbol, error }) | |
412 | + }) | |
413 | + } else { | |
414 | + reject('alwaysResolve: 传入的参数不是一个Promise对象或返回Promise对象的方法') | |
415 | + } | |
416 | + }) | |
298 | 417 | } |
299 | 418 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/views/account/center/Index.vue
... | ... | @@ -133,7 +133,7 @@ |
133 | 133 | methods: { |
134 | 134 | ...mapGetters(["nickname", "avatar"]), |
135 | 135 | getAvatar(){ |
136 | - return window._CONFIG['imgDomainURL']+"/"+this.avatar(); | |
136 | + return window._CONFIG['staticDomainURL']+"/"+this.avatar(); | |
137 | 137 | }, |
138 | 138 | getTeams() { |
139 | 139 | this.$http.get('/api/workplace/teams') |
... | ... |
ant-design-vue-jeecg/src/views/dashboard/IndexChart.vue
... | ... | @@ -20,14 +20,14 @@ |
20 | 20 | </chart-card> |
21 | 21 | </a-col> |
22 | 22 | <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }"> |
23 | - <chart-card :loading="loading" title="访问量" :total="8846 | NumberFormat"> | |
23 | + <chart-card :loading="loading" title="订单量" :total="8846 | NumberFormat"> | |
24 | 24 | <a-tooltip title="指标说明" slot="action"> |
25 | 25 | <a-icon type="info-circle-o" /> |
26 | 26 | </a-tooltip> |
27 | 27 | <div> |
28 | 28 | <mini-area /> |
29 | 29 | </div> |
30 | - <template slot="footer">日访问量<span> {{ '1234' | NumberFormat }}</span></template> | |
30 | + <template slot="footer">日订单量<span> {{ '1234' | NumberFormat }}</span></template> | |
31 | 31 | </chart-card> |
32 | 32 | </a-col> |
33 | 33 | <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }"> |
... | ... | @@ -85,7 +85,7 @@ |
85 | 85 | </a-col> |
86 | 86 | </a-row> |
87 | 87 | </a-tab-pane> |
88 | - <a-tab-pane tab="访问量" key="2"> | |
88 | + <a-tab-pane tab="销售趋势" key="2"> | |
89 | 89 | <a-row> |
90 | 90 | <a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24"> |
91 | 91 | <bar title="销售额趋势" :dataSource="barData"/> |
... | ... | @@ -101,10 +101,10 @@ |
101 | 101 | |
102 | 102 | <a-row> |
103 | 103 | <a-col :span="24"> |
104 | - <a-card :loading="loading" :bordered="false" title="最近一周访问次数统计" :style="{ marginTop: '24px' }"> | |
104 | + <a-card :loading="loading" :bordered="false" title="最近一周访问量统计" :style="{ marginTop: '24px' }"> | |
105 | 105 | <a-row> |
106 | 106 | <a-col :span="6"> |
107 | - <head-info title="今日访问IP数" :content="loginfo.todayIp"></head-info> | |
107 | + <head-info title="今日IP" :content="loginfo.todayIp"></head-info> | |
108 | 108 | </a-col> |
109 | 109 | <a-col :span="2"> |
110 | 110 | <a-spin class='circle-cust'> |
... | ... | @@ -112,7 +112,7 @@ |
112 | 112 | </a-spin> |
113 | 113 | </a-col> |
114 | 114 | <a-col :span="6"> |
115 | - <head-info title="今日访问次数" :content="loginfo.todayVisitCount"></head-info> | |
115 | + <head-info title="今日访问" :content="loginfo.todayVisitCount"></head-info> | |
116 | 116 | </a-col> |
117 | 117 | <a-col :span="2"> |
118 | 118 | <a-spin class='circle-cust'> |
... | ... | @@ -120,7 +120,7 @@ |
120 | 120 | </a-spin> |
121 | 121 | </a-col> |
122 | 122 | <a-col :span="6"> |
123 | - <head-info title="访问总次数" :content="loginfo.totalVisitCount"></head-info> | |
123 | + <head-info title="总访问量" :content="loginfo.totalVisitCount"></head-info> | |
124 | 124 | </a-col> |
125 | 125 | <a-col :span="2"> |
126 | 126 | <a-spin class='circle-cust'> |
... | ... |
ant-design-vue-jeecg/src/views/dashboard/Workplace.vue
... | ... | @@ -185,7 +185,7 @@ |
185 | 185 | }, |
186 | 186 | created() { |
187 | 187 | this.user = this.userInfo |
188 | - this.avatar = window._CONFIG['imgDomainURL'] +"/"+ this.userInfo.avatar | |
188 | + this.avatar = window._CONFIG['staticDomainURL'] +"/"+ this.userInfo.avatar | |
189 | 189 | console.log('this.avatar :'+ this.avatar) |
190 | 190 | |
191 | 191 | getRoleList().then(res => { |
... | ... |
ant-design-vue-jeecg/src/views/jeecg/SelectDemo.vue
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <a-row :gutter="24"> |
10 | 10 | <a-col :span="12"> |
11 | 11 | <a-form-item label="性别"> |
12 | - <j-dict-select-tag v-model="formData.sex" title="性别" dictCode="sex"/> | |
12 | + <j-dict-select-tag v-model="formData.sex" title="性别" dictCode="sex" placeholder="请选择性别"/> | |
13 | 13 | <!-- <j-dict-select-tag title="性别" dictCode="sex" disabled/>--> |
14 | 14 | </a-form-item> |
15 | 15 | </a-col> |
... | ... | @@ -176,34 +176,28 @@ |
176 | 176 | <a-row :gutter="24"> |
177 | 177 | <a-col> |
178 | 178 | |
179 | - <a-form-item label="最大化弹窗"> | |
180 | - <a-button @click="()=>modal.visible=true">最大化弹窗</a-button> | |
179 | + <a-form-item label="JModal弹窗"> | |
180 | + <a-button style="margin-right: 8px;" @click="()=>modal.visible=true">点击弹出JModal</a-button> | |
181 | + <span style="margin-right: 8px;">全屏化:<a-switch v-model="modal.fullscreen"/></span> | |
182 | + <span style="margin-right: 8px;">允许切换全屏:<a-switch v-model="modal.switchFullscreen"/></span> | |
183 | + <span>锁定Body滚动:<a-switch v-model="modal.lockScroll"/></span> | |
184 | + | |
181 | 185 | </a-form-item> |
182 | 186 | |
183 | - <a-modal | |
184 | - :visible="modal.visible" | |
185 | - :width="modal.width" | |
186 | - :style="modal.style" | |
187 | - @ok="()=>modal.visible=false" | |
188 | - @cancel="()=>modal.visible=false"> | |
189 | - | |
190 | - <template slot="title"> | |
191 | - <div style="width: 100%;height:20px;padding-right:32px;"> | |
192 | - <div style="float: left;">{{ modal.title }}</div> | |
193 | - <div style="float: right;"> | |
194 | - <a-button | |
195 | - icon="fullscreen" | |
196 | - style="width:56px;height:100%;border:0" | |
197 | - @click="handleClickToggleFullScreen"/> | |
198 | - </div> | |
199 | - </div> | |
200 | - </template> | |
187 | + <j-modal | |
188 | + :visible.sync="modal.visible" | |
189 | + :width="1200" | |
190 | + :title="modal.title" | |
191 | + :lockScroll="modal.lockScroll" | |
192 | + :fullscreen.sync="modal.fullscreen" | |
193 | + :switchFullscreen="modal.switchFullscreen" | |
194 | + > | |
201 | 195 | |
202 | 196 | <template v-for="(i,k) of 30"> |
203 | 197 | <p :key="k">这是主体内容,高度是自适应的</p> |
204 | 198 | </template> |
205 | 199 | |
206 | - </a-modal> | |
200 | + </j-modal> | |
207 | 201 | |
208 | 202 | </a-col> |
209 | 203 | </a-row> |
... | ... | @@ -217,10 +211,10 @@ |
217 | 211 | <a-row :gutter="24"> |
218 | 212 | <a-col :span="12"> |
219 | 213 | <a-form-item label="树字典"> |
220 | - <j-tree-dict parentCode="B01" /> | |
214 | + <j-tree-dict v-model="formData.treeDict" placeholder="请选择树字典" parentCode="A01" /> | |
221 | 215 | </a-form-item> |
222 | 216 | </a-col> |
223 | - <a-col :span="12"></a-col> | |
217 | + <a-col :span="12">选中的值(v-model):{{ formData.treeDict }}</a-col> | |
224 | 218 | </a-row> |
225 | 219 | |
226 | 220 | <a-row :gutter="24"> |
... | ... | @@ -262,6 +256,45 @@ |
262 | 256 | </a-form-item> |
263 | 257 | </a-col> |
264 | 258 | </a-row> |
259 | + | |
260 | + <a-row :gutter="24"> | |
261 | + <a-col :span="12"> | |
262 | + <a-form-item label="高级查询"> | |
263 | + <j-super-query :fieldList="superQuery.fieldList" /> | |
264 | + </a-form-item> | |
265 | + </a-col> | |
266 | + </a-row> | |
267 | + | |
268 | + <a-row :gutter="24"> | |
269 | + <a-col :span="12"> | |
270 | + <a-form-item label="高级查询(自定义按钮)"> | |
271 | + <j-super-query :fieldList="superQuery.fieldList"> | |
272 | + <!-- 直接在内部写一个按钮即可,点击事件自动添加 --> | |
273 | + <a-button type="primary" ghost icon="clock-circle">高级查询</a-button> | |
274 | + </j-super-query> | |
275 | + </a-form-item> | |
276 | + </a-col> | |
277 | + </a-row> | |
278 | + <a-row :gutter="24"> | |
279 | + <a-col :span="12"> | |
280 | + <a-form-item label="图片上传"> | |
281 | + <j-image-upload v-model="imgList"></j-image-upload> | |
282 | + </a-form-item> | |
283 | + </a-col> | |
284 | + <a-col :spapn="12">选中的值(v-model):{{ imgList }}</a-col> | |
285 | + </a-row> | |
286 | + <a-row :gutter="24" style="margin-top: 65px;margin-bottom:50px;"> | |
287 | + <a-col :span="12"> | |
288 | + <a-form-item label="文件上传"> | |
289 | + <j-upload v-model="fileList"></j-upload> | |
290 | + </a-form-item> | |
291 | + </a-col> | |
292 | + <a-col :spapn="12"> | |
293 | + 选中的值(v-model): | |
294 | + <j-ellipsis :value="fileList" :length="30" v-if="fileList.length>0"/> | |
295 | + </a-col> | |
296 | + </a-row> | |
297 | + | |
265 | 298 | </a-form> |
266 | 299 | </div> |
267 | 300 | |
... | ... | @@ -286,10 +319,15 @@ |
286 | 319 | import JTreeDict from "../../components/jeecg/JTreeDict.vue"; |
287 | 320 | import JCron from "@/components/jeecg/JCron.vue"; |
288 | 321 | import JTreeSelect from '@/components/jeecg/JTreeSelect' |
322 | + import JSuperQuery from '@/components/jeecg/JSuperQuery' | |
323 | + import JUpload from '@/components/jeecg/JUpload' | |
324 | + import JImageUpload from '@/components/jeecg/JImageUpload' | |
289 | 325 | |
290 | 326 | export default { |
291 | 327 | name: 'SelectDemo', |
292 | 328 | components: { |
329 | + JImageUpload, | |
330 | + JUpload, | |
293 | 331 | JTreeDict, |
294 | 332 | JDictSelectTag, |
295 | 333 | JSelectDepart, |
... | ... | @@ -299,7 +337,7 @@ |
299 | 337 | JCheckbox, |
300 | 338 | JCodeEditor, |
301 | 339 | JDate, JEditor, JEllipsis, JGraphicCode, JSlider, JSelectMultiple, |
302 | - JCron, JTreeSelect | |
340 | + JCron, JTreeSelect, JSuperQuery | |
303 | 341 | }, |
304 | 342 | data() { |
305 | 343 | return { |
... | ... | @@ -352,11 +390,20 @@ sayHi('hello, world!')` |
352 | 390 | modal: { |
353 | 391 | title: '这里是标题', |
354 | 392 | visible: false, |
355 | - width: '100%', | |
356 | - style: { top: '20px' }, | |
357 | - fullScreen: true | |
393 | + lockScroll: true, | |
394 | + fullscreen: true, | |
395 | + switchFullscreen: true, | |
358 | 396 | }, |
359 | 397 | cron: '', |
398 | + superQuery: { | |
399 | + fieldList: [ | |
400 | + { type: 'input', value: 'name', text: '姓名', }, | |
401 | + { type: 'select', value: 'sex', text: '性别', dictCode: 'sex' }, | |
402 | + { type: 'number', value: 'age', text: '年龄', } | |
403 | + ] | |
404 | + }, | |
405 | + fileList:[], | |
406 | + imgList:[], | |
360 | 407 | } |
361 | 408 | }, |
362 | 409 | computed: { |
... | ... | @@ -399,18 +446,6 @@ sayHi('hello, world!')` |
399 | 446 | handleJSliderSuccess(value) { |
400 | 447 | this.jslider.value = value |
401 | 448 | }, |
402 | - /** 切换全屏显示 */ | |
403 | - handleClickToggleFullScreen() { | |
404 | - let mode = !this.modal.fullScreen | |
405 | - if (mode) { | |
406 | - this.modal.width = '100%' | |
407 | - this.modal.style.top = '20px' | |
408 | - } else { | |
409 | - this.modal.width = '1200px' | |
410 | - this.modal.style.top = '50px' | |
411 | - } | |
412 | - this.modal.fullScreen = mode | |
413 | - }, | |
414 | 449 | setCorn(data){ |
415 | 450 | this.$nextTick(() => { |
416 | 451 | this.form.cronExpression = data; |
... | ... |
ant-design-vue-jeecg/src/views/jeecg/helloworld.vue
... | ... | @@ -21,7 +21,9 @@ |
21 | 21 | </a-col> |
22 | 22 | <a-form-item :wrapperCol="{ span: 12, offset: 5 }"> |
23 | 23 | <a-col :md="24" :sm="24"> |
24 | - <a-button type="primary" htmlType="submit">Submit</a-button> | |
24 | + <a-form-item :wrapperCol="{ span: 12, offset: 5 }"> | |
25 | + <a-button type="primary" htmlType="submit">Submit</a-button> | |
26 | + </a-form-item> | |
25 | 27 | </a-col> |
26 | 28 | </a-form-item> |
27 | 29 | </a-form> |
... | ... |
ant-design-vue-jeecg/src/views/jeecg/modules/JeecgDemoModal.vue
... | ... | @@ -35,12 +35,13 @@ |
35 | 35 | <a-form-item |
36 | 36 | :labelCol="labelCol" |
37 | 37 | :wrapperCol="wrapperCol" |
38 | - label="sex"> | |
39 | - <a-select v-decorator="['sex', {}]" placeholder="请选择性别"> | |
40 | - <a-select-option value="">请选择性别</a-select-option> | |
41 | - <a-select-option value="1">男性</a-select-option> | |
42 | - <a-select-option value="2">女性</a-select-option> | |
43 | - </a-select> | |
38 | + label="性别"> | |
39 | + <!-- <a-select v-decorator="['sex', {}]" placeholder="请选择性别"> | |
40 | + <a-select-option value="">请选择</a-select-option> | |
41 | + <a-select-option value="1">男</a-select-option> | |
42 | + <a-select-option value="2">女</a-select-option> | |
43 | + </a-select>--> | |
44 | + <j-dict-select-tag type="radio" v-decorator="['sex', {}]" :trigger-change="true" dictCode="sex"/> | |
44 | 45 | </a-form-item> |
45 | 46 | <a-form-item |
46 | 47 | :labelCol="labelCol" |
... | ... |
ant-design-vue-jeecg/src/views/jeecg/report/ArchivesStatisticst.vue
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | <a-card :bordered="false"> |
3 | 3 | <a-tabs defaultActiveKey="1" @change="callback"> |
4 | 4 | <a-tab-pane tab="柱状图" key="1"> |
5 | - <a-row :gutter="24"> | |
5 | + <a-row> | |
6 | 6 | <a-col :span="10"> |
7 | 7 | <a-radio-group :value="barType" @change="statisticst"> |
8 | 8 | <a-radio-button value="year">按年统计</a-radio-button> |
... | ... |
ant-design-vue-jeecg/src/views/jeecg/tablist/form/JeecgOrderCustomerModal.vue
... | ... | @@ -43,24 +43,7 @@ |
43 | 43 | :wrapperCol="wrapperCol" |
44 | 44 | label="身份证扫描件" |
45 | 45 | hasFeedback> |
46 | - <a-upload | |
47 | - :action="uploadAction" | |
48 | - listType="picture-card" | |
49 | - :headers="headers" | |
50 | - :fileList="fileList" | |
51 | - @change="handleChange" | |
52 | - @preview="handlePreview" | |
53 | - > | |
54 | - <a-button> | |
55 | - <a-icon type="upload"/> | |
56 | - upload | |
57 | - </a-button> | |
58 | - </a-upload> | |
59 | - <a-modal :visible="previewVisible" :footer="null" @cancel="handlePicCancel"> | |
60 | - <img alt="example" style="width: 100%" :src="previewImage"/> | |
61 | - </a-modal> | |
62 | - | |
63 | - <br/> | |
46 | + <j-image-upload text="上传" v-model="fileList" :isMultiple="true"></j-image-upload> | |
64 | 47 | </a-form-item> |
65 | 48 | <a-form-item |
66 | 49 | :labelCol="labelCol" |
... | ... | @@ -88,11 +71,11 @@ |
88 | 71 | import pick from 'lodash.pick' |
89 | 72 | import Vue from 'vue' |
90 | 73 | import {ACCESS_TOKEN} from "@/store/mutation-types" |
91 | - | |
92 | - import { getUploadFileList,getFilePaths } from '@/utils/commonUploadFile.js' | |
74 | + import JImageUpload from '../../../../components/jeecg/JImageUpload' | |
93 | 75 | |
94 | 76 | export default { |
95 | 77 | name: "JeecgOrderCustomerModal", |
78 | + components: { JImageUpload }, | |
96 | 79 | data() { |
97 | 80 | return { |
98 | 81 | title: "操作", |
... | ... | @@ -177,7 +160,7 @@ |
177 | 160 | add: "/test/order/addCustomer", |
178 | 161 | edit: "/test/order/editCustomer", |
179 | 162 | fileUpload: window._CONFIG['domianURL'] + "/sys/common/upload", |
180 | - imgerver: window._CONFIG['domianURL'] + "/sys/common/view", | |
163 | + imgerver: window._CONFIG['staticDomainURL'], | |
181 | 164 | getOrderCustomerList: "/test/order/listOrderCustomerByMainId", |
182 | 165 | }, |
183 | 166 | validatorRules: { |
... | ... | @@ -222,8 +205,6 @@ |
222 | 205 | |
223 | 206 | this.form.resetFields(); |
224 | 207 | this.orderId = record.orderId; |
225 | - let currFileList = getUploadFileList(record.idcardPic) | |
226 | - this.fileList = [...currFileList] | |
227 | 208 | this.model = Object.assign({}, record); |
228 | 209 | if (record.id) { |
229 | 210 | this.hiding = false; |
... | ... | @@ -232,6 +213,9 @@ |
232 | 213 | this.$nextTick(() => { |
233 | 214 | this.form.setFieldsValue(pick(this.model, 'id', 'name', 'sex', 'idcard','telphone', 'orderId', 'createBy', 'createTime', 'updateBy', 'updateTime')) |
234 | 215 | }); |
216 | + setTimeout(() => { | |
217 | + this.fileList = record.idcardPic | |
218 | + }, 5) | |
235 | 219 | } else { |
236 | 220 | this.addStatus = false; |
237 | 221 | this.editStatus = true; |
... | ... | @@ -262,7 +246,7 @@ |
262 | 246 | let formData = Object.assign(this.model, values); |
263 | 247 | console.log(formData); |
264 | 248 | formData.orderId = this.orderId; |
265 | - formData.idcardPic = getFilePaths(this.fileList) | |
249 | + formData.idcardPic = this.fileList; | |
266 | 250 | httpAction(httpurl, formData, method).then((res) => { |
267 | 251 | if (res.success) { |
268 | 252 | that.$message.success(res.message); |
... | ... |
ant-design-vue-jeecg/src/views/modules/online/cgform/OnlCgformCopyList.vue
... | ... | @@ -6,13 +6,13 @@ |
6 | 6 | <a-form layout="inline"> |
7 | 7 | <a-row :gutter="24"> |
8 | 8 | |
9 | - <a-col :md="6" :sm="24"> | |
9 | + <a-col :xl="6" :lg="7" :md="8" :sm="24"> | |
10 | 10 | <a-form-item label="表名"> |
11 | 11 | <a-input placeholder="请输入表名" v-model="queryParam.tableName"></a-input> |
12 | 12 | </a-form-item> |
13 | 13 | </a-col> |
14 | 14 | |
15 | - <a-col :md="6" :sm="24"> | |
15 | + <a-col :xl="6" :lg="7" :md="8" :sm="24"> | |
16 | 16 | <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons"> |
17 | 17 | <a-button type="primary" @click="searchQuery" icon="search">查询</a-button> |
18 | 18 | <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button> |
... | ... | @@ -25,10 +25,10 @@ |
25 | 25 | |
26 | 26 | <!-- 操作按钮区域 --> |
27 | 27 | <div class="table-operator"> |
28 | - <a-button @click="doCgformButton" type="primary" icon="highlight" style="margin-left:8px">自定义按钮</a-button> | |
29 | - <a-button @click="doEnhanceJs" type="primary" icon="strikethrough" style="margin-left:8px">JS增强</a-button> | |
30 | - <a-button @click="doEnhanceSql" type="primary" icon="filter" style="margin-left:8px">SQL增强</a-button> | |
31 | - <a-button @click="doEnhanceJava" type="primary" icon="tool" style="margin-left:8px">Java增强</a-button> | |
28 | + <a-button @click="doCgformButton" type="primary" icon="highlight">自定义按钮</a-button> | |
29 | + <a-button @click="doEnhanceJs" type="primary" icon="strikethrough">JS增强</a-button> | |
30 | + <a-button @click="doEnhanceSql" type="primary" icon="filter">SQL增强</a-button> | |
31 | + <a-button @click="doEnhanceJava" type="primary" icon="tool">Java增强</a-button> | |
32 | 32 | |
33 | 33 | <a-dropdown v-if="selectedRowKeys.length > 0"> |
34 | 34 | <a-menu slot="overlay"> |
... | ... | @@ -37,7 +37,7 @@ |
37 | 37 | 删除 |
38 | 38 | </a-menu-item> |
39 | 39 | </a-menu> |
40 | - <a-button style="margin-left: 8px"> 批量操作 | |
40 | + <a-button> 批量操作 | |
41 | 41 | <a-icon type="down"/> |
42 | 42 | </a-button> |
43 | 43 | </a-dropdown> |
... | ... | @@ -348,6 +348,9 @@ |
348 | 348 | } |
349 | 349 | } |
350 | 350 | </script> |
351 | +<style scoped> | |
352 | + @import '~@assets/less/common.less'; | |
353 | +</style> | |
351 | 354 | <style lang="less"> |
352 | 355 | .ant-card-body .table-operator { |
353 | 356 | margin-bottom: 18px; |
... | ... |
ant-design-vue-jeecg/src/views/modules/online/cgform/OnlCgformHeadList.vue
... | ... | @@ -6,18 +6,22 @@ |
6 | 6 | <a-form layout="inline"> |
7 | 7 | <a-row :gutter="24"> |
8 | 8 | |
9 | - <a-col :md="6" :sm="24"> | |
9 | + <a-col :xl="6" :lg="7" :md="8" :sm="24"> | |
10 | 10 | <a-form-item label="表名"> |
11 | 11 | <a-input placeholder="请输入表名" v-model="queryParam.tableName"></a-input> |
12 | 12 | </a-form-item> |
13 | 13 | </a-col> |
14 | - <a-col :md="6" :sm="24"> | |
14 | + <a-col :xl="6" :lg="7" :md="8" :sm="24"> | |
15 | 15 | <a-form-item label="表类型"> |
16 | 16 | <j-dict-select-tag dictCode="cgform_table_type" v-model="queryParam.tableType"/> |
17 | 17 | </a-form-item> |
18 | 18 | </a-col> |
19 | - | |
20 | - <a-col :md="6" :sm="24"> | |
19 | + <a-col :xl="6" :lg="7" :md="8" :sm="24"> | |
20 | + <a-form-item label="表描述"> | |
21 | + <a-input placeholder="请输入表描述" v-model="queryParam.tableTxt"></a-input> | |
22 | + </a-form-item> | |
23 | + </a-col> | |
24 | + <a-col :xl="6" :lg="7" :md="8" :sm="24"> | |
21 | 25 | <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons"> |
22 | 26 | <a-button type="primary" @click="searchQuery" icon="search">查询</a-button> |
23 | 27 | <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button> |
... | ... | @@ -31,12 +35,12 @@ |
31 | 35 | <!-- 操作按钮区域 --> |
32 | 36 | <div class="table-operator"> |
33 | 37 | <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button> |
34 | - <a-button @click="doCgformButton" type="primary" icon="highlight" style="margin-left:8px">自定义按钮</a-button> | |
35 | - <a-button @click="doEnhanceJs" type="primary" icon="strikethrough" style="margin-left:8px">JS增强</a-button> | |
36 | - <a-button @click="doEnhanceSql" type="primary" icon="filter" v-has="'online:sql'" style="margin-left:8px">SQL增强</a-button> | |
37 | - <a-button @click="doEnhanceJava" type="primary" icon="tool" style="margin-left:8px">Java增强</a-button> | |
38 | - <a-button @click="importOnlineForm" type="primary" icon="database" style="margin-left:8px">从数据库导入表单</a-button> | |
39 | - <a-button @click="goGenerateCode" v-has="'online:goGenerateCode'" type="primary" icon="database" style="margin-left:8px">代码生成</a-button> | |
38 | + <a-button @click="doCgformButton" type="primary" icon="highlight">自定义按钮</a-button> | |
39 | + <a-button @click="doEnhanceJs" type="primary" icon="strikethrough">JS增强</a-button> | |
40 | + <a-button @click="doEnhanceSql" type="primary" icon="filter">SQL增强</a-button> | |
41 | + <a-button @click="doEnhanceJava" type="primary" icon="tool">Java增强</a-button> | |
42 | + <a-button @click="importOnlineForm" type="primary" icon="database">从数据库导入表单</a-button> | |
43 | + <a-button @click="goGenerateCode" type="primary" icon="database">代码生成</a-button> | |
40 | 44 | |
41 | 45 | <a-dropdown v-if="selectedRowKeys.length > 0"> |
42 | 46 | <a-menu slot="overlay"> |
... | ... | @@ -45,7 +49,7 @@ |
45 | 49 | 删除 |
46 | 50 | </a-menu-item> |
47 | 51 | </a-menu> |
48 | - <a-button style="margin-left: 8px"> 批量操作 | |
52 | + <a-button> 批量操作 | |
49 | 53 | <a-icon type="down"/> |
50 | 54 | </a-button> |
51 | 55 | </a-dropdown> |
... | ... | @@ -204,8 +208,12 @@ |
204 | 208 | title: '表类型', |
205 | 209 | align: 'center', |
206 | 210 | dataIndex: 'tableType', |
207 | - customRender: (text) => { | |
208 | - return filterDictText(this.tableTypeDictOptions, `${text}`) | |
211 | + customRender: (text, record) => { | |
212 | + let tbTypeText = filterDictText(this.tableTypeDictOptions, `${text}`) | |
213 | + if(record.isTree === 'Y'){ | |
214 | + tbTypeText+='(树)' | |
215 | + } | |
216 | + return tbTypeText; | |
209 | 217 | } |
210 | 218 | }, |
211 | 219 | { |
... | ... | @@ -316,10 +324,14 @@ |
316 | 324 | this.syncFormId = id |
317 | 325 | }, |
318 | 326 | goPageOnline(rd) { |
319 | - if(rd.isTree=='Y'){ | |
320 | - this.$router.push({ path: '/online/cgformTreeList/' + rd.id }) | |
327 | + if(rd.themeTemplate === 'erp'){ | |
328 | + this.$router.push({ path: '/online/cgformErpList/' + rd.id }) | |
321 | 329 | }else{ |
322 | - this.$router.push({ path: '/online/cgformList/' + rd.id }) | |
330 | + if(rd.isTree=='Y'){ | |
331 | + this.$router.push({ path: '/online/cgformTreeList/' + rd.id }) | |
332 | + }else{ | |
333 | + this.$router.push({ path: '/online/cgformList/' + rd.id }) | |
334 | + } | |
323 | 335 | } |
324 | 336 | }, |
325 | 337 | handleOnlineUrlClose() { |
... | ... | @@ -438,6 +450,9 @@ |
438 | 450 | } |
439 | 451 | } |
440 | 452 | </script> |
453 | +<style scoped> | |
454 | + @import '~@assets/less/common.less'; | |
455 | +</style> | |
441 | 456 | <style lang="less"> |
442 | 457 | .ant-card-body .table-operator { |
443 | 458 | margin-bottom: 18px; |
... | ... |
ant-design-vue-jeecg/src/views/modules/online/cgform/auto/OnlCgformAutoList.vue
... | ... | @@ -40,16 +40,15 @@ |
40 | 40 | <!-- 操作按钮区域 --> |
41 | 41 | <div class="table-operator"> |
42 | 42 | <a-button v-if="buttonSwitch.add" @click="handleAdd" type="primary" icon="plus">新增</a-button> |
43 | - <a-button v-if="buttonSwitch.import" @click="handleImportXls" type="primary" icon="upload" style="margin-left:8px">导入</a-button> | |
44 | - <a-button v-if="buttonSwitch.export" @click="handleExportXls" type="primary" icon="download" style="margin-left:8px">导出</a-button> | |
43 | + <a-button v-if="buttonSwitch.import" @click="handleImportXls" type="primary" icon="upload">导入</a-button> | |
44 | + <a-button v-if="buttonSwitch.export" @click="handleExportXls" type="primary" icon="download">导出</a-button> | |
45 | 45 | <template v-if="cgButtonList && cgButtonList.length>0" v-for="(item,index) in cgButtonList"> |
46 | 46 | <a-button |
47 | 47 | v-if=" item.optType=='js' " |
48 | 48 | :key=" 'cgbtn'+index " |
49 | 49 | @click="cgButtonJsHandler(item.buttonCode)" |
50 | 50 | type="primary" |
51 | - :icon="item.buttonIcon" | |
52 | - style="margin-left:8px"> | |
51 | + :icon="item.buttonIcon"> | |
53 | 52 | {{ item.buttonName }} |
54 | 53 | </a-button> |
55 | 54 | <a-button |
... | ... | @@ -57,8 +56,7 @@ |
57 | 56 | :key=" 'cgbtn'+index " |
58 | 57 | @click="cgButtonActionHandler(item.buttonCode)" |
59 | 58 | type="primary" |
60 | - :icon="item.buttonIcon" | |
61 | - style="margin-left:8px"> | |
59 | + :icon="item.buttonIcon"> | |
62 | 60 | {{ item.buttonName }} |
63 | 61 | </a-button> |
64 | 62 | </template> |
... | ... | @@ -69,13 +67,11 @@ |
69 | 67 | :fieldList="superQuery.fieldList" |
70 | 68 | :saveCode="$route.fullPath" |
71 | 69 | :loading="table.loading" |
72 | - style="margin-left: 8px;" | |
73 | 70 | @handleSuperQuery="handleSuperQuery"/> |
74 | 71 | |
75 | 72 | <a-button |
76 | 73 | v-if="buttonSwitch.batch_delete" |
77 | 74 | @click="handleDelBatch" |
78 | - style="margin-left:8px" | |
79 | 75 | v-show="table.selectedRowKeys.length > 0" |
80 | 76 | ghost |
81 | 77 | type="primary" |
... | ... | @@ -103,6 +99,16 @@ |
103 | 99 | :scroll="table.scroll" |
104 | 100 | style="min-height: 300px"> |
105 | 101 | |
102 | + <!-- 支持链接href跳转 --> | |
103 | + <template | |
104 | + v-for="field of fieldHrefSlots" | |
105 | + :slot="field.slotName" | |
106 | + slot-scope="text, record" | |
107 | + > | |
108 | + <a @click="handleClickFieldHref(field,record)">{{ text }}</a> | |
109 | + </template> | |
110 | + | |
111 | + | |
106 | 112 | <template slot="dateSlot" slot-scope="text"> |
107 | 113 | <span>{{ getFormatDate(text) }}</span> |
108 | 114 | </template> |
... | ... | @@ -149,23 +155,17 @@ |
149 | 155 | 更多 <a-icon type="down" /> |
150 | 156 | </a> |
151 | 157 | <a-menu slot="overlay"> |
152 | - <a-menu-item > | |
158 | + <a-menu-item v-if="buttonSwitch.detail"> | |
153 | 159 | <a href="javascript:;" @click="handleDetail(record)">详情</a> |
154 | 160 | </a-menu-item> |
155 | 161 | <template v-if="hasBpmStatus"> |
156 | 162 | <template v-if="record.bpm_status == '1'||record.bpm_status == ''|| record.bpm_status == null"> |
157 | - <a-menu-item> | |
158 | - <a href="javascript:;" @click="startProcess(record)">提交流程</a> | |
159 | - </a-menu-item> | |
160 | 163 | <a-menu-item v-if="buttonSwitch.delete"> |
161 | 164 | <a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)"> |
162 | 165 | <a>删除</a> |
163 | 166 | </a-popconfirm> |
164 | 167 | </a-menu-item> |
165 | 168 | </template> |
166 | - <template v-else> | |
167 | - <a-menu-item @click="handlePreviewPic(record)">审批进度</a-menu-item> | |
168 | - </template> | |
169 | 169 | </template> |
170 | 170 | <template v-else> |
171 | 171 | <a-menu-item v-if="buttonSwitch.delete"> |
... | ... | @@ -175,7 +175,7 @@ |
175 | 175 | </a-menu-item> |
176 | 176 | </template> |
177 | 177 | <template v-if="cgButtonLinkList && cgButtonLinkList.length>0" v-for="(btnItem,btnIndex) in cgButtonLinkList"> |
178 | - <a-menu-item :key=" 'cgbtnLink'+btnIndex "> | |
178 | + <a-menu-item :key=" 'cgbtnLink'+btnIndex " v-if="showLinkButton(btnItem,record)"> | |
179 | 179 | <a href="javascript:void(0);" @click="cgButtonLinkHandler(record,btnItem.buttonCode,btnItem.optType)"> |
180 | 180 | <a-icon v-if="btnItem.buttonIcon" :type="btnItem.buttonIcon" /> |
181 | 181 | {{ btnItem.buttonName }} |
... | ... | @@ -192,20 +192,27 @@ |
192 | 192 | |
193 | 193 | <j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal> |
194 | 194 | |
195 | + <!-- 跳转Href的动态组件方式 --> | |
196 | + <a-modal v-bind="hrefComponent.model" v-on="hrefComponent.on"> | |
197 | + <component :is="hrefComponent.is" v-bind="hrefComponent.params"/> | |
198 | + </a-modal> | |
199 | + | |
195 | 200 | </div> |
196 | 201 | </a-card> |
197 | 202 | </template> |
198 | 203 | |
199 | 204 | <script> |
200 | 205 | |
206 | + import { HrefJump } from '@/mixins/OnlAutoListMixin' | |
201 | 207 | import { postAction,getAction,deleteAction,downFile } from '@/api/manage' |
202 | 208 | import { filterMultiDictText } from '@/components/dict/JDictSelectUtil' |
203 | - import { filterObj } from '@/utils/util'; | |
209 | + import { cloneObject, filterObj } from '@/utils/util' | |
204 | 210 | import JImportModal from '@/components/jeecg/JImportModal' |
205 | 211 | import JSuperQuery from '@comp/jeecg/JSuperQuery' |
206 | 212 | |
207 | 213 | export default { |
208 | 214 | name: 'OnlCgFormAutoList', |
215 | + mixins: [HrefJump], | |
209 | 216 | components: { |
210 | 217 | JSuperQuery, |
211 | 218 | JImportModal, |
... | ... | @@ -222,7 +229,6 @@ |
222 | 229 | optPre:"/online/cgform/api/form/", |
223 | 230 | exportXls:'/online/cgform/api/exportXls/', |
224 | 231 | buttonAction:'/online/cgform/api/doButton', |
225 | - startProcess: "/process/extActProcess/startMutilProcess", | |
226 | 232 | }, |
227 | 233 | flowCodePre:"onl_", |
228 | 234 | isorter:{ |
... | ... | @@ -282,7 +288,8 @@ |
282 | 288 | delete:true, |
283 | 289 | batch_delete:true, |
284 | 290 | import:true, |
285 | - export:true | |
291 | + export:true, | |
292 | + detail:true | |
286 | 293 | }, |
287 | 294 | hasBpmStatus:false, |
288 | 295 | checkboxFlag:false, |
... | ... | @@ -304,8 +311,7 @@ |
304 | 311 | this.cgButtonJsHandler('mounted') |
305 | 312 | }, |
306 | 313 | watch: { |
307 | - '$route.path'(newVal,oldVal) { | |
308 | - console.log('$route.path: ',oldVal) | |
314 | + '$route'() { | |
309 | 315 | // 刷新参数放到这里去触发,就可以刷新相同界面了 |
310 | 316 | this.initAutoList() |
311 | 317 | } |
... | ... | @@ -343,30 +349,6 @@ |
343 | 349 | this.hasBpmStatus = false; |
344 | 350 | } |
345 | 351 | }, |
346 | - startProcess: function(record){ | |
347 | - var that = this; | |
348 | - this.$confirm({ | |
349 | - title:"提示", | |
350 | - content:"确认提交流程吗?", | |
351 | - onOk: function(){ | |
352 | - var param = { | |
353 | - flowCode:that.flowCodePre+that.currentTableName, | |
354 | - id:record.id, | |
355 | - formUrl:"modules/bpm/task/form/OnlineFormDetail", | |
356 | - formUrlMobile:"modules/bpm/task/form/OnlineFormDetail" | |
357 | - } | |
358 | - postAction(that.url.startProcess,param).then((res)=>{ | |
359 | - if(res.success){ | |
360 | - that.$message.success(res.message); | |
361 | - that.loadData(); | |
362 | - that.onClearSelected(); | |
363 | - }else{ | |
364 | - that.$message.warning(res.message); | |
365 | - } | |
366 | - }); | |
367 | - } | |
368 | - }); | |
369 | - }, | |
370 | 352 | initQueryInfo(){ |
371 | 353 | getAction(`${this.url.getQueryInfo}${this.code}`).then((res)=>{ |
372 | 354 | console.log("--onlineList-获取查询条件配置",res); |
... | ... | @@ -407,6 +389,7 @@ |
407 | 389 | this.table.pagination = false |
408 | 390 | } |
409 | 391 | |
392 | + this.fieldHrefSlots = res.result.fieldHrefSlots | |
410 | 393 | this.dictOptions = res.result.dictOptions |
411 | 394 | this.formTemplate = res.result.formTemplate |
412 | 395 | this.description = res.result.description |
... | ... | @@ -441,6 +424,8 @@ |
441 | 424 | this.hasBpmStatusFilter(); |
442 | 425 | this.loadData(); |
443 | 426 | this.initQueryInfo(); |
427 | + //加载新路由,清空checkbox选中 | |
428 | + this.table.selectedRowKeys = []; | |
444 | 429 | }else{ |
445 | 430 | this.$message.warning(res.message) |
446 | 431 | } |
... | ... | @@ -569,6 +554,10 @@ |
569 | 554 | this.cgButtonLinkHandler(record,"beforeEdit","js") |
570 | 555 | this.$refs.modal.edit(this.formTemplate,record.id); |
571 | 556 | }, |
557 | + showLinkButton(item,record){ | |
558 | + let btn = new ButtonExpHandler(item.exp,record); | |
559 | + return btn.show; | |
560 | + }, | |
572 | 561 | handleDetail(record){ |
573 | 562 | this.$refs.modal.detail(this.formTemplate,record.id); |
574 | 563 | }, |
... | ... | @@ -604,7 +593,8 @@ |
604 | 593 | dictCode: field.dictCode, |
605 | 594 | dictTable: field.dictTable, |
606 | 595 | dictText: field.dictText, |
607 | - options: field.enum || field.options | |
596 | + options: field.enum || field.options, | |
597 | + order: field.order, | |
608 | 598 | }) |
609 | 599 | } |
610 | 600 | let fieldList = [] |
... | ... | @@ -630,6 +620,17 @@ |
630 | 620 | setField(fieldList, field) |
631 | 621 | } |
632 | 622 | } |
623 | + // 冒泡排序 | |
624 | + for (let i = 0; i < fieldList.length; i++) { | |
625 | + for (let j = i + 1; j < fieldList.length; j++) { | |
626 | + let temp1 = fieldList[i] | |
627 | + let temp2 = fieldList[j] | |
628 | + if (temp1.order > temp2.order) { | |
629 | + fieldList[i] = temp2 | |
630 | + fieldList[j] = temp1 | |
631 | + } | |
632 | + } | |
633 | + } | |
633 | 634 | this.superQuery.fieldList = fieldList |
634 | 635 | } |
635 | 636 | }, |
... | ... | @@ -641,7 +642,7 @@ |
641 | 642 | if(text && text.indexOf(",")>0){ |
642 | 643 | text = text.substring(0,text.indexOf(",")) |
643 | 644 | } |
644 | - return window._CONFIG['imgDomainURL']+"/"+text | |
645 | + return window._CONFIG['staticDomainURL']+"/"+text | |
645 | 646 | }, |
646 | 647 | downloadRowFile(text){ |
647 | 648 | if(!text){ |
... | ... | @@ -651,7 +652,7 @@ |
651 | 652 | if(text.indexOf(",")>0){ |
652 | 653 | text = text.substring(0,text.indexOf(",")) |
653 | 654 | } |
654 | - window.open(window._CONFIG['downloadUrl']+"/"+text);//TODO 下载的方法 | |
655 | + window.open(window._CONFIG['staticDomainURL']+"/"+text);//TODO 下载的方法 | |
655 | 656 | }, |
656 | 657 | handleDelBatch(){ |
657 | 658 | if(this.table.selectedRowKeys.length<=0){ |
... | ... | @@ -777,13 +778,15 @@ |
777 | 778 | } |
778 | 779 | }, |
779 | 780 | initButtonSwitch(hideColumns){ |
781 | + Object.keys(this.buttonSwitch).forEach(key=>{ | |
782 | + this.buttonSwitch[key]=true | |
783 | + }) | |
780 | 784 | if(hideColumns && hideColumns.length>0){ |
781 | 785 | Object.keys(this.buttonSwitch).forEach(key=>{ |
782 | 786 | if(hideColumns.indexOf(key)>=0){ |
783 | 787 | this.buttonSwitch[key]=false |
784 | 788 | } |
785 | 789 | }) |
786 | - | |
787 | 790 | } |
788 | 791 | }, |
789 | 792 | |
... | ... | @@ -801,6 +804,9 @@ |
801 | 804 | } |
802 | 805 | } |
803 | 806 | </script> |
807 | +<style scoped> | |
808 | + @import '~@assets/less/common.less'; | |
809 | +</style> | |
804 | 810 | <style> |
805 | 811 | .ant-card-body .table-operator{ |
806 | 812 | margin-bottom: 18px; |
... | ... |
ant-design-vue-jeecg/src/views/modules/online/cgform/auto/OnlCgformTreeList.vue
... | ... | @@ -98,15 +98,6 @@ |
98 | 98 | <a-menu-item > |
99 | 99 | <a @click="handleDetail(record)">详情</a> |
100 | 100 | </a-menu-item> |
101 | - | |
102 | - <a-menu-item v-if="showSubmitFlowButton(record)"> | |
103 | - <a @click="startProcess(record)">提交流程</a> | |
104 | - </a-menu-item> | |
105 | - | |
106 | - <template v-if="showViewFlowButton(record)"> | |
107 | - <a-menu-item @click="handlePreviewPic(record)">审批进度</a-menu-item> | |
108 | - </template> | |
109 | - | |
110 | 101 | <a-menu-item v-if="showOptButton('delete',record)"> |
111 | 102 | <a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)"> |
112 | 103 | <a>删除</a> |
... | ... | @@ -146,7 +137,7 @@ |
146 | 137 | export default { |
147 | 138 | name: 'OnlCgformTreeList', |
148 | 139 | components: { |
149 | - JImportModal | |
140 | + JImportModal, | |
150 | 141 | }, |
151 | 142 | data() { |
152 | 143 | return { |
... | ... | @@ -183,7 +174,6 @@ |
183 | 174 | optPre:"/online/cgform/api/form/", |
184 | 175 | exportXls:'/online/cgform/api/exportXls/', |
185 | 176 | buttonAction:'/online/cgform/api/doButton', |
186 | - startProcess: "/process/extActProcess/startMutilProcess" | |
187 | 177 | }, |
188 | 178 | isorter:{ |
189 | 179 | column: 'create_time', |
... | ... | @@ -482,7 +472,7 @@ |
482 | 472 | if(text && text.indexOf(",")>0){ |
483 | 473 | text = text.substring(0,text.indexOf(",")) |
484 | 474 | } |
485 | - return window._CONFIG['imgDomainURL']+"/"+text | |
475 | + return window._CONFIG['staticDomainURL']+"/"+text | |
486 | 476 | }, |
487 | 477 | downloadRowFile(text){ |
488 | 478 | if(!text){ |
... | ... | @@ -492,7 +482,7 @@ |
492 | 482 | if(text.indexOf(",")>0){ |
493 | 483 | text = text.substring(0,text.indexOf(",")) |
494 | 484 | } |
495 | - window.open(window._CONFIG['downloadUrl']+"/"+text); | |
485 | + window.open(window._CONFIG['staticDomainURL']+"/"+text); | |
496 | 486 | }, |
497 | 487 | /*-------数据格式化-end----------*/ |
498 | 488 | |
... | ... | @@ -651,14 +641,6 @@ |
651 | 641 | } |
652 | 642 | return true |
653 | 643 | }, |
654 | - showSubmitFlowButton(record){ | |
655 | - if(this.hasBpmStatus){ | |
656 | - if(record.bpm_status ==null || record.bpm_status =='' || record.bpm_status == '1'){ | |
657 | - return true | |
658 | - } | |
659 | - } | |
660 | - return false | |
661 | - }, | |
662 | 644 | showViewFlowButton(record){ |
663 | 645 | if(this.hasBpmStatus){ |
664 | 646 | if(record.bpm_status !=null && record.bpm_status !='' && record.bpm_status != '1'){ |
... | ... | @@ -691,6 +673,7 @@ |
691 | 673 | } |
692 | 674 | }); |
693 | 675 | }, |
676 | + | |
694 | 677 | } |
695 | 678 | } |
696 | 679 | </script> |
... | ... |
ant-design-vue-jeecg/src/views/modules/online/cgform/auto/erp/OnlCgformErpList.vue
0 → 100644
1 | +<template> | |
2 | + <a-card :bordered="false" style="height: 100%"> | |
3 | + <online-common-list | |
4 | + :ref="'onl_'+mainModel.currentTableName" | |
5 | + :code="code" | |
6 | + :model="mainModel" | |
7 | + @seleted="onSelected"> | |
8 | + </online-common-list> | |
9 | + | |
10 | + <a-tabs defaultActiveKey="0"> | |
11 | + <a-tab-pane v-for="(item,index) in subList" :tab="item.description" :key="index+''" :forceRender="true" > | |
12 | + <online-common-list | |
13 | + :ref="item.currentTableName" | |
14 | + :code="item.code" | |
15 | + :model="item" | |
16 | + :main="selectedRow"> | |
17 | + </online-common-list> | |
18 | + </a-tab-pane> | |
19 | + </a-tabs> | |
20 | + </a-card> | |
21 | +</template> | |
22 | + | |
23 | +<script> | |
24 | + import { getAction } from '@/api/manage' | |
25 | + | |
26 | + export default { | |
27 | + name: 'OnlCgformErpList', | |
28 | + components:{ | |
29 | + }, | |
30 | + data(){ | |
31 | + return { | |
32 | + code:'', | |
33 | + url: { | |
34 | + getColumns: '/online/cgform/api/getErpColumns/', | |
35 | + }, | |
36 | + mainModel:{}, | |
37 | + subList:[], | |
38 | + mainId:'', | |
39 | + selectedRow:{} | |
40 | + | |
41 | + } | |
42 | + }, | |
43 | + watch: { | |
44 | + '$route'() { | |
45 | + // 刷新参数放到这里去触发,就可以刷新相同界面了 | |
46 | + this.initColumnConfig() | |
47 | + } | |
48 | + }, | |
49 | + | |
50 | + created() { | |
51 | + this.initColumnConfig(); | |
52 | + }, | |
53 | + methods:{ | |
54 | + getSubIndex(index){ | |
55 | + return index+1 + '' | |
56 | + }, | |
57 | + getSubRef(item){ | |
58 | + let ref = item.currentTableName | |
59 | + console.log("ref string",ref) | |
60 | + return ref; | |
61 | + }, | |
62 | + initColumnConfig(){ | |
63 | + if(!this.$route.params.code){ | |
64 | + return false | |
65 | + } | |
66 | + this.code = this.$route.params.code | |
67 | + getAction(`${this.url.getColumns}${this.code}`).then((res)=>{ | |
68 | + console.log("erp表单配置",res) | |
69 | + if(res.success){ | |
70 | + this.mainModel = res.result.main | |
71 | + this.subList = res.result.subList | |
72 | + | |
73 | + this.$nextTick(()=>{ | |
74 | + this.$refs['onl_'+this.mainModel.currentTableName].initListByModel(); | |
75 | + if(this.subList && this.subList.length>0){ | |
76 | + for(let item of this.subList){ | |
77 | + this.$refs[item.currentTableName][0].initListByModel(); | |
78 | + } | |
79 | + } | |
80 | + }); | |
81 | + | |
82 | + } | |
83 | + }) | |
84 | + }, | |
85 | + onSelected(row){ | |
86 | + console.log("onSelected",row) | |
87 | + this.selectedRow = row; | |
88 | + } | |
89 | + | |
90 | + | |
91 | + } | |
92 | + } | |
93 | +</script> | |
94 | + | |
95 | +<style> | |
96 | + .ant-card-body .table-operator{ | |
97 | + margin-bottom: 18px; | |
98 | + } | |
99 | + .ant-table-tbody .ant-table-row td{ | |
100 | + padding-top:15px; | |
101 | + padding-bottom:15px; | |
102 | + } | |
103 | + .anty-row-operator button{margin: 0 5px} | |
104 | + .ant-btn-danger{background-color: #ffffff} | |
105 | + | |
106 | + .anty-img-wrap{height:25px;position: relative;} | |
107 | + .anty-img-wrap > img{max-height:100%;} | |
108 | + .ant-modal-cust-warp{height: 100%} | |
109 | + .ant-modal-cust-warp .ant-modal-body{height:calc(100% - 110px) !important;overflow-y: auto} | |
110 | + .ant-modal-cust-warp .ant-modal-content{height:90% !important;overflow-y: hidden} | |
111 | +</style> | |
0 | 112 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/views/modules/online/cgform/util/TableUtils.js
ant-design-vue-jeecg/src/views/modules/oss/OSSFileList.vue
... | ... | @@ -31,7 +31,21 @@ |
31 | 31 | @change="handleChange"> |
32 | 32 | <a-button> |
33 | 33 | <a-icon type="upload"/> |
34 | - 文件上传 | |
34 | + OSS文件上传 | |
35 | + </a-button> | |
36 | + </a-upload> | |
37 | + | |
38 | + <a-upload | |
39 | + name="file" | |
40 | + :multiple="false" | |
41 | + :action="minioUploadAction" | |
42 | + :headers="tokenHeader" | |
43 | + :showUploadList="false" | |
44 | + :beforeUpload="beforeUpload" | |
45 | + @change="handleChange"> | |
46 | + <a-button> | |
47 | + <a-icon type="upload"/> | |
48 | + MINIO文件上传 | |
35 | 49 | </a-button> |
36 | 50 | </a-upload> |
37 | 51 | </div> |
... | ... | @@ -58,7 +72,9 @@ |
58 | 72 | @change="handleTableChange"> |
59 | 73 | |
60 | 74 | <span slot="action" slot-scope="text, record"> |
61 | - <a @click="ossDelete(record.id)">删除</a> | |
75 | + <a @click="handlePreview(record)">预览</a> | |
76 | + <a-divider type="vertical"/> | |
77 | + <a @click="ossDelete(record.id)">删除</a> | |
62 | 78 | </span> |
63 | 79 | |
64 | 80 | </a-table> |
... | ... | @@ -108,14 +124,18 @@ |
108 | 124 | url: { |
109 | 125 | upload: "/oss/file/upload", |
110 | 126 | list: "/oss/file/list", |
111 | - delete: "/oss/file/delete" | |
127 | + delete: "/oss/file/delete", | |
128 | + minioUpload: "/sys/upload/uploadMinio" | |
112 | 129 | } |
113 | 130 | } |
114 | 131 | }, |
115 | 132 | computed: { |
116 | 133 | uploadAction() { |
117 | 134 | return window._CONFIG['domianURL'] + this.url.upload; |
118 | - } | |
135 | + }, | |
136 | + minioUploadAction() { | |
137 | + return window._CONFIG['domianURL'] + this.url.minioUpload; | |
138 | + }, | |
119 | 139 | }, |
120 | 140 | methods: { |
121 | 141 | beforeUpload(file) { |
... | ... | @@ -139,10 +159,10 @@ |
139 | 159 | this.loadData() |
140 | 160 | this.$message.success(`${info.file.name} 上传成功!`); |
141 | 161 | } else { |
142 | - this.$message.error(`${info.file.name} 上传失败.`); | |
162 | + this.$message.error(`${info.file.response.message}`); | |
143 | 163 | } |
144 | 164 | } else if (info.file.status === 'error') { |
145 | - this.$message.error(`${info.file.name} 上传失败.`); | |
165 | + this.$message.error(`${info.file.response.message}`); | |
146 | 166 | } |
147 | 167 | }, |
148 | 168 | ossDelete(id) { |
... | ... | @@ -154,11 +174,17 @@ |
154 | 174 | that.handleDelete(id) |
155 | 175 | } |
156 | 176 | }); |
177 | + }, | |
178 | + handlePreview(record) { | |
179 | + if (record && record.url) { | |
180 | + let url = window._CONFIG['onlinePreviewDomainURL'] + '?url=' + encodeURIComponent(record.url) | |
181 | + window.open(url, '_blank') | |
182 | + } | |
157 | 183 | } |
158 | 184 | } |
159 | 185 | } |
160 | 186 | </script> |
161 | 187 | |
162 | 188 | <style scoped> |
163 | - @import '~@assets/less/common.less' | |
189 | + @import '~@assets/less/common.less'; | |
164 | 190 | </style> |
... | ... |
ant-design-vue-jeecg/src/views/system/DepartList.vue
... | ... | @@ -17,8 +17,7 @@ |
17 | 17 | <div style="background: #fff;padding-left:16px;height: 100%; margin-top: 5px"> |
18 | 18 | <a-alert type="info" :showIcon="true"> |
19 | 19 | <div slot="message"> |
20 | - 当前选择: | |
21 | - <a v-if="this.currSelected.title">{{ getCurrSelectedTitle() }}</a> | |
20 | + 当前选择:<span v-if="this.currSelected.title">{{ getCurrSelectedTitle() }}</span> | |
22 | 21 | <a v-if="this.currSelected.title" style="margin-left: 10px" @click="onClearSelected">取消选择</a> |
23 | 22 | </div> |
24 | 23 | </a-alert> |
... | ... | @@ -72,82 +71,90 @@ |
72 | 71 | <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------> |
73 | 72 | </a-col> |
74 | 73 | <a-col :md="12" :sm="24"> |
75 | - <a-card :bordered="false"> | |
76 | - <a-form :form="form"> | |
77 | - <a-form-item | |
78 | - :labelCol="labelCol" | |
79 | - :wrapperCol="wrapperCol" | |
80 | - label="机构名称"> | |
81 | - <a-input placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/> | |
82 | - </a-form-item> | |
83 | - <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门"> | |
84 | - <a-tree-select | |
85 | - style="width:100%" | |
86 | - :dropdownStyle="{maxHeight:'200px',overflow:'auto'}" | |
87 | - :treeData="treeData" | |
88 | - :disabled="disable" | |
89 | - v-model="model.parentId" | |
90 | - placeholder="无"> | |
91 | - </a-tree-select> | |
92 | - </a-form-item> | |
93 | - <a-form-item | |
94 | - :labelCol="labelCol" | |
95 | - :wrapperCol="wrapperCol" | |
96 | - label="机构编码"> | |
97 | - <a-input disabled placeholder="请输入机构编码" v-decorator="['orgCode', validatorRules.orgCode ]"/> | |
98 | - </a-form-item> | |
99 | - <a-form-item | |
100 | - :labelCol="labelCol" | |
101 | - :wrapperCol="wrapperCol" | |
102 | - label="机构类型"> | |
103 | - <template v-if="orgCategoryDisabled"> | |
104 | - <a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型"> | |
105 | - <a-radio value="1"> | |
106 | - 公司 | |
107 | - </a-radio> | |
108 | - </a-radio-group> | |
109 | - </template> | |
110 | - <template v-else> | |
111 | - <a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型"> | |
112 | - <a-radio value="2"> | |
113 | - 部门 | |
114 | - </a-radio> | |
115 | - <a-radio value="3"> | |
116 | - 岗位 | |
117 | - </a-radio> | |
118 | - </a-radio-group> | |
119 | - </template> | |
120 | - </a-form-item> | |
121 | - <a-form-item | |
122 | - :labelCol="labelCol" | |
123 | - :wrapperCol="wrapperCol" | |
124 | - label="排序"> | |
125 | - <a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/> | |
126 | - </a-form-item> | |
127 | - <a-form-item | |
128 | - :labelCol="labelCol" | |
129 | - :wrapperCol="wrapperCol" | |
130 | - label="手机号"> | |
131 | - <a-input placeholder="请输入手机号" v-decorator="['mobile', {'initialValue':''}]"/> | |
132 | - </a-form-item> | |
133 | - <a-form-item | |
134 | - :labelCol="labelCol" | |
135 | - :wrapperCol="wrapperCol" | |
136 | - label="地址"> | |
137 | - <a-input placeholder="请输入地址" v-decorator="['address', {'initialValue':''}]"/> | |
138 | - </a-form-item> | |
139 | - <a-form-item | |
140 | - :labelCol="labelCol" | |
141 | - :wrapperCol="wrapperCol" | |
142 | - label="备注"> | |
143 | - <a-textarea placeholder="请输入备注" v-decorator="['memo', {'initialValue':''}]"/> | |
144 | - </a-form-item> | |
145 | - </a-form> | |
146 | - <div class="anty-form-btn"> | |
147 | - <a-button @click="emptyCurrForm" type="default" htmlType="button" icon="sync">重置</a-button> | |
148 | - <a-button @click="submitCurrForm" type="primary" htmlType="button" icon="form">修改并保存</a-button> | |
149 | - </div> | |
150 | - </a-card> | |
74 | + <a-tabs defaultActiveKey="1"> | |
75 | + <a-tab-pane tab="基本信息" key="1" > | |
76 | + <a-card :bordered="false"> | |
77 | + <a-form :form="form"> | |
78 | + <a-form-item | |
79 | + :labelCol="labelCol" | |
80 | + :wrapperCol="wrapperCol" | |
81 | + label="机构名称"> | |
82 | + <a-input placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/> | |
83 | + </a-form-item> | |
84 | + <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门"> | |
85 | + <a-tree-select | |
86 | + style="width:100%" | |
87 | + :dropdownStyle="{maxHeight:'200px',overflow:'auto'}" | |
88 | + :treeData="treeData" | |
89 | + :disabled="disable" | |
90 | + v-model="model.parentId" | |
91 | + placeholder="无"> | |
92 | + </a-tree-select> | |
93 | + </a-form-item> | |
94 | + <a-form-item | |
95 | + :labelCol="labelCol" | |
96 | + :wrapperCol="wrapperCol" | |
97 | + label="机构编码"> | |
98 | + <a-input disabled placeholder="请输入机构编码" v-decorator="['orgCode', validatorRules.orgCode ]"/> | |
99 | + </a-form-item> | |
100 | + <a-form-item | |
101 | + :labelCol="labelCol" | |
102 | + :wrapperCol="wrapperCol" | |
103 | + label="机构类型"> | |
104 | + <template v-if="orgCategoryDisabled"> | |
105 | + <a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型"> | |
106 | + <a-radio value="1"> | |
107 | + 公司 | |
108 | + </a-radio> | |
109 | + </a-radio-group> | |
110 | + </template> | |
111 | + <template v-else> | |
112 | + <a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型"> | |
113 | + <a-radio value="2"> | |
114 | + 部门 | |
115 | + </a-radio> | |
116 | + <a-radio value="3"> | |
117 | + 岗位 | |
118 | + </a-radio> | |
119 | + </a-radio-group> | |
120 | + </template> | |
121 | + </a-form-item> | |
122 | + <a-form-item | |
123 | + :labelCol="labelCol" | |
124 | + :wrapperCol="wrapperCol" | |
125 | + label="排序"> | |
126 | + <a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/> | |
127 | + </a-form-item> | |
128 | + <a-form-item | |
129 | + :labelCol="labelCol" | |
130 | + :wrapperCol="wrapperCol" | |
131 | + label="手机号"> | |
132 | + <a-input placeholder="请输入手机号" v-decorator="['mobile', {'initialValue':''}]"/> | |
133 | + </a-form-item> | |
134 | + <a-form-item | |
135 | + :labelCol="labelCol" | |
136 | + :wrapperCol="wrapperCol" | |
137 | + label="地址"> | |
138 | + <a-input placeholder="请输入地址" v-decorator="['address', {'initialValue':''}]"/> | |
139 | + </a-form-item> | |
140 | + <a-form-item | |
141 | + :labelCol="labelCol" | |
142 | + :wrapperCol="wrapperCol" | |
143 | + label="备注"> | |
144 | + <a-textarea placeholder="请输入备注" v-decorator="['memo', {'initialValue':''}]"/> | |
145 | + </a-form-item> | |
146 | + </a-form> | |
147 | + <div class="anty-form-btn"> | |
148 | + <a-button @click="emptyCurrForm" type="default" htmlType="button" icon="sync">重置</a-button> | |
149 | + <a-button @click="submitCurrForm" type="primary" htmlType="button" icon="form">修改并保存</a-button> | |
150 | + </div> | |
151 | + </a-card> | |
152 | + </a-tab-pane> | |
153 | + <a-tab-pane tab="部门权限" key="2" forceRender> | |
154 | + <depart-auth-modal ref="departAuth"/> | |
155 | + </a-tab-pane> | |
156 | + </a-tabs> | |
157 | + | |
151 | 158 | </a-col> |
152 | 159 | <depart-modal ref="departModal" @ok="loadTree"></depart-modal> |
153 | 160 | </a-row> |
... | ... | @@ -158,6 +165,7 @@ |
158 | 165 | import {queryDepartTreeList, searchByKeywords, deleteByDepartId} from '@/api/api' |
159 | 166 | import {httpAction, deleteAction} from '@/api/manage' |
160 | 167 | import {JeecgListMixin} from '@/mixins/JeecgListMixin' |
168 | + import DepartAuthModal from './modules/DepartAuthModal' | |
161 | 169 | // 表头 |
162 | 170 | const columns = [ |
163 | 171 | { |
... | ... | @@ -201,6 +209,7 @@ |
201 | 209 | name: 'DepartList', |
202 | 210 | mixins: [JeecgListMixin], |
203 | 211 | components: { |
212 | + DepartAuthModal, | |
204 | 213 | DepartModal |
205 | 214 | }, |
206 | 215 | data() { |
... | ... | @@ -403,7 +412,7 @@ |
403 | 412 | this.selectedKeys = [record.key] |
404 | 413 | this.model.parentId = record.parentId |
405 | 414 | this.setValuesToForm(record) |
406 | - | |
415 | + this.$refs.departAuth.show(record.id); | |
407 | 416 | |
408 | 417 | }, |
409 | 418 | // 触发onSelect事件时,为部门树右侧的form表单赋值 |
... | ... | @@ -425,6 +434,7 @@ |
425 | 434 | this.currSelected = {} |
426 | 435 | this.form.resetFields() |
427 | 436 | this.selectedKeys = [] |
437 | + this.$refs.departAuth.departId = '' | |
428 | 438 | }, |
429 | 439 | handleNodeTypeChange(val) { |
430 | 440 | this.currSelected.nodeType = val |
... | ... |
ant-design-vue-jeecg/src/views/system/DepartUserList.vue
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | <a-input-search @search="onSearch" style="width:100%;margin-top: 10px" placeholder="请输入部门名称"/> |
7 | 7 | <!-- 树--> |
8 | 8 | |
9 | - <template> | |
9 | + <template v-if="userIdentity === '2' && departTree.length>0"> | |
10 | 10 | |
11 | 11 | <!--组织机构--> |
12 | 12 | <a-tree |
... | ... | @@ -16,10 +16,14 @@ |
16 | 16 | @select="onSelect" |
17 | 17 | :dropdownStyle="{maxHeight:'200px',overflow:'auto'}" |
18 | 18 | :treeData="departTree" |
19 | + :autoExpandParent="autoExpandParent" | |
19 | 20 | /> |
20 | 21 | |
21 | 22 | </template> |
22 | - | |
23 | + <div style="margin-top: 24px;" v-else-if="userIdentity === '2' && departTree.length==0"> | |
24 | + <h3><span>您的部门下暂无有效部门信息</span></h3> | |
25 | + </div> | |
26 | + <div style="margin-top: 24px;" v-else><h3>普通员工暂此权限</h3></div> | |
23 | 27 | </div> |
24 | 28 | </a-card> |
25 | 29 | </a-col> |
... | ... | @@ -30,7 +34,10 @@ |
30 | 34 | <Dept-Base-Info ref="DeptBaseInfo"></Dept-Base-Info> |
31 | 35 | </a-tab-pane> |
32 | 36 | <a-tab-pane tab="用户信息" key="2"> |
33 | - <Dept-User-Info ref="DeptUserInfo"></Dept-User-Info> | |
37 | + <Dept-User-Info ref="DeptUserInfo" @clearSelectedDepartKeys="clearSelectedDepartKeys"></Dept-User-Info> | |
38 | + </a-tab-pane> | |
39 | + <a-tab-pane tab="部门角色" key="3" forceRender> | |
40 | + <dept-role-info ref="DeptRoleInfo" @clearSelectedDepartKeys="clearSelectedDepartKeys"/> | |
34 | 41 | </a-tab-pane> |
35 | 42 | </a-tabs> |
36 | 43 | </a-card> |
... | ... | @@ -40,13 +47,15 @@ |
40 | 47 | <script> |
41 | 48 | import DeptBaseInfo from './modules/DeptBaseInfo' |
42 | 49 | import DeptUserInfo from './modules/DeptUserInfo' |
43 | - import {queryDepartTreeList, searchByKeywords} from '@/api/api' | |
50 | + import {queryMyDepartTreeList, searchByKeywords} from '@/api/api' | |
44 | 51 | import {JeecgListMixin} from '@/mixins/JeecgListMixin' |
52 | + import DeptRoleInfo from './modules/DeptRoleInfo' | |
45 | 53 | |
46 | 54 | export default { |
47 | 55 | name: 'DepartUserList', |
48 | 56 | mixins: [JeecgListMixin], |
49 | 57 | components: { |
58 | + DeptRoleInfo, | |
50 | 59 | DeptBaseInfo, |
51 | 60 | DeptUserInfo, |
52 | 61 | }, |
... | ... | @@ -85,6 +94,7 @@ |
85 | 94 | nodes: [], |
86 | 95 | edges: [] |
87 | 96 | }, |
97 | + userIdentity:"", | |
88 | 98 | } |
89 | 99 | }, |
90 | 100 | methods: { |
... | ... | @@ -94,12 +104,19 @@ |
94 | 104 | loadData() { |
95 | 105 | this.refresh(); |
96 | 106 | }, |
107 | + clearSelectedDepartKeys() { | |
108 | + this.checkedKeys = []; | |
109 | + this.selectedKeys = []; | |
110 | + this.currentDeptId = ''; | |
111 | + this.$refs.DeptUserInfo.currentDeptId=''; | |
112 | + this.$refs.DeptRoleInfo.currentDeptId=''; | |
113 | + }, | |
97 | 114 | loadTree() { |
98 | 115 | var that = this |
99 | 116 | that.treeData = [] |
100 | 117 | that.departTree = [] |
101 | - queryDepartTreeList().then((res) => { | |
102 | - if (res.success) { | |
118 | + queryMyDepartTreeList().then((res) => { | |
119 | + if (res.success && res.result ) { | |
103 | 120 | for (let i = 0; i < res.result.length; i++) { |
104 | 121 | let temp = res.result[i] |
105 | 122 | that.treeData.push(temp) |
... | ... | @@ -109,6 +126,7 @@ |
109 | 126 | } |
110 | 127 | this.loading = false |
111 | 128 | } |
129 | + that.userIdentity = res.message | |
112 | 130 | }) |
113 | 131 | }, |
114 | 132 | setThisExpandedKeys(node) { |
... | ... | @@ -161,6 +179,7 @@ |
161 | 179 | |
162 | 180 | this.$refs.DeptBaseInfo.open(record); |
163 | 181 | this.$refs.DeptUserInfo.open(record); |
182 | + this.$refs.DeptRoleInfo.open(record); | |
164 | 183 | // } |
165 | 184 | // else { |
166 | 185 | // this.checkedKeys = []; |
... | ... | @@ -180,6 +199,8 @@ |
180 | 199 | this.$refs.DeptBaseInfo.open(record); |
181 | 200 | this.$refs.DeptUserInfo.onClearSelected(); |
182 | 201 | this.$refs.DeptUserInfo.open(record); |
202 | + this.$refs.DeptRoleInfo.onClearSelected(); | |
203 | + this.$refs.DeptRoleInfo.open(record); | |
183 | 204 | }, |
184 | 205 | }, |
185 | 206 | created() { |
... | ... |
ant-design-vue-jeecg/src/views/system/DictList.vue
... | ... | @@ -30,6 +30,7 @@ |
30 | 30 | <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel"> |
31 | 31 | <a-button type="primary" icon="import">导入</a-button> |
32 | 32 | </a-upload> |
33 | + <a-button type="primary" icon="sync" @click="refleshCache()">刷新缓存</a-button> | |
33 | 34 | |
34 | 35 | <a-button type="primary" icon="hdd" @click="openDeleteList">回收站</a-button> |
35 | 36 | </div> |
... | ... | @@ -70,6 +71,7 @@ |
70 | 71 | import DictModal from './modules/DictModal' |
71 | 72 | import DictItemList from './DictItemList' |
72 | 73 | import DictDeleteList from './DictDeleteList' |
74 | + import { getAction } from '@/api/manage' | |
73 | 75 | |
74 | 76 | export default { |
75 | 77 | name: "DictList", |
... | ... | @@ -132,6 +134,7 @@ |
132 | 134 | delete: "/sys/dict/delete", |
133 | 135 | exportXlsUrl: "sys/dict/exportXls", |
134 | 136 | importExcelUrl: "sys/dict/importExcel", |
137 | + refleshCache: "sys/dict/refleshCache", | |
135 | 138 | }, |
136 | 139 | } |
137 | 140 | }, |
... | ... | @@ -165,9 +168,18 @@ |
165 | 168 | that.queryParam.dictCode = ""; |
166 | 169 | that.loadData(this.ipagination.current); |
167 | 170 | }, |
168 | - | |
169 | 171 | openDeleteList(){ |
170 | 172 | this.$refs.dictDeleteList.show() |
173 | + }, | |
174 | + refleshCache(){ | |
175 | + getAction(this.url.refleshCache).then((res) => { | |
176 | + if (res.success) { | |
177 | + this.$message.success("刷新缓存完成!"); | |
178 | + } | |
179 | + }).catch(e=>{ | |
180 | + this.$message.warn("刷新缓存失败!"); | |
181 | + console.log("刷新失败",e) | |
182 | + }) | |
171 | 183 | } |
172 | 184 | }, |
173 | 185 | watch: { |
... | ... |
ant-design-vue-jeecg/src/views/system/NewPermissionList.vue
... | ... | @@ -29,7 +29,9 @@ |
29 | 29 | :dataSource="dataSource" |
30 | 30 | :loading="loading" |
31 | 31 | @expand="expandSubmenu" |
32 | - :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"> | |
32 | + :expandedRowKeys="expandedRowKeys" | |
33 | + :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" | |
34 | + @expandedRowsChange="handleExpandedRowsChange"> | |
33 | 35 | |
34 | 36 | <span slot="action" slot-scope="text, record"> |
35 | 37 | <a @click="handleEdit(record)">编辑</a> |
... | ... | @@ -79,7 +81,7 @@ |
79 | 81 | |
80 | 82 | <script> |
81 | 83 | import PermissionModal from './modules/PermissionModal' |
82 | - import { getSystemMenuList,getSystemSubmenu } from '@/api/api' | |
84 | + import { getSystemMenuList, getSystemSubmenu, getSystemSubmenuBatch } from '@/api/api' | |
83 | 85 | import { JeecgListMixin } from '@/mixins/JeecgListMixin' |
84 | 86 | import PermissionDataRuleList from './PermissionDataRuleList' |
85 | 87 | import JEllipsis from '@/components/jeecg/JEllipsis' |
... | ... | @@ -140,7 +142,7 @@ |
140 | 142 | ] |
141 | 143 | |
142 | 144 | export default { |
143 | - name: 'PermissionList', | |
145 | + name: 'PermissionListAsync', | |
144 | 146 | mixins: [JeecgListMixin], |
145 | 147 | components: { |
146 | 148 | PermissionDataRuleList, |
... | ... | @@ -153,6 +155,8 @@ |
153 | 155 | // 表头 |
154 | 156 | columns: columns, |
155 | 157 | loading: false, |
158 | + // 展开的行,受控属性 | |
159 | + expandedRowKeys: [], | |
156 | 160 | url: { |
157 | 161 | list: '/sys/permission/list', |
158 | 162 | delete: '/sys/permission/delete', |
... | ... | @@ -162,23 +166,45 @@ |
162 | 166 | }, |
163 | 167 | methods: { |
164 | 168 | loadData() { |
165 | - this.dataSource = [] | |
169 | + this.loading = true | |
166 | 170 | getSystemMenuList().then((res) => { |
167 | 171 | if (res.success) { |
168 | - console.log(res.result) | |
169 | 172 | this.dataSource = res.result |
173 | + return this.loadDataByExpandedRows(this.dataSource) | |
170 | 174 | } |
175 | + }).finally(()=>{ | |
176 | + this.loading = false | |
171 | 177 | }) |
172 | 178 | }, |
173 | 179 | expandSubmenu(expanded, record){ |
174 | - if(expanded){ | |
180 | + if (expanded && (!record.children || record.children.length === 0)) { | |
175 | 181 | getSystemSubmenu({parentId:record.id}).then((res) => { |
176 | 182 | if (res.success) { |
177 | 183 | record.children = res.result |
178 | 184 | } |
179 | 185 | }) |
180 | 186 | } |
181 | - | |
187 | + }, | |
188 | + // 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据) | |
189 | + loadDataByExpandedRows(dataList) { | |
190 | + if (this.expandedRowKeys.length > 0) { | |
191 | + return getSystemSubmenuBatch({ parentIds: this.expandedRowKeys.join(',') }).then((res) => { | |
192 | + if (res.success) { | |
193 | + let childrenMap = res.result | |
194 | + let fn = (list) => { | |
195 | + list.forEach(data => { | |
196 | + if (this.expandedRowKeys.includes(data.id)) { | |
197 | + data.children = childrenMap[data.id] | |
198 | + fn(data.children) | |
199 | + } | |
200 | + }) | |
201 | + } | |
202 | + fn(dataList) | |
203 | + } | |
204 | + }) | |
205 | + } else { | |
206 | + return Promise.resolve() | |
207 | + } | |
182 | 208 | }, |
183 | 209 | // 打开数据规则编辑 |
184 | 210 | handleDataRule(record) { |
... | ... | @@ -189,10 +215,13 @@ |
189 | 215 | this.$refs.modalForm.localMenuType = 1; |
190 | 216 | this.$refs.modalForm.disableSubmit = false; |
191 | 217 | this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id}); |
192 | - } | |
218 | + }, | |
219 | + handleExpandedRowsChange(expandedRows) { | |
220 | + this.expandedRowKeys = expandedRows | |
221 | + }, | |
193 | 222 | } |
194 | 223 | } |
195 | 224 | </script> |
196 | 225 | <style scoped> |
197 | - @import '~@assets/less/common.less' | |
226 | + @import '~@assets/less/common.less'; | |
198 | 227 | </style> |
199 | 228 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/views/system/PermissionList.vue
... | ... | @@ -28,7 +28,9 @@ |
28 | 28 | :pagination="false" |
29 | 29 | :dataSource="dataSource" |
30 | 30 | :loading="loading" |
31 | - :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"> | |
31 | + :expandedRowKeys="expandedRowKeys" | |
32 | + :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" | |
33 | + @expandedRowsChange="handleExpandedRowsChange"> | |
32 | 34 | |
33 | 35 | <span slot="action" slot-scope="text, record"> |
34 | 36 | <a @click="handleEdit(record)">编辑</a> |
... | ... | @@ -152,6 +154,8 @@ |
152 | 154 | // 表头 |
153 | 155 | columns: columns, |
154 | 156 | loading: false, |
157 | + // 展开的行,受控属性 | |
158 | + expandedRowKeys: [], | |
155 | 159 | url: { |
156 | 160 | list: '/sys/permission/list', |
157 | 161 | delete: '/sys/permission/delete', |
... | ... | @@ -178,10 +182,13 @@ |
178 | 182 | this.$refs.modalForm.localMenuType = 1; |
179 | 183 | this.$refs.modalForm.disableSubmit = false; |
180 | 184 | this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id}); |
181 | - } | |
185 | + }, | |
186 | + handleExpandedRowsChange(expandedRows) { | |
187 | + this.expandedRowKeys = expandedRows | |
188 | + }, | |
182 | 189 | } |
183 | 190 | } |
184 | 191 | </script> |
185 | 192 | <style scoped> |
186 | - @import '~@assets/less/common.less' | |
193 | + @import '~@assets/less/common.less'; | |
187 | 194 | </style> |
188 | 195 | \ No newline at end of file |
... | ... |
ant-design-vue-jeecg/src/views/system/RoleList.vue
ant-design-vue-jeecg/src/views/system/RoleUserList.vue
... | ... | @@ -60,26 +60,27 @@ |
60 | 60 | :rowSelection="{selectedRowKeys: selectedRowKeys1, onChange: onSelectChange1, type:'radio'}" |
61 | 61 | @change="handleTableChange"> |
62 | 62 | <span slot="action" slot-scope="text, record"> |
63 | - <a @click="handleOpen(record)">用户</a> | |
64 | - <a-divider type="vertical"/> | |
65 | - <a-dropdown> | |
66 | - <a class="ant-dropdown-link"> | |
67 | - 更多 <a-icon type="down"/> | |
68 | - </a> | |
69 | - <a-menu slot="overlay"> | |
70 | - <a-menu-item> | |
71 | - <a @click="handlePerssion(record.id)">授权</a> | |
72 | - </a-menu-item> | |
73 | - <a-menu-item> | |
74 | - <a @click="handleEdit(record)">编辑</a> | |
75 | - </a-menu-item> | |
76 | - <a-menu-item> | |
77 | - <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete1(record.id)"> | |
78 | - <a>删除</a> | |
79 | - </a-popconfirm> | |
80 | - </a-menu-item> | |
81 | - </a-menu> | |
82 | - </a-dropdown> | |
63 | + <a @click="handleOpen(record)">用户</a> | |
64 | + <a-divider type="vertical"/> | |
65 | + | |
66 | + <a-dropdown> | |
67 | + <a class="ant-dropdown-link"> | |
68 | + 更多 <a-icon type="down"/> | |
69 | + </a> | |
70 | + <a-menu slot="overlay"> | |
71 | + <a-menu-item> | |
72 | + <a @click="handlePerssion(record.id)">授权</a> | |
73 | + </a-menu-item> | |
74 | + <a-menu-item> | |
75 | + <a @click="handleEdit(record)">编辑</a> | |
76 | + </a-menu-item> | |
77 | + <a-menu-item> | |
78 | + <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete1(record.id)"> | |
79 | + <a>删除</a> | |
80 | + </a-popconfirm> | |
81 | + </a-menu-item> | |
82 | + </a-menu> | |
83 | + </a-dropdown> | |
83 | 84 | </span> |
84 | 85 | </a-table> |
85 | 86 | </div> |
... | ... | @@ -530,7 +531,7 @@ |
530 | 531 | }, |
531 | 532 | handlePerssion(roleId){ |
532 | 533 | this.$refs.modalUserRole.show(roleId); |
533 | - } | |
534 | + }, | |
534 | 535 | } |
535 | 536 | } |
536 | 537 | </script> |
... | ... |