vue2-client 1.2.25 → 1.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,48 +1,56 @@
1
- # Change Log
2
- > 所有关于本项目的变化都在该文档里。
3
-
4
- **##1.2.25 -2022-03-26 @江超**
5
- - 功能修改:
6
- - [查询配置生成]:表单[新增/修改场景]增加[version(版本号)]类型
7
- - [api.js]:移除[跨域代理前缀]
8
- - 问题修复:
9
- - [查询配置生成]:修复修改已有查询配置时,部分数据显示状态不一致的问题
10
- - [设备详情页]:修复设备抄表记录,异常记录查询报错的问题
11
- - [XFormItem]:修复非懒加载搜索的下拉框显示问题
12
-
13
- **##1.2.20 - 1.2.24 -2022-03-25 @朱子峰**
14
- - 功能修改:
15
- - [工单关闭/开始处理]:工单关闭和开始处理时,不由id来进行判断,改由姓名进行判断是否为同一个人
16
-
17
- **##1.2.17 - 1.2.19 -2022-03-25 @朱子峰**
18
- - 问题修复:
19
- - [钉钉消息推送]:将类别字段从int修改为String,直接传字典中的值
20
- - 功能修改:
21
- - [问题描述]:如果用户没有填写描述,新增默认值:“该用户没有填写描述信息”
22
- - [问题描述]:展示问题描述时,按时间倒序展示,最新的信息显示在最上面
23
-
24
- **##1.2.16 -2022-03-25 @张振宇**
25
- - 功能修改:
26
- - [查询配置生成]:逻辑修改,取消选择组和顺序,用户新增数组字段时需要选择是否为根节点,根节点index为1,不是根节点得数据字段index默认为父节点index+1
27
-
28
- **##1.2.9 - 1.2.15 -2022-03-24 @江超**
29
- - 功能新增:
30
- - [查询配置生成]:下拉框表单选择业务逻辑作为数据源时,可以选择数据源加载方式
31
- - [XFormItem]:当数据源加载方式为懒加载搜索时,将渲染一个可以根据关键词实时查询的选择框
32
- - 问题修复:
33
- - [查询配置生成]:修复修改已有查询配置时,显示状态不一致的问题
34
- - [指令详情页]:修复操作记录查询报错的问题
35
-
36
- **##1.2.8 -2022-03-24 @江超**
37
- - 问题修复:
38
- - [登录页面]:修复登录后欢迎提示出现undefined的问题
39
- - [查询配置生成]:修复修改表单查询方式下拉框报错的问题
40
-
41
- **##1.2.7 -2022-03-24 @江超**
42
- - 功能新增:
43
- - [系统设置]:新增 [工单提交] 功能(submitTicket),用户在操作业务时如发现系统异常,可使用该功能反馈问题
44
- - [登录页面]:登陆人部门为 [用户工单登记] 时会直接跳转到[工单提交]页面(在基于新架构的营收全面使用时,会取消该限制,并将[工单提交]作为常驻功能)
45
-
46
- **##1.0.0 - 1.2.6 -2022-03-23 @陈栋扬**
47
- - 初始化:
48
- - 公共组件和配置抽取完成
1
+ # Change Log
2
+ > 所有关于本项目的变化都在该文档里。
3
+
4
+ **##1.2.28 -2022-03-29 @朱子峰**
5
+ - 功能修改:
6
+ - [Cookie]:去除自定义Cookie
7
+
8
+ **##1.2.27 -2022-03-29 @朱子峰**
9
+ - 功能新增:
10
+ - [XAddNativeForm]:将XAddForm从模态框中抽取,用于页面直接展示Form
11
+
12
+ **##1.2.25 -2022-03-26 @江超**
13
+ - 功能修改:
14
+ - [查询配置生成]:表单[新增/修改场景]增加[version(版本号)]类型
15
+ - [api.js]:移除[跨域代理前缀]
16
+ - 问题修复:
17
+ - [查询配置生成]:修复修改已有查询配置时,部分数据显示状态不一致的问题
18
+ - [设备详情页]:修复设备抄表记录,异常记录查询报错的问题
19
+ - [XFormItem]:修复非懒加载搜索的下拉框显示问题
20
+
21
+ **##1.2.20 - 1.2.24 -2022-03-25 @朱子峰**
22
+ - 功能修改:
23
+ - [工单关闭/开始处理]:工单关闭和开始处理时,不由id来进行判断,改由姓名进行判断是否为同一个人
24
+
25
+ **##1.2.17 - 1.2.19 -2022-03-25 @朱子峰**
26
+ - 问题修复:
27
+ - [钉钉消息推送]:将类别字段从int修改为String,直接传字典中的值
28
+ - 功能修改:
29
+ - [问题描述]:如果用户没有填写描述,新增默认值:“该用户没有填写描述信息”
30
+ - [问题描述]:展示问题描述时,按时间倒序展示,最新的信息显示在最上面
31
+
32
+ **##1.2.16 -2022-03-25 @张振宇**
33
+ - 功能修改:
34
+ - [查询配置生成]:逻辑修改,取消选择组和顺序,用户新增数组字段时需要选择是否为根节点,根节点index为1,不是根节点得数据字段index默认为父节点index+1
35
+
36
+ **##1.2.9 - 1.2.15 -2022-03-24 @江超**
37
+ - 功能新增:
38
+ - [查询配置生成]:下拉框表单选择业务逻辑作为数据源时,可以选择数据源加载方式
39
+ - [XFormItem]:当数据源加载方式为懒加载搜索时,将渲染一个可以根据关键词实时查询的选择框
40
+ - 问题修复:
41
+ - [查询配置生成]:修复修改已有查询配置时,显示状态不一致的问题
42
+ - [指令详情页]:修复操作记录查询报错的问题
43
+
44
+ **##1.2.8 -2022-03-24 @江超**
45
+ - 问题修复:
46
+ - [登录页面]:修复登录后欢迎提示出现undefined的问题
47
+ - [查询配置生成]:修复修改表单查询方式下拉框报错的问题
48
+
49
+ **##1.2.7 -2022-03-24 @江超**
50
+ - 功能新增:
51
+ - [系统设置]:新增 [工单提交] 功能(submitTicket),用户在操作业务时如发现系统异常,可使用该功能反馈问题
52
+ - [登录页面]:登陆人部门为 [用户工单登记] 时会直接跳转到[工单提交]页面(在基于新架构的营收全面使用时,会取消该限制,并将[工单提交]作为常驻功能)
53
+
54
+ **##1.0.0 - 1.2.6 -2022-03-23 @陈栋扬**
55
+ - 初始化:
56
+ - 公共组件和配置抽取完成
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2-client",
3
- "version": "1.2.25",
3
+ "version": "1.2.28",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -0,0 +1,315 @@
1
+ <template>
2
+ <div class="table-page-search-wrapper">
3
+ <a-form-model
4
+ v-if="loaded"
5
+ ref="selectForm"
6
+ :model="form"
7
+ :rules="rules">
8
+ <a-row :gutter="16">
9
+ <x-form-item
10
+ v-for="(item, index) in realJsonData"
11
+ mode="新增/修改"
12
+ :attr="item"
13
+ :form="form"
14
+ :key="index"
15
+ :disabled="itemDisabled(item)"
16
+ :xl="12"
17
+ :xxl="8"
18
+ />
19
+ <div v-for="group in realJsonSelectsData" :key="group[0].group">
20
+ <x-form-col v-for="groupItem in group" :key="groupItem.group + groupItem.groupIndex" :xl="12" :xxl="8">
21
+ <a-form-model-item :label="groupItem.name" :disabled="itemDisabled(groupItem)">
22
+ <a-select v-model="form[groupItem.model]" :disabled="itemDisabledPlus(groupItem.group,groupItem.groupIndex)" :allowClear="true" @change="selectsItemCheck(groupItem.group,groupItem.groupIndex,form[groupItem.model],group)" placeholder="请选择">
23
+ <template v-for="option in SelectsArray[groupItem.group][groupItem.groupIndex]">
24
+ <a-select-option :key="option.label" :value="option.value">
25
+ {{ option.label }}
26
+ </a-select-option>
27
+ </template>
28
+ </a-select>
29
+ </a-form-model-item>
30
+ </x-form-col>
31
+ </div>
32
+ </a-row>
33
+ </a-form-model>
34
+ </div>
35
+ </template>
36
+ <script>
37
+ import XFormItem from '@vue2-client/base-client/components/common/XForm/XFormItem'
38
+ import { formatDate } from '@vue2-client/utils/util'
39
+ import { mapState } from 'vuex'
40
+ import { post } from '@vue2-client/services/api/restTools'
41
+
42
+ export default {
43
+ name: 'XAddNativeForm',
44
+ components: {
45
+ XFormItem
46
+ },
47
+ data () {
48
+ return {
49
+ // 内容加载是否完成
50
+ loaded: false,
51
+ // 表单Model
52
+ form: undefined,
53
+ // 多层下拉框组 数据储存
54
+ SelectsArray: {},
55
+ // 多层下拉框组 各组数量
56
+ SelectsNumber: {},
57
+ // 校验
58
+ rules: {},
59
+ // 图标样式
60
+ iconStyle: {
61
+ position: 'relative',
62
+ top: '1px'
63
+ }
64
+ }
65
+ },
66
+ computed: {
67
+ // 过滤出用于新增/修改场景的表单项
68
+ realJsonData: function () {
69
+ return this.jsonData.filter(function (item) {
70
+ return item.addOrEdit && item.addOrEdit !== 'no' && item.addOrEdit !== 'silenceAdd' && !item.group
71
+ })
72
+ },
73
+ // 过滤出多个下拉框分组级联得数据
74
+ realJsonSelectsData: function () {
75
+ const Selectsata = this.jsonData.filter(item => !item.isOnlyAddOrEdit && item.group)
76
+ const groupName = [...new Set(Selectsata.map(item => item.group))]
77
+ // 初始化数据组
78
+ groupName.forEach(item => {
79
+ this.SelectsArray[item] = []
80
+ })
81
+ return groupName.map(groupName => {
82
+ const SelectsItem = Selectsata.filter(item => {
83
+ if (item.groupIndex === 1) {
84
+ if (item.keyName.substring(0, 6) === 'logic@') {
85
+ // 请求logic
86
+ post('/webmeterapi/' + item.keyName.substring(6), {}).then(res => {
87
+ this.SelectsArray[item.group][item.groupIndex] = res
88
+ })
89
+ } else {
90
+ this.SelectsArray[item.group][item.groupIndex] = JSON.parse(item.keyName)
91
+ }
92
+ }
93
+ return item.group === groupName
94
+ }
95
+ )
96
+ this.SelectsNumber[groupName] = SelectsItem.length ? SelectsItem.length : 0
97
+ return SelectsItem
98
+ })
99
+ },
100
+ // 过滤出用于静默新增场景的表单项
101
+ silenceAddJsonData: function () {
102
+ return this.jsonData.filter(function (item) {
103
+ return item.addOrEdit === 'silenceAdd'
104
+ })
105
+ },
106
+ // 过滤出版本号表单项
107
+ versionJsonData: function () {
108
+ return this.jsonData.filter(function (item) {
109
+ return item.addOrEdit === 'version'
110
+ })
111
+ },
112
+ ...mapState('account', { currUser: 'user' })
113
+ },
114
+ props: {
115
+ jsonData: {
116
+ type: Array,
117
+ default: () => {
118
+ return []
119
+ }
120
+ },
121
+ // 业务类型
122
+ businessType: {
123
+ type: String,
124
+ default: ''
125
+ },
126
+ // 修改操作前查询出的业务数据
127
+ modifyModelData: {
128
+ type: Object,
129
+ default: () => {
130
+ return {}
131
+ }
132
+ },
133
+ // 新增或修改业务是否执行中
134
+ loading: {
135
+ type: Boolean,
136
+ default: () => {
137
+ return false
138
+ }
139
+ },
140
+ // 固定新增表单
141
+ fixedAddForm: {
142
+ type: Object,
143
+ default: () => {
144
+ return {}
145
+ }
146
+ }
147
+ },
148
+ watch: {
149
+ visible (rel) {
150
+ if (rel) {
151
+ this.formItemLoad()
152
+ }
153
+ }
154
+ },
155
+ mounted () {
156
+ this.formItemLoad()
157
+ },
158
+ methods: {
159
+ selectsItemCheck (groupName, index, value, group) {
160
+ const tem = { }
161
+ // 获取当前下拉框子下拉框的数据
162
+ this.SelectsArray[groupName][index + 1] = this.SelectsArray[groupName][index].filter(item => item.value === value)[0].children
163
+ // 清空子下拉框的子们的数据
164
+ for (let i = index; i < this.SelectsNumber[groupName]; i++) {
165
+ tem[group[i].model] = undefined
166
+ }
167
+ this.form = Object.assign({}, this.form, tem)
168
+ // 清空子下拉框的子们的数据源
169
+ for (let i = index + 2; i <= this.SelectsNumber[groupName]; i++) {
170
+ this.SelectsArray[groupName][i] = []
171
+ }
172
+ },
173
+ formItemLoad () {
174
+ const formData = Object.assign({}, this.fixedAddForm)
175
+ for (let i = 0; i < this.realJsonData.length; i++) {
176
+ const item = this.realJsonData[i]
177
+ formData[item.model] = undefined
178
+ // 处理表单校验情况
179
+ if (item.rule) {
180
+ this.rules[item.model] = []
181
+ const required = item.rule.required ? item.rule.required === true || item.rule.required === 'true' : false
182
+ let trigger
183
+ let message
184
+ if (required) {
185
+ switch (item.type) {
186
+ case 'select':
187
+ message = '请选择' + item.name
188
+ trigger = 'change'
189
+ break
190
+ default:
191
+ message = '请输入' + item.name
192
+ trigger = 'blur'
193
+ }
194
+ this.rules[item.model].push({
195
+ required: true,
196
+ message: message,
197
+ trigger: trigger
198
+ })
199
+ }
200
+
201
+ switch (item.rule.type) {
202
+ case 'number':
203
+ case 'integer':
204
+ case 'float':
205
+ let defaultValue
206
+ let message
207
+ switch (item.rule.type) {
208
+ case 'number':
209
+ message = '数字'
210
+ defaultValue = 0
211
+ break
212
+ case 'integer':
213
+ message = '整数'
214
+ defaultValue = 0
215
+ break
216
+ case 'float':
217
+ message = '小数'
218
+ defaultValue = 0.0
219
+ break
220
+ }
221
+ this.rules[item.model].push({
222
+ type: item.rule.type,
223
+ message: item.name + '必须为' + message,
224
+ transform: (value) => {
225
+ if (value && value.length !== 0) {
226
+ return Number(value)
227
+ } else {
228
+ return defaultValue
229
+ }
230
+ },
231
+ trigger: 'blur'
232
+ })
233
+ break
234
+ }
235
+ }
236
+ }
237
+ this.form = formData
238
+ if (Object.keys(this.modifyModelData).length > 0) {
239
+ this.getModifyModelData()
240
+ }
241
+ this.loaded = true
242
+ },
243
+ itemDisabled (value) {
244
+ return (this.businessType === '新增' && value.addOrEdit === 'edit') ||
245
+ (this.businessType === '修改' && value.addOrEdit === 'add')
246
+ },
247
+ itemDisabledPlus (group, index) {
248
+ return (!this.SelectsArray[group][index]) || (this.SelectsArray[group][index] && this.SelectsArray[group][index].length === 0)
249
+ },
250
+ resetForm () {
251
+ this.$refs.selectForm.resetFields()
252
+ },
253
+ async onSubmit () {
254
+ this.$refs.selectForm.validate(async valid => {
255
+ for (const key of Object.keys(this.form)) {
256
+ if (this.form[key] === null || this.form[key] === '') {
257
+ this.form[key] = undefined
258
+ }
259
+ }
260
+ const requestParameters = Object.assign({}, this.form)
261
+ // 追加静默新增字段
262
+ if (this.businessType === '新增') {
263
+ for (const item of this.silenceAddJsonData) {
264
+ switch (item.silencePurpose) {
265
+ case 'createTime':
266
+ requestParameters[item.model] = formatDate('now')
267
+ break
268
+ case 'operator':
269
+ requestParameters[item.model] = this.currUser.name
270
+ break
271
+ case 'orgId':
272
+ requestParameters[item.model] = this.currUser.orgid
273
+ break
274
+ }
275
+ }
276
+ // 通过请求追加静默新增:自定义字段
277
+ for (const item of this.silenceAddJsonData.filter((item) => item.silencePurpose === 'customize')) {
278
+ requestParameters[item.model] = await this.getSilenceSource(item.silenceSource, requestParameters)
279
+ }
280
+ }
281
+ const data = {
282
+ valid: valid,
283
+ form: requestParameters
284
+ }
285
+ this.$emit('onSubmit', data)
286
+ })
287
+ },
288
+ async getSilenceSource (silenceSource, requestParameters) {
289
+ const result = await post('/webmeterapi/' + silenceSource, requestParameters)
290
+ return result
291
+ },
292
+ getModifyModelData () {
293
+ for (let i = 0; i < this.realJsonData.length; i++) {
294
+ const item = this.realJsonData[i]
295
+ if (this.modifyModelData[item.model] || this.modifyModelData[item.model] === 0) {
296
+ this.form[item.model] = this.modifyModelData[item.model] + ''
297
+ } else {
298
+ this.form[item.model] = undefined
299
+ }
300
+ }
301
+ // 追加版本号信息
302
+ for (const item of this.versionJsonData) {
303
+ if (!this.modifyModelData[item.model]) {
304
+ this.form[item.model] = 0
305
+ } else {
306
+ this.form[item.model] = this.modifyModelData[item.model] + ''
307
+ }
308
+ }
309
+ },
310
+ onClose () {
311
+ this.$emit('update:visible', false)
312
+ }
313
+ }
314
+ }
315
+ </script>
@@ -0,0 +1,3 @@
1
+ import XAddNativeForm from './XAddNativeForm'
2
+
3
+ export default XAddNativeForm
@@ -0,0 +1,56 @@
1
+ # XAddNativeForm
2
+
3
+ 动态新增/修改表单控件,根据JSON配置生成一个完整的可供新增/修改数据的动态表单
4
+
5
+
6
+ ## 何时使用
7
+
8
+ 当需要一个可供新增/修改数据的动态生成的表单时
9
+
10
+
11
+ 引用方式:
12
+
13
+ ```javascript
14
+ import XAddNativeForm from '@vue2-client/base-client/components/XAddNativeForm/XAddNativeForm'
15
+
16
+ export default {
17
+ components: {
18
+ XAddNativeForm
19
+ }
20
+ }
21
+ ```
22
+
23
+
24
+
25
+ ## 代码演示
26
+
27
+ ```html
28
+ <x-add-form
29
+ :business-type="businessType"
30
+ :json-data="formItems"
31
+ :modify-model-data="modifyModelData"
32
+ :loading="loading"
33
+ @onSubmit="onSubmit">
34
+ </x-add-form>
35
+ ```
36
+
37
+ ## API
38
+
39
+ | 参数 | 说明 | 类型 | 默认值 |
40
+ |-----------------|--------------------------|---------|-------|
41
+ | businessType | 业务类型 | String | '' |
42
+ | jsonData | JSON配置,根据[工具>查询配置生成]功能生成 | Object | {} |
43
+ | modifyModelData | 修改操作前查询出的业务数据 | Object | {} |
44
+ | loading | 新增或修改业务是否执行中 | Boolean | false |
45
+ | fixedAddForm | 固定新增表单,会和新增表单合并 | Object | {} |
46
+ | @onSubmit | 表单的提交事件 | event | - |
47
+
48
+ ## 例子1
49
+ ----
50
+ 参考XFormTable组件
51
+ ```
52
+
53
+ 注意事项
54
+ ----
55
+
56
+ > 本组件已经实现了自适应布局,在不同分辨率下的设备均可得到基本理想的展示效果
@@ -1,197 +1,197 @@
1
- import axios from 'axios'
2
- import Cookie from 'js-cookie'
3
- import Vue from 'vue'
4
- import { ACCESS_TOKEN } from '@vue2-client/store/mutation-types'
5
- import notification from 'ant-design-vue/es/notification'
6
-
7
- // 跨域认证信息 header 名
8
- const xsrfHeaderName = 'Authorization'
9
-
10
- axios.defaults.timeout = 5000
11
- axios.defaults.withCredentials = true
12
- axios.defaults.xsrfHeaderName = xsrfHeaderName
13
- axios.defaults.xsrfCookieName = xsrfHeaderName
14
-
15
- // 认证类型
16
- const AUTH_TYPE = {
17
- BEARER: 'Bearer',
18
- BASIC: 'basic',
19
- AUTH1: 'auth1',
20
- AUTH2: 'auth2'
21
- }
22
-
23
- // http method
24
- const METHOD = {
25
- GET: 'get',
26
- POST: 'post'
27
- }
28
-
29
- /**
30
- * axios请求
31
- * @param url 请求地址
32
- * @param method {METHOD} http method
33
- * @param params 请求参数
34
- * @returns {Promise<AxiosResponse<T>>}
35
- */
36
- async function request (url, method, params, config) {
37
- switch (method) {
38
- case METHOD.GET:
39
- return axios.get(url, { params, ...config })
40
- case METHOD.POST:
41
- return axios.post(url, params, config)
42
- default:
43
- return axios.get(url, { params, ...config })
44
- }
45
- }
46
-
47
- /**
48
- * 设置认证信息
49
- * @param auth {Object}
50
- * @param authType {AUTH_TYPE} 认证类型,默认:{AUTH_TYPE.BEARER}
51
- */
52
- function setAuthorization (auth, authType = AUTH_TYPE.BEARER) {
53
- switch (authType) {
54
- case AUTH_TYPE.BEARER:
55
- Cookie.set(xsrfHeaderName, 'Bearer ' + auth.token, { expires: auth.expireAt })
56
- break
57
- case AUTH_TYPE.BASIC:
58
- case AUTH_TYPE.AUTH1:
59
- case AUTH_TYPE.AUTH2:
60
- default:
61
- break
62
- }
63
- }
64
-
65
- /**
66
- * 移出认证信息
67
- * @param authType {AUTH_TYPE} 认证类型
68
- */
69
- function removeAuthorization (authType = AUTH_TYPE.BEARER) {
70
- switch (authType) {
71
- case AUTH_TYPE.BEARER:
72
- Cookie.remove(xsrfHeaderName)
73
- break
74
- case AUTH_TYPE.BASIC:
75
- case AUTH_TYPE.AUTH1:
76
- case AUTH_TYPE.AUTH2:
77
- default:
78
- break
79
- }
80
- }
81
-
82
- /**
83
- * 检查认证信息
84
- * @param authType
85
- * @returns {boolean}
86
- */
87
- function checkAuthorization (authType = AUTH_TYPE.BEARER) {
88
- switch (authType) {
89
- case AUTH_TYPE.BEARER:
90
- if (Cookie.get(xsrfHeaderName)) {
91
- return true
92
- }
93
- break
94
- case AUTH_TYPE.BASIC:
95
- case AUTH_TYPE.AUTH1:
96
- case AUTH_TYPE.AUTH2:
97
- default:
98
- break
99
- }
100
- return false
101
- }
102
-
103
- /**
104
- * 加载 axios 拦截器
105
- * @param interceptors
106
- * @param options
107
- */
108
- function loadInterceptors () {
109
- // 加载请求拦截器
110
- axios.interceptors.request.use(config => {
111
- const token = localStorage.getItem(ACCESS_TOKEN)
112
- // 如果 token 存在
113
- // 让每个请求携带自定义 token 请根据实际情况自行修改
114
- if (token) {
115
- config.headers['Access-Token'] = token
116
- }
117
- if (!config.headers['Content-Type']) {
118
- config.headers['Content-Type'] = 'application/json;charset=UTF-8'
119
- }
120
- return config
121
- }, errorHandler)
122
- // 加载响应拦截器
123
- axios.interceptors.response.use((response) => {
124
- return response.data
125
- }, errorHandler)
126
- }
127
-
128
- // 异常拦截处理器
129
- const errorHandler = (error) => {
130
- if (error.response) {
131
- const data = error.response.data
132
- // 从 localstorage 获取 token
133
- const token = localStorage.getItem(ACCESS_TOKEN)
134
- if (error.response.status === 403) {
135
- notification.error({
136
- message: '禁止访问',
137
- description: data
138
- })
139
- } else if (error.response.status === 401 && !(data.result && data.result.isLogin)) {
140
- notification.error({
141
- message: '鉴权失败',
142
- description: data
143
- })
144
- if (token) {
145
- Vue.$store.dispatch('Logout').then(() => {
146
- setTimeout(() => {
147
- window.location.reload()
148
- }, 1500)
149
- })
150
- }
151
- } else if (error.response.status === 500) {
152
- notification.error({
153
- message: '系统异常',
154
- description: data
155
- })
156
- } else {
157
- notification.error({
158
- message: '数据异常',
159
- description: data
160
- })
161
- }
162
- }
163
- return Promise.reject(error)
164
- }
165
-
166
- /**
167
- * 解析 url 中的参数
168
- * @param url
169
- * @returns {Object}
170
- */
171
- function parseUrlParams (url) {
172
- const params = {}
173
- if (!url || url === '' || typeof url !== 'string') {
174
- return params
175
- }
176
- const paramsStr = url.split('?')[1]
177
- if (!paramsStr) {
178
- return params
179
- }
180
- const paramsArr = paramsStr.replace(/&|=/g, ' ').split(' ')
181
- for (let i = 0; i < paramsArr.length / 2; i++) {
182
- const value = paramsArr[i * 2 + 1]
183
- params[paramsArr[i * 2]] = value === 'true' ? true : (value === 'false' ? false : value)
184
- }
185
- return params
186
- }
187
-
188
- export {
189
- METHOD,
190
- AUTH_TYPE,
191
- request,
192
- setAuthorization,
193
- removeAuthorization,
194
- checkAuthorization,
195
- loadInterceptors,
196
- parseUrlParams
197
- }
1
+ import axios from 'axios'
2
+ import Cookie from 'js-cookie'
3
+ import Vue from 'vue'
4
+ import { ACCESS_TOKEN } from '@vue2-client/store/mutation-types'
5
+ import notification from 'ant-design-vue/es/notification'
6
+
7
+ // 跨域认证信息 header 名
8
+ const xsrfHeaderName = 'Authorization'
9
+
10
+ axios.defaults.timeout = 5000
11
+ axios.defaults.withCredentials = true
12
+ axios.defaults.xsrfHeaderName = xsrfHeaderName
13
+ axios.defaults.xsrfCookieName = xsrfHeaderName
14
+
15
+ // 认证类型
16
+ const AUTH_TYPE = {
17
+ BEARER: 'Bearer',
18
+ BASIC: 'basic',
19
+ AUTH1: 'auth1',
20
+ AUTH2: 'auth2'
21
+ }
22
+
23
+ // http method
24
+ const METHOD = {
25
+ GET: 'get',
26
+ POST: 'post'
27
+ }
28
+
29
+ /**
30
+ * axios请求
31
+ * @param url 请求地址
32
+ * @param method {METHOD} http method
33
+ * @param params 请求参数
34
+ * @returns {Promise<AxiosResponse<T>>}
35
+ */
36
+ async function request (url, method, params, config) {
37
+ switch (method) {
38
+ case METHOD.GET:
39
+ return axios.get(url, { params, ...config })
40
+ case METHOD.POST:
41
+ return axios.post(url, params, config)
42
+ default:
43
+ return axios.get(url, { params, ...config })
44
+ }
45
+ }
46
+
47
+ /**
48
+ * 设置认证信息
49
+ * @param auth {Object}
50
+ * @param authType {AUTH_TYPE} 认证类型,默认:{AUTH_TYPE.BEARER}
51
+ */
52
+ function setAuthorization (auth, authType = AUTH_TYPE.BEARER) {
53
+ switch (authType) {
54
+ case AUTH_TYPE.BEARER:
55
+ Cookie.set(xsrfHeaderName, 'Bearer ' + auth.token, { expires: auth.expireAt })
56
+ break
57
+ case AUTH_TYPE.BASIC:
58
+ case AUTH_TYPE.AUTH1:
59
+ case AUTH_TYPE.AUTH2:
60
+ default:
61
+ break
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 移出认证信息
67
+ * @param authType {AUTH_TYPE} 认证类型
68
+ */
69
+ function removeAuthorization (authType = AUTH_TYPE.BEARER) {
70
+ switch (authType) {
71
+ case AUTH_TYPE.BEARER:
72
+ Cookie.remove(xsrfHeaderName)
73
+ break
74
+ case AUTH_TYPE.BASIC:
75
+ case AUTH_TYPE.AUTH1:
76
+ case AUTH_TYPE.AUTH2:
77
+ default:
78
+ break
79
+ }
80
+ }
81
+
82
+ /**
83
+ * 检查认证信息
84
+ * @param authType
85
+ * @returns {boolean}
86
+ */
87
+ function checkAuthorization (authType = AUTH_TYPE.BEARER) {
88
+ switch (authType) {
89
+ case AUTH_TYPE.BEARER:
90
+ if (Cookie.get(xsrfHeaderName)) {
91
+ return true
92
+ }
93
+ break
94
+ case AUTH_TYPE.BASIC:
95
+ case AUTH_TYPE.AUTH1:
96
+ case AUTH_TYPE.AUTH2:
97
+ default:
98
+ break
99
+ }
100
+ return false
101
+ }
102
+
103
+ /**
104
+ * 加载 axios 拦截器
105
+ * @param interceptors
106
+ * @param options
107
+ */
108
+ function loadInterceptors () {
109
+ // 加载请求拦截器
110
+ axios.interceptors.request.use(config => {
111
+ const token = localStorage.getItem(ACCESS_TOKEN)
112
+ // 如果 token 存在
113
+ // 让每个请求携带自定义 token 请根据实际情况自行修改
114
+ if (token) {
115
+ config.headers['Access-Token'] = token
116
+ }
117
+ if (!config.headers['Content-Type']) {
118
+ config.headers['Content-Type'] = 'application/json;charset=UTF-8'
119
+ }
120
+ return config
121
+ }, errorHandler)
122
+ // 加载响应拦截器
123
+ axios.interceptors.response.use((response) => {
124
+ return response.data
125
+ }, errorHandler)
126
+ }
127
+
128
+ // 异常拦截处理器
129
+ const errorHandler = (error) => {
130
+ if (error.response) {
131
+ const data = error.response.data
132
+ // 从 localstorage 获取 token
133
+ const token = localStorage.getItem(ACCESS_TOKEN)
134
+ if (error.response.status === 403) {
135
+ notification.error({
136
+ message: '禁止访问',
137
+ description: data
138
+ })
139
+ } else if (error.response.status === 401 && !(data.result && data.result.isLogin)) {
140
+ notification.error({
141
+ message: '鉴权失败',
142
+ description: data
143
+ })
144
+ if (token) {
145
+ Vue.$store.dispatch('Logout').then(() => {
146
+ setTimeout(() => {
147
+ window.location.reload()
148
+ }, 1500)
149
+ })
150
+ }
151
+ } else if (error.response.status === 500) {
152
+ notification.error({
153
+ message: '系统异常',
154
+ description: data
155
+ })
156
+ } else {
157
+ notification.error({
158
+ message: '数据异常',
159
+ description: data
160
+ })
161
+ }
162
+ }
163
+ return Promise.reject(error)
164
+ }
165
+
166
+ /**
167
+ * 解析 url 中的参数
168
+ * @param url
169
+ * @returns {Object}
170
+ */
171
+ function parseUrlParams (url) {
172
+ const params = {}
173
+ if (!url || url === '' || typeof url !== 'string') {
174
+ return params
175
+ }
176
+ const paramsStr = url.split('?')[1]
177
+ if (!paramsStr) {
178
+ return params
179
+ }
180
+ const paramsArr = paramsStr.replace(/&|=/g, ' ').split(' ')
181
+ for (let i = 0; i < paramsArr.length / 2; i++) {
182
+ const value = paramsArr[i * 2 + 1]
183
+ params[paramsArr[i * 2]] = value === 'true' ? true : (value === 'false' ? false : value)
184
+ }
185
+ return params
186
+ }
187
+
188
+ export {
189
+ METHOD,
190
+ AUTH_TYPE,
191
+ request,
192
+ setAuthorization,
193
+ removeAuthorization,
194
+ checkAuthorization,
195
+ loadInterceptors,
196
+ parseUrlParams
197
+ }
@@ -1,3 +1,4 @@
1
+ import Vue from 'vue'
1
2
  import routerMap from '@vue2-client/router/async/router.map'
2
3
  import { mergeI18nFromRoutes } from '@vue2-client/utils/i18n'
3
4
  import Router from 'vue-router'
@@ -135,6 +136,11 @@ function loadRoutes (routesConfig) {
135
136
  // 应用配置
136
137
  const { router, store, i18n } = appOptions
137
138
 
139
+ // 刷新页面时,有些全局状态丢失,在此处从本地缓存拿出来赋值
140
+ if (JSON.stringify(Vue.$login.f) == '{}') {
141
+ const login = store.getters['account/login']
142
+ Object.assign(Vue.$login, login)
143
+ }
138
144
  // 如果 routesConfig 有值,则更新到本地,否则从本地获取
139
145
  if (routesConfig) {
140
146
  store.commit('account/setRoutesConfig', routesConfig)