From ff56a184ca9383a6b72ccc8c823a5e49c9f5275f Mon Sep 17 00:00:00 2001 From: ktianc Date: Mon, 13 Mar 2023 14:34:26 +0800 Subject: [PATCH] =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8D=87=E7=BA=A7=EF=BC=9A?= =?UTF-8?q?=201.=20=E4=BF=AE=E5=A4=8D=EF=BC=88kinit-admin=EF=BC=89?= =?UTF-8?q?=EF=BC=9A=E9=A1=B5=E9=9D=A2=E7=BC=93=E5=AD=98=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=202.=20=E6=9B=B4=E6=96=B0=EF=BC=88kinit-api?= =?UTF-8?q?=EF=BC=8Ckinit-admin=EF=BC=89=EF=BC=9A=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=96=B0=E5=A2=9E=E6=98=AF=E5=90=A6=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E5=AD=97=E6=AE=B5=203.=20=E6=9B=B4=E6=96=B0=EF=BC=88k?= =?UTF-8?q?init-admin=EF=BC=89=EF=BC=9A=E5=B0=86=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=AD=98=E5=82=A8=E5=9C=A8localStorage?= =?UTF-8?q?=E4=B8=AD=204.=20=E6=9B=B4=E6=96=B0=EF=BC=88kinit-api=EF=BC=89?= =?UTF-8?q?=EF=BC=9A=E5=B0=86python-jose=E5=BA=93=E6=9B=B4=E6=8D=A2?= =?UTF-8?q?=E4=B8=BApyjwt=E5=BA=93=205.=20=E4=BC=98=E5=8C=96=EF=BC=88kinit?= =?UTF-8?q?-admin=EF=BC=8Ckinit-uni=EF=BC=89=EF=BC=9A=E9=80=80=E5=87=BA?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=96=B9=E6=B3=95=E4=BC=98=E5=8C=96=206.=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=88kinit-admin=EF=BC=8Ckinit-uni?= =?UTF-8?q?=EF=BC=89=EF=BC=9Aresponse=E6=8B=A6=E6=88=AA=E4=BC=98=E5=8C=96?= =?UTF-8?q?=207.=20=E6=96=B0=E5=A2=9E=EF=BC=88kinit-api=EF=BC=8Ckinit-admi?= =?UTF-8?q?n=EF=BC=8Ckinit-uni=EF=BC=89=EF=BC=9Ajwt=E5=88=B0=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E7=BC=A9=E7=9F=AD=EF=BC=8C=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E5=88=B7=E6=96=B0token=E5=8A=9F=E8=83=BD=208.=20=EF=BC=88kinit?= =?UTF-8?q?-uni=EF=BC=89=E5=88=87=E6=8D=A2=E5=88=B0=20vscode=20=E5=BC=80?= =?UTF-8?q?=E5=8F=91=20uniapp=20=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kinit-admin/src/config/axios/service.ts | 95 +- kinit-admin/src/hooks/web/useCache.ts | 4 +- kinit-admin/src/store/modules/app.ts | 5 + kinit-admin/src/store/modules/auth.ts | 4 +- .../vadmin/auth/menu/components/Write.vue | 1 + .../vadmin/auth/menu/components/menu.data.ts | 32 + .../src/views/vadmin/auth/menu/index.vue | 12 +- .../src/views/vadmin/auth/role/index.vue | 6 + .../src/views/vadmin/auth/user/index.vue | 6 + .../vadmin/help/issue/components/Write.vue | 6 + .../src/views/vadmin/help/issue/index.vue | 6 + .../components/issueCategory.data.ts | 2 +- .../views/vadmin/help/issueCategory/index.vue | 6 + .../src/views/vadmin/system/dict/detail.vue | 6 + .../src/views/vadmin/system/dict/index.vue | 6 + .../vadmin/system/record/login/index.vue | 6 + .../vadmin/system/record/operation/index.vue | 6 + .../views/vadmin/system/settings/index.vue | 6 + kinit-api/application/settings.py | 11 +- kinit-api/apps/vadmin/analysis/views.py | 14 +- kinit-api/apps/vadmin/auth/utils/current.py | 31 +- kinit-api/apps/vadmin/auth/utils/login.py | 48 +- .../apps/vadmin/auth/utils/login_manage.py | 21 +- .../apps/vadmin/auth/utils/validation/auth.py | 39 +- kinit-api/apps/vadmin/auth/views.py | 65 +- kinit-api/apps/vadmin/help/views.py | 26 +- kinit-api/apps/vadmin/record/views.py | 8 +- kinit-api/apps/vadmin/system/views.py | 52 +- kinit-api/core/event.py | 24 + kinit-api/core/exception.py | 3 +- kinit-api/requirements.txt | Bin 1545 -> 3246 bytes kinit-uni/.eslintrc.js | 37 + kinit-uni/App.vue | 25 +- kinit-uni/README.md | 20 + kinit-uni/common/mixins/auth.js | 109 +- kinit-uni/common/mixins/share.js | 90 +- kinit-uni/common/request/api/login.js | 24 +- .../common/request/api/vadmin/auth/user.js | 11 +- .../common/request/api/vadmin/help/issue.js | 8 +- .../common/request/api/vadmin/system/dict.js | 2 +- .../request/api/vadmin/system/settings.js | 4 +- kinit-uni/common/request/errorCode.js | 10 +- kinit-uni/common/request/request.js | 159 ++- kinit-uni/common/utils/auth.js | 14 + kinit-uni/common/utils/common.js | 34 +- kinit-uni/common/utils/constant.js | 14 +- kinit-uni/common/utils/cookies.js | 80 -- kinit-uni/common/utils/logs.js | 8 +- kinit-uni/common/utils/permission.js | 14 +- kinit-uni/common/utils/postFile.js | 48 +- kinit-uni/common/utils/ruoyi.js | 227 +-- kinit-uni/common/utils/storage.js | 10 +- kinit-uni/common/utils/upload.js | 82 +- kinit-uni/config.js | 14 +- kinit-uni/jsconfig.json | 8 + kinit-uni/main.js | 52 +- kinit-uni/package.json | 6 + kinit-uni/pages/common/textview/index.vue | 62 +- kinit-uni/pages/common/webview/index.vue | 46 +- kinit-uni/pages/index.vue | 76 +- kinit-uni/pages/login/login.vue | 315 +++-- kinit-uni/pages/mine/about/index.vue | 89 +- kinit-uni/pages/mine/avatar/index.vue | 1234 +++++++++-------- kinit-uni/pages/mine/help/issue/index.vue | 115 +- kinit-uni/pages/mine/help/issue/info.vue | 111 +- kinit-uni/pages/mine/index.vue | 308 ++-- kinit-uni/pages/mine/info/edit.vue | 260 ++-- kinit-uni/pages/mine/info/index.vue | 76 +- kinit-uni/pages/mine/pwd/index.vue | 149 +- kinit-uni/pages/mine/setting/index.vue | 72 +- kinit-uni/pages/work/index.vue | 151 +- kinit-uni/permission.js | 82 +- kinit-uni/plugins/auth.js | 16 +- kinit-uni/plugins/modal.js | 6 +- kinit-uni/prettier.config.js | 19 + kinit-uni/store/getters.js | 46 +- kinit-uni/store/index.js | 4 +- kinit-uni/store/modules/app.js | 123 +- kinit-uni/store/modules/auth.js | 318 +++-- kinit-uni/store/modules/dict.js | 73 +- kinit-uni/vue.config.js | 40 +- 81 files changed, 2950 insertions(+), 2508 deletions(-) create mode 100644 kinit-uni/.eslintrc.js delete mode 100644 kinit-uni/common/utils/cookies.js create mode 100644 kinit-uni/jsconfig.json create mode 100644 kinit-uni/prettier.config.js diff --git a/kinit-admin/src/config/axios/service.ts b/kinit-admin/src/config/axios/service.ts index 986d8dc..5a03118 100644 --- a/kinit-admin/src/config/axios/service.ts +++ b/kinit-admin/src/config/axios/service.ts @@ -5,6 +5,7 @@ import { useAuthStore } from '@/store/modules/auth' import qs from 'qs' import { config } from './config' import { ElMessage } from 'element-plus' +import request from '@/config/axios' const { result_code, unauthorized_code, request_timeout } = config @@ -62,33 +63,99 @@ service.interceptors.request.use( // response 拦截器 service.interceptors.response.use( (response: AxiosResponse) => { + // 这个状态码是和后端约定好的 + const code = response.data.code || unauthorized_code + const message = response.data.message || '后端接口无返回内容' + const refresh = response.data.refresh || false + if (response.config.responseType === 'blob') { // 如果是文件流,直接过 return response - } else if (response.data.code === result_code) { + } else if (code === result_code) { + if (refresh) { + // 因token快过期,刷新token + refreshToken().then((res) => { + const appStore = useAppStore() + wsCache.set(appStore.getToken, `${res.data.token_type} ${res.data.access_token}`) + wsCache.set(appStore.getRefreshToken, res.data.refresh_token) + }) + // .catch(() => { + // const authStore = useAuthStore() + // authStore.logout() + // ElMessage.error('未认证,请登录') + // }) + } return response.data - } else if (response.data.code === unauthorized_code) { - // 请重新登录 - ElMessage.error(response.data.message) - const authStore = useAuthStore() - authStore.logout() + } else if (code === unauthorized_code) { + // 因token无效,token过期导致 + refreshToken().then((res) => { + const appStore = useAppStore() + wsCache.set(appStore.getToken, `${res.data.token_type} ${res.data.access_token}`) + wsCache.set(appStore.getRefreshToken, res.data.refresh_token) + ElMessage.error('操作失败,请重试') + }) + // .catch(() => { + // const authStore = useAuthStore() + // authStore.logout() + // ElMessage.error('未认证,请登录') + // }) } else { - ElMessage.error(response.data.message) + ElMessage.error(message) } }, (error: AxiosError) => { - console.log('err' + error) let { message } = error - if (message == 'Network Error') { - message = '后端接口连接异常' - } else if (message.includes('timeout')) { - message = '系统接口请求超时' - } else if (message.includes('Request failed with status code')) { - message = '系统接口' + message.substr(message.length - 3) + '异常' + const status = error.response?.status + switch (status) { + case 400: + message = '请求错误' + break + case 401: + // 强制要求重新登录,因账号已冻结,账号已过期,手机号码错误,刷新token无效等问题导致 + const authStore = useAuthStore() + authStore.logout() + message = '未认证,请登录' + break + case 403: + message = '拒绝访问' + break + case 404: + message = `请求地址出错: ${error.response?.config.url}` + break + case 408: + message = '请求超时' + break + case 500: + message = '服务器内部错误' + break + case 501: + message = '服务未实现' + break + case 502: + message = '网关错误' + break + case 503: + message = '服务不可用' + break + case 504: + message = '网关超时' + break + case 505: + message = 'HTTP版本不受支持' + break + default: + break } ElMessage.error(message) return Promise.reject(error) } ) +// 刷新Token +const refreshToken = (): Promise => { + const appStore = useAppStore() + const data = wsCache.get(appStore.getRefreshToken) + return request.post({ url: '/auth/token/refresh/', data }) +} + export { service } diff --git a/kinit-admin/src/hooks/web/useCache.ts b/kinit-admin/src/hooks/web/useCache.ts index b405ef3..d2725b3 100644 --- a/kinit-admin/src/hooks/web/useCache.ts +++ b/kinit-admin/src/hooks/web/useCache.ts @@ -1,12 +1,14 @@ /** * 配置浏览器本地存储的方式,可直接存储对象数组。 + * sessionStorage 多标签页情况下互不共享 + * localStorage 多标签页情况下互相共享 */ import WebStorageCache from 'web-storage-cache' type CacheType = 'sessionStorage' | 'localStorage' -export const useCache = (type: CacheType = 'sessionStorage') => { +export const useCache = (type: CacheType = 'localStorage') => { const wsCache: WebStorageCache = new WebStorageCache({ storage: type }) diff --git a/kinit-admin/src/store/modules/app.ts b/kinit-admin/src/store/modules/app.ts index 75b0849..3191009 100644 --- a/kinit-admin/src/store/modules/app.ts +++ b/kinit-admin/src/store/modules/app.ts @@ -39,6 +39,7 @@ interface AppState { footerContent: string icpNumber: string token: string + refreshToken: string } export const useAppStore = defineStore('app', { @@ -46,6 +47,7 @@ export const useAppStore = defineStore('app', { return { userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突 token: 'Token', // 存储Token字段 + refreshToken: 'RefreshToken', // 存储刷新Token字段 sizeMap: ['default', 'large', 'small'], mobile: false, // 是否是移动端 title: import.meta.env.VITE_APP_TITLE, // 标题 @@ -170,6 +172,9 @@ export const useAppStore = defineStore('app', { getToken(): string { return this.token }, + getRefreshToken(): string { + return this.refreshToken + }, getIsDark(): boolean { return this.isDark }, diff --git a/kinit-admin/src/store/modules/auth.ts b/kinit-admin/src/store/modules/auth.ts index 48fe27e..1f8aae7 100644 --- a/kinit-admin/src/store/modules/auth.ts +++ b/kinit-admin/src/store/modules/auth.ts @@ -7,6 +7,7 @@ import { useCache } from '@/hooks/web/useCache' import { getCurrentAdminUserInfo } from '@/api/vadmin/auth/user' import { resetRouter } from '@/router' import { useTagsViewStore } from '@/store/modules/tagsView' +import router from '@/router' const { wsCache } = useCache() @@ -48,6 +49,7 @@ export const useAuthStore = defineStore('auth', { if (res) { const appStore = useAppStore() wsCache.set(appStore.getToken, `${res.data.token_type} ${res.data.access_token}`) + wsCache.set(appStore.getRefreshToken, res.data.refresh_token) // 存储用户信息 const auth = useAuthStore() await auth.getUserInfo() @@ -61,7 +63,7 @@ export const useAuthStore = defineStore('auth', { const tagsViewStore = useTagsViewStore() tagsViewStore.delAllViews() resetRouter() - window.location.href = '/login' + router.push('/login') }, updateUser(data: UserState) { this.user.gender = data.gender diff --git a/kinit-admin/src/views/vadmin/auth/menu/components/Write.vue b/kinit-admin/src/views/vadmin/auth/menu/components/Write.vue index d511375..683b5dc 100644 --- a/kinit-admin/src/views/vadmin/auth/menu/components/Write.vue +++ b/kinit-admin/src/views/vadmin/auth/menu/components/Write.vue @@ -24,6 +24,7 @@ const rules = reactive({ disabled: [required()], hidden: [required()], path: [required()], + noCache: [required()], order: [required()] }) diff --git a/kinit-admin/src/views/vadmin/auth/menu/components/menu.data.ts b/kinit-admin/src/views/vadmin/auth/menu/components/menu.data.ts index 0626b54..5790ca5 100644 --- a/kinit-admin/src/views/vadmin/auth/menu/components/menu.data.ts +++ b/kinit-admin/src/views/vadmin/auth/menu/components/menu.data.ts @@ -44,6 +44,12 @@ export const columns = reactive([ label: '组件路径', show: true }, + { + field: 'noCache', + label: '页面缓存', + width: '120px', + show: true + }, { field: 'hidden', label: '显示状态', @@ -224,5 +230,31 @@ export const schema = reactive([ span: 12 }, ifshow: (values) => values.menu_type === '2' + }, + { + field: 'noCache', + label: '页面缓存', + colProps: { + span: 12 + }, + component: 'Radio', + componentProps: { + style: { + width: '100%' + }, + options: [ + { + label: '缓存', + value: false + }, + { + label: '不缓存', + value: true + } + ] + }, + value: false, + ifshow: (values) => values.menu_type === '1', + labelMessage: '开启页面缓存,需要组件名称必须与xx.vue页面的name一致' } ]) diff --git a/kinit-admin/src/views/vadmin/auth/menu/index.vue b/kinit-admin/src/views/vadmin/auth/menu/index.vue index f1ac3be..b28576b 100644 --- a/kinit-admin/src/views/vadmin/auth/menu/index.vue +++ b/kinit-admin/src/views/vadmin/auth/menu/index.vue @@ -1,3 +1,9 @@ + + + + + + + + + + + + diff --git a/kinit-uni/README.md b/kinit-uni/README.md index c5f6853..ea84f30 100644 --- a/kinit-uni/README.md +++ b/kinit-uni/README.md @@ -47,3 +47,23 @@ RuoYi App 移动解决方案,采用uniapp框架,一份代码多终端适配 - 文档地址:https://uviewui.com uView UI,是[uni-app](https://uniapp.dcloud.io/)全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水 + +## 开发工具 + +在此项目中我将开发`uni-app`的开发工具从 Hbuilder X 换到了 VSCode,没有谁好谁坏,只是本人更习惯使用 VSCode,但是在运行项目时依然使用的是 Hbuilder X,VSCode只是用来编写代码。当然使用 Hbuilder X 也是支持的,只做一个分享。 + +以下是我在VSCode中安装的几个插件: + +1. 名称: Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code +2. 名称: ESLint +3. 名称: Image preview +4. 名称: Markdown Preview Enhanced +5. 名称: Path Intellisense +6. 名称: Prettier - Code formatter +7. 名称: Sass (.sass only) +8. 名称: SCSS IntelliSense +9. 名称: Stylelint +10. 名称: uni-app-schemas +11. 名称: uni-app-snippets +12. 名称: uni-create-view +13. 名称: Vetur diff --git a/kinit-uni/common/mixins/auth.js b/kinit-uni/common/mixins/auth.js index 8c69019..a8195fd 100644 --- a/kinit-uni/common/mixins/auth.js +++ b/kinit-uni/common/mixins/auth.js @@ -8,58 +8,57 @@ import { setUserOpenid } from '@/common/request/api/login.js' import { toast } from '@/common/utils/common' export const wxLoginMixins = { - computed: { - ...mapGetters([ - 'isUserOpenid', - ]) - }, - data () { - return { - } - }, - methods: { - onGetPhoneNumber(e) { - return new Promise((resolve, reject) => { - // 获取手机号官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html - if (e.detail.errMsg === "getPhoneNumber:fail user deny") { - // 用户拒绝授权 - toast("已取消授权") - reject("已取消授权") - } else if (e.detail.errMsg === "getPhoneNumber:fail no permission") { - // 微信公众平台未认证或未使用企业认证 - toast("微信公众平台未认证或未使用企业认证") - reject("微信公众平台未认证或未使用企业认证") - } else if (e.detail.errMsg === "getPhoneNumber:ok") { - // code换取用户手机号。 每个code只能使用一次,code的有效期为5min - this.$store.dispatch('auth/wxLogin', e.detail.code).then(res => { - this.setOpenid(); - this.$store.dispatch('auth/GetInfo').then(result => { - resolve(result) - }) - }) - } else { - toast("授权失败") - reject("授权失败") - } - }) - }, - setOpenid() { - let self = this; - // uniapp 官方文档:https://uniapp.dcloud.io/api/plugins/login.html#login - if (self.isUserOpenid) { return; }; - uni.login({ - provider: 'weixin', - success: function (loginRes) { - if (loginRes.code) { - setUserOpenid(loginRes.code).then(res => { - // console.log("更新openid成功", res) - self.$store.commit("auth/SET_IS_USER_OPENID", true); - }) - } else { - console.log('登录失败!获取code失败!' + res.errMsg) - } - } - }); - } - } -} \ No newline at end of file + computed: { + ...mapGetters(['isUserOpenid']) + }, + data() { + return {} + }, + methods: { + onGetPhoneNumber(e) { + return new Promise((resolve, reject) => { + // 获取手机号官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html + if (e.detail.errMsg === 'getPhoneNumber:fail user deny') { + // 用户拒绝授权 + toast('已取消授权') + reject('已取消授权') + } else if (e.detail.errMsg === 'getPhoneNumber:fail no permission') { + // 微信公众平台未认证或未使用企业认证 + toast('微信公众平台未认证或未使用企业认证') + reject('微信公众平台未认证或未使用企业认证') + } else if (e.detail.errMsg === 'getPhoneNumber:ok') { + // code换取用户手机号。 每个code只能使用一次,code的有效期为5min + this.$store.dispatch('auth/wxLogin', e.detail.code).then((res) => { + this.setOpenid() + this.$store.dispatch('auth/GetInfo').then((result) => { + resolve(result) + }) + }) + } else { + toast('授权失败') + reject('授权失败') + } + }) + }, + setOpenid() { + let self = this + // uniapp 官方文档:https://uniapp.dcloud.io/api/plugins/login.html#login + if (self.isUserOpenid) { + return + } + uni.login({ + provider: 'weixin', + success: function (loginRes) { + if (loginRes.code) { + setUserOpenid(loginRes.code).then(() => { + // console.log("更新openid成功", res) + self.$store.commit('auth/SET_IS_USER_OPENID', true) + }) + } else { + console.log('登录失败!获取code失败!' + loginRes.errMsg) + } + } + }) + } + } +} diff --git a/kinit-uni/common/mixins/share.js b/kinit-uni/common/mixins/share.js index 5759c4f..74c71ff 100644 --- a/kinit-uni/common/mixins/share.js +++ b/kinit-uni/common/mixins/share.js @@ -1,46 +1,46 @@ export const wxShareMixins = { - data() { - return { - share: { - title: "", - path: "", - imageUrl: "" - } - } - }, - onLoad: function() { - wx.showShareMenu({ - withShareTicket: true, - menus: ["shareAppMessage", "shareTimeline"] - }) - }, - onShareAppMessage(res) { - let that = this; - let imageUrl = that.share.imageUrl || ''; - if (res.from === 'button') { - //这块需要传参,不然链接地址进去获取不到数据 - let path = `/` + that.$scope.route + `?item=` + that.$scope.options.item; - return { - title: '商品分享~', - path: path, - imageUrl: imageUrl - }; - } - if (res.from === 'menu') { - return { - title: that.share.title, - path: that.share.path, - imageUrl: that.share.imageUrl - }; - } - }, - // 分享到朋友圈 - onShareTimeline() { - return { - title: this.share.title, - path: this.share.path, - imageUrl: this.share.imageUrl - }; - }, - methods: {} -} \ No newline at end of file + data() { + return { + share: { + title: '', + path: '', + imageUrl: '' + } + } + }, + onLoad: function () { + wx.showShareMenu({ + withShareTicket: true, + menus: ['shareAppMessage', 'shareTimeline'] + }) + }, + onShareAppMessage(res) { + let that = this + let imageUrl = that.share.imageUrl || '' + if (res.from === 'button') { + //这块需要传参,不然链接地址进去获取不到数据 + let path = '/' + that.$scope.route + '?item=' + that.$scope.options.item + return { + title: '商品分享~', + path: path, + imageUrl: imageUrl + } + } + if (res.from === 'menu') { + return { + title: that.share.title, + path: that.share.path, + imageUrl: that.share.imageUrl + } + } + }, + // 分享到朋友圈 + onShareTimeline() { + return { + title: this.share.title, + path: this.share.path, + imageUrl: this.share.imageUrl + } + }, + methods: {} +} diff --git a/kinit-uni/common/request/api/login.js b/kinit-uni/common/request/api/login.js index 20a5818..64788c0 100644 --- a/kinit-uni/common/request/api/login.js +++ b/kinit-uni/common/request/api/login.js @@ -5,29 +5,29 @@ export function login(telephone, password) { const data = { telephone, password, - method: '0', - platform: '1' + method: '0', + platform: '1' } - return request.post(`/auth/login/`, data) + return request.post('/auth/login/', data) } // 获取用户详细信息 export function getInfo() { - return request.get(`/vadmin/auth/user/admin/current/info/`) + return request.get('/vadmin/auth/user/admin/current/info/') } // 更新用户openid export function setUserOpenid(code) { - const params = {code} - return request.put(`/vadmin/auth/users/wx/server/openid/`, {}, {params: params}) + const params = { code } + return request.put('/vadmin/auth/users/wx/server/openid/', {}, { params: params }) } // 使用微信一键登录 export function wxCodeLogin(code) { - const data = { - code, - method: '2', - platform: '1' - } - return request.post(`/auth/wx/login/`, data) + const data = { + code, + method: '2', + platform: '1' + } + return request.post('/auth/wx/login/', data) } diff --git a/kinit-uni/common/request/api/vadmin/auth/user.js b/kinit-uni/common/request/api/vadmin/auth/user.js index 240e2f9..b3227e6 100644 --- a/kinit-uni/common/request/api/vadmin/auth/user.js +++ b/kinit-uni/common/request/api/vadmin/auth/user.js @@ -2,15 +2,18 @@ import request from '@/common/request/request' // 更新当前用户基本信息 export function updateCurrentUser(data) { - return request.post(`/vadmin/auth/user/current/update/info/`, data) + return request.post('/vadmin/auth/user/current/update/info/', data) } // 重置当前用户密码 export function postCurrentUserResetPassword(data) { - return request.post(`/vadmin/auth/user/current/reset/password/`, data) + return request.post('/vadmin/auth/user/current/reset/password/', data) } // 更新当前用户头像 export function postCurrentUserUploadAvatar(filePath) { - return request.upload(`/vadmin/auth/user/current/update/avatar/`, {filePath: filePath, name: 'file'}) -} \ No newline at end of file + return request.upload('/vadmin/auth/user/current/update/avatar/', { + filePath: filePath, + name: 'file' + }) +} diff --git a/kinit-uni/common/request/api/vadmin/help/issue.js b/kinit-uni/common/request/api/vadmin/help/issue.js index 5d2a284..71b61d5 100644 --- a/kinit-uni/common/request/api/vadmin/help/issue.js +++ b/kinit-uni/common/request/api/vadmin/help/issue.js @@ -2,15 +2,15 @@ import request from '@/common/request/request.js' // 获取平台中的常见问题类别列表 export function getIssueCategoryList() { - return request.get(`/vadmin/help/issue/categorys/platform/1/`) + return request.get('/vadmin/help/issue/categorys/platform/1/') } // 获取问题详情 export function getIssue(dataId) { - return request.get(`/vadmin/help/issues/${dataId}/`) + return request.get(`/vadmin/help/issues/${dataId}/`) } // 更新常见问题查看次数+1 export function updateIssueAddViewNumber(dataId) { - return request.get(`/vadmin/help/issues/add/view/number/${dataId}/`) -} \ No newline at end of file + return request.get(`/vadmin/help/issues/add/view/number/${dataId}/`) +} diff --git a/kinit-uni/common/request/api/vadmin/system/dict.js b/kinit-uni/common/request/api/vadmin/system/dict.js index 457a42e..2affa65 100644 --- a/kinit-uni/common/request/api/vadmin/system/dict.js +++ b/kinit-uni/common/request/api/vadmin/system/dict.js @@ -2,5 +2,5 @@ import request from '@/common/request/request.js' // 获取多个字典类型下的字典元素列表 export function getDictTypeDetailsApi(data) { - return request.post(`/vadmin/system/dict/types/details/`, data) + return request.post('/vadmin/system/dict/types/details/', data) } diff --git a/kinit-uni/common/request/api/vadmin/system/settings.js b/kinit-uni/common/request/api/vadmin/system/settings.js index af737e4..bb37fa7 100644 --- a/kinit-uni/common/request/api/vadmin/system/settings.js +++ b/kinit-uni/common/request/api/vadmin/system/settings.js @@ -2,5 +2,5 @@ import request from '@/common/request/request' // 获取系统基本配置 export function getSystemBaseConfigApi() { - return request.get(`/vadmin/system/settings/base/config/`) -} \ No newline at end of file + return request.get('/vadmin/system/settings/base/config/') +} diff --git a/kinit-uni/common/request/errorCode.js b/kinit-uni/common/request/errorCode.js index 954019e..93e34d6 100644 --- a/kinit-uni/common/request/errorCode.js +++ b/kinit-uni/common/request/errorCode.js @@ -1,6 +1,6 @@ export default { - "401": "认证失败,无法访问系统资源", - "403": "当前操作没有权限", - "404": "访问资源不存在", - "default": "系统未知错误,请反馈给管理员" -}; + 401: '认证失败,无法访问系统资源', + 403: '当前操作没有权限', + 404: '访问资源不存在', + default: '系统未知错误,请反馈给管理员' +} diff --git a/kinit-uni/common/request/request.js b/kinit-uni/common/request/request.js index f9ce222..f533228 100644 --- a/kinit-uni/common/request/request.js +++ b/kinit-uni/common/request/request.js @@ -1,78 +1,127 @@ import luchRequest from '@/components/luch-request' // 使用npm -import config from '@/config.js'; -import errorCode from "@/common/request/errorCode"; -import { getToken } from '@/common/utils/auth' -import { toast, showConfirm } from '@/common/utils/common' +import config from '@/config.js' +import errorCode from '@/common/request/errorCode' +import { getToken, getRefreshToken, setToken, setRefreshToken } from '@/common/utils/auth' +import { toast } from '@/common/utils/common' import store from '@/store' +import request from '@/common/request/request.js' // luch-request插件官网:https://www.quanzhan.co/luch-request/guide/3.x/#%E5%85%A8%E5%B1%80%E8%AF%B7%E6%B1%82%E9%85%8D%E7%BD%AE // 创建luchRequest实例 -console.log(config.baseUrl) const http = new luchRequest({ baseURL: config.baseUrl, timeout: 20000, // 请求超时时间 dataType: 'json', custom: { - loading: true - }, - sslVerify: true, - header: {} + loading: true + } }) - // 请求拦截器 http.interceptors.request.use( - config => { + (config) => { // 在发送请求之前 - let token = getToken() - if (token) { - // 添加头信息,token验证 - config.header["Authorization"] = token - } + let token = getToken() + if (token) { + // 添加头信息,token验证 + config.header['Authorization'] = token + } return config }, - error => { + (error) => { return Promise.reject(error) } ) // 响应拦截器 -http.interceptors.response.use(res => { - // console.log("响应拦截器:", res) - // 未设置状态码则默认成功状态 - const code = res.data.code || 200; - // 获取错误信息 - const msg = res.data.message || errorCode[code] || errorCode["default"]; - if (code === 500) { - toast(msg) - return Promise.reject(new Error(msg)); - } else if (code === 401) { - showConfirm("登录状态已过期,您可以继续留在该页面,或者重新登录?").then(res => { - if (res.confirm) { - store.dispatch('auth/LogOut') - } - }) - return Promise.reject("error"); - } else if (code !== 200) { - toast(msg) - return Promise.reject("error"); - } else { - return res.data; - } - }, - error => { - console.log("请求状态码服务器直接报错", error); - let { errMsg } = error; - if (errMsg == "request:fail") { - errMsg = "接口连接异常"; - } else if (errMsg == "request:fail timeout") { - errMsg = "接口连接超时"; - } else { - errMsg = error.data.message; - } - toast(errMsg) - return Promise.reject(error); - } -); +http.interceptors.response.use( + (res) => { + // console.log("响应拦截器:", res) + // 未设置状态码则默认401状态 + const code = res.data.code || 200 + // 获取错误信息 + const msg = res.data.message || errorCode[code] || errorCode['default'] + // 是否刷新token + const refresh = res.data.refresh || false + if (code === 500) { + toast(msg) + return Promise.reject(new Error(msg)) + } else if (code === 401) { + // 因token快过期,刷新token + refreshToken().then((res) => { + setToken(`${res.data.token_type} ${res.data.access_token}`) + setRefreshToken(res.data.refresh_token) + }) + toast('操作失败,请重试') + return Promise.reject('error') + } else if (code !== 200) { + toast(msg) + return Promise.reject('error') + } else if (code === 200) { + if (refresh) { + // 因token快过期,刷新token + refreshToken().then((res) => { + setToken(`${res.data.token_type} ${res.data.access_token}`) + setRefreshToken(res.data.refresh_token) + }) + } + return res.data + } else { + return res.data + } + }, + (error) => { + console.log('err', error) + let message = error.data.message || error.errMsg + const status = error.statusCode + switch (status) { + case 400: + message = '请求错误' + break + case 401: + // 强制要求重新登录,因账号已冻结,账号已过期,手机号码错误,刷新token无效等问题导致 + store.dispatch('auth/LogOut') + message = '未认证,请登录' + break + case 403: + message = '拒绝访问' + break + case 404: + message = '请求地址出错' + break + case 408: + message = '请求超时' + break + case 500: + message = '服务器内部错误' + break + case 501: + message = '服务未实现' + break + case 502: + message = '网关错误' + break + case 503: + message = '服务不可用' + break + case 504: + message = '网关超时' + break + case 505: + message = 'HTTP版本不受支持' + break + default: + break + } + toast(message) + return Promise.reject(error) + } +) -export default http \ No newline at end of file +// 刷新 token +function refreshToken() { + const data = JSON.stringify(getRefreshToken()) + return request.post('/auth/token/refresh/', data) +} + +export default http diff --git a/kinit-uni/common/utils/auth.js b/kinit-uni/common/utils/auth.js index 9a7cc04..a29e803 100644 --- a/kinit-uni/common/utils/auth.js +++ b/kinit-uni/common/utils/auth.js @@ -11,3 +11,17 @@ export function setToken(token) { export function removeToken() { return uni.removeStorageSync(TokenKey) } + +const RefreshTokenKey = 'Refresh-Token' + +export function getRefreshToken() { + return uni.getStorageSync(RefreshTokenKey) +} + +export function setRefreshToken(token) { + return uni.setStorageSync(RefreshTokenKey, token) +} + +export function removeRefreshToken() { + return uni.removeStorageSync(RefreshTokenKey) +} diff --git a/kinit-uni/common/utils/common.js b/kinit-uni/common/utils/common.js index 00d4137..54d3e7a 100644 --- a/kinit-uni/common/utils/common.js +++ b/kinit-uni/common/utils/common.js @@ -1,7 +1,7 @@ /** -* 显示消息提示框 -* @param content 提示的标题 -*/ + * 显示消息提示框 + * @param content 提示的标题 + */ export function toast(content) { uni.showToast({ icon: 'none', @@ -10,9 +10,9 @@ export function toast(content) { } /** -* 显示模态弹窗 -* @param content 提示的标题 -*/ + * 显示模态弹窗 + * @param content 提示的标题 + */ export function showConfirm(content) { return new Promise((resolve, reject) => { uni.showModal({ @@ -20,7 +20,7 @@ export function showConfirm(content) { content: content, cancelText: '取消', confirmText: '确定', - success: function(res) { + success: function (res) { resolve(res) } }) @@ -28,27 +28,27 @@ export function showConfirm(content) { } /** -* 参数处理 -* @param params 参数 -*/ + * 参数处理 + * @param params 参数 + */ export function tansParams(params) { let result = '' for (const propName of Object.keys(params)) { const value = params[propName] - var part = encodeURIComponent(propName) + "=" - if (value !== null && value !== "" && typeof (value) !== "undefined") { + var part = encodeURIComponent(propName) + '=' + if (value !== null && value !== '' && typeof value !== 'undefined') { if (typeof value === 'object') { for (const key of Object.keys(value)) { - if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') { + if (value[key] !== null && value[key] !== '' && typeof value[key] !== 'undefined') { let params = propName + '[' + key + ']' - var subPart = encodeURIComponent(params) + "=" - result += subPart + encodeURIComponent(value[key]) + "&" + var subPart = encodeURIComponent(params) + '=' + result += subPart + encodeURIComponent(value[key]) + '&' } } } else { - result += part + encodeURIComponent(value) + "&" + result += part + encodeURIComponent(value) + '&' } } } return result -} \ No newline at end of file +} diff --git a/kinit-uni/common/utils/constant.js b/kinit-uni/common/utils/constant.js index 8b07e88..ac5c530 100644 --- a/kinit-uni/common/utils/constant.js +++ b/kinit-uni/common/utils/constant.js @@ -1,11 +1,11 @@ export const auth = { - isUser: 'vuex_auth_isUser', - isUserOpenid: 'vuex_auth_isUserOpenid', - isResetPassword: 'vuex_auth_isResetPassword', - name: 'vuex_auth_name', - nickname: 'vuex_auth_nickname', - gender: 'vuex_auth_gender', - telephone: 'vuex_auth_telephone', + isUser: 'vuex_auth_isUser', + isUserOpenid: 'vuex_auth_isUserOpenid', + isResetPassword: 'vuex_auth_isResetPassword', + name: 'vuex_auth_name', + nickname: 'vuex_auth_nickname', + gender: 'vuex_auth_gender', + telephone: 'vuex_auth_telephone', avatar: 'vuex_auth_avatar', createDatetime: 'vuex_auth_createDatetime', roles: 'vuex_auth_roles', diff --git a/kinit-uni/common/utils/cookies.js b/kinit-uni/common/utils/cookies.js deleted file mode 100644 index 0a49f98..0000000 --- a/kinit-uni/common/utils/cookies.js +++ /dev/null @@ -1,80 +0,0 @@ -const TokenKey = 'Admin-Token' - -// 获取客户端token -export function getToken() { - try { - const value = uni.getStorageSync(TokenKey); - if (value) { - return value; - } - return "" - } catch (e) { - // error - return "" - } -} - -// 设置客户端token -export function setToken(token) { - uni.setStorage({ - key: TokenKey, - data: token, - success: function (res) { - console.log('成功存储token'); - }, - fail:function(e){ - console.log(e) - console.log("存储token失败"); - } - }); -} - -// 删除客户端token -export function removeToken() { - uni.removeStorage({ - key: TokenKey, - success: function (res) { - console.log('成功删除token'); - } - }); -} - -// 获取客户端 -export function getStorage(key) { - try { - const value = uni.getStorageSync(key); - if (value) { - // console.log("成功获取到 Storage:", value); - return value; - } - return "" - } catch (e) { - // error - return "" - } -} - -// 设置客户端 Storage -export function setStorage(key, value) { - uni.setStorage({ - key: key, - data: value, - success: function (res) { - console.log('成功存储'); - }, - fail:function(e){ - console.log(e) - console.log("存储失败"); - } - }); -} - -// 删除客户端 Storage -export function removeStorage(key) { - uni.removeStorage({ - key: key, - success: function (res) { - console.log('成功删除Storage'); - } - }); -} \ No newline at end of file diff --git a/kinit-uni/common/utils/logs.js b/kinit-uni/common/utils/logs.js index ec555d3..035b1d5 100644 --- a/kinit-uni/common/utils/logs.js +++ b/kinit-uni/common/utils/logs.js @@ -17,14 +17,16 @@ module.exports = { if (!log) return log.error.apply(log, arguments) }, - setFilterMsg(msg) { // 从基础库2.7.3开始支持 + setFilterMsg(msg) { + // 从基础库2.7.3开始支持 if (!log || !log.setFilterMsg) return if (typeof msg !== 'string') return log.setFilterMsg(msg) }, - addFilterMsg(msg) { // 从基础库2.8.1开始支持 + addFilterMsg(msg) { + // 从基础库2.8.1开始支持 if (!log || !log.addFilterMsg) return if (typeof msg !== 'string') return log.addFilterMsg(msg) } -} \ No newline at end of file +} diff --git a/kinit-uni/common/utils/permission.js b/kinit-uni/common/utils/permission.js index 17969f2..1a4e75b 100644 --- a/kinit-uni/common/utils/permission.js +++ b/kinit-uni/common/utils/permission.js @@ -9,9 +9,9 @@ export function checkPermi(value) { if (value && value instanceof Array && value.length > 0) { const permissions = store.getters && store.getters.permissions const permissionDatas = value - const all_permission = "*:*:*" + const all_permission = '*:*:*' - const hasPermission = permissions.some(permission => { + const hasPermission = permissions.some((permission) => { return all_permission === permission || permissionDatas.includes(permission) }) @@ -20,7 +20,7 @@ export function checkPermi(value) { } return true } else { - console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`) + console.error('未获取到校验的字符权限!') return false } } @@ -34,9 +34,9 @@ export function checkRole(value) { if (value && value instanceof Array && value.length > 0) { const roles = store.getters && store.getters.roles const permissionRoles = value - const super_admin = "admin" + const super_admin = 'admin' - const hasRole = roles.some(role => { + const hasRole = roles.some((role) => { return super_admin === role || permissionRoles.includes(role) }) @@ -45,7 +45,7 @@ export function checkRole(value) { } return true } else { - console.error(`need roles! Like checkRole="['admin','editor']"`) + console.error('未获取到校验的角色!') return false } -} \ No newline at end of file +} diff --git a/kinit-uni/common/utils/postFile.js b/kinit-uni/common/utils/postFile.js index b75fadc..a6dcfc0 100644 --- a/kinit-uni/common/utils/postFile.js +++ b/kinit-uni/common/utils/postFile.js @@ -5,34 +5,32 @@ 博客:https://www.jianshu.com/p/71ad2f45120c */ - import config from '@/config.js' -import { getToken, removeToken } from '@/common/utils/cookies' - +import { getToken } from '@/common/utils/auth' // 单个文件上传 -export function uploadFile(api, file, data={}) { +export function uploadFile(api, file, data = {}) { return new Promise((resolve, reject) => { - uni.uploadFile({ - url: config.baseUrl + api, - filePath: file, - name: 'file', - timeout: 60000, - formData: data, - header: { - Authorization: getToken() - }, - success: (res) => { - let data = JSON.parse(res.data); - if (data.code !== 200) { - reject(data); - } - resolve(data); - }, - fail: (err) => { - console.log("上传失败", err); - reject(err); - } - }); + uni.uploadFile({ + url: config.baseUrl + api, + filePath: file, + name: 'file', + timeout: 60000, + formData: data, + header: { + Authorization: getToken() + }, + success: (res) => { + let data = JSON.parse(res.data) + if (data.code !== 200) { + reject(data) + } + resolve(data) + }, + fail: (err) => { + console.log('上传失败', err) + reject(err) + } + }) }) } diff --git a/kinit-uni/common/utils/ruoyi.js b/kinit-uni/common/utils/ruoyi.js index ba2c172..494ddcc 100644 --- a/kinit-uni/common/utils/ruoyi.js +++ b/kinit-uni/common/utils/ruoyi.js @@ -13,47 +13,47 @@ * getDate(new Date(), 3).fullDate # 三天后的日期 */ export function getDate(date, AddDayCount = 0) { - if (!date) { - date = new Date() - } - if (typeof date !== 'object') { - date = date.replace(/-/g, '/') - } - const dd = new Date(date) + if (!date) { + date = new Date() + } + if (typeof date !== 'object') { + date = date.replace(/-/g, '/') + } + const dd = new Date(date) - dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期 + dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期 - const y = dd.getFullYear() - const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0 - const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0 - return { - fullDate: y + '-' + m + '-' + d, - year: y, - month: m, - date: d, - day: dd.getDay() - } + const y = dd.getFullYear() + const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0 + const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0 + return { + fullDate: y + '-' + m + '-' + d, + year: y, + month: m, + date: d, + day: dd.getDay() + } } // 日期格式化 export function parseTime(time, pattern) { if (arguments.length === 0 || !time) { - return null; + return null } - const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}"; - let date; - if (typeof time === "object") { - date = time; + const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time } else { - if ((typeof time === "string") && (/^[0-9]+$/.test(time))) { - time = parseInt(time); - } else if (typeof time === "string") { - time = time.replace(new RegExp(/-/gm), "/"); + if (typeof time === 'string' && /^[0-9]+$/.test(time)) { + time = parseInt(time) + } else if (typeof time === 'string') { + time = time.replace(new RegExp(/-/gm), '/') } - if ((typeof time === "number") && (time.toString().length === 10)) { - time = time * 1000; + if (typeof time === 'number' && time.toString().length === 10) { + time = time * 1000 } - date = new Date(time); + date = new Date(time) } const formatObj = { y: date.getFullYear(), @@ -63,129 +63,132 @@ export function parseTime(time, pattern) { i: date.getMinutes(), s: date.getSeconds(), a: date.getDay() - }; + } const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { - let value = formatObj[key]; + let value = formatObj[key] // Note: getDay() returns 0 on Sunday - if (key === "a") { return ["日", "一", "二", "三", "四", "五", "六"][value]; } - if (result.length > 0 && value < 10) { - value = "0" + value; + if (key === 'a') { + return ['日', '一', '二', '三', '四', '五', '六'][value] } - return value || 0; - }); - return time_str; + if (result.length > 0 && value < 10) { + value = '0' + value + } + return value || 0 + }) + return time_str } // 表单重置 export function resetForm(refName) { if (this.$refs[refName]) { - this.$refs[refName].resetFields(); + this.$refs[refName].resetFields() } } // 添加日期范围 export function addDateRange(params, dateRange, propName) { - const search = JSON.parse(JSON.stringify(params)); - if (dateRange != null && dateRange !== "" && dateRange.length !== 0) { - search.as = JSON.stringify({ create_datetime__range: dateRange }); + const search = JSON.parse(JSON.stringify(params)) + if (dateRange != null && dateRange !== '' && dateRange.length !== 0) { + search.as = JSON.stringify({ create_datetime__range: dateRange }) } - return search; + return search } // 回显数据字典 export function selectDictLabel(datas, value) { - var actions = []; + var actions = [] Object.keys(datas).some((key) => { - if (String(datas[key].value) === ("" + String(value))) { - actions.push(datas[key].label); - return true; + if (String(datas[key].value) === '' + String(value)) { + actions.push(datas[key].label) + return true } - }); - return actions.join(""); + }) + return actions.join('') } // 获取字典默认值 export function selectDictDefault(datas) { - var actions = []; + var actions = [] Object.keys(datas).some((key) => { if (datas[key].is_default === true) { - actions.push(datas[key].dictValue); - return true; + actions.push(datas[key].dictValue) + return true } - }); + }) if (!actions[0] && datas[0]) { - actions.push(datas[0].dictValue); + actions.push(datas[0].dictValue) } - return actions.join(""); + return actions.join('') } // 回显数据字典(字符串数组) export function selectDictLabels(datas, value, separator) { - var actions = []; - var currentSeparator = undefined === separator ? "," : separator; - var temp = value.split(currentSeparator); + var actions = [] + var currentSeparator = undefined === separator ? ',' : separator + var temp = value.split(currentSeparator) Object.keys(value.split(currentSeparator)).some((val) => { Object.keys(datas).some((key) => { - if (datas[key].dictValue == ("" + temp[val])) { - actions.push(datas[key].dictLabel + currentSeparator); + if (datas[key].dictValue == '' + temp[val]) { + actions.push(datas[key].dictLabel + currentSeparator) } - }); - }); - return actions.join("").substring(0, actions.join("").length - 1); + }) + }) + return actions.join('').substring(0, actions.join('').length - 1) } // 转换字符串,undefined,null等转化为"" export function praseStrEmpty(str) { - if (!str || str == "undefined" || str == "null") { - return ""; + if (!str || str == 'undefined' || str == 'null') { + return '' } - return str; + return str } // js模仿微信朋友圈计算时间显示几天/几小时/几分钟/刚刚 //datetime 格式为2019-11-22 12:23:59样式 -export function timeConversion(datetime) { //dateTimeStamp是一个时间毫秒,注意时间戳是秒的形式,在这个毫秒的基础上除以1000,就是十位数的时间戳。13位数的都是时间毫秒。 - // var dateTimeStamp = new Date(datetime.replace(/ /, 'T')).getTime()-8 * 60 * 60 * 1000;//这里要减去中国的时区8小时 - var dateTimeStamp = new Date(datetime.replace(/ /, 'T')).getTime();//这里不减去中国的时区8小时 - var minute = 1000 * 60; //把分,时,天,周,半个月,一个月用毫秒表示 - var hour = minute * 60; - var day = hour * 24; - var week = day * 7; - var halfamonth = day * 15; - var month = day * 30; - var now = new Date().getTime(); //获取当前时间毫秒 - var diffValue = now - dateTimeStamp; //时间差 - - if (diffValue < 0) { - return '刚刚'; - } - var minC = diffValue / minute; //计算时间差的分,时,天,周,月 - var hourC = diffValue / hour; - var dayC = diffValue / day; - var weekC = diffValue / week; - var monthC = diffValue / month; - var result = "2"; - if (monthC >= 1 && monthC <= 3) { - result = " " + parseInt(monthC) + "月前" - } else if (weekC >= 1 && weekC <= 3) { - result = " " + parseInt(weekC) + "周前" - } else if (dayC >= 1 && dayC <= 6) { - result = " " + parseInt(dayC) + "天前" - } else if (hourC >= 1 && hourC <= 23) { - result = " " + parseInt(hourC) + "小时前" - } else if (minC >= 1 && minC <= 59) { - result = " " + parseInt(minC) + "分钟前" - } else if (diffValue >= 0 && diffValue <= minute) { - result = "刚刚" - } else { - var datetime = new Date(); - datetime.setTime(dateTimeStamp); - var Nyear = datetime.getFullYear(); {} - var Nmonth = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1; - var Ndate = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate(); - var Nhour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours(); - var Nminute = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes(); - var Nsecond = datetime.getSeconds() < 10 ? "0" + datetime.getSeconds() : datetime.getSeconds(); - result = Nyear + "-" + Nmonth + "-" + Ndate - } - return result; -} \ No newline at end of file +export function timeConversion(datetime) { + //dateTimeStamp是一个时间毫秒,注意时间戳是秒的形式,在这个毫秒的基础上除以1000,就是十位数的时间戳。13位数的都是时间毫秒。 + // var dateTimeStamp = new Date(datetime.replace(/ /, 'T')).getTime()-8 * 60 * 60 * 1000;//这里要减去中国的时区8小时 + var dateTimeStamp = new Date(datetime.replace(/ /, 'T')).getTime() //这里不减去中国的时区8小时 + var minute = 1000 * 60 //把分,时,天,周,半个月,一个月用毫秒表示 + var hour = minute * 60 + var day = hour * 24 + var week = day * 7 + var month = day * 30 + var now = new Date().getTime() //获取当前时间毫秒 + var diffValue = now - dateTimeStamp //时间差 + + if (diffValue < 0) { + return '刚刚' + } + var minC = diffValue / minute //计算时间差的分,时,天,周,月 + var hourC = diffValue / hour + var dayC = diffValue / day + var weekC = diffValue / week + var monthC = diffValue / month + var result = '2' + if (monthC >= 1 && monthC <= 3) { + result = ' ' + parseInt(monthC) + '月前' + } else if (weekC >= 1 && weekC <= 3) { + result = ' ' + parseInt(weekC) + '周前' + } else if (dayC >= 1 && dayC <= 6) { + result = ' ' + parseInt(dayC) + '天前' + } else if (hourC >= 1 && hourC <= 23) { + result = ' ' + parseInt(hourC) + '小时前' + } else if (minC >= 1 && minC <= 59) { + result = ' ' + parseInt(minC) + '分钟前' + } else if (diffValue >= 0 && diffValue <= minute) { + result = '刚刚' + } else { + let datetime = new Date() + datetime.setTime(dateTimeStamp) + let Nyear = datetime.getFullYear() + var Nmonth = + datetime.getMonth() + 1 < 10 ? '0' + (datetime.getMonth() + 1) : datetime.getMonth() + 1 + var Ndate = datetime.getDate() < 10 ? '0' + datetime.getDate() : datetime.getDate() + var Nhour = datetime.getHours() < 10 ? '0' + datetime.getHours() : datetime.getHours() + var Nminute = datetime.getMinutes() < 10 ? '0' + datetime.getMinutes() : datetime.getMinutes() + var Nsecond = datetime.getSeconds() < 10 ? '0' + datetime.getSeconds() : datetime.getSeconds() + result = Nyear + '-' + Nmonth + '-' + Ndate + } + return result +} diff --git a/kinit-uni/common/utils/storage.js b/kinit-uni/common/utils/storage.js index dcc8227..1932f12 100644 --- a/kinit-uni/common/utils/storage.js +++ b/kinit-uni/common/utils/storage.js @@ -13,7 +13,7 @@ let storageNodeKeys = [...Object.values(auth)] let storageData = uni.getStorageSync(storageKey) || {} const storage = { - set: function(key, value) { + set: function (key, value) { if (storageNodeKeys.indexOf(key) != -1) { let tmp = uni.getStorageSync(storageKey) tmp = tmp ? tmp : {} @@ -21,14 +21,14 @@ const storage = { uni.setStorageSync(storageKey, tmp) } }, - get: function(key) { - return storageData[key] || "" + get: function (key) { + return storageData[key] || '' }, - remove: function(key) { + remove: function (key) { delete storageData[key] uni.setStorageSync(storageKey, storageData) }, - clean: function() { + clean: function () { uni.removeStorageSync(storageKey) } } diff --git a/kinit-uni/common/utils/upload.js b/kinit-uni/common/utils/upload.js index c775f0e..7ca774a 100644 --- a/kinit-uni/common/utils/upload.js +++ b/kinit-uni/common/utils/upload.js @@ -7,7 +7,7 @@ import { toast, showConfirm, tansParams } from '@/common/utils/common' let timeout = 10000 const baseUrl = config.baseUrl -const upload = config => { +const upload = (config) => { // 是否需要设置 token const isToken = (config.headers || {}).isToken === false config.header = config.header || {} @@ -21,47 +21,47 @@ const upload = config => { config.url = url } return new Promise((resolve, reject) => { - uni.uploadFile({ - timeout: config.timeout || timeout, - url: baseUrl + config.url, - filePath: config.filePath, - name: config.name || 'file', - header: config.header, - formData: config.formData, - success: (res) => { - let result = JSON.parse(res.data) - const code = result.code || 200 - const msg = errorCode[code] || result.msg || errorCode['default'] - if (code === 200) { - resolve(result) - } else if (code == 401) { - showConfirm("登录状态已过期,您可以继续留在该页面,或者重新登录?").then(res => { - if (res.confirm) { - store.dispatch('LogOut') - } - }) - reject('无效的会话,或者会话已过期,请重新登录。') - } else if (code === 500) { - toast(msg) - reject('500') - } else if (code !== 200) { - toast(msg) - reject(code) - } - }, - fail: (error) => { - let { message } = error - if (message == 'Network Error') { - message = '后端接口连接异常' - } else if (message.includes('timeout')) { - message = '系统接口请求超时' - } else if (message.includes('Request failed with status code')) { - message = '系统接口' + message.substr(message.length - 3) + '异常' - } - toast(message) - reject(error) + uni.uploadFile({ + timeout: config.timeout || timeout, + url: baseUrl + config.url, + filePath: config.filePath, + name: config.name || 'file', + header: config.header, + formData: config.formData, + success: (res) => { + let result = JSON.parse(res.data) + const code = result.code || 200 + const msg = errorCode[code] || result.msg || errorCode['default'] + if (code === 200) { + resolve(result) + } else if (code == 401) { + showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then((res) => { + if (res.confirm) { + store.dispatch('LogOut') + } + }) + reject('无效的会话,或者会话已过期,请重新登录。') + } else if (code === 500) { + toast(msg) + reject('500') + } else if (code !== 200) { + toast(msg) + reject(code) } - }) + }, + fail: (error) => { + let { message } = error + if (message == 'Network Error') { + message = '后端接口连接异常' + } else if (message.includes('timeout')) { + message = '系统接口请求超时' + } else if (message.includes('Request failed with status code')) { + message = '系统接口' + message.substr(message.length - 3) + '异常' + } + toast(message) + reject(error) + } + }) }) } diff --git a/kinit-uni/config.js b/kinit-uni/config.js index 22880af..fa3d59d 100644 --- a/kinit-uni/config.js +++ b/kinit-uni/config.js @@ -1,16 +1,14 @@ // 应用全局配置 module.exports = { - // 测试环境 + // 测试环境 baseUrl: 'http://127.0.0.1:9000', - // 生产环境 - // baseUrl: 'https://api.kinit.ktianc.top', // 应用信息 appInfo: { // 应用版本 - version: "1.1.0", - // 隐私政策,不支持本地路径 - privacy: "http://kinit.ktianc.top/docs/privacy", - // 用户协议,不支持本地路径 - agreement: "http://kinit.ktianc.top/docs/agreement" + version: '1.2.0', + // 隐私政策,不支持本地路径 + privacy: 'http://kinit.ktianc.top/docs/privacy', + // 用户协议,不支持本地路径 + agreement: 'http://kinit.ktianc.top/docs/agreement' } } diff --git a/kinit-uni/jsconfig.json b/kinit-uni/jsconfig.json new file mode 100644 index 0000000..747f056 --- /dev/null +++ b/kinit-uni/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } + } +} \ No newline at end of file diff --git a/kinit-uni/main.js b/kinit-uni/main.js index 7a28ed2..ea0a4c3 100644 --- a/kinit-uni/main.js +++ b/kinit-uni/main.js @@ -2,8 +2,8 @@ import Vue from 'vue' import App from './App' import store from './store' // store import plugins from './plugins' // plugins -import {router,RouterMount} from './permission.js' // 路由拦截 -import uView from "uview-ui" +import { router, RouterMount } from './permission.js' // 路由拦截 +import uView from 'uview-ui' Vue.use(uView) Vue.use(router) @@ -14,28 +14,28 @@ Vue.use(plugins) // 配置后,很多组件的默认尺寸就变了,需要手动调整,不熟悉不建议开启 // 需要在Vue.use(uView)之后执行 uni.$u.setConfig({ - // 修改$u.config对象的属性 - config: { - // 修改默认单位为rpx,相当于执行 uni.$u.config.unit = 'rpx' - unit: 'rpx' - }, - // 修改$u.props对象的属性 - props: { - // 修改radio组件的size参数的默认值,相当于执行 uni.$u.props.radio.size = 30 - radio: { - size: 33, - labelSize: 30 - }, - button: { - loadingSize: 28 - }, - text: { - size: 30, - color: '#000' - } - // 其他组件属性配置 - // ...... - } + // 修改$u.config对象的属性 + config: { + // 修改默认单位为rpx,相当于执行 uni.$u.config.unit = 'rpx' + unit: 'rpx' + }, + // 修改$u.props对象的属性 + props: { + // 修改radio组件的size参数的默认值,相当于执行 uni.$u.props.radio.size = 30 + radio: { + size: 33, + labelSize: 30 + }, + button: { + loadingSize: 28 + }, + text: { + size: 30, + color: '#000' + } + // 其他组件属性配置 + // ...... + } }) Vue.config.productionTip = false @@ -49,9 +49,9 @@ const app = new Vue({ //v1.3.5起 H5端 你应该去除原有的app.$mount();使用路由自带的渲染方式 // #ifdef H5 - RouterMount(app, router, '#app') +RouterMount(app, router, '#app') // #endif // #ifndef H5 - app.$mount(); //为了兼容小程序及app端必须这样写才有效果 +app.$mount() //为了兼容小程序及app端必须这样写才有效果 // #endif diff --git a/kinit-uni/package.json b/kinit-uni/package.json index f60d4e0..8d7af47 100644 --- a/kinit-uni/package.json +++ b/kinit-uni/package.json @@ -3,5 +3,11 @@ "uni-read-pages": "^1.0.5", "uni-simple-router": "^2.0.8-beta.3", "uview-ui": "^2.0.34" + }, + "devDependencies": { + "eslint": "^8.35.0", + "eslint-config-prettier": "^8.7.0", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-vue": "^9.9.0" } } diff --git a/kinit-uni/pages/common/textview/index.vue b/kinit-uni/pages/common/textview/index.vue index 8d43399..1fb5159 100644 --- a/kinit-uni/pages/common/textview/index.vue +++ b/kinit-uni/pages/common/textview/index.vue @@ -7,42 +7,42 @@ diff --git a/kinit-uni/pages/common/webview/index.vue b/kinit-uni/pages/common/webview/index.vue index 3f1c616..7292925 100644 --- a/kinit-uni/pages/common/webview/index.vue +++ b/kinit-uni/pages/common/webview/index.vue @@ -1,35 +1,35 @@ diff --git a/kinit-uni/pages/index.vue b/kinit-uni/pages/index.vue index 3196665..14905fd 100644 --- a/kinit-uni/pages/index.vue +++ b/kinit-uni/pages/index.vue @@ -8,48 +8,48 @@ diff --git a/kinit-uni/pages/login/login.vue b/kinit-uni/pages/login/login.vue index cf1c580..44aec52 100644 --- a/kinit-uni/pages/login/login.vue +++ b/kinit-uni/pages/login/login.vue @@ -1,201 +1,212 @@ diff --git a/kinit-uni/pages/mine/about/index.vue b/kinit-uni/pages/mine/about/index.vue index 1638889..7d39446 100644 --- a/kinit-uni/pages/mine/about/index.vue +++ b/kinit-uni/pages/mine/about/index.vue @@ -1,8 +1,7 @@ diff --git a/kinit-uni/pages/mine/avatar/index.vue b/kinit-uni/pages/mine/avatar/index.vue index 7b772da..c8e892a 100644 --- a/kinit-uni/pages/mine/avatar/index.vue +++ b/kinit-uni/pages/mine/avatar/index.vue @@ -1,349 +1,427 @@ diff --git a/kinit-uni/pages/mine/help/issue/index.vue b/kinit-uni/pages/mine/help/issue/index.vue index ea2e403..d7781b6 100644 --- a/kinit-uni/pages/mine/help/issue/index.vue +++ b/kinit-uni/pages/mine/help/issue/index.vue @@ -5,10 +5,15 @@ {{ item.name }} - + {{ issue.title }} - + @@ -16,68 +21,68 @@ diff --git a/kinit-uni/pages/mine/help/issue/info.vue b/kinit-uni/pages/mine/help/issue/info.vue index 2c20516..c6c1f4a 100644 --- a/kinit-uni/pages/mine/help/issue/info.vue +++ b/kinit-uni/pages/mine/help/issue/info.vue @@ -1,70 +1,71 @@ diff --git a/kinit-uni/pages/mine/index.vue b/kinit-uni/pages/mine/index.vue index 0b8b9f2..8dbe175 100644 --- a/kinit-uni/pages/mine/index.vue +++ b/kinit-uni/pages/mine/index.vue @@ -1,5 +1,5 @@ diff --git a/kinit-uni/pages/mine/info/edit.vue b/kinit-uni/pages/mine/info/edit.vue index 5bf3b57..153dd8f 100644 --- a/kinit-uni/pages/mine/info/edit.vue +++ b/kinit-uni/pages/mine/info/edit.vue @@ -1,168 +1,128 @@ diff --git a/kinit-uni/pages/mine/info/index.vue b/kinit-uni/pages/mine/info/index.vue index 6f35433..1b8fc2f 100644 --- a/kinit-uni/pages/mine/info/index.vue +++ b/kinit-uni/pages/mine/info/index.vue @@ -1,49 +1,49 @@ diff --git a/kinit-uni/pages/mine/pwd/index.vue b/kinit-uni/pages/mine/pwd/index.vue index 2081c81..2c8c9dd 100644 --- a/kinit-uni/pages/mine/pwd/index.vue +++ b/kinit-uni/pages/mine/pwd/index.vue @@ -1,104 +1,87 @@ diff --git a/kinit-uni/pages/mine/setting/index.vue b/kinit-uni/pages/mine/setting/index.vue index 785cb84..75f4f6d 100644 --- a/kinit-uni/pages/mine/setting/index.vue +++ b/kinit-uni/pages/mine/setting/index.vue @@ -1,5 +1,5 @@ diff --git a/kinit-uni/pages/work/index.vue b/kinit-uni/pages/work/index.vue index 5652b27..8eddb3c 100644 --- a/kinit-uni/pages/work/index.vue +++ b/kinit-uni/pages/work/index.vue @@ -2,99 +2,92 @@ + :list="images" + indicator + indicator-mode="line" + circular + :height="`${windowWidth / 2.5}px`" + > - - - - - - - - + + + + + + + + diff --git a/kinit-uni/permission.js b/kinit-uni/permission.js index 046e0a9..73455f6 100644 --- a/kinit-uni/permission.js +++ b/kinit-uni/permission.js @@ -1,54 +1,60 @@ import { getToken } from '@/common/utils/auth' import store from '@/store' -import { RouterMount, createRouter } from 'uni-simple-router'; +import { RouterMount, createRouter } from 'uni-simple-router' + +// uni-simple-router 官方文档:https://www.hhyang.cn/v2/start/cross/codeRoute.html // 登录页面 -const loginPage = "/pages/login/login" +const loginPage = '/pages/login/login' +// 首页 +const indexPage = '/pages/index' const router = createRouter({ - platform: process.env.VUE_APP_PLATFORM, - routes: [...ROUTES] -}); + platform: process.env.VUE_APP_PLATFORM, + detectBeforeLock: (router, to, navType) => { + if (navType === 'replaceAll' && (to.path === loginPage || to.path === indexPage)) { + router.$lockStatus = false // 取消跳转锁 + } + }, + routes: [...ROUTES] // ROUTES是通过webpack的defaultPlugin编译成全局变量 +}) //全局路由前置守卫 router.beforeEach((to, from, next) => { - if (to.meta.loginAuth) { - // 如果跳转的路由需要登录权限,则验证该权限 - if (getToken()) { - if (!store.state.auth.isUser) { - store.dispatch('auth/GetInfo') - } - if (to.path === loginPage) { - next({ - path: `/pages/index`, - NAVTYPE: 'replaceAll' - }) - } - next(); - } else { - next({ - path: loginPage, - NAVTYPE: 'replaceAll' - }) - } - } else if (to.path === loginPage && getToken()) { - // 如果跳转路由为登录页面并且存在token,则跳转到首页 - next({ - path: `/pages/index`, + if (to.meta.loginAuth) { + // 如果跳转的路由需要登录权限,则验证该权限 + if (getToken()) { + if (!store.state.auth.isUser) { + store.dispatch('auth/GetInfo') + } + if (to.path === loginPage) { + next({ + path: indexPage, + NAVTYPE: 'replaceAll' + }) + } + next() + } else { + next({ + path: loginPage, + NAVTYPE: 'replaceAll' + }) + } + } else if (to.path === loginPage && getToken()) { + // 如果跳转路由为登录页面并且存在token,则跳转到首页 + next({ + path: indexPage, NAVTYPE: 'replaceAll' }) - } else { - // 不需要权限,且不是登录页面则不进行验证 - next(); - } -}); + } else { + // 不需要权限,且不是登录页面则不进行验证 + next() + } +}) // 全局路由后置守卫 router.afterEach((to, from) => { - // console.log('跳转结束') + // console.log('跳转结束') }) -export { - router, - RouterMount -} +export { router, RouterMount } diff --git a/kinit-uni/plugins/auth.js b/kinit-uni/plugins/auth.js index 3b91c14..ac9a379 100644 --- a/kinit-uni/plugins/auth.js +++ b/kinit-uni/plugins/auth.js @@ -1,10 +1,10 @@ import store from '@/store' function authPermission(permission) { - const all_permission = "*:*:*" + const all_permission = '*:*:*' const permissions = store.getters && store.getters.permissions if (permission && permission.length > 0) { - return permissions.some(v => { + return permissions.some((v) => { return all_permission === v || v === permission }) } else { @@ -13,10 +13,10 @@ function authPermission(permission) { } function authRole(role) { - const super_admin = "admin" + const super_admin = 'admin' const roles = store.getters && store.getters.roles if (role && role.length > 0) { - return roles.some(v => { + return roles.some((v) => { return super_admin === v || v === role }) } else { @@ -31,13 +31,13 @@ export default { }, // 验证用户是否含有指定权限,只需包含其中一个 hasPermiOr(permissions) { - return permissions.some(item => { + return permissions.some((item) => { return authPermission(item) }) }, // 验证用户是否含有指定权限,必须全部拥有 hasPermiAnd(permissions) { - return permissions.every(item => { + return permissions.every((item) => { return authPermission(item) }) }, @@ -47,13 +47,13 @@ export default { }, // 验证用户是否含有指定角色,只需包含其中一个 hasRoleOr(roles) { - return roles.some(item => { + return roles.some((item) => { return authRole(item) }) }, // 验证用户是否含有指定角色,必须全部拥有 hasRoleAnd(roles) { - return roles.every(item => { + return roles.every((item) => { return authRole(item) }) } diff --git a/kinit-uni/plugins/modal.js b/kinit-uni/plugins/modal.js index 87960fd..276552c 100644 --- a/kinit-uni/plugins/modal.js +++ b/kinit-uni/plugins/modal.js @@ -40,7 +40,7 @@ export default { content: content, cancelText: '取消', confirmText: '确定', - success: function(res) { + success: function (res) { if (res.confirm) { resolve(res.confirm) } @@ -50,12 +50,12 @@ export default { }, // 提示信息 showToast(option) { - if (typeof option === "object") { + if (typeof option === 'object') { uni.showToast(option) } else { uni.showToast({ title: option, - icon: "none", + icon: 'none', duration: 2500 }) } diff --git a/kinit-uni/prettier.config.js b/kinit-uni/prettier.config.js new file mode 100644 index 0000000..b46239f --- /dev/null +++ b/kinit-uni/prettier.config.js @@ -0,0 +1,19 @@ +module.exports = { + printWidth: 100, + tabWidth: 2, + useTabs: false, + semi: false, + vueIndentScriptAndStyle: false, + singleQuote: true, + quoteProps: 'as-needed', + bracketSpacing: true, + trailingComma: 'none', + jsxSingleQuote: false, + arrowParens: 'always', + insertPragma: false, + requirePragma: false, + proseWrap: 'never', + htmlWhitespaceSensitivity: 'strict', + endOfLine: 'auto', + rangeStart: 0 +} diff --git a/kinit-uni/store/getters.js b/kinit-uni/store/getters.js index e2f7769..bb529d5 100644 --- a/kinit-uni/store/getters.js +++ b/kinit-uni/store/getters.js @@ -1,26 +1,26 @@ const getters = { - isUser: state => state.auth.isUser, - isUserOpenid: state => state.auth.isUserOpenid, - isResetPassword: state => state.auth.isResetPassword, - token: state => state.auth.token, - avatar: state => state.auth.avatar, - name: state => state.auth.name, - roles: state => state.auth.roles, - permissions: state => state.auth.permissions, - telephone: state => state.auth.telephone, - - version: state => state.app.version, - title: state => state.app.title, - logo: state => state.app.logo, - logoImage: state => state.app.logoImage, - footer: state => state.app.footer, - footerContent: state => state.app.footerContent, - icpNumber: state => state.app.icpNumber, - privacy: state => state.app.privacy, - agreement: state => state.app.agreement, - siteUrl: state => state.app.siteUrl, - WXEmail: state => state.app.WXEmail, - WXPhone: state => state.app.WXPhone, - dictObj: state => state.dict.dictObj, + isUser: (state) => state.auth.isUser, + isUserOpenid: (state) => state.auth.isUserOpenid, + isResetPassword: (state) => state.auth.isResetPassword, + token: (state) => state.auth.token, + avatar: (state) => state.auth.avatar, + name: (state) => state.auth.name, + roles: (state) => state.auth.roles, + permissions: (state) => state.auth.permissions, + telephone: (state) => state.auth.telephone, + + version: (state) => state.app.version, + title: (state) => state.app.title, + logo: (state) => state.app.logo, + logoImage: (state) => state.app.logoImage, + footer: (state) => state.app.footer, + footerContent: (state) => state.app.footerContent, + icpNumber: (state) => state.app.icpNumber, + privacy: (state) => state.app.privacy, + agreement: (state) => state.app.agreement, + siteUrl: (state) => state.app.siteUrl, + WXEmail: (state) => state.app.WXEmail, + WXPhone: (state) => state.app.WXPhone, + dictObj: (state) => state.dict.dictObj } export default getters diff --git a/kinit-uni/store/index.js b/kinit-uni/store/index.js index 1e5bbb4..0388541 100644 --- a/kinit-uni/store/index.js +++ b/kinit-uni/store/index.js @@ -21,5 +21,5 @@ const store = new Vuex.Store({ modules, getters }) - -export default store \ No newline at end of file + +export default store diff --git a/kinit-uni/store/modules/app.js b/kinit-uni/store/modules/app.js index 98838af..aba61c3 100644 --- a/kinit-uni/store/modules/app.js +++ b/kinit-uni/store/modules/app.js @@ -2,76 +2,77 @@ import config from '@/config.js' import { getSystemBaseConfigApi } from '@/common/request/api/vadmin/system/settings.js' const state = { - title: "", // 标题 - logo: true, // 是否开启logo显示 - logoImage: '', // logo图片 - footer: true, // 显示页脚 - footerContent: '', // 页脚内容 - icpNumber: '', // 备案号 - version: config.appInfo.version, // 版本 - privacy: config.appInfo.privacy, // 隐私政策 - agreement: config.appInfo.agreement, // 用户协议 - siteUrl: "", // 源码地址 - WXEmail: "", // 官方邮箱 - WXPhone: "" // 服务热线 + title: '', // 标题 + logo: true, // 是否开启logo显示 + logoImage: '', // logo图片 + footer: true, // 显示页脚 + footerContent: '', // 页脚内容 + icpNumber: '', // 备案号 + version: config.appInfo.version, // 版本 + privacy: config.appInfo.privacy, // 隐私政策 + agreement: config.appInfo.agreement, // 用户协议 + siteUrl: '', // 源码地址 + WXEmail: '', // 官方邮箱 + WXPhone: '' // 服务热线 } const mutations = { - SET_TITLE: (state, title) => { - state.title = title - }, - SET_LOGO: (state, logo) => { - state.logo = logo - }, - SET_LOGO_IMAGE: (state, logoImage) => { - state.logoImage = logoImage - }, - SET_FOOTER: (state, footer) => { - state.footer = footer - }, - SET_FOOTER_CONTENT: (state, footerContent) => { - state.footerContent = footerContent - }, - SET_ICPNUMBER: (state, icpNumber) => { - state.icpNumber = icpNumber - }, - SET_VERSION: (state, version) => { - state.version = version - }, - SET_SITE_URL: (state, siteUrl) => { - state.siteUrl = siteUrl - }, - SET_WX_EMAIL: (state, WXEmail) => { - state.WXEmail = WXEmail - }, - SET_WX_PHONE: (state, WXPhone) => { - state.WXPhone = WXPhone - }, + SET_TITLE: (state, title) => { + state.title = title + }, + SET_LOGO: (state, logo) => { + state.logo = logo + }, + SET_LOGO_IMAGE: (state, logoImage) => { + state.logoImage = logoImage + }, + SET_FOOTER: (state, footer) => { + state.footer = footer + }, + SET_FOOTER_CONTENT: (state, footerContent) => { + state.footerContent = footerContent + }, + SET_ICPNUMBER: (state, icpNumber) => { + state.icpNumber = icpNumber + }, + SET_VERSION: (state, version) => { + state.version = version + }, + SET_SITE_URL: (state, siteUrl) => { + state.siteUrl = siteUrl + }, + SET_WX_EMAIL: (state, WXEmail) => { + state.WXEmail = WXEmail + }, + SET_WX_PHONE: (state, WXPhone) => { + state.WXPhone = WXPhone + } } const actions = { - // 初始化系统配置 - InitConfig({ commit }) { - return new Promise((resolve, reject) => { - getSystemBaseConfigApi().then(res => { - commit('SET_TITLE', res.data.web_title || 'Kinit') - commit('SET_LOGO_IMAGE', config.baseUrl + (res.data.web_logo || '/media/system/logo.png')) - commit('SET_FOOTER_CONTENT', res.data.web_copyright || 'Copyright ©2022-present K') - commit('SET_ICPNUMBER', res.data.web_icp_number || '') - commit('SET_SITE_URL', res.data.wx_server_site || '') - commit('SET_WX_EMAIL', res.data.wx_server_email || '') - commit('SET_WX_PHONE', res.data.wx_server_phone || '') - resolve() - }).catch(error => { - reject(error) - }) - }) - } + // 初始化系统配置 + InitConfig({ commit }) { + return new Promise((resolve, reject) => { + getSystemBaseConfigApi() + .then((res) => { + commit('SET_TITLE', res.data.web_title || 'Kinit') + commit('SET_LOGO_IMAGE', config.baseUrl + (res.data.web_logo || '/media/system/logo.png')) + commit('SET_FOOTER_CONTENT', res.data.web_copyright || 'Copyright ©2022-present K') + commit('SET_ICPNUMBER', res.data.web_icp_number || '') + commit('SET_SITE_URL', res.data.wx_server_site || '') + commit('SET_WX_EMAIL', res.data.wx_server_email || '') + commit('SET_WX_PHONE', res.data.wx_server_phone || '') + resolve() + }) + .catch((error) => { + reject(error) + }) + }) + } } - export default { - namespaced: true, // 使用命名空间去访问模块中属性,user/login + namespaced: true, // 使用命名空间去访问模块中属性,user/login state, mutations, actions diff --git a/kinit-uni/store/modules/auth.js b/kinit-uni/store/modules/auth.js index 4c0acc3..176a988 100644 --- a/kinit-uni/store/modules/auth.js +++ b/kinit-uni/store/modules/auth.js @@ -1,164 +1,192 @@ import storage from '@/common/utils/storage' import { auth } from '@/common/utils/constant' import { getInfo, wxCodeLogin, login } from '@/common/request/api/login' -import { getToken, setToken, removeToken } from '@/common/utils/auth' +import { + getToken, + setToken, + removeToken, + getRefreshToken, + setRefreshToken, + removeRefreshToken +} from '@/common/utils/auth' const state = { - token: getToken(), - isUser: storage.get(auth.isUser) || false, - isUserOpenid: storage.get(auth.isUserOpenid) || false, - isResetPassword: storage.get(auth.isResetPassword) || false, - name: storage.get(auth.name), - nickname: storage.get(auth.nickname), - gender: storage.get(auth.gender), - telephone: storage.get(auth.telephone), - avatar: storage.get(auth.avatar), - createDatetime: storage.get(auth.createDatetime), - roles: storage.get(auth.roles), - permissions: storage.get(auth.permissions) + token: getToken(), + refreshToken: getRefreshToken(), + isUser: storage.get(auth.isUser) || false, + isUserOpenid: storage.get(auth.isUserOpenid) || false, + isResetPassword: storage.get(auth.isResetPassword) || false, + name: storage.get(auth.name), + nickname: storage.get(auth.nickname), + gender: storage.get(auth.gender), + telephone: storage.get(auth.telephone), + avatar: storage.get(auth.avatar), + createDatetime: storage.get(auth.createDatetime), + roles: storage.get(auth.roles), + permissions: storage.get(auth.permissions) } const mutations = { - SET_TOKEN: (state, token) => { - state.token = token - }, - SET_IS_USER_OPENID: (state, isUserOpenid) => { - state.isUserOpenid = isUserOpenid - storage.set(auth.isUserOpenid, isUserOpenid) - }, - SET_IS_RESET_PASSWORD: (state, isResetPassword) => { - state.isResetPassword = isResetPassword - storage.set(auth.isResetPassword, isResetPassword) - }, - SET_NAME: (state, name) => { - state.name = name - storage.set(auth.name, name) - }, - SET_GENDER: (state, gender) => { - state.gender = gender - storage.set(auth.gender, gender) - }, - SET_NICKNAME: (state, nickname) => { - state.nickname = nickname - storage.set(auth.nickname, nickname) - }, - SET_CREATE_DATETIME: (state, createDatetime) => { - state.createDatetime = createDatetime - storage.set(auth.createDatetime, createDatetime) - }, - SET_AVATAR: (state, avatar) => { - state.avatar = avatar - storage.set(auth.avatar, avatar) - }, - SET_ROLES: (state, roles) => { - state.roles = roles - storage.set(auth.roles, roles) - }, - SET_PERMISSIONS: (state, permissions) => { - state.permissions = permissions - storage.set(auth.permissions, permissions) - }, - SET_TELEPHONE: (state, telephone) => { - state.telephone = telephone - storage.set(auth.telephone, telephone) - }, - SET_ISUSER: (state, isUser) => { - state.isUser = isUser - storage.set(auth.isUser, isUser) - }, + SET_TOKEN: (state, token) => { + state.token = token + }, + SET_REFRESH_TOKEN: (state, refreshToken) => { + state.refreshToken = refreshToken + setRefreshToken(refreshToken) + }, + SET_IS_USER_OPENID: (state, isUserOpenid) => { + state.isUserOpenid = isUserOpenid + storage.set(auth.isUserOpenid, isUserOpenid) + }, + SET_IS_RESET_PASSWORD: (state, isResetPassword) => { + state.isResetPassword = isResetPassword + storage.set(auth.isResetPassword, isResetPassword) + }, + SET_NAME: (state, name) => { + state.name = name + storage.set(auth.name, name) + }, + SET_GENDER: (state, gender) => { + state.gender = gender + storage.set(auth.gender, gender) + }, + SET_NICKNAME: (state, nickname) => { + state.nickname = nickname + storage.set(auth.nickname, nickname) + }, + SET_CREATE_DATETIME: (state, createDatetime) => { + state.createDatetime = createDatetime + storage.set(auth.createDatetime, createDatetime) + }, + SET_AVATAR: (state, avatar) => { + state.avatar = avatar + storage.set(auth.avatar, avatar) + }, + SET_ROLES: (state, roles) => { + state.roles = roles + storage.set(auth.roles, roles) + }, + SET_PERMISSIONS: (state, permissions) => { + state.permissions = permissions + storage.set(auth.permissions, permissions) + }, + SET_TELEPHONE: (state, telephone) => { + state.telephone = telephone + storage.set(auth.telephone, telephone) + }, + SET_ISUSER: (state, isUser) => { + state.isUser = isUser + storage.set(auth.isUser, isUser) + } } const actions = { - // 手机号密码登录 - Login({ commit }, userInfo) { - const telephone = userInfo.telephone.trim() - const password = userInfo.password - return new Promise((resolve, reject) => { - login(telephone, password).then(res => { - setToken(`${res.data.token_type} ${res.data.access_token}`) - commit('SET_TOKEN', `${res.data.token_type} ${res.data.access_token}`) - commit('SET_IS_USER_OPENID', res.data.is_wx_server_openid) - commit('SET_IS_RESET_PASSWORD', res.data.is_reset_password) - resolve(res) - }).catch(error => { - reject(error) - }) - }) - }, - - // 微信一键登录 - // 微信文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html - wxLogin({ commit }, code) { - return new Promise((resolve, reject) => { - wxCodeLogin(code).then(res => { - setToken(`${res.data.token_type} ${res.data.access_token}`) - commit('SET_TOKEN', `${res.data.token_type} ${res.data.access_token}`) - commit('SET_IS_USER_OPENID', res.data.is_wx_server_openid) - commit('SET_IS_RESET_PASSWORD', res.data.is_reset_password) - resolve(res) - }).catch(error => { - reject(error) - }) - }) - }, + // 手机号密码登录 + Login({ commit }, userInfo) { + const telephone = userInfo.telephone.trim() + const password = userInfo.password + return new Promise((resolve, reject) => { + login(telephone, password) + .then((res) => { + setToken(`${res.data.token_type} ${res.data.access_token}`) + commit('SET_TOKEN', `${res.data.token_type} ${res.data.access_token}`) + commit('SET_REFRESH_TOKEN', res.data.refresh_token) + commit('SET_IS_USER_OPENID', res.data.is_wx_server_openid) + commit('SET_IS_RESET_PASSWORD', res.data.is_reset_password) + resolve(res) + }) + .catch((error) => { + reject(error) + }) + }) + }, - // 获取用户信息 - GetInfo({ commit }) { - return new Promise((resolve, reject) => { - getInfo().then(res => { - const user = res.data - const avatar = (user == null || user.avatar == "" || user.avatar == null) ? "https://vv-reserve.oss-cn-hangzhou.aliyuncs.com/avatar/2023-01-27/1674820804e81e7631.png" : user.avatar - const name = (user == null || user.name == "" || user.name == null) ? "" : user.name - commit('SET_ROLES', user.roles.map((item) => item.name) || ['ROLE_DEFAULT']) - commit('SET_PERMISSIONS', user.permissions) - commit('SET_NAME', name) - commit('SET_NICKNAME', user.nickname) - commit('SET_GENDER', user.gender) - commit('SET_TELEPHONE', user.telephone) - commit('SET_AVATAR', avatar) - commit('SET_CREATE_DATETIME', user.create_datetime) - commit('SET_ISUSER', true) - resolve(res) - }).catch(error => { - reject(error) - }) - }) - }, - - // 更新用户基本信息 - UpdateInfo({ commit }, user) { - commit('SET_NAME', user.name) - commit('SET_NICKNAME', user.nickname) - commit('SET_GENDER', user.gender) - commit('SET_TELEPHONE', user.telephone) - }, + // 微信一键登录 + // 微信文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html + wxLogin({ commit }, code) { + return new Promise((resolve, reject) => { + wxCodeLogin(code) + .then((res) => { + setToken(`${res.data.token_type} ${res.data.access_token}`) + commit('SET_TOKEN', `${res.data.token_type} ${res.data.access_token}`) + commit('SET_REFRESH_TOKEN', res.data.refresh_token) + commit('SET_IS_USER_OPENID', res.data.is_wx_server_openid) + commit('SET_IS_RESET_PASSWORD', res.data.is_reset_password) + resolve(res) + }) + .catch((error) => { + reject(error) + }) + }) + }, - // 退出系统 - LogOut({ commit }) { - return new Promise((resolve, reject) => { - commit('SET_TOKEN', '') - commit('SET_ROLES', []) - commit('SET_PERMISSIONS', []) - commit('SET_NAME', "") - commit('SET_NICKNAME', "") - commit('SET_GENDER', "") - commit('SET_TELEPHONE', "") - commit('SET_AVATAR', "") - commit('SET_CREATE_DATETIME', "") - commit('SET_IS_USER_OPENID', false) - commit('SET_IS_RESET_PASSWORD', false) - commit('SET_ISUSER', false) - removeToken() - storage.clean() - uni.reLaunch({ url: '/pages/login/login' }) - resolve() - }) - } + // 获取用户信息 + GetInfo({ commit }) { + return new Promise((resolve, reject) => { + getInfo() + .then((res) => { + const user = res.data + const avatar = + user == null || user.avatar == '' || user.avatar == null + ? 'https://vv-reserve.oss-cn-hangzhou.aliyuncs.com/avatar/2023-01-27/1674820804e81e7631.png' + : user.avatar + const name = user == null || user.name == '' || user.name == null ? '' : user.name + commit('SET_ROLES', user.roles.map((item) => item.name) || ['ROLE_DEFAULT']) + commit('SET_PERMISSIONS', user.permissions) + commit('SET_NAME', name) + commit('SET_NICKNAME', user.nickname) + commit('SET_GENDER', user.gender) + commit('SET_TELEPHONE', user.telephone) + commit('SET_AVATAR', avatar) + commit('SET_CREATE_DATETIME', user.create_datetime) + commit('SET_ISUSER', true) + resolve(res) + }) + .catch((error) => { + reject(error) + }) + }) + }, + + // 更新用户基本信息 + UpdateInfo({ commit }, user) { + commit('SET_NAME', user.name) + commit('SET_NICKNAME', user.nickname) + commit('SET_GENDER', user.gender) + commit('SET_TELEPHONE', user.telephone) + }, + + // 退出系统 + LogOut({ commit }) { + return new Promise((resolve, reject) => { + commit('SET_TOKEN', '') + commit('SET_REFRESH_TOKEN', '') + commit('SET_ROLES', []) + commit('SET_PERMISSIONS', []) + commit('SET_NAME', '') + commit('SET_NICKNAME', '') + commit('SET_GENDER', '') + commit('SET_TELEPHONE', '') + commit('SET_AVATAR', '') + commit('SET_CREATE_DATETIME', '') + commit('SET_IS_USER_OPENID', false) + commit('SET_IS_RESET_PASSWORD', false) + commit('SET_ISUSER', false) + removeToken() + removeRefreshToken() + storage.clean() + uni.reLaunch({ + url: '/pages/login/login', + complete: () => { + resolve() + } + }) + }) + } } - export default { - namespaced: true, // 使用命名空间去访问模块中属性,user/login + namespaced: true, // 使用命名空间去访问模块中属性,user/login state, mutations, actions diff --git a/kinit-uni/store/modules/dict.js b/kinit-uni/store/modules/dict.js index e6ff574..a479e43 100644 --- a/kinit-uni/store/modules/dict.js +++ b/kinit-uni/store/modules/dict.js @@ -1,51 +1,52 @@ import { getDictTypeDetailsApi } from '@/common/request/api/vadmin/system/dict.js' const state = { - dictObj: {}, // 字典元素 + dictObj: {} // 字典元素 } const mutations = { - SET_DICT_OBJ: (state, dictObj) => { - state.dictObj = dictObj - } + SET_DICT_OBJ: (state, dictObj) => { + state.dictObj = dictObj + } } const actions = { - // 获取字典选项 - getDicts({ commit, state }, dictTypes) { - return new Promise((resolve, reject) => { - const result = {} - const addList = [] - const dictObj = JSON.parse(JSON.stringify(state.dictObj)) - for (const item of dictTypes) { - if (item in dictObj) { - result[item] = dictObj[item] - } else { - result[item] = [] - addList.push(item) - } - } - if (addList.length > 0) { - getDictTypeDetailsApi(addList).then(res => { - for (const item of addList) { - result[item] = res.data[item] - dictObj[item] = res.data[item] - } - commit('SET_DICT_OBJ', dictObj) - resolve(result) - }).catch(error => { - reject(error) - }) - } else { - resolve(result) - } - }) - } + // 获取字典选项 + getDicts({ commit, state }, dictTypes) { + return new Promise((resolve, reject) => { + const result = {} + const addList = [] + const dictObj = JSON.parse(JSON.stringify(state.dictObj)) + for (const item of dictTypes) { + if (item in dictObj) { + result[item] = dictObj[item] + } else { + result[item] = [] + addList.push(item) + } + } + if (addList.length > 0) { + getDictTypeDetailsApi(addList) + .then((res) => { + for (const item of addList) { + result[item] = res.data[item] + dictObj[item] = res.data[item] + } + commit('SET_DICT_OBJ', dictObj) + resolve(result) + }) + .catch((error) => { + reject(error) + }) + } else { + resolve(result) + } + }) + } } - export default { - namespaced: true, // 使用命名空间去访问模块中属性,user/login + namespaced: true, // 使用命名空间去访问模块中属性,user/login state, mutations, actions diff --git a/kinit-uni/vue.config.js b/kinit-uni/vue.config.js index 5c77e1e..807aa7e 100644 --- a/kinit-uni/vue.config.js +++ b/kinit-uni/vue.config.js @@ -1,26 +1,26 @@ //vue.config.js const TransformPages = require('uni-read-pages') -const {webpack} = new TransformPages() +const { webpack } = new TransformPages() module.exports = { - configureWebpack: { - plugins: [ - new webpack.DefinePlugin({ - ROUTES: webpack.DefinePlugin.runtimeValue(() => { - const tfPages = new TransformPages({ - // includes 中包含的是router会读取pages路由中的字段名 - // 后续如果有用到meta等路由信息,可以在 includes 里增加 'meta', - // 在pages路由中写对应的数据,router中就可以获取得到 - includes: ['path', 'name', 'aliasPath', 'meta'] - }); - return JSON.stringify(tfPages.routes) - }, true ) - }) - ] - }, + configureWebpack: { + plugins: [ + new webpack.DefinePlugin({ + ROUTES: webpack.DefinePlugin.runtimeValue(() => { + const tfPages = new TransformPages({ + // includes 中包含的是router会读取pages路由中的字段名 + // 后续如果有用到meta等路由信息,可以在 includes 里增加 'meta', + // 在pages路由中写对应的数据,router中就可以获取得到 + includes: ['path', 'name', 'aliasPath', 'meta'] + }) + return JSON.stringify(tfPages.routes) + }, true) + }) + ] + }, devServer: { - port: 8080, - https: false, - disableHostCheck: true // 禁止访问本地host文件 + port: 8080, + https: false, + disableHostCheck: true // 禁止访问本地host文件 } -} \ No newline at end of file +}