feat(sj_map_reduce): 登录新增验证码功能
This commit is contained in:
parent
cac00f15b4
commit
090763eec9
2
.env
2
.env
@ -52,3 +52,5 @@ VITE_STORAGE_PREFIX=
|
|||||||
VITE_ICONIFY_URL=/iconify
|
VITE_ICONIFY_URL=/iconify
|
||||||
|
|
||||||
VITE_UPDATE_NOTIFY=N
|
VITE_UPDATE_NOTIFY=N
|
||||||
|
|
||||||
|
VITE_LOGIN_CODE=N
|
||||||
|
@ -72,7 +72,8 @@
|
|||||||
"vue-drag-resize": "^1.5.4",
|
"vue-drag-resize": "^1.5.4",
|
||||||
"vue-draggable-plus": "0.5.0",
|
"vue-draggable-plus": "0.5.0",
|
||||||
"vue-i18n": "9.13.1",
|
"vue-i18n": "9.13.1",
|
||||||
"vue-router": "4.3.2"
|
"vue-router": "4.3.2",
|
||||||
|
"vue3-puzzle-vcode": "^1.1.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@elegant-router/vue": "0.3.7",
|
"@elegant-router/vue": "0.3.7",
|
||||||
|
487
pnpm-lock.yaml
487
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
1
src/assets/svg-icon/close.svg
Normal file
1
src/assets/svg-icon/close.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g fill="currentColor" fill-rule="nonzero"><path d="M2.08859116,2.2156945 L2.14644661,2.14644661 C2.32001296,1.97288026 2.58943736,1.95359511 2.7843055,2.08859116 L2.85355339,2.14644661 L6,5.293 L9.14644661,2.14644661 C9.34170876,1.95118446 9.65829124,1.95118446 9.85355339,2.14644661 C10.0488155,2.34170876 10.0488155,2.65829124 9.85355339,2.85355339 L6.707,6 L9.85355339,9.14644661 C10.0271197,9.32001296 10.0464049,9.58943736 9.91140884,9.7843055 L9.85355339,9.85355339 C9.67998704,10.0271197 9.41056264,10.0464049 9.2156945,9.91140884 L9.14644661,9.85355339 L6,6.707 L2.85355339,9.85355339 C2.65829124,10.0488155 2.34170876,10.0488155 2.14644661,9.85355339 C1.95118446,9.65829124 1.95118446,9.34170876 2.14644661,9.14644661 L5.293,6 L2.14644661,2.85355339 C1.97288026,2.67998704 1.95359511,2.41056264 2.08859116,2.2156945 L2.14644661,2.14644661 L2.08859116,2.2156945 Z"></path></g></g></svg>
|
After Width: | Height: | Size: 1.0 KiB |
@ -80,6 +80,8 @@ const local: App.I18n.Schema = {
|
|||||||
confirmPause: 'Are you sure you want to pause?',
|
confirmPause: 'Are you sure you want to pause?',
|
||||||
confirmFinish: 'Are you sure you want to finishe?',
|
confirmFinish: 'Are you sure you want to finishe?',
|
||||||
confirmRetry: 'Are you sure you want to retry?',
|
confirmRetry: 'Are you sure you want to retry?',
|
||||||
|
idDetailTip: 'Click on ID for details',
|
||||||
|
log: 'Log',
|
||||||
yesOrNo: {
|
yesOrNo: {
|
||||||
yes: 'Yes',
|
yes: 'Yes',
|
||||||
no: 'No'
|
no: 'No'
|
||||||
@ -347,7 +349,8 @@ const local: App.I18n.Schema = {
|
|||||||
back: 'Back',
|
back: 'Back',
|
||||||
validateSuccess: 'Verification passed',
|
validateSuccess: 'Verification passed',
|
||||||
loginSuccess: 'Login successfully',
|
loginSuccess: 'Login successfully',
|
||||||
welcomeBack: 'Welcome back, {userName} !'
|
welcomeBack: 'Welcome back, {userName} !',
|
||||||
|
codeTip: 'Drag the sliders to complete the puzzle'
|
||||||
},
|
},
|
||||||
pwdLogin: {
|
pwdLogin: {
|
||||||
title: 'Password Login',
|
title: 'Password Login',
|
||||||
|
@ -80,6 +80,8 @@ const local: App.I18n.Schema = {
|
|||||||
confirmPause: '确认暂停吗?',
|
confirmPause: '确认暂停吗?',
|
||||||
confirmFinish: '确认完成吗?',
|
confirmFinish: '确认完成吗?',
|
||||||
confirmRetry: '确认重试吗?',
|
confirmRetry: '确认重试吗?',
|
||||||
|
log: '日志',
|
||||||
|
idDetailTip: '点击 ID 查看详情',
|
||||||
yesOrNo: {
|
yesOrNo: {
|
||||||
yes: '是',
|
yes: '是',
|
||||||
no: '否'
|
no: '否'
|
||||||
@ -347,7 +349,8 @@ const local: App.I18n.Schema = {
|
|||||||
back: '返回',
|
back: '返回',
|
||||||
validateSuccess: '验证成功',
|
validateSuccess: '验证成功',
|
||||||
loginSuccess: '登录成功',
|
loginSuccess: '登录成功',
|
||||||
welcomeBack: '欢迎回来,{userName} !'
|
welcomeBack: '欢迎回来,{userName} !',
|
||||||
|
codeTip: '拖动滑块完成拼图'
|
||||||
},
|
},
|
||||||
pwdLogin: {
|
pwdLogin: {
|
||||||
title: '密码登录',
|
title: '密码登录',
|
||||||
|
3
src/typings/app.d.ts
vendored
3
src/typings/app.d.ts
vendored
@ -332,6 +332,8 @@ declare namespace App {
|
|||||||
confirmPause: string;
|
confirmPause: string;
|
||||||
confirmFinish: string;
|
confirmFinish: string;
|
||||||
confirmRetry: string;
|
confirmRetry: string;
|
||||||
|
log: string;
|
||||||
|
idDetailTip: string;
|
||||||
yesOrNo: {
|
yesOrNo: {
|
||||||
yes: string;
|
yes: string;
|
||||||
no: string;
|
no: string;
|
||||||
@ -534,6 +536,7 @@ declare namespace App {
|
|||||||
validateSuccess: string;
|
validateSuccess: string;
|
||||||
loginSuccess: string;
|
loginSuccess: string;
|
||||||
welcomeBack: string;
|
welcomeBack: string;
|
||||||
|
codeTip: string;
|
||||||
};
|
};
|
||||||
pwdLogin: {
|
pwdLogin: {
|
||||||
title: string;
|
title: string;
|
||||||
|
1
src/typings/env.d.ts
vendored
1
src/typings/env.d.ts
vendored
@ -105,5 +105,6 @@ declare namespace Env {
|
|||||||
readonly VITE_ICONIFY_URL?: string;
|
readonly VITE_ICONIFY_URL?: string;
|
||||||
/** Used to differentiate storage across different domains */
|
/** Used to differentiate storage across different domains */
|
||||||
readonly VITE_STORAGE_PREFIX?: string;
|
readonly VITE_STORAGE_PREFIX?: string;
|
||||||
|
readonly VITE_LOGIN_CODE?: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
|
import Vcode from 'vue3-puzzle-vcode';
|
||||||
import { md5 } from '@/utils/common';
|
import { md5 } from '@/utils/common';
|
||||||
import { $t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
|
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
|
||||||
@ -33,10 +34,29 @@ const rules: Record<RuleKey, App.Global.FormRule> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
await validate();
|
|
||||||
const password = md5(model.password);
|
const password = md5(model.password);
|
||||||
await authStore.login(model.userName, password);
|
await authStore.login(model.userName, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const codeShow = ref(false);
|
||||||
|
|
||||||
|
const validateCode = async () => {
|
||||||
|
const { VITE_LOGIN_CODE } = import.meta.env;
|
||||||
|
await validate();
|
||||||
|
if (VITE_LOGIN_CODE === 'Y') {
|
||||||
|
codeShow.value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handleSubmit();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
codeShow.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSuccess = () => {
|
||||||
|
handleSubmit();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -53,9 +73,23 @@ async function handleSubmit() {
|
|||||||
/>
|
/>
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
<NSpace vertical :size="24">
|
<NSpace vertical :size="24">
|
||||||
<NButton type="primary" size="large" round block :loading="authStore.loginLoading" @click="handleSubmit">
|
<NPopover :show="codeShow" row style="padding: 0">
|
||||||
|
<template #trigger>
|
||||||
|
<NButton type="primary" size="large" round block :loading="authStore.loginLoading" @click="validateCode">
|
||||||
{{ $t('page.login.common.login') }}
|
{{ $t('page.login.common.login') }}
|
||||||
</NButton>
|
</NButton>
|
||||||
|
</template>
|
||||||
|
<NCard :title="$t('page.login.common.codeTip')" :header-style="{ padding: '10px 24px' }">
|
||||||
|
<template #header-extra>
|
||||||
|
<NButton text @click="onClose">
|
||||||
|
<template #icon>
|
||||||
|
<SvgIcon local-icon="close" />
|
||||||
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
<Vcode type="inside" show @success="onSuccess" @close="onClose" />
|
||||||
|
</NCard>
|
||||||
|
</NPopover>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
</NForm>
|
</NForm>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import { NButton, NPopconfirm, NTag } from 'naive-ui';
|
import { NButton, NPopconfirm, NTag, NTooltip } from 'naive-ui';
|
||||||
import { useBoolean } from '@sa/hooks';
|
import { useBoolean } from '@sa/hooks';
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
@ -9,6 +9,7 @@ import { useAppStore } from '@/store/modules/app';
|
|||||||
import { useTable } from '@/hooks/common/table';
|
import { useTable } from '@/hooks/common/table';
|
||||||
import { operationReasonRecord, taskBatchStatusRecord, taskTypeRecord } from '@/constants/business';
|
import { operationReasonRecord, taskBatchStatusRecord, taskTypeRecord } from '@/constants/business';
|
||||||
import { tagColor } from '@/utils/common';
|
import { tagColor } from '@/utils/common';
|
||||||
|
import SvgIcon from '@/components/custom/svg-icon.vue';
|
||||||
import JobBatchSearch from './modules/job-batch-search.vue';
|
import JobBatchSearch from './modules/job-batch-search.vue';
|
||||||
import JobBatchDetailDrawer from './modules/job-batch-detail-drawer.vue';
|
import JobBatchDetailDrawer from './modules/job-batch-detail-drawer.vue';
|
||||||
|
|
||||||
@ -32,9 +33,25 @@ const { columnChecks, columns, data, getData, loading, mobilePagination, searchP
|
|||||||
columns: () => [
|
columns: () => [
|
||||||
{
|
{
|
||||||
key: 'id',
|
key: 'id',
|
||||||
title: $t('common.index'),
|
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 120,
|
width: 120,
|
||||||
|
title: () => {
|
||||||
|
return (
|
||||||
|
<div class="flex-center">
|
||||||
|
<span>{$t('page.jobBatch.jobTask.id')}</span>
|
||||||
|
<NTooltip trigger="hover">
|
||||||
|
{{
|
||||||
|
trigger: () => (
|
||||||
|
<span class="mb-2px ml-5px text-16px">
|
||||||
|
<SvgIcon icon="ant-design:info-circle-outlined" />
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
default: () => <span>{$t('common.idDetailTip')}</span>
|
||||||
|
}}
|
||||||
|
</NTooltip>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
render: row => {
|
render: row => {
|
||||||
function showDetailDrawer() {
|
function showDetailDrawer() {
|
||||||
detailData.value = row;
|
detailData.value = row;
|
||||||
|
@ -55,7 +55,7 @@ const { columns, data, loading, mobilePagination } = useTable({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'index',
|
key: 'index',
|
||||||
title: $t('common.index'),
|
title: $t('common.log'),
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 64,
|
width: 64,
|
||||||
render: row => (
|
render: row => (
|
||||||
|
Loading…
Reference in New Issue
Block a user