Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
M
msg-middle-manage
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
张超
msg-middle-manage
Commits
5636555f
提交
5636555f
authored
4月 04, 2023
作者:
ziwencao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
build: build更新.
上级
8f396e34
隐藏空白字符变更
内嵌
并排
正在显示
30 个修改的文件
包含
837 行增加
和
830 行删除
+837
-830
.eslintrc.cjs
.eslintrc.cjs
+42
-42
.prettierrc.json
.prettierrc.json
+9
-2
cypress.config.ts
cypress.config.ts
+8
-8
example.cy.ts
cypress/e2e/example.cy.ts
+8
-8
commands.ts
cypress/support/commands.ts
+39
-39
e2e.ts
cypress/support/e2e.ts
+20
-20
env.d.ts
env.d.ts
+7
-7
index.html
index.html
+1
-1
postcss.config.js
postcss.config.js
+7
-7
index.ts
src/api/index.ts
+72
-72
user.ts
src/api/user.ts
+16
-16
index.ts
src/components/index.ts
+5
-5
SvgIcon.vue
src/components/sys/SvgIcon.vue
+23
-23
DefaultFooter.vue
src/layouts/default/components/DefaultFooter.vue
+11
-11
emitter.ts
src/libs/emitter.ts
+5
-5
index.ts
src/libs/request/index.ts
+172
-172
shims.d.ts
src/libs/request/shims.d.ts
+27
-27
baseApiUrl.ts
src/libs/utils/baseApiUrl.ts
+7
-7
baseStaticUrl.ts
src/libs/utils/baseStaticUrl.ts
+8
-8
index.ts
src/libs/utils/index.ts
+3
-3
setTitle.ts
src/libs/utils/setTitle.ts
+5
-5
[...all].vue
src/pages/[...all].vue
+21
-21
index.vue
src/pages/home/index.vue
+43
-43
index.vue
src/pages/index.vue
+1
-1
index.vue
src/pages/user/index.vue
+7
-7
index.vue
src/pages/user/login/index.vue
+76
-76
index.vue
src/pages/user/regist/index.vue
+21
-21
permission.ts
src/router/permission.ts
+54
-54
counter.ts
src/stores/counter.ts
+16
-16
user.ts
src/stores/user.ts
+103
-103
没有找到文件。
.eslintrc.cjs
浏览文件 @
5636555f
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution");
module.exports = {
root: true,
extends: [
"plugin:vue/vue3-essential",
"airbnb-base",
"eslint:recommended",
"@vue/eslint-config-typescript",
"@vue/eslint-config-prettier",
"vue-global-api",
],
overrides: [
{
files: ["cypress/e2e/**.{cy,spec}.{js,ts,jsx,tsx}"],
extends: ["plugin:cypress/recommended"],
},
],
parserOptions: {
ecmaVersion: "latest",
parser: "@typescript-eslint/parser",
sourceType: "module",
},
plugins: ["vue", "@typescript-eslint"],
rules: {
// 关闭名称校验
"vue/multi-word-component-names": "off",
"import/no-unresolved": "off",
"import/extensions": "off",
"import/no-absolute-path": "off",
"import/no-extraneous-dependencies": "off",
"vue/no-multiple-template-root": "off",
"no-param-reassign": [
"error",
{
props: true,
ignorePropertyModificationsFor: ["state", "config"],
},
],
},
};
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution");
module.exports = {
root: true,
extends: [
"plugin:vue/vue3-essential",
"airbnb-base",
"eslint:recommended",
"@vue/eslint-config-typescript",
"@vue/eslint-config-prettier",
"vue-global-api",
],
overrides: [
{
files: ["cypress/e2e/**.{cy,spec}.{js,ts,jsx,tsx}"],
extends: ["plugin:cypress/recommended"],
},
],
parserOptions: {
ecmaVersion: "latest",
parser: "@typescript-eslint/parser",
sourceType: "module",
},
plugins: ["vue", "@typescript-eslint"],
rules: {
// 关闭名称校验
"vue/multi-word-component-names": "off",
"import/no-unresolved": "off",
"import/extensions": "off",
"import/no-absolute-path": "off",
"import/no-extraneous-dependencies": "off",
"vue/no-multiple-template-root": "off",
"no-param-reassign": [
"error",
{
props: true,
ignorePropertyModificationsFor: ["state", "config"],
},
],
},
};
.prettierrc.json
浏览文件 @
5636555f
{}
\ No newline at end of file
{
"prettier/prettier"
:
[
"error"
,
{
"endOfLine"
:
"auto"
}
]
}
\ No newline at end of file
cypress.config.ts
浏览文件 @
5636555f
import
{
defineConfig
}
from
"cypress"
;
export
default
defineConfig
({
e2e
:
{
specPattern
:
"cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}"
,
baseUrl
:
"http://localhost:4173"
,
},
});
import
{
defineConfig
}
from
"cypress"
;
export
default
defineConfig
({
e2e
:
{
specPattern
:
"cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}"
,
baseUrl
:
"http://localhost:4173"
,
},
});
cypress/e2e/example.cy.ts
浏览文件 @
5636555f
// https://docs.cypress.io/api/introduction/api.html
describe
(
"My First Test"
,
()
=>
{
it
(
"visits the app root url"
,
()
=>
{
cy
.
visit
(
"/"
);
cy
.
contains
(
"h1"
,
"You did it!"
);
});
});
// https://docs.cypress.io/api/introduction/api.html
describe
(
"My First Test"
,
()
=>
{
it
(
"visits the app root url"
,
()
=>
{
cy
.
visit
(
"/"
);
cy
.
contains
(
"h1"
,
"You did it!"
);
});
});
cypress/support/commands.ts
浏览文件 @
5636555f
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
export
{};
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
export
{};
cypress/support/e2e.ts
浏览文件 @
5636555f
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import
"./commands"
;
// Alternatively you can use CommonJS syntax:
// require('./commands')
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import
"./commands"
;
// Alternatively you can use CommonJS syntax:
// require('./commands')
env.d.ts
浏览文件 @
5636555f
/// <reference types="vite/client" />
declare
module
"*.vue"
{
import
{
ComponentOptions
}
from
"vue"
;
const
componentOptions
:
ComponentOptions
;
export
default
componentOptions
;
}
/// <reference types="vite/client" />
declare
module
"*.vue"
{
import
{
ComponentOptions
}
from
"vue"
;
const
componentOptions
:
ComponentOptions
;
export
default
componentOptions
;
}
index.html
浏览文件 @
5636555f
...
...
@@ -4,7 +4,7 @@
<meta
charset=
"UTF-8"
/>
<link
rel=
"icon"
href=
"/favicon.ico"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<title>
Vite App
</title>
<title></title>
</head>
<body>
<div
id=
"app"
></div>
...
...
postcss.config.js
浏览文件 @
5636555f
// eslint-disable-next-line no-undef
module
.
exports
=
{
plugins
:
{
tailwindcss
:
{},
autoprefixer
:
{},
},
};
// eslint-disable-next-line no-undef
module
.
exports
=
{
plugins
:
{
tailwindcss
:
{},
autoprefixer
:
{},
},
};
src/api/index.ts
浏览文件 @
5636555f
import
type
{
AxiosRequestConfig
}
from
"axios"
;
import
request
,
{
useRequest
}
from
"@/libs/request"
;
type
ResponseType
<
T
>
=
{
code
:
number
;
data
:
T
;
msg
:
string
;
pageNum
:
number
;
total
:
number
;
};
export
default
function
requestAxios
()
{
return
request
<
any
>
({
method
:
"get"
,
url
:
"/api"
,
});
}
class
Ajax
{
static
get
<
T
>
(
url
:
string
,
data
:
{
[
args
:
string
]:
any
},
axiosConfig
:
AxiosRequestConfig
=
{}
)
{
return
useRequest
<
ResponseType
<
T
>>
({
method
:
"get"
,
url
,
data
,
...
axiosConfig
,
}).
content
;
}
static
post
<
T
>
(
url
:
string
,
data
:
{
[
args
:
string
]:
any
},
axiosConfig
:
AxiosRequestConfig
=
{}
)
{
return
useRequest
<
ResponseType
<
T
>>
({
method
:
"post"
,
url
,
data
,
...
axiosConfig
,
}).
content
;
}
static
put
<
T
>
(
url
:
string
,
data
:
{
[
args
:
string
]:
any
},
axiosConfig
:
AxiosRequestConfig
=
{}
)
{
return
useRequest
<
ResponseType
<
T
>>
({
method
:
"put"
,
url
,
data
,
...
axiosConfig
,
}).
content
;
}
static
delete
<
T
>
(
url
:
string
,
data
:
{
[
args
:
string
]:
any
},
axiosConfig
:
AxiosRequestConfig
=
{}
)
{
return
useRequest
<
ResponseType
<
T
>>
({
method
:
"delete"
,
url
,
data
,
...
axiosConfig
,
}).
content
;
}
}
export
const
clxAjax
=
Ajax
;
import
type
{
AxiosRequestConfig
}
from
"axios"
;
import
request
,
{
useRequest
}
from
"@/libs/request"
;
type
ResponseType
<
T
>
=
{
code
:
number
;
data
:
T
;
msg
:
string
;
pageNum
:
number
;
total
:
number
;
};
export
default
function
requestAxios
()
{
return
request
<
any
>
({
method
:
"get"
,
url
:
"/api"
,
});
}
class
Ajax
{
static
get
<
T
>
(
url
:
string
,
data
:
{
[
args
:
string
]:
any
},
axiosConfig
:
AxiosRequestConfig
=
{}
)
{
return
useRequest
<
ResponseType
<
T
>>
({
method
:
"get"
,
url
,
data
,
...
axiosConfig
,
}).
content
;
}
static
post
<
T
>
(
url
:
string
,
data
:
{
[
args
:
string
]:
any
},
axiosConfig
:
AxiosRequestConfig
=
{}
)
{
return
useRequest
<
ResponseType
<
T
>>
({
method
:
"post"
,
url
,
data
,
...
axiosConfig
,
}).
content
;
}
static
put
<
T
>
(
url
:
string
,
data
:
{
[
args
:
string
]:
any
},
axiosConfig
:
AxiosRequestConfig
=
{}
)
{
return
useRequest
<
ResponseType
<
T
>>
({
method
:
"put"
,
url
,
data
,
...
axiosConfig
,
}).
content
;
}
static
delete
<
T
>
(
url
:
string
,
data
:
{
[
args
:
string
]:
any
},
axiosConfig
:
AxiosRequestConfig
=
{}
)
{
return
useRequest
<
ResponseType
<
T
>>
({
method
:
"delete"
,
url
,
data
,
...
axiosConfig
,
}).
content
;
}
}
export
const
clxAjax
=
Ajax
;
src/api/user.ts
浏览文件 @
5636555f
import
type
{
UserInfo
}
from
"@/stores/user"
;
import
{
clxAjax
}
from
"."
;
/** 登录接口 */
export
const
loginRequset
=
()
=>
{
return
clxAjax
.
post
<
UserInfo
>
(
"user-service/owner/user/login"
,
{
captcha
:
"11"
,
mobile
:
"12222222222"
,
platform
:
6
,
pwd
:
"e10adc3949ba59abbe56e057f20f883e"
,
});
};
export
default
{
loginRequset
,
};
import
type
{
UserInfo
}
from
"@/stores/user"
;
import
{
clxAjax
}
from
"."
;
/** 登录接口 */
export
const
loginRequset
=
()
=>
{
return
clxAjax
.
post
<
UserInfo
>
(
"user-service/owner/user/login"
,
{
captcha
:
"11"
,
mobile
:
"12222222222"
,
platform
:
6
,
pwd
:
"e10adc3949ba59abbe56e057f20f883e"
,
});
};
export
default
{
loginRequset
,
};
src/components/index.ts
浏览文件 @
5636555f
import
SvgIcon
from
"@/components/sys/SvgIcon.vue"
;
export
const
components
=
[
SvgIcon
];
export
const
plugins
=
[];
import
SvgIcon
from
"@/components/sys/SvgIcon.vue"
;
export
const
components
=
[
SvgIcon
];
export
const
plugins
=
[];
src/components/sys/SvgIcon.vue
浏览文件 @
5636555f
<
script
setup
lang=
"ts"
>
import
{
computed
,
withDefaults
}
from
"vue"
;
type
SvgProps
=
{
prefix
?:
string
;
name
?:
string
;
color
?:
string
;
};
const
props
=
withDefaults
(
defineProps
<
SvgProps
>
(),
{
prefix
:
"icon"
,
name
:
""
,
color
:
"#000"
,
});
const
symbolId
=
computed
(()
=>
`#
${
props
.
prefix
}
-
${
props
.
name
}
`
);
</
script
>
<
template
>
<svg
aria-hidden=
"true"
>
<use
:xlink:href=
"symbolId"
:fill=
"color"
/>
</svg>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
withDefaults
}
from
"vue"
;
type
SvgProps
=
{
prefix
?:
string
;
name
?:
string
;
color
?:
string
;
};
const
props
=
withDefaults
(
defineProps
<
SvgProps
>
(),
{
prefix
:
"icon"
,
name
:
""
,
color
:
"#000"
,
});
const
symbolId
=
computed
(()
=>
`#
${
props
.
prefix
}
-
${
props
.
name
}
`
);
</
script
>
<
template
>
<svg
aria-hidden=
"true"
>
<use
:xlink:href=
"symbolId"
:fill=
"color"
/>
</svg>
</
template
>
src/layouts/default/components/DefaultFooter.vue
浏览文件 @
5636555f
<
template
>
<footer>
底部
</footer>
</
template
>
<
script
lang=
"ts"
setup
name=
"DefaultFooter"
></
script
>
<
style
scoped
>
footer
{
background-color
:
antiquewhite
;
}
</
style
>
<
template
>
<footer>
底部
</footer>
</
template
>
<
script
lang=
"ts"
setup
name=
"DefaultFooter"
></
script
>
<
style
scoped
>
footer
{
background-color
:
antiquewhite
;
}
</
style
>
src/libs/emitter.ts
浏览文件 @
5636555f
import
mitt
,
{
type
Emitter
}
from
"mitt"
;
const
emitter
:
Emitter
<
any
>
=
mitt
();
export
default
emitter
;
import
mitt
,
{
type
Emitter
}
from
"mitt"
;
const
emitter
:
Emitter
<
any
>
=
mitt
();
export
default
emitter
;
src/libs/request/index.ts
浏览文件 @
5636555f
import
{
ref
,
type
Ref
}
from
"vue"
;
import
axios
,
{
AxiosError
,
type
AxiosResponse
,
type
AxiosRequestConfig
,
}
from
"axios"
;
import
storage
from
"store"
;
// import { ElMessage } from "element-plus";
import
{
useUserStore
,
USER_INFO
,
type
UserInfo
}
from
"@/stores/user"
;
const
{
VITE_APP_BASE_URL
}
=
import
.
meta
.
env
;
const
request
=
axios
.
create
({
// API 请求的默认前缀
baseURL
:
VITE_APP_BASE_URL
as
string
,
timeout
:
10000
,
// 请求超时时间
});
// 异常拦截处理器
const
errorHandler
=
(
error
:
AxiosError
)
=>
{
const
status
=
error
.
response
?.
status
;
const
useStore
=
useUserStore
();
switch
(
status
)
{
/* eslint-disable no-param-reassign */
case
400
:
error
.
message
=
"请求错误"
;
break
;
case
401
:
useStore
.
logout
();
error
.
message
=
"未授权,请登录"
;
break
;
case
403
:
error
.
message
=
"拒绝访问"
;
break
;
case
404
:
error
.
message
=
`请求地址出错:
${
error
.
response
?.
config
.
url
}
`;
break;
case 408:
error.message = "请求超时";
break;
case 500:
error.message = "服务器内部错误";
break;
case 501:
error.message = "服务未实现";
break;
case 502:
error.message = "网关错误";
break;
case 503:
error.message = "服务不可用";
break;
case 504:
error.message = "网关超时";
break;
case 505:
error.message = "HTTP版本不受支持";
break;
default:
break;
}
return Promise.reject(error);
};
request.interceptors.request.use((config) => {
// 如果 token 存在
// 让每个请求携带自定义 token 请根据实际情况自行修改
// config.headers.Authorization = `
Bearer
$
{
storage
.
get
(
ACCESS_TOKEN
)}
`;
const userInfo = (storage.get(USER_INFO) as UserInfo) || {};
config.headers = {
...config.headers,
Authorization: `
Bearer
$
{
userInfo
?.
accessToken
}
`,
userId: userInfo?.userId,
childId: userInfo?.childId,
userMin: "vip",
accessToken: userInfo?.accessToken,
};
return config;
}, errorHandler);
// response interceptor
request.interceptors.response.use((response: AxiosResponse) => {
const dataAxios = response.data;
const useStore = useUserStore();
// 这个状态码是和后端约定的
const { code, msg } = dataAxios;
// 根据 code 进行判断
if (code === undefined) {
// 如果没有 code 代表这不是项目后端开发的接口
return dataAxios;
}
// 有 code 代表这是一个后端接口 可以进行进一步的判断
// if (code) ElMessage.error(msg);
if (code) alert(msg);
switch (code) {
case 0:
// code === 0 代表没有错误
return dataAxios;
case 1:
// code === 1 代表请求错误
throw Error(msg);
case 401:
useStore.logout();
throw Error(msg);
default:
// 不是正确的 code
return dataAxios;
}
}, errorHandler);
export default request;
export interface RequestConfig {
successMessage?: string;
errorMessage?: string;
/** 立即发送请求 */
immediate?: boolean;
}
export function useRequest<T>(
axiosConfig: AxiosRequestConfig,
requestConfig?: RequestConfig
) {
// 最终返回的数据
const data = ref<T>();
// 请求失败返回的 Error 对象
const error = ref<Error>();
// 请求状态
const loading = ref(false);
// 立即发送请求
const immediate = requestConfig?.immediate !== false;
// 终止请求
const { CancelToken } = axios;
const { token, cancel } = CancelToken.source();
// 合并求情配置
const config = { ...axiosConfig, cancelToken: token };
// 请求 Promise
function run() {
loading.value = true;
return new Promise<Ref<T | undefined>>((resolve, reject) => {
request<T>(config)
.then((res: T) => {
data.value = res;
resolve(data);
})
.catch((err: Error) => {
error.value = err;
reject(err);
if (requestConfig?.errorMessage) {
throw Error(requestConfig.errorMessage);
}
})
.finally(() => {
loading.value = false;
});
});
}
const content = new Promise<Ref<T | undefined>>((resolve, reject) => {
if (immediate) {
run()
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
}
});
return { data, error, loading, content, run, cancel };
}
import
{
ref
,
type
Ref
}
from
"vue"
;
import
axios
,
{
AxiosError
,
type
AxiosResponse
,
type
AxiosRequestConfig
,
}
from
"axios"
;
import
storage
from
"store"
;
// import { ElMessage } from "element-plus";
import
{
useUserStore
,
USER_INFO
,
type
UserInfo
}
from
"@/stores/user"
;
const
{
VITE_APP_BASE_URL
}
=
import
.
meta
.
env
;
const
request
=
axios
.
create
({
// API 请求的默认前缀
baseURL
:
VITE_APP_BASE_URL
as
string
,
timeout
:
10000
,
// 请求超时时间
});
// 异常拦截处理器
const
errorHandler
=
(
error
:
AxiosError
)
=>
{
const
status
=
error
.
response
?.
status
;
const
useStore
=
useUserStore
();
switch
(
status
)
{
/* eslint-disable no-param-reassign */
case
400
:
error
.
message
=
"请求错误"
;
break
;
case
401
:
useStore
.
logout
();
error
.
message
=
"未授权,请登录"
;
break
;
case
403
:
error
.
message
=
"拒绝访问"
;
break
;
case
404
:
error
.
message
=
`请求地址出错:
${
error
.
response
?.
config
.
url
}
`;
break;
case 408:
error.message = "请求超时";
break;
case 500:
error.message = "服务器内部错误";
break;
case 501:
error.message = "服务未实现";
break;
case 502:
error.message = "网关错误";
break;
case 503:
error.message = "服务不可用";
break;
case 504:
error.message = "网关超时";
break;
case 505:
error.message = "HTTP版本不受支持";
break;
default:
break;
}
return Promise.reject(error);
};
request.interceptors.request.use((config) => {
// 如果 token 存在
// 让每个请求携带自定义 token 请根据实际情况自行修改
// config.headers.Authorization = `
Bearer
$
{
storage
.
get
(
ACCESS_TOKEN
)}
`;
const userInfo = (storage.get(USER_INFO) as UserInfo) || {};
config.headers = {
...config.headers,
Authorization: `
Bearer
$
{
userInfo
?.
accessToken
}
`,
userId: userInfo?.userId,
childId: userInfo?.childId,
userMin: "vip",
accessToken: userInfo?.accessToken,
};
return config;
}, errorHandler);
// response interceptor
request.interceptors.response.use((response: AxiosResponse) => {
const dataAxios = response.data;
const useStore = useUserStore();
// 这个状态码是和后端约定的
const { code, msg } = dataAxios;
// 根据 code 进行判断
if (code === undefined) {
// 如果没有 code 代表这不是项目后端开发的接口
return dataAxios;
}
// 有 code 代表这是一个后端接口 可以进行进一步的判断
// if (code) ElMessage.error(msg);
if (code) alert(msg);
switch (code) {
case 0:
// code === 0 代表没有错误
return dataAxios;
case 1:
// code === 1 代表请求错误
throw Error(msg);
case 401:
useStore.logout();
throw Error(msg);
default:
// 不是正确的 code
return dataAxios;
}
}, errorHandler);
export default request;
export interface RequestConfig {
successMessage?: string;
errorMessage?: string;
/** 立即发送请求 */
immediate?: boolean;
}
export function useRequest<T>(
axiosConfig: AxiosRequestConfig,
requestConfig?: RequestConfig
) {
// 最终返回的数据
const data = ref<T>();
// 请求失败返回的 Error 对象
const error = ref<Error>();
// 请求状态
const loading = ref(false);
// 立即发送请求
const immediate = requestConfig?.immediate !== false;
// 终止请求
const { CancelToken } = axios;
const { token, cancel } = CancelToken.source();
// 合并求情配置
const config = { ...axiosConfig, cancelToken: token };
// 请求 Promise
function run() {
loading.value = true;
return new Promise<Ref<T | undefined>>((resolve, reject) => {
request<T>(config)
.then((res: T) => {
data.value = res;
resolve(data);
})
.catch((err: Error) => {
error.value = err;
reject(err);
if (requestConfig?.errorMessage) {
throw Error(requestConfig.errorMessage);
}
})
.finally(() => {
loading.value = false;
});
});
}
const content = new Promise<Ref<T | undefined>>((resolve, reject) => {
if (immediate) {
run()
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
}
});
return { data, error, loading, content, run, cancel };
}
src/libs/request/shims.d.ts
浏览文件 @
5636555f
import
{
AxiosRequestConfig
}
from
"axios"
;
declare
module
"axios"
{
export
interface
AxiosInstance
{
/* eslint-disable no-unused-vars */
<
T
=
any
>
(
config
:
AxiosRequestConfig
):
Promise
<
T
>
;
request
<
T
=
any
>
(
config
:
AxiosRequestConfig
):
Promise
<
T
>
;
get
<
T
=
any
>
(
url
:
string
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
delete
<
T
=
any
>
(
url
:
string
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
head
<
T
=
any
>
(
url
:
string
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
post
<
T
=
any
>
(
url
:
string
,
data
?:
any
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
put
<
T
=
any
>
(
url
:
string
,
data
?:
any
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
patch
<
T
=
any
>
(
url
:
string
,
data
?:
any
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
}
}
import
{
AxiosRequestConfig
}
from
"axios"
;
declare
module
"axios"
{
export
interface
AxiosInstance
{
/* eslint-disable no-unused-vars */
<
T
=
any
>
(
config
:
AxiosRequestConfig
):
Promise
<
T
>
;
request
<
T
=
any
>
(
config
:
AxiosRequestConfig
):
Promise
<
T
>
;
get
<
T
=
any
>
(
url
:
string
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
delete
<
T
=
any
>
(
url
:
string
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
head
<
T
=
any
>
(
url
:
string
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
post
<
T
=
any
>
(
url
:
string
,
data
?:
any
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
put
<
T
=
any
>
(
url
:
string
,
data
?:
any
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
patch
<
T
=
any
>
(
url
:
string
,
data
?:
any
,
config
?:
AxiosRequestConfig
):
Promise
<
T
>
;
}
}
src/libs/utils/baseApiUrl.ts
浏览文件 @
5636555f
export
default
function
baseApiUrl
(
port
?:
number
)
{
const
{
VITE_APP_BASE_URL
}
=
import
.
meta
.
env
;
if
(
port
)
{
return
`
${
VITE_APP_BASE_URL
}
:
${
port
}
`
;
}
return
VITE_APP_BASE_URL
;
}
export
default
function
baseApiUrl
(
port
?:
number
)
{
const
{
VITE_APP_BASE_URL
}
=
import
.
meta
.
env
;
if
(
port
)
{
return
`
${
VITE_APP_BASE_URL
}
:
${
port
}
`
;
}
return
VITE_APP_BASE_URL
;
}
src/libs/utils/baseStaticUrl.ts
浏览文件 @
5636555f
// 处理静态资源链接
export
default
function
baseStaticUrl
(
src
=
""
)
{
const
{
VITE_APP_STATIC_URL
}
=
import
.
meta
.
env
;
if
(
src
)
{
return
`
${
VITE_APP_STATIC_URL
}${
src
}
`
;
}
return
VITE_APP_STATIC_URL
as
string
;
}
// 处理静态资源链接
export
default
function
baseStaticUrl
(
src
=
""
)
{
const
{
VITE_APP_STATIC_URL
}
=
import
.
meta
.
env
;
if
(
src
)
{
return
`
${
VITE_APP_STATIC_URL
}${
src
}
`
;
}
return
VITE_APP_STATIC_URL
as
string
;
}
src/libs/utils/index.ts
浏览文件 @
5636555f
export
{
default
as
baseStaticUrl
}
from
"./baseStaticUrl"
;
export
{
default
as
baseApiUrl
}
from
"./baseApiUrl"
;
export
{
default
as
setTitle
}
from
"./setTitle"
;
export
{
default
as
baseStaticUrl
}
from
"./baseStaticUrl"
;
export
{
default
as
baseApiUrl
}
from
"./baseApiUrl"
;
export
{
default
as
setTitle
}
from
"./setTitle"
;
src/libs/utils/setTitle.ts
浏览文件 @
5636555f
export
default
function
setTitle
(
title
?:
string
)
{
const
{
VITE_APP_TITLE
}
=
import
.
meta
.
env
;
const
processTitle
=
VITE_APP_TITLE
||
"CLX"
;
window
.
document
.
title
=
`
${
title
?
`
${
title
}
| `
:
""
}
${
processTitle
}
`
;
}
export
default
function
setTitle
(
title
?:
string
)
{
const
{
VITE_APP_TITLE
}
=
import
.
meta
.
env
;
const
processTitle
=
VITE_APP_TITLE
||
"CLX"
;
window
.
document
.
title
=
`
${
title
?
`
${
title
}
| `
:
""
}
${
processTitle
}
`
;
}
src/pages/[...all].vue
浏览文件 @
5636555f
<
script
lang=
"ts"
setup
name=
"404"
>
import
{
ref
}
from
"vue"
;
import
router
from
"@/router"
;
const
countdown
=
ref
(
3
);
const
countdownInterval
=
setInterval
(()
=>
{
countdown
.
value
-=
1
;
if
(
countdown
.
value
===
0
)
{
router
.
push
(
"/"
);
clearInterval
(
countdownInterval
);
}
},
1000
);
</
script
>
<
template
>
<div
class=
"h-screen flex flex-col justify-center items-center"
>
<h1
class=
"text-3xl"
>
404
</h1>
<p>
{{
countdown
}}
seconds after the jump...
</p>
</div>
</
template
>
<
script
lang=
"ts"
setup
name=
"404"
>
import
{
ref
}
from
"vue"
;
import
router
from
"@/router"
;
const
countdown
=
ref
(
3
);
const
countdownInterval
=
setInterval
(()
=>
{
countdown
.
value
-=
1
;
if
(
countdown
.
value
===
0
)
{
router
.
push
(
"/"
);
clearInterval
(
countdownInterval
);
}
},
1000
);
</
script
>
<
template
>
<div
class=
"h-screen flex flex-col justify-center items-center"
>
<h1
class=
"text-3xl"
>
404
</h1>
<p>
{{
countdown
}}
seconds after the jump...
</p>
</div>
</
template
>
src/pages/home/index.vue
浏览文件 @
5636555f
<route
lang=
"yaml"
>
name: home
meta:
auth: true
</route>
<
script
lang=
"ts"
setup
name=
"PageHome"
>
import
{
useRouter
}
from
"vue-router"
;
const
router
=
useRouter
();
function
regist
()
{
router
.
push
({
path
:
"/user/regist"
,
query
:
{
id
:
123
,
},
});
}
</
script
>
<
template
>
<div>
<div
class=
"page-example"
>
home
</div>
<router-link
to=
"/user/login"
><button>
登錄
</button></router-link>
<button
type=
"primary"
@
click=
"regist()"
>
注册
</button>
<div
class=
"p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4"
>
<div
class=
"flex-shrink-0"
>
<svg-icon
class=
"h-12 w-12"
name=
"tooling"
></svg-icon>
</div>
<div>
<div
class=
"text-xl font-medium text-black"
>
ChitChat
</div>
<p
class=
"text-gray-500"
>
You have a new message!
</p>
</div>
</div>
</div>
</
template
>
<
style
scoped
>
.login-icon
{
width
:
20px
;
height
:
20px
;
}
</
style
>
<route
lang=
"yaml"
>
name: home
meta:
auth: true
</route>
<
script
lang=
"ts"
setup
name=
"PageHome"
>
import
{
useRouter
}
from
"vue-router"
;
const
router
=
useRouter
();
function
regist
()
{
router
.
push
({
path
:
"/user/regist"
,
query
:
{
id
:
123
,
},
});
}
</
script
>
<
template
>
<div>
<div
class=
"page-example"
>
home
</div>
<router-link
to=
"/user/login"
><button>
登錄
</button></router-link>
<button
type=
"primary"
@
click=
"regist()"
>
注册
</button>
<div
class=
"p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4"
>
<div
class=
"flex-shrink-0"
>
<svg-icon
class=
"h-12 w-12"
name=
"tooling"
></svg-icon>
</div>
<div>
<div
class=
"text-xl font-medium text-black"
>
ChitChat
</div>
<p
class=
"text-gray-500"
>
You have a new message!
</p>
</div>
</div>
</div>
</
template
>
<
style
scoped
>
.login-icon
{
width
:
20px
;
height
:
20px
;
}
</
style
>
src/pages/index.vue
浏览文件 @
5636555f
...
...
@@ -2,4 +2,4 @@
redirect:
name: home
</route>
<
template
></
template
>
<
!-- <template></template> --
>
src/pages/user/index.vue
浏览文件 @
5636555f
<route
lang=
"yaml"
>
name: user
meta:
auth: false
title: 用户
layout: BlankLayout
</route>
<route
lang=
"yaml"
>
name: user
meta:
auth: false
title: 用户
layout: BlankLayout
</route>
src/pages/user/login/index.vue
浏览文件 @
5636555f
<route
lang=
"yaml"
>
name: login
meta:
auth: false
title: 登录
layout: BlankLayout
</route>
<
template
>
<div>
<div
class=
"page-example"
>
login
</div>
<div
class=
"p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4"
>
<div
class=
"flex-shrink-0"
>
<svg-icon
class=
"h-12 w-12"
name=
"tooling"
></svg-icon>
</div>
<div>
<div
class=
"text-xl font-medium text-black"
>
<button
type=
"link"
@
click=
"login()"
>
登錄
</button>
</div>
<p
class=
"text-gray-500"
>
点击登录!
</p>
</div>
</div>
</div>
</
template
>
<
script
lang=
"ts"
setup
name=
"PageLogin"
>
import
{
useRoute
,
useRouter
}
from
"vue-router"
;
// import { ElMessage } from "element-plus";
import
{
loginRequset
}
from
"@/api/user"
;
import
{
useUserStore
}
from
"@/stores/user"
;
import
{
baseStaticUrl
}
from
"@/libs/utils"
;
const
router
=
useRouter
();
const
route
=
useRoute
();
function
GetRequest
(
urlStr
:
string
)
{
if
(
!
urlStr
.
includes
(
"?"
))
return
{};
const
url
=
urlStr
.
split
(
"?"
)[
1
].
split
(
"&"
);
// 获取url中"?"符后的字串
const
query
:
{
[
args
:
string
]:
any
}
=
{};
url
.
forEach
((
item
:
string
)
=>
{
query
[
item
.
split
(
"="
)[
0
]]
=
decodeURIComponent
(
item
.
split
(
"="
)[
1
]);
// 转码
});
return
query
;
}
console
.
log
(
import
.
meta
.
env
);
function
login
()
{
loginRequset
()
.
then
((
res
)
=>
{
console
.
log
(
res
);
const
data
=
res
?.
value
?.
data
;
if
(
!
data
)
return
;
const
user
=
useUserStore
();
user
.
setUserInfo
({
...
data
,
});
const
queryRedirect
=
route
.
query
?.
redirect
as
string
;
router
.
push
({
path
:
queryRedirect
||
"/"
,
query
:
GetRequest
(
queryRedirect
||
""
),
});
})
.
catch
((
error
)
=>
{
// ElMessage.error(error);
alert
(
error
);
});
}
</
script
>
<
style
scoped
>
.login-icon
{
width
:
20px
;
height
:
20px
;
}
</
style
>
<route
lang=
"yaml"
>
name: login
meta:
auth: false
title: 登录
layout: BlankLayout
</route>
<
template
>
<div>
<div
class=
"page-example"
>
login
</div>
<div
class=
"p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4"
>
<div
class=
"flex-shrink-0"
>
<svg-icon
class=
"h-12 w-12"
name=
"tooling"
></svg-icon>
</div>
<div>
<div
class=
"text-xl font-medium text-black"
>
<button
type=
"link"
@
click=
"login()"
>
登錄
</button>
</div>
<p
class=
"text-gray-500"
>
点击登录!
</p>
</div>
</div>
</div>
</
template
>
<
script
lang=
"ts"
setup
name=
"PageLogin"
>
import
{
useRoute
,
useRouter
}
from
"vue-router"
;
// import { ElMessage } from "element-plus";
import
{
loginRequset
}
from
"@/api/user"
;
import
{
useUserStore
}
from
"@/stores/user"
;
import
{
baseStaticUrl
}
from
"@/libs/utils"
;
const
router
=
useRouter
();
const
route
=
useRoute
();
function
GetRequest
(
urlStr
:
string
)
{
if
(
!
urlStr
.
includes
(
"?"
))
return
{};
const
url
=
urlStr
.
split
(
"?"
)[
1
].
split
(
"&"
);
// 获取url中"?"符后的字串
const
query
:
{
[
args
:
string
]:
any
}
=
{};
url
.
forEach
((
item
:
string
)
=>
{
query
[
item
.
split
(
"="
)[
0
]]
=
decodeURIComponent
(
item
.
split
(
"="
)[
1
]);
// 转码
});
return
query
;
}
console
.
log
(
import
.
meta
.
env
);
function
login
()
{
loginRequset
()
.
then
((
res
)
=>
{
console
.
log
(
res
);
const
data
=
res
?.
value
?.
data
;
if
(
!
data
)
return
;
const
user
=
useUserStore
();
user
.
setUserInfo
({
...
data
,
});
const
queryRedirect
=
route
.
query
?.
redirect
as
string
;
router
.
push
({
path
:
queryRedirect
||
"/"
,
query
:
GetRequest
(
queryRedirect
||
""
),
});
})
.
catch
((
error
)
=>
{
// ElMessage.error(error);
alert
(
error
);
});
}
</
script
>
<
style
scoped
>
.login-icon
{
width
:
20px
;
height
:
20px
;
}
</
style
>
src/pages/user/regist/index.vue
浏览文件 @
5636555f
<route
lang=
"yaml"
>
name: regist
meta:
auth: true
title: 注册
layout: BlankLayout
</route>
<
script
lang=
"ts"
setup
name=
"PageRegist"
>
import
{
useRoute
}
from
"vue-router"
;
const
route
=
useRoute
();
console
.
log
(
route
.
query
);
</
script
>
<
template
>
<div>
<div
class=
"page-example"
>
注册
</div>
</div>
</
template
>
<
style
scoped
></
style
>
<route
lang=
"yaml"
>
name: regist
meta:
auth: true
title: 注册
layout: BlankLayout
</route>
<
script
lang=
"ts"
setup
name=
"PageRegist"
>
import
{
useRoute
}
from
"vue-router"
;
const
route
=
useRoute
();
console
.
log
(
route
.
query
);
</
script
>
<
template
>
<div>
<div
class=
"page-example"
>
注册
</div>
</div>
</
template
>
<
style
scoped
></
style
>
src/router/permission.ts
浏览文件 @
5636555f
import
storage
from
"store"
;
import
NProgress
from
"nprogress"
;
import
router
from
"@/router"
;
import
{
USER_INFO
,
useUserStore
,
type
UserInfo
}
from
"@/stores/user"
;
import
{
setTitle
}
from
"@/libs/utils"
;
// 进度条
import
"nprogress/nprogress.css"
;
const
loginRoutePath
=
"/user/login"
;
const
defaultRoutePath
=
"/home"
;
/**
* 路由拦截
* 权限验证
*/
router
.
beforeEach
(
async
(
to
,
from
,
next
)
=>
{
const
userStore
=
useUserStore
();
const
userInfo
=
(
storage
.
get
(
USER_INFO
)
as
UserInfo
)
||
{};
const
token
=
userInfo
?.
accessToken
;
// 进度条
NProgress
.
start
();
// 验证当前路由所有的匹配中是否需要有登录验证的
if
(
to
.
matched
.
some
((
r
)
=>
r
.
meta
.
auth
))
{
// 是否存有token作为验证是否登录的条件
if
(
token
&&
token
!==
"undefined"
)
{
if
(
to
.
path
===
loginRoutePath
)
{
next
({
path
:
defaultRoutePath
});
}
else
{
next
();
}
}
else
{
// 没有登录的时候跳转到登录界面
// 携带上登录成功之后需要跳转的页面完整路径
next
({
name
:
"login"
,
query
:
{
redirect
:
to
.
fullPath
,
},
});
NProgress
.
done
();
}
}
else
{
// 不需要身份校验 直接通过
next
();
}
});
router
.
afterEach
((
to
)
=>
{
// 进度条
NProgress
.
done
();
setTitle
(
to
.
meta
.
title
as
string
);
});
import
storage
from
"store"
;
import
NProgress
from
"nprogress"
;
import
router
from
"@/router"
;
import
{
USER_INFO
,
useUserStore
,
type
UserInfo
}
from
"@/stores/user"
;
import
{
setTitle
}
from
"@/libs/utils"
;
// 进度条
import
"nprogress/nprogress.css"
;
const
loginRoutePath
=
"/user/login"
;
const
defaultRoutePath
=
"/home"
;
/**
* 路由拦截
* 权限验证
*/
router
.
beforeEach
(
async
(
to
,
from
,
next
)
=>
{
const
userStore
=
useUserStore
();
const
userInfo
=
(
storage
.
get
(
USER_INFO
)
as
UserInfo
)
||
{};
const
token
=
userInfo
?.
accessToken
;
// 进度条
NProgress
.
start
();
// 验证当前路由所有的匹配中是否需要有登录验证的
if
(
to
.
matched
.
some
((
r
)
=>
r
.
meta
.
auth
))
{
// 是否存有token作为验证是否登录的条件
if
(
token
&&
token
!==
"undefined"
)
{
if
(
to
.
path
===
loginRoutePath
)
{
next
({
path
:
defaultRoutePath
});
}
else
{
next
();
}
}
else
{
// 没有登录的时候跳转到登录界面
// 携带上登录成功之后需要跳转的页面完整路径
next
({
name
:
"login"
,
query
:
{
redirect
:
to
.
fullPath
,
},
});
NProgress
.
done
();
}
}
else
{
// 不需要身份校验 直接通过
next
();
}
});
router
.
afterEach
((
to
)
=>
{
// 进度条
NProgress
.
done
();
setTitle
(
to
.
meta
.
title
as
string
);
});
src/stores/counter.ts
浏览文件 @
5636555f
import
{
ref
,
computed
}
from
"vue"
;
import
{
defineStore
}
from
"pinia"
;
export
const
useCounterStore
=
defineStore
(
"counter"
,
()
=>
{
const
count
=
ref
(
0
);
const
doubleCount
=
computed
(()
=>
count
.
value
*
2
);
function
increment
()
{
count
.
value
+=
1
;
}
return
{
count
,
doubleCount
,
increment
};
});
export
default
{
useCounterStore
,
};
import
{
ref
,
computed
}
from
"vue"
;
import
{
defineStore
}
from
"pinia"
;
export
const
useCounterStore
=
defineStore
(
"counter"
,
()
=>
{
const
count
=
ref
(
0
);
const
doubleCount
=
computed
(()
=>
count
.
value
*
2
);
function
increment
()
{
count
.
value
+=
1
;
}
return
{
count
,
doubleCount
,
increment
};
});
export
default
{
useCounterStore
,
};
src/stores/user.ts
浏览文件 @
5636555f
import
{
defineStore
}
from
"pinia"
;
import
storage
from
"store"
;
import
UaParser
from
"ua-parser-js"
;
import
type
{
IResult
as
UaResult
}
from
"ua-parser-js"
;
import
router
from
"@/router"
;
/**
* 用户信息-类型
*/
export
interface
UserInfo
{
accessToken
:
string
;
authed
:
number
;
childId
:
number
;
company
:
string
;
domain
:
string
;
equipmentFlag
:
number
;
headImg
:
string
;
logo
:
string
;
mobile
:
string
;
name
:
string
;
openid
:
string
;
placeId
:
number
;
placeName
:
string
;
role
:
number
;
shortName
:
string
;
tradeAuth
:
number
;
truckNo
:
number
;
userId
:
number
;
walletCode
:
number
;
}
export
interface
UserState
{
userInfo
:
UserInfo
;
ua
:
UaResult
;
}
/** userInfo 存储信息 字段名 */
export
const
USER_INFO
:
"USER_INFO"
=
"USER_INFO"
;
/** token 字段名 */
export
const
ACCESS_TOKEN
:
"accessToken"
=
"accessToken"
;
/** userId 字段名 */
export
const
USER_ID
:
"userId"
=
"userId"
;
const
defaultUserInfo
=
{
accessToken
:
""
,
authed
:
0
,
childId
:
0
,
company
:
""
,
domain
:
""
,
equipmentFlag
:
0
,
headImg
:
""
,
logo
:
""
,
mobile
:
""
,
name
:
""
,
openid
:
""
,
placeId
:
0
,
placeName
:
""
,
role
:
0
,
shortName
:
""
,
tradeAuth
:
0
,
truckNo
:
0
,
userId
:
0
,
walletCode
:
0
,
};
export
const
useUserStore
=
defineStore
({
id
:
"clxUser"
,
state
:
():
UserState
=>
({
userInfo
:
{
...
defaultUserInfo
},
ua
:
new
UaParser
().
getResult
(),
}),
actions
:
{
setUserInfo
(
payload
:
UserInfo
)
{
this
.
userInfo
=
payload
;
storage
.
set
(
USER_INFO
,
this
.
userInfo
||
{});
},
resetUserInfo
()
{
this
.
userInfo
=
{
...
defaultUserInfo
};
},
async
getUserInfo
()
{
const
userInfo
=
(
storage
.
get
(
USER_INFO
)
as
UserInfo
)
||
{};
const
userID
=
userInfo
?.
userId
;
if
(
!
userID
)
{
// 异步调用查询用户信息接口
}
},
async
login
()
{
// 调用登陆接口
// this.setUserInfo(payload);
// router.push({ path: '/' });
},
async
logout
()
{
// 调用退出登陆接口
this
.
resetUserInfo
();
router
.
push
({
name
:
"login"
});
},
async
verification
(
token
:
string
)
{
// 调用 token 验证接口
return
Promise
.
resolve
(
token
);
},
},
});
import
{
defineStore
}
from
"pinia"
;
import
storage
from
"store"
;
import
UaParser
from
"ua-parser-js"
;
import
type
{
IResult
as
UaResult
}
from
"ua-parser-js"
;
import
router
from
"@/router"
;
/**
* 用户信息-类型
*/
export
interface
UserInfo
{
accessToken
:
string
;
authed
:
number
;
childId
:
number
;
company
:
string
;
domain
:
string
;
equipmentFlag
:
number
;
headImg
:
string
;
logo
:
string
;
mobile
:
string
;
name
:
string
;
openid
:
string
;
placeId
:
number
;
placeName
:
string
;
role
:
number
;
shortName
:
string
;
tradeAuth
:
number
;
truckNo
:
number
;
userId
:
number
;
walletCode
:
number
;
}
export
interface
UserState
{
userInfo
:
UserInfo
;
ua
:
UaResult
;
}
/** userInfo 存储信息 字段名 */
export
const
USER_INFO
:
"USER_INFO"
=
"USER_INFO"
;
/** token 字段名 */
export
const
ACCESS_TOKEN
:
"accessToken"
=
"accessToken"
;
/** userId 字段名 */
export
const
USER_ID
:
"userId"
=
"userId"
;
const
defaultUserInfo
=
{
accessToken
:
""
,
authed
:
0
,
childId
:
0
,
company
:
""
,
domain
:
""
,
equipmentFlag
:
0
,
headImg
:
""
,
logo
:
""
,
mobile
:
""
,
name
:
""
,
openid
:
""
,
placeId
:
0
,
placeName
:
""
,
role
:
0
,
shortName
:
""
,
tradeAuth
:
0
,
truckNo
:
0
,
userId
:
0
,
walletCode
:
0
,
};
export
const
useUserStore
=
defineStore
({
id
:
"clxUser"
,
state
:
():
UserState
=>
({
userInfo
:
{
...
defaultUserInfo
},
ua
:
new
UaParser
().
getResult
(),
}),
actions
:
{
setUserInfo
(
payload
:
UserInfo
)
{
this
.
userInfo
=
payload
;
storage
.
set
(
USER_INFO
,
this
.
userInfo
||
{});
},
resetUserInfo
()
{
this
.
userInfo
=
{
...
defaultUserInfo
};
},
async
getUserInfo
()
{
const
userInfo
=
(
storage
.
get
(
USER_INFO
)
as
UserInfo
)
||
{};
const
userID
=
userInfo
?.
userId
;
if
(
!
userID
)
{
// 异步调用查询用户信息接口
}
},
async
login
()
{
// 调用登陆接口
// this.setUserInfo(payload);
// router.push({ path: '/' });
},
async
logout
()
{
// 调用退出登陆接口
this
.
resetUserInfo
();
router
.
push
({
name
:
"login"
});
},
async
verification
(
token
:
string
)
{
// 调用 token 验证接口
return
Promise
.
resolve
(
token
);
},
},
});
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论