Merge branch 'main' of https://git.jsspisoft.com/ry-das
This commit is contained in:
commit
26699c4910
@ -4,9 +4,6 @@ ENV = 'development'
|
|||||||
# base路径
|
# base路径
|
||||||
VITE_BASE_PATH = './'
|
VITE_BASE_PATH = './'
|
||||||
|
|
||||||
# 网站是否不需要权限认证: NoAuth Auth
|
|
||||||
VITE_APP_NO_AUTH='NoAuth'
|
|
||||||
|
|
||||||
# 代理配置(开发使用),必须在一行中
|
# 代理配置(开发使用),必须在一行中
|
||||||
VITE_APP_PROXY=[["/api","https://usp2.jsspisoft.com/api"]]
|
VITE_APP_PROXY=[["/api","https://usp2.jsspisoft.com/api"]]
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
"@typescript-eslint/parser": "7.12.0",
|
"@typescript-eslint/parser": "7.12.0",
|
||||||
"@vitejs/plugin-vue": "5.0.5",
|
"@vitejs/plugin-vue": "5.0.5",
|
||||||
"async-validator": "4.2.5",
|
"async-validator": "4.2.5",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
"eslint": "8.56.0",
|
"eslint": "8.56.0",
|
||||||
"eslint-config-prettier": "9.1.0",
|
"eslint-config-prettier": "9.1.0",
|
||||||
"eslint-plugin-vue": "9.26.0",
|
"eslint-plugin-vue": "9.26.0",
|
||||||
|
@ -24,12 +24,9 @@ export function login(method: 'get' | 'post', params: object = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function logout() {
|
export function logout() {
|
||||||
const adminInfo = useAdminInfo()
|
// const adminInfo = useAdminInfo()
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/api/auth/token/revoke',
|
url: '/api/auth/token/revoke',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: {
|
|
||||||
refreshToken: adminInfo.getToken('refresh'),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* frontend common language package
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
Integral: 'Integral',
|
|
||||||
Balance: 'Balance',
|
|
||||||
Language: 'Language',
|
|
||||||
Copyright: 'Copyright',
|
|
||||||
'Member Center': 'Member Center',
|
|
||||||
'Logout login': 'Logout',
|
|
||||||
'Member center disabled': 'The member center has been disabled. Please contact the webmaster to turn it on.',
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Steve Jobs': "Great art don't have to follow the trend, it alone can lead.-- Steve Jobs",
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Change time': 'Change time',
|
|
||||||
'Current balance': 'Current balance',
|
|
||||||
'Balance after change': 'Balance after change',
|
|
||||||
'Balance change record': 'Balance change record',
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Change Password': 'Change Password',
|
|
||||||
'Old password': 'Old password',
|
|
||||||
'New password': 'New password',
|
|
||||||
'Confirm new password': 'Confirm new password',
|
|
||||||
'Please enter your current password': 'Please enter your current password',
|
|
||||||
'The duplicate password does not match the new password': 'The duplicate password does not match the new password',
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Change time': 'Change time',
|
|
||||||
'Current points': 'Current points',
|
|
||||||
'Points after change': 'Points after change',
|
|
||||||
'Score change record': 'Score change record',
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Account information': 'Account information',
|
|
||||||
'personal data': 'personal data',
|
|
||||||
'Filled in': 'Filled in',
|
|
||||||
'Not filled in': 'Not filled in',
|
|
||||||
mobile: 'mobile',
|
|
||||||
email: 'email',
|
|
||||||
'Last login IP': 'Last login IP',
|
|
||||||
'Last login': 'Last login',
|
|
||||||
'Growth statistics': 'Growth statistics',
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
export default {
|
|
||||||
'personal data': 'personal data',
|
|
||||||
'Change Password': 'Change Password',
|
|
||||||
'head portrait': 'head portrait',
|
|
||||||
'User name': 'User name',
|
|
||||||
'User nickname': 'User nickname',
|
|
||||||
mail: 'mail',
|
|
||||||
email: 'email',
|
|
||||||
'Operation via right button': 'Operation via right button',
|
|
||||||
'Click Modify': 'Click Modify',
|
|
||||||
bind: 'bind',
|
|
||||||
mobile: 'mobile',
|
|
||||||
Gender: 'Gender',
|
|
||||||
secrecy: 'secrecy',
|
|
||||||
male: 'male',
|
|
||||||
female: 'female',
|
|
||||||
birthday: 'birthday',
|
|
||||||
'Personal signature': 'Personal signature',
|
|
||||||
'Account verification': 'Account verification',
|
|
||||||
'Account password verification': 'Account password verification',
|
|
||||||
'Mail verification': 'Mail verification',
|
|
||||||
'SMS verification': 'SMS verification',
|
|
||||||
password: 'password',
|
|
||||||
accept: 'accept',
|
|
||||||
'next step': 'next step',
|
|
||||||
'New email': 'New email',
|
|
||||||
'New mobile': 'New mobile',
|
|
||||||
'Verification Code': 'Captcha',
|
|
||||||
send: 'send',
|
|
||||||
seconds: 'seconds',
|
|
||||||
nickname: 'nickname',
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
export default {
|
|
||||||
reach: ' Reach ',
|
|
||||||
login: 'Login',
|
|
||||||
register: 'Register',
|
|
||||||
'Via email': 'By email',
|
|
||||||
'Via mobile number': 'By mobile number',
|
|
||||||
'User name': 'User name',
|
|
||||||
account: 'Username/Email/Mobile',
|
|
||||||
password: 'Password',
|
|
||||||
'Verification Code': 'Captcha',
|
|
||||||
mobile: 'mobile',
|
|
||||||
email: 'email',
|
|
||||||
send: 'send',
|
|
||||||
seconds: 'seconds',
|
|
||||||
'Remember me': 'Remember me',
|
|
||||||
'Forgot your password?': 'Forgot your password?',
|
|
||||||
'Back to login': 'Back to login',
|
|
||||||
'No account yet? Click Register': 'No account yet? Click Register',
|
|
||||||
'Retrieve password': 'Retrieve password',
|
|
||||||
'Retrieval method': 'Retrieval method',
|
|
||||||
'New password': 'New password',
|
|
||||||
second: 'second',
|
|
||||||
'Account name': 'Account name',
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* 前台公共语言包
|
|
||||||
* 覆盖风险:请避免使用页面语言包的目录名、文件名作为翻译 key
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
Integral: '积分',
|
|
||||||
Balance: '余额',
|
|
||||||
Language: '语言',
|
|
||||||
Copyright: '版权所有',
|
|
||||||
'Member Center': '会员中心',
|
|
||||||
'Logout login': '注销登录',
|
|
||||||
'Member center disabled': '会员中心已禁用,请联系网站管理员开启。',
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Steve Jobs': '伟大的艺术品不必追随潮流,他本身就能引领潮流。 -- 乔布斯',
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Change time': '变更时间',
|
|
||||||
'Current balance': '当前余额',
|
|
||||||
'Balance after change': '变更后余额',
|
|
||||||
'Balance change record': '余额变更记录',
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Change Password': '修改密码',
|
|
||||||
'Old password': '旧密码',
|
|
||||||
'New password': '新密码',
|
|
||||||
'Confirm new password': '确认新密码',
|
|
||||||
'Please enter your current password': '请输入现在的密码',
|
|
||||||
'The duplicate password does not match the new password': '重复密码与新密码不相符',
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Change time': '变更时间',
|
|
||||||
'Current points': '当前积分',
|
|
||||||
'Points after change': '变更后积分',
|
|
||||||
'Score change record': '积分变更记录',
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
export default {
|
|
||||||
'Account information': '账户信息',
|
|
||||||
'personal data': '个人资料',
|
|
||||||
'Filled in': '已填写',
|
|
||||||
'Not filled in': '未填写',
|
|
||||||
mobile: '手机号',
|
|
||||||
email: '电子邮箱',
|
|
||||||
'Last login IP': '最后登录IP',
|
|
||||||
'Last login': '最后登录',
|
|
||||||
'Growth statistics': '增长统计',
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
export default {
|
|
||||||
'personal data': '个人资料',
|
|
||||||
'Change Password': '修改密码',
|
|
||||||
'head portrait': '头像',
|
|
||||||
'User name': '用户名',
|
|
||||||
'User nickname': '用户昵称',
|
|
||||||
mail: '邮箱',
|
|
||||||
email: '电子邮箱',
|
|
||||||
'Operation via right button': '通过右侧按钮操作',
|
|
||||||
'Click Modify': '点击修改',
|
|
||||||
bind: '绑定',
|
|
||||||
mobile: '手机号',
|
|
||||||
Gender: '性别',
|
|
||||||
secrecy: '保密',
|
|
||||||
male: '男',
|
|
||||||
female: '女',
|
|
||||||
birthday: '生日',
|
|
||||||
'Personal signature': '个性签名',
|
|
||||||
'Account verification': '账户验证',
|
|
||||||
'Account password verification': '账户密码验证',
|
|
||||||
'Mail verification': '邮件验证',
|
|
||||||
'SMS verification': '短信验证',
|
|
||||||
password: '密码',
|
|
||||||
accept: '接受',
|
|
||||||
'next step': '下一步',
|
|
||||||
'New email': '新邮箱',
|
|
||||||
'New mobile': '新手机号',
|
|
||||||
'Verification Code': '验证码',
|
|
||||||
send: '发送',
|
|
||||||
seconds: '秒',
|
|
||||||
nickname: '昵称',
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
export default {
|
|
||||||
reach: '到',
|
|
||||||
login: '登录',
|
|
||||||
register: '注册',
|
|
||||||
'Via email': '通过邮箱',
|
|
||||||
'Via mobile number': '通过手机号',
|
|
||||||
'User name': '用户名',
|
|
||||||
account: '用户名/邮箱/手机号',
|
|
||||||
password: '密码',
|
|
||||||
'Verification Code': '验证码',
|
|
||||||
mobile: '手机号',
|
|
||||||
email: '电子邮箱',
|
|
||||||
send: '发送',
|
|
||||||
seconds: '秒',
|
|
||||||
'Remember me': '记住我',
|
|
||||||
'Forgot your password?': '忘记密码?',
|
|
||||||
'Back to login': '回到登录',
|
|
||||||
'No account yet? Click Register': '还没有账户?点击注册',
|
|
||||||
'Retrieve password': '找回密码',
|
|
||||||
'Retrieval method': '找回方式',
|
|
||||||
'New password': '新密码',
|
|
||||||
second: '确定',
|
|
||||||
'Account name': '账户',
|
|
||||||
}
|
|
@ -160,6 +160,7 @@ const onAdminInfo = () => {
|
|||||||
|
|
||||||
const onLogout = () => {
|
const onLogout = () => {
|
||||||
logout().then(() => {
|
logout().then(() => {
|
||||||
|
debugger
|
||||||
Local.remove(ADMIN_INFO)
|
Local.remove(ADMIN_INFO)
|
||||||
router.go(0)
|
router.go(0)
|
||||||
})
|
})
|
||||||
|
@ -18,7 +18,7 @@ export const useSiteConfig = defineStore('siteConfig', {
|
|||||||
},
|
},
|
||||||
headNav: [],
|
headNav: [],
|
||||||
initialize: false,
|
initialize: false,
|
||||||
userInitialize: false,
|
userInitialize: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -8,7 +8,7 @@ import adminBaseRoute from '/@/router/static/adminBase'
|
|||||||
import { useAdminInfo } from '/@/stores/adminInfo'
|
import { useAdminInfo } from '/@/stores/adminInfo'
|
||||||
import { useConfig } from '/@/stores/config'
|
import { useConfig } from '/@/stores/config'
|
||||||
import { useUserInfo } from '/@/stores/userInfo'
|
import { useUserInfo } from '/@/stores/userInfo'
|
||||||
import { isAdminApp } from '/@/utils/common'
|
import { encrypt_aes, decrypt_aes, generateRandomNumber } from './crypto'
|
||||||
|
|
||||||
window.requests = []
|
window.requests = []
|
||||||
window.tokenRefreshing = false
|
window.tokenRefreshing = false
|
||||||
@ -50,7 +50,6 @@ function createAxios<Data = any, T = ApiPromise<Data>>(axiosConfig: AxiosRequest
|
|||||||
headers: {
|
headers: {
|
||||||
'think-lang': config.lang.defaultLang,
|
'think-lang': config.lang.defaultLang,
|
||||||
server: true,
|
server: true,
|
||||||
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
||||||
},
|
},
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
})
|
})
|
||||||
@ -59,6 +58,7 @@ function createAxios<Data = any, T = ApiPromise<Data>>(axiosConfig: AxiosRequest
|
|||||||
// if (adminBaseRoute.path != '/admin' && isAdminApp() && /^\/admin\//.test(axiosConfig.url!)) {
|
// if (adminBaseRoute.path != '/admin' && isAdminApp() && /^\/admin\//.test(axiosConfig.url!)) {
|
||||||
// axiosConfig.url = axiosConfig.url!.replace(/^\/admin\//, adminBaseRoute.path + '.php/')
|
// axiosConfig.url = axiosConfig.url!.replace(/^\/admin\//, adminBaseRoute.path + '.php/')
|
||||||
// }
|
// }
|
||||||
|
alert(axiosConfig.data)
|
||||||
|
|
||||||
// 合并默认请求选项
|
// 合并默认请求选项
|
||||||
options = Object.assign(
|
options = Object.assign(
|
||||||
@ -89,8 +89,11 @@ function createAxios<Data = any, T = ApiPromise<Data>>(axiosConfig: AxiosRequest
|
|||||||
|
|
||||||
// 自动携带token
|
// 自动携带token
|
||||||
if (config.headers) {
|
if (config.headers) {
|
||||||
|
const v = generateRandomNumber(16)
|
||||||
|
config.headers.v = v
|
||||||
const token = adminInfo.getToken()
|
const token = adminInfo.getToken()
|
||||||
if (token) (config.headers as anyObj).token = token
|
if (token) (config.headers as anyObj).token = encrypt_aes(token, v)
|
||||||
|
|
||||||
// const userToken = options.anotherToken || userInfo.getToken()
|
// const userToken = options.anotherToken || userInfo.getToken()
|
||||||
// if (userToken) (config.headers as anyObj)['token'] = userToken
|
// if (userToken) (config.headers as anyObj)['token'] = userToken
|
||||||
}
|
}
|
||||||
@ -105,76 +108,54 @@ function createAxios<Data = any, T = ApiPromise<Data>>(axiosConfig: AxiosRequest
|
|||||||
// 响应拦截
|
// 响应拦截
|
||||||
Axios.interceptors.response.use(
|
Axios.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
debugger
|
|
||||||
removePending(response.config)
|
removePending(response.config)
|
||||||
options.loading && closeLoading(options) // 关闭loading
|
options.loading && closeLoading(options) // 关闭loading
|
||||||
|
|
||||||
if (response.config.responseType == 'json') {
|
if (response.config.responseType == 'json') {
|
||||||
if (response.data && response.data.code !== 200) {
|
if (response.data && response.data.code !== 200) {
|
||||||
if (response.data.code == 409) {
|
// if (response.data.code == 409) {
|
||||||
if (!window.tokenRefreshing) {
|
// if (!window.tokenRefreshing) {
|
||||||
window.tokenRefreshing = true
|
// window.tokenRefreshing = true
|
||||||
return refreshToken()
|
// return refreshToken()
|
||||||
.then((res) => {
|
// .then((res) => {
|
||||||
if (res.data.type == 'admin-refresh') {
|
// adminInfo.setToken(res.data.token, 'auth')
|
||||||
adminInfo.setToken(res.data.token, 'auth')
|
// response.headers.token = `${res.data.token}`
|
||||||
response.headers.batoken = `${res.data.token}`
|
// window.requests.forEach((cb) => cb(res.data.token, 'admin-refresh'))
|
||||||
window.requests.forEach((cb) => cb(res.data.token, 'admin-refresh'))
|
// window.requests = []
|
||||||
} else if (res.data.type == 'user-refresh') {
|
// return Axios(response.config)
|
||||||
userInfo.setToken(res.data.token, 'auth')
|
// })
|
||||||
response.headers['ba-user-token'] = `${res.data.token}`
|
// .catch((err) => {
|
||||||
window.requests.forEach((cb) => cb(res.data.token, 'user-refresh'))
|
// adminInfo.removeToken()
|
||||||
}
|
// router.push({ name: 'adminLogin' })
|
||||||
window.requests = []
|
// return Promise.reject(err)
|
||||||
return Axios(response.config)
|
// })
|
||||||
})
|
// .finally(() => {
|
||||||
.catch((err) => {
|
// window.tokenRefreshing = false
|
||||||
adminInfo.removeToken()
|
// })
|
||||||
if (router.currentRoute.value.name != 'adminLogin') {
|
// } else {
|
||||||
router.push({ name: 'adminLogin' })
|
// return new Promise((resolve) => {
|
||||||
return Promise.reject(err)
|
// // 用函数形式将 resolve 存入,等待刷新后再执行
|
||||||
} else {
|
// window.requests.push((token: string, type: string) => {
|
||||||
response.headers.batoken = ''
|
// response.headers.token = `${token}`
|
||||||
window.requests.forEach((cb) => cb('', 'admin-refresh'))
|
// resolve(Axios(response.config))
|
||||||
window.requests = []
|
// })
|
||||||
return Axios(response.config)
|
// })
|
||||||
}
|
// }
|
||||||
})
|
// }
|
||||||
.finally(() => {
|
// if (options.showCodeMessage) {
|
||||||
window.tokenRefreshing = false
|
// ElNotification({
|
||||||
})
|
// type: 'error',
|
||||||
} else {
|
// message: response.data.msg,
|
||||||
return new Promise((resolve) => {
|
// })
|
||||||
// 用函数形式将 resolve 存入,等待刷新后再执行
|
// }
|
||||||
window.requests.push((token: string, type: string) => {
|
// // 自动跳转到路由name或path
|
||||||
if (type == 'admin-refresh') {
|
// if (response.data.code == 302) {
|
||||||
response.headers.batoken = `${token}`
|
// router.push({ path: response.data.data.routePath ?? '', name: response.data.data.routeName ?? '' })
|
||||||
} else {
|
// }
|
||||||
response.headers['ba-user-token'] = `${token}`
|
if (response.data.code == 401) {
|
||||||
}
|
|
||||||
resolve(Axios(response.config))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (options.showCodeMessage) {
|
|
||||||
ElNotification({
|
|
||||||
type: 'error',
|
|
||||||
message: response.data.msg,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 自动跳转到路由name或path
|
|
||||||
if (response.data.code == 302) {
|
|
||||||
router.push({ path: response.data.data.routePath ?? '', name: response.data.data.routeName ?? '' })
|
|
||||||
}
|
|
||||||
if (response.data.code == 303) {
|
|
||||||
let routerPath = adminBaseRoute.path
|
let routerPath = adminBaseRoute.path
|
||||||
|
userInfo.removeToken()
|
||||||
// 需要登录,清理 token,转到登录页
|
routerPath += '/login'
|
||||||
if (response.data.data.type == 'need login') {
|
|
||||||
userInfo.removeToken()
|
|
||||||
routerPath += '/login'
|
|
||||||
}
|
|
||||||
router.push({ path: routerPath })
|
router.push({ path: routerPath })
|
||||||
}
|
}
|
||||||
// code不等于1, 页面then内的具体逻辑就不执行了
|
// code不等于1, 页面then内的具体逻辑就不执行了
|
||||||
|
44
ui/dasadmin/src/utils/crypto.ts
Normal file
44
ui/dasadmin/src/utils/crypto.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import CryptoJS from 'crypto-js'
|
||||||
|
|
||||||
|
const key = ''
|
||||||
|
|
||||||
|
export function encrypt_aes(plaintText: string, iv: string) {
|
||||||
|
const encryptedData = CryptoJS.AES.encrypt(plaintText, key, {
|
||||||
|
iv,
|
||||||
|
|
||||||
|
mode: CryptoJS.mode.CBC,
|
||||||
|
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
})
|
||||||
|
|
||||||
|
const encryptedBase64Str = encryptedData.toString()
|
||||||
|
|
||||||
|
// 需要读取encryptedData上的ciphertext.toString()才能拿到跟Java一样的密文
|
||||||
|
|
||||||
|
const encryptedStr = encryptedData.ciphertext.toString()
|
||||||
|
|
||||||
|
return encryptedData.toString(CryptoJS.format.Base64)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decrypt_aes(word: string, iv: string) {
|
||||||
|
var decrypt = CryptoJS.AES.decrypt(word, key, {
|
||||||
|
iv,
|
||||||
|
mode: CryptoJS.mode.CBC,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
})
|
||||||
|
//解密后,需要按照Utf8的方式将明文转位字符串
|
||||||
|
var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
|
||||||
|
|
||||||
|
return decryptedStr
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateRandomNumber(length: number) {
|
||||||
|
// 生成一个指定长度的随机数字字符串
|
||||||
|
let result = ''
|
||||||
|
const characters = '0123456789'
|
||||||
|
const charactersLength = characters.length
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
result += characters.charAt(Math.floor(Math.random() * charactersLength))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user