Skip to content

Commit 5e1f838

Browse files
committed
refactor🎨: 增加验证码功能
1 parent bb6eaab commit 5e1f838

File tree

17 files changed

+137
-22
lines changed

17 files changed

+137
-22
lines changed

.env

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# port
2+
VITE_PORT = 3100
3+
4+
# spa-title
5+
VITE_GLOB_APP_TITLE = Artemis Admin
6+
7+
# spa shortname
8+
VITE_GLOB_APP_SHORT_NAME = artemis_admin

.env.development

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ VITE_PUBLIC_PATH = /
66

77
# Cross-domain proxy, you can configure multiple
88
# Please note that no line breaks
9-
VITE_PROXY = [["/basic-api","http://localhost:3000"],["/upload","http://localhost:3300/upload"]]
9+
# VITE_PROXY = [["/basic-api","http://localhost:3000"],["/upload","http://localhost:3300/upload"]]
10+
VITE_PROXY = [["/api","http://localhost:10001"],["/upload","http://localhost:3300/upload"]]
1011
# VITE_PROXY=[["/api","https://vvbin.cn/test"]]
1112

1213
# Delete console
1314
VITE_DROP_CONSOLE = false
1415

1516
# Basic interface address SPA
16-
VITE_GLOB_API_URL=/basic-api
17+
VITE_GLOB_API_URL=/api
1718

1819
# File upload address, optional
1920
VITE_GLOB_UPLOAD_URL=/upload

.gitpod.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
ports:
2+
- port: 3344
3+
onOpen: open-preview
4+
tasks:
5+
- init: yarn
6+
command: yarn dev

.yarnclean

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# test directories
2+
__tests__
3+
test
4+
tests
5+
powered-test
6+
7+
# asset directories
8+
docs
9+
doc
10+
website
11+
images
12+
assets
13+
14+
# examples
15+
example
16+
examples
17+
18+
# code coverage directories
19+
coverage
20+
.nyc_output
21+
22+
# build scripts
23+
Makefile
24+
Gulpfile.js
25+
Gruntfile.js
26+
27+
# configs
28+
appveyor.yml
29+
circle.yml
30+
codeship-services.yml
31+
codeship-steps.yml
32+
wercker.yml
33+
.tern-project
34+
.gitattributes
35+
.editorconfig
36+
.*ignore
37+
.eslintrc
38+
.jshintrc
39+
.flowconfig
40+
.documentup.json
41+
.yarn-metadata.json
42+
.travis.yml
43+
44+
# misc
45+
*.md
46+
47+
!istanbul-reports/lib/html/assets
48+
!istanbul-api/node_modules/istanbul-reports/lib/html/assets

public/favicon.ico

2 Bytes
Binary file not shown.

public/resource/img/logo.png

2.79 KB
Loading

src/api/sys/model/userModel.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,10 @@ export interface GetUserInfoModel {
3636
// 介绍
3737
desc?: string;
3838
}
39+
40+
export interface GetCaptchaModel {
41+
// 验证码地址
42+
codeUrl: string;
43+
// 惟一key
44+
key: string;
45+
}

src/api/sys/user.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { defHttp } from '/@/utils/http/axios';
2-
import { LoginParams, LoginResultModel, GetUserInfoModel } from './model/userModel';
2+
import {
3+
LoginParams,
4+
LoginResultModel,
5+
GetUserInfoModel,
6+
GetCaptchaModel,
7+
} from './model/userModel';
38

49
import { ErrorMessageMode } from '/#/axios';
510

@@ -8,6 +13,7 @@ enum Api {
813
Logout = '/logout',
914
GetUserInfo = '/getUserInfo',
1015
GetPermCode = '/getPermCode',
16+
GetCaptcha = '/mate-uaa/auth/code',
1117
}
1218

1319
/**
@@ -39,3 +45,7 @@ export function getPermCode() {
3945
export function doLogout() {
4046
return defHttp.get({ url: Api.Logout });
4147
}
48+
49+
export function getCaptcha() {
50+
return defHttp.get<GetCaptchaModel>({ url: Api.GetCaptcha });
51+
}

src/assets/images/logo.png

-20.9 KB
Loading

src/enums/httpEnum.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
* @description: Request result set
33
*/
44
export enum ResultEnum {
5-
SUCCESS = 0,
6-
ERROR = 1,
5+
SUCCESS = 200,
6+
ERROR = 500,
77
TIMEOUT = 401,
88
TYPE = 'success',
99
}

src/locales/lang/en/sys.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,6 @@ export default {
100100
email: 'Email',
101101
smsCode: 'SMS code',
102102
mobile: 'Mobile',
103+
captcha: 'Captcha',
103104
},
104105
};

src/locales/lang/zh-CN/sys.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export default {
6565
signUpFormTitle: '注册',
6666
forgetFormTitle: '重置密码',
6767

68-
signInTitle: '开箱即用的中后台管理系统',
68+
signInTitle: '迈特云,您的微服务管家',
6969
signInDesc: '输入您的个人详细信息开始使用!',
7070
policy: '我同意xxx隐私政策',
7171
scanSign: `扫码后点击"确认",即可完成登录`,
@@ -94,5 +94,6 @@ export default {
9494
email: '邮箱',
9595
smsCode: '短信验证码',
9696
mobile: '手机号码',
97+
captcha: '验证码',
9798
},
9899
};

src/utils/http/axios/Axios.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { AxiosRequestConfig, AxiosInstance, AxiosResponse } from 'axios';
2-
import type { RequestOptions, Result, UploadFileParams } from '../../../../types/axios';
2+
import type { RequestOptions, Data, UploadFileParams } from '../../../../types/axios';
33
import type { CreateAxiosOptions } from './axiosTransform';
44
import axios from 'axios';
55
import qs from 'qs';
@@ -207,8 +207,8 @@ export class VAxios {
207207

208208
return new Promise((resolve, reject) => {
209209
this.axiosInstance
210-
.request<any, AxiosResponse<Result>>(conf)
211-
.then((res: AxiosResponse<Result>) => {
210+
.request<any, AxiosResponse<Data>>(conf)
211+
.then((res: AxiosResponse<Data>) => {
212212
if (transformRequestHook && isFunction(transformRequestHook)) {
213213
try {
214214
const ret = transformRequestHook(res, opt);

src/utils/http/axios/axiosTransform.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Data processing class, can be configured according to the project
33
*/
44
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
5-
import type { RequestOptions, Result } from '/#/axios';
5+
import type { RequestOptions, Data } from '/#/axios';
66

77
export interface CreateAxiosOptions extends AxiosRequestConfig {
88
authenticationScheme?: string;
@@ -21,7 +21,7 @@ export abstract class AxiosTransform {
2121
/**
2222
* @description: Request successfully processed
2323
*/
24-
transformRequestHook?: (res: AxiosResponse<Result>, options: RequestOptions) => any;
24+
transformRequestHook?: (res: AxiosResponse<Data>, options: RequestOptions) => any;
2525

2626
/**
2727
* @description: 请求失败处理

src/utils/http/axios/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// The axios configuration can be changed according to the project, just change the file, other files can be left unchanged
33

44
import type { AxiosResponse } from 'axios';
5-
import type { RequestOptions, Result } from '/#/axios';
5+
import type { RequestOptions, Data } from '/#/axios';
66
import type { AxiosTransform, CreateAxiosOptions } from './axiosTransform';
77
import { VAxios } from './Axios';
88
import { checkStatus } from './checkStatus';
@@ -27,7 +27,7 @@ const transform: AxiosTransform = {
2727
/**
2828
* @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
2929
*/
30-
transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => {
30+
transformRequestHook: (res: AxiosResponse<Data>, options: RequestOptions) => {
3131
const { t } = useI18n();
3232
const { isTransformResponse, isReturnNativeResponse } = options;
3333
// 是否返回原生响应头 比如:需要获取响应头时使用该属性
@@ -47,24 +47,24 @@ const transform: AxiosTransform = {
4747
throw new Error(t('sys.api.apiRequestFailed'));
4848
}
4949
// 这里 code,result,message为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式
50-
const { code, result, message } = data;
50+
// const { code, result, msg } = data;
5151

5252
// 这里逻辑可以根据项目进行修改
53-
const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS;
53+
const hasSuccess = data && Reflect.has(data, 'code') && data.code === ResultEnum.SUCCESS;
5454
if (hasSuccess) {
55-
return result;
55+
return data.data;
5656
}
5757

5858
// 在此处根据自己项目的实际情况对不同的code执行不同的操作
5959
// 如果不希望中断当前请求,请return数据,否则直接抛出异常即可
6060
let timeoutMsg = '';
61-
switch (code) {
61+
switch (data.code) {
6262
case ResultEnum.TIMEOUT:
6363
timeoutMsg = t('sys.api.timeoutMessage');
6464
break;
6565
default:
66-
if (message) {
67-
timeoutMsg = message;
66+
if (data.msg) {
67+
timeoutMsg = data.msg;
6868
}
6969
}
7070

src/views/sys/login/LoginForm.vue

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
v-show="getShow"
99
@keypress.enter="handleLogin"
1010
>
11+
<FormItem name="key">
12+
<Input size="large" v-model:value="formData.key" :hidden="true" />
13+
</FormItem>
1114
<FormItem name="account" class="enter-x">
1215
<Input
1316
size="large"
@@ -24,6 +27,16 @@
2427
:placeholder="t('sys.login.password')"
2528
/>
2629
</FormItem>
30+
<ARow class="enter-x">
31+
<ACol :span="16">
32+
<FormItem name="code">
33+
<Input size="large" :placeholder="t('sys.login.captcha')" />
34+
</FormItem>
35+
</ACol>
36+
<ACol :span="8">
37+
<img :src="codeUrl" @click="getCode" />
38+
</ACol>
39+
</ARow>
2740

2841
<ARow class="enter-x">
2942
<ACol :span="12">
@@ -82,7 +95,7 @@
8295
</Form>
8396
</template>
8497
<script lang="ts" setup>
85-
import { reactive, ref, toRaw, unref, computed } from 'vue';
98+
import { reactive, ref, toRaw, unref, computed, onMounted } from 'vue';
8699
87100
import { Checkbox, Form, Input, Row, Col, Button, Divider } from 'ant-design-vue';
88101
import {
@@ -100,6 +113,7 @@
100113
import { useUserStore } from '/@/store/modules/user';
101114
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
102115
import { useDesign } from '/@/hooks/web/useDesign';
116+
import { getCaptcha } from '/@/api/sys/user';
103117
//import { onKeyStroke } from '@vueuse/core';
104118
105119
const ACol = Col;
@@ -117,18 +131,30 @@
117131
const formRef = ref();
118132
const loading = ref(false);
119133
const rememberMe = ref(false);
134+
const codeUrl = ref();
120135
121136
const formData = reactive({
122-
account: 'vben',
123-
password: '123456',
137+
account: 'admin',
138+
password: 'matecloud',
139+
key: '',
124140
});
125141
126142
const { validForm } = useFormValid(formRef);
127143
144+
onMounted(() => {
145+
getCode();
146+
});
147+
128148
//onKeyStroke('Enter', handleLogin);
129149
130150
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
131151
152+
async function getCode() {
153+
const codeModel = await getCaptcha();
154+
codeUrl.value = codeModel.codeUrl;
155+
formData.key = codeModel.key;
156+
}
157+
132158
async function handleLogin() {
133159
const data = await validForm();
134160
if (!data) return;

types/axios.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ export interface Result<T = any> {
3030
result: T;
3131
}
3232

33+
export interface Data<T = any> {
34+
code: number;
35+
msg: string;
36+
time: string;
37+
data: T;
38+
}
39+
3340
// multipart/form-data: upload file
3441
export interface UploadFileParams {
3542
// Other parameters

0 commit comments

Comments
 (0)