Merge branch 'main' into shen

pull/1/head
Dragon 1 year ago
commit ba7add68c0

@ -1 +1,14 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1710418001545" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16757" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M1024 628.992l-256.448-224v125.12H384v197.824h383.616v125.056l256.384-224z m-384-354.88H256.384v-125.12L0 372.992l256.448 224v-125.056H640V274.112z" p-id="16758"></path></svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>BBD切换</title>
<g id="-index备份" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="index_1.1备份-7" transform="translate(-708.000000, -455.000000)" fill-rule="nonzero">
<g id="编组-31" transform="translate(408.000000, 150.000000)">
<g id="BBD切换" transform="translate(300.000000, 305.000000)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="20" height="20"></rect>
<path d="M20,12.285 L14.99125,7.91 L14.99125,10.35375 L7.5,10.35375 L7.5,14.2175 L14.9925,14.2175 L14.9925,16.66 L20,12.285 L20,12.285 Z M12.5,5.35375 L5.0075,5.35375 L5.0075,2.91 L0,7.285 L5.00875,11.66 L5.00875,9.2175 L12.5,9.2175 L12.5,5.35375 L12.5,5.35375 Z" id="形状" fill="#999999"></path>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 509 B

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -201,7 +201,7 @@ const transform: AxiosTransform = {
// eslint-disable-next-line ts/no-use-before-define
const instance = http.getAxios()
const config = response.config
const whitelist = ['/api/captcha/captchatoken', '/api/captcha/captchaImage', '/api/backstage/adminlogin', '/api/oauthweb/token']
const whitelist = ['/api/captcha/captchatoken', '/api/captcha/captchaImage', '/api/backstage/adminlogin', '/api/oauthweb/token','/api/web/smslogin/login','/api/web/smslogin/sendcode']
const expirationTime = storage.get(TOKEN_EXPIRATION_TIME)
// console.log('剩余失效时间(分):', (expirationTime - Date.now()) / 1000 / 60, config.url)
@ -264,7 +264,7 @@ const transform: AxiosTransform = {
if (err && err.includes('Network Error')) {
$dialog.info({
title: '网络异常',
content: '请检查您的网络连接是否正常',
content: '网络错误,请重试!',
positiveText: '确定',
// negativeText: '取消',
closable: false,

@ -1,249 +1,249 @@
<script lang="ts" setup>
import { setFilter } from '@/api/home/filter'
import { asideMap } from '@/config/final'
import { useFinal } from '@/store/modules/final'
import { debounce, difference } from 'lodash-es'
import { computed, ref, watch } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
const show = ref(false)
const checkAll = ref(false)
const selectIds = ref<string[]>([])
const finalStore = useFinal()
import { setFilter } from "@/api/home/filter";
import { asideMap } from "@/config/final";
import { useFinal } from "@/store/modules/final";
import { debounce, difference } from "lodash-es";
import { computed, ref, watch } from "vue";
import { VueDraggable } from "vue-draggable-plus";
const show = ref(false);
const checkAll = ref(false);
const selectIds = ref<string[]>([]);
const finalStore = useFinal();
function showModal() {
show.value = true
show.value = true;
}
function closeModal() {
show.value = false
show.value = false;
}
//
const offList = ref<any[]>([])
const offList = ref<any[]>([]);
//
const onList = ref<any[]>([])
const onList = ref<any[]>([]);
const allCount = computed(() => {
return `全部筛选(共${offList.value.length - 1}个)`
})
return `全部筛选(共${offList.value.length - 1}个)`;
});
const selectCount = computed(() => {
return `全部筛选(共${onList.value.length}个)`
})
return `全部筛选(共${onList.value.length}个)`;
});
defineExpose({
showModal,
})
});
function generateDefaultList() {
return Object.keys(asideMap).reduce((acc, key) => {
const { label, isDefaultFilter } = asideMap[key]
const { label, isDefaultFilter } = asideMap[key];
//
if (isDefaultFilter) {
const config = {
id: key,
name: label || '未配置',
name: label || "未配置",
fix: isDefaultFilter,
checked: true,
}
return [...acc, config]
}
else {
return acc
};
return [...acc, config];
} else {
return acc;
}
}, [])
}, []);
}
function generatList(customConfig) {
const keys = Object.keys(asideMap)
let onList: object[] = []
const offList: object[] = []
const showKeys = customConfig.map((key: string) => key.toLowerCase())
const keys = Object.keys(asideMap);
let onList: object[] = [];
const offList: object[] = [];
const showKeys = customConfig.map((key: string) => key.toLowerCase());
for (const key of keys) {
if (!key.startsWith('iz') || asideMap[key] === undefined)
continue
if (!key.startsWith("iz") || asideMap[key] === undefined) continue;
const name = asideMap[key]?.label
const isDefaultFilter = asideMap[key]?.isDefaultFilter
const name = asideMap[key]?.label;
const isDefaultFilter = asideMap[key]?.isDefaultFilter;
//
const isChecked = asideMap[key].isDefaultFilter || showKeys.includes(key)
const isChecked = asideMap[key].isDefaultFilter || showKeys.includes(key);
offList.push({
id: key,
name: name || '未配置',
name: name || "未配置",
fix: isDefaultFilter,
checked: isChecked,
})
});
isChecked && selectIds.value.push(key)
isChecked && selectIds.value.push(key);
}
onList = showKeys.reduce((acc, key) => {
const isDefaultFilter = asideMap[key]?.isDefaultFilter
const isDefaultFilter = asideMap[key]?.isDefaultFilter;
// ()
if (isDefaultFilter === false) {
const config = {
id: key,
name: asideMap[key].label || '未配置',
name: asideMap[key].label || "未配置",
fix: asideMap[key].isDefaultFilter,
}
return [...acc, config]
};
return [...acc, config];
} else {
return acc;
}
else {
return acc
}
}, [])
}, []);
const fixedList = generateDefaultList()
onList.unshift(...fixedList)
return { showList: onList, hideList: offList }
const fixedList = generateDefaultList();
onList.unshift(...fixedList);
return { showList: onList, hideList: offList };
}
finalStore.$subscribe(() => {
const customConfig = finalStore.getCustomConfig
const customConfig = finalStore.getCustomConfig;
if (customConfig === null)
return
if (customConfig === null) return;
const { showList, hideList } = generatList(customConfig)
onList.value = showList
offList.value = hideList
})
const { showList, hideList } = generatList(customConfig);
onList.value = showList;
offList.value = hideList;
});
async function handleSumbit(e: MouseEvent) {
e.preventDefault()
e.preventDefault();
const param = onList.value.filter(item => !asideMap[item.id].isDefaultFilter).map((item) => {
return item.id
}).join(',')
const param = onList.value
.filter((item) => !asideMap[item.id].isDefaultFilter)
.map((item) => {
return item.id;
})
.join(",");
await setFilter({ searchcount: param, type: 1 })
finalStore.fetchCustomConfig()
closeModal()
await setFilter({ searchcount: param, type: 1 });
finalStore.fetchCustomConfig();
closeModal();
}
function onCheckAllChange(value) {
const ids: string[] = []
const ids: string[] = [];
for (const item of offList.value) {
if (!item.fix) {
item.checked = value
ids.push(item.id)
item.checked = value;
ids.push(item.id);
}
}
selectIds.value = value ? ids : []
selectIds.value = value ? ids : [];
}
function onCheckChange(checked: any, item: any) {
const index = selectIds.value.indexOf(item.id)
const index = selectIds.value.indexOf(item.id);
item.checked = checked
item.checked = checked;
if (index === -1 && checked)
selectIds.value.push(item.id)
else
selectIds.value.splice(index, 1)
if (index === -1 && checked) selectIds.value.push(item.id);
else selectIds.value.splice(index, 1);
}
const showIds = computed(() => {
return onList.value.map((item) => {
return item.id
})
})
return item.id;
});
});
watch(
() => selectIds.value.length,
(newVal, oldVal) => {
if (newVal === oldVal)
return
if (newVal === oldVal) return;
const action = newVal > oldVal ? 'add' : 'remove'
const diff = action === 'add' ? difference(selectIds.value, showIds.value) : difference(showIds.value, selectIds.value)
const action = newVal > oldVal ? "add" : "remove";
const diff =
action === "add"
? difference(selectIds.value, showIds.value)
: difference(showIds.value, selectIds.value);
if (diff.length === 0)
return
if (diff.length === 0) return;
if (action === 'add') {
if (action === "add") {
for (const item of offList.value) {
if (!item.fix && diff.includes(item.id)) {
onList.value.push({
id: item.id,
name: item.name || '未配置',
name: item.name || "未配置",
fix: item.fix || false,
})
});
}
}
}
else {
const list = onList.value
} else {
const list = onList.value;
for (let index = 0; index < list.length; index++) {
const item = list[index]
const item = list[index];
if (!item.fix && diff.includes(item.id)) {
list.splice(index, 1)
index--
list.splice(index, 1);
index--;
}
}
}
},
)
}
);
watch(
() => showIds.value.length,
(newVal, oldVal) => {
if (newVal === oldVal)
return
if (newVal === oldVal) return;
const diff = difference(selectIds.value, showIds.value)
const diff = difference(selectIds.value, showIds.value);
if (diff.length === 0)
return
if (diff.length === 0) return;
for (const item of offList.value) {
if (!item.fix && diff.includes(item.id)) {
const index = selectIds.value.indexOf(item.id)
item.checked = false
selectIds.value.splice(index, 1)
const index = selectIds.value.indexOf(item.id);
item.checked = false;
selectIds.value.splice(index, 1);
}
}
},
)
}
);
function clearDragSource() {
onList.value = onList.value.filter((item) => {
return item.fix === true
})
return item.fix === true;
});
}
function removeHandler(id: string) {
const index = onList.value.findIndex((item) => {
return item.id === id
})
return item.id === id;
});
if (index !== -1)
onList.value.splice(index, 1)
if (index !== -1) onList.value.splice(index, 1);
}
const offKeyword = ref('')
const onKeyword = ref('')
const offKeyword = ref("");
const onKeyword = ref("");
const leftInputHandler = debounce((keyword) => {
offKeyword.value = keyword
}, 300)
offKeyword.value = keyword;
}, 300);
const rightInputHandler = debounce((keyword) => {
onKeyword.value = keyword
}, 300)
onKeyword.value = keyword;
}, 300);
</script>
<template>
<n-modal v-model:show="show" transform-origin="center" :mask-closable="false">
<n-card class="cardstyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<n-card
class="cardstyle"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<div class="wrapper">
<span class="wrapper-title">自定义筛选</span>
<div class="wrapper-bar">
@ -255,7 +255,10 @@ const rightInputHandler = debounce((keyword) => {
<n-grid cols="24" class="mt-4 proCard" responsive="screen" :x-gap="24">
<n-grid-item span="11">
<NCard
:title="allCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small"
:title="allCount"
class="dragcardStyle"
:segmented="{ content: true, footer: true }"
size="small"
:bordered="false"
>
<div>
@ -264,17 +267,28 @@ const rightInputHandler = debounce((keyword) => {
<SvgIcon size="14px" name="magnifying-1" />
</template>
</n-input>
<n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;">
<n-scrollbar
style="max-height: 500px; border: 1px solid #cad2dd; border-radius: 2px"
>
<div class="draggable-ul">
<div class="draggable-li">
<n-checkbox v-model:checked="checkAll" label="全部" @update:checked="onCheckAllChange" />
<n-checkbox
v-model:checked="checkAll"
label="全部"
@update:checked="onCheckAllChange"
/>
</div>
<div
v-for="item in offList" v-show="item.name.includes(offKeyword)" :key="item.id"
:class="{ 'disable-check': item.fix }" class="draggable-li"
v-for="item in offList"
v-show="item.name.includes(offKeyword)"
:key="item.id"
:class="{ 'disable-check': item.fix }"
class="draggable-li"
>
<n-checkbox
v-model:checked="item.checked" :label="item.name" :disabled="item.fix"
v-model:checked="item.checked"
:label="item.name"
:disabled="item.fix"
@update:checked="onCheckChange($event, item)"
/>
</div>
@ -283,12 +297,15 @@ const rightInputHandler = debounce((keyword) => {
</div>
</NCard>
</n-grid-item>
<n-grid-item style="display: flex;align-items: center;" span="2">
<n-grid-item style="display: flex; align-items: center" span="2">
<SvgIcon size="20" name="switchsvg" />
</n-grid-item>
<n-grid-item span="11">
<NCard
:title="selectCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small"
:title="selectCount"
class="dragcardStyle"
:segmented="{ content: true, footer: true }"
size="small"
:bordered="false"
>
<template #header-extra>
@ -300,17 +317,33 @@ const rightInputHandler = debounce((keyword) => {
<SvgIcon size="14px" name="magnifying-1" />
</template>
</n-input>
<n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;" class="scroll">
<VueDraggable v-model="onList" class="draggable-ul" filter=".draggable-li[draggable='false']" :animation="150" group="shared">
<n-scrollbar
style="max-height: 500px; border: 1px solid #cad2dd; border-radius: 2px"
class="scroll"
>
<VueDraggable
v-model="onList"
class="draggable-ul"
filter=".draggable-li[draggable='false']"
:animation="150"
group="shared"
>
<div
v-for="item in onList" v-show="item.name.includes(onKeyword)" :key="item.id" :draggable="!item.fix"
:class="{ fix: item.fix }" class="cursor-move draggable-li"
v-for="item in onList"
v-show="item.name.includes(onKeyword)"
:key="item.id"
:draggable="!item.fix"
:class="{ fix: item.fix }"
class="cursor-move draggable-li"
>
<SvgIcon v-show="!item.fix" name="drag" size="24" />
<span class="ml-2">{{ item.name }}</span>
<SvgIcon
v-if="!item.fix" size="16px" style="display:block;margin-left: auto;cursor: pointer;"
name="clear" @click="removeHandler(item.id)"
v-if="!item.fix"
size="16px"
style="display: block; margin-left: auto; cursor: pointer"
name="clear"
@click="removeHandler(item.id)"
/>
</div>
</VueDraggable>
@ -322,10 +355,8 @@ const rightInputHandler = debounce((keyword) => {
</div>
<template #footer>
<div class="wrapper-footer">
<n-button type="info" @click="handleSumbit">
确认
</n-button>
<n-button secondary style="margin-left:15px" @click="closeModal">
<n-button type="info" @click="handleSumbit"> </n-button>
<n-button secondary style="margin-left: 15px" @click="closeModal">
取消
</n-button>
</div>
@ -360,7 +391,7 @@ const rightInputHandler = debounce((keyword) => {
position: relative;
&:before {
background-color: #1980FF;
background-color: #1980ff;
content: "";
width: 5px;
border-radius: 2px;
@ -385,7 +416,7 @@ const rightInputHandler = debounce((keyword) => {
.textbtnStyle {
cursor: pointer;
color: #1980FF;
color: #1980ff;
}
.draggable-ul {
@ -412,6 +443,12 @@ const rightInputHandler = debounce((keyword) => {
::v-deep(.n-card > .n-card-header) {
--n-padding-top: 0px;
--n-padding-bottom: 12px
--n-padding-bottom: 12px;
}
::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important;
}
::v-deep(.n-scrollbar){
border-top: none !important;
}
</style>

@ -561,4 +561,10 @@ function removeHandler(id: string, type: "fix" | "unfix") {
--n-padding-top: 0px;
--n-padding-bottom: 12px;
}
::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important;
}
::v-deep(.n-scrollbar){
border-top: none !important;
}
</style>

@ -433,6 +433,13 @@ onMounted(()=>{
::v-deep(.n-card > .n-card-header) {
--n-padding-top: 0px;
--n-padding-bottom: 12px
--n-padding-bottom: 12px;
}
::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important;
}
::v-deep(.n-scrollbar){
border-top: none !important;
}
</style>

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { computed, reactive, ref } from "vue";
import { computed, onMounted, reactive, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useMessage } from "naive-ui";
@ -26,24 +26,26 @@ const formRef = ref();
const formRefSms = ref();
const message = useMessage();
const loading = ref(false);
const autoLogin = ref(true);
const autoLogin = ref(false);
const LOGIN_NAME = PageEnum.BASE_LOGIN_NAME;
const userStore = useUserStore();
const router = useRouter();
const route = useRoute();
const show = ref(false);
const flag = ref(true);
const loginSuccess = ref(true);
const loginRejectMessge = ref("");
const formInline: FormState = reactive({
let formInline: FormState = reactive({
// enterprisecode: "",
// username: "yanshi01",
// password: "123456",
enterprisecode: '',
username: '',
password: '',
enterprisecode: "",
username: "",
password: ""
});
const formSms: FormSms = reactive({
let formSms: FormSms = reactive({
agentcode: "",
phone: "",
phonecode: "",
@ -51,11 +53,66 @@ const formSms: FormSms = reactive({
const tab = ref(0);
const countTime = ref("获取验证码");
const rules = {
enterprisecode: { required: true, message: "请输入企业编码", trigger: "blur" },
agentcode: { required: true, message: "请输入企业编码", trigger: "blur" },
enterprisecode: [
{ required: true, message: "请输入企业编码", trigger: "blur" },
{
trigger: ["blur"],
level: "error",
validator(_rule, value) {
if (loginSuccess.value) {
return true;
} else {
return new Error(loginRejectMessge.value);
}
},
},
],
agentcode: [
{ required: true, message: "请输入企业编码", trigger: "blur" },
{
trigger: ["blur"],
level: "error",
validator(_rule, value) {
if (loginSuccess.value) {
return true;
} else {
return new Error(loginRejectMessge.value);
}
},
},
],
phone: { required: true, message: "请输入手机号", trigger: "blur" },
phonecode: { required: true, message: "请输入验证码", trigger: "blur" },
username: { required: true, message: "请输入用户名", trigger: "blur" },
phonecode: [
{ required: true, message: "请输入验证码", trigger: "blur" },
{
trigger: ["blur"],
level: "error",
validator(_rule, value) {
if (value.length < 4 && value.length > 0) {
return new Error("请正确填写4位手机短信验证码");
}
if (loginSuccess.value) {
return true;
} else {
return new Error("验证码错误");
}
},
},
],
username: [
{ required: true, message: "请输入用户名", trigger: "blur" },
{
trigger: ["blur"],
level: "error",
validator(_rule, value) {
if (loginSuccess.value) {
return true;
} else {
return new Error(loginRejectMessge.value);
}
},
},
],
password: { required: true, message: "请输入密码", trigger: "blur" },
captcha: { required: true, message: "请输入验证码", trigger: "blur" },
};
@ -67,7 +124,6 @@ function handleSubmit(e) {
const { username, password, enterprisecode } = formInline;
message.loading("登录中...");
loading.value = true;
const params = {
username,
password,
@ -77,15 +133,23 @@ function handleSubmit(e) {
try {
const { code, message: msg } = await userStore.login(params);
loginRejectMessge.value = msg;
if (code === ResultEnum.SUCCESS) {
//
if (autoLogin.value) {
localStorage.setItem("LOGIN_FORM_PASS", JSON.stringify(formInline));
} else {
localStorage.removeItem("LOGIN_FORM_PASS");
}
loginSuccess.value = true;
await userStore.getInformation();
message.destroyAll();
const toPath = decodeURIComponent((route.query?.redirect || "/") as string);
message.success("登录成功,即将进入系统");
if (route.name === LOGIN_NAME) router.replace("/");
else router.replace(toPath);
} else {
loginSuccess.value = false;
message.destroyAll();
message.info(msg || "登录失败");
}
@ -98,6 +162,25 @@ function handleSubmit(e) {
});
}
onMounted(() => {
let data:any = localStorage.getItem("LOGIN_FORM_SMS");
if (data) {
data = JSON.parse(data) as any
formSms.agentcode = data.agentcode;
formSms.phone = data.phone;
formSms.phonecode = "";
autoLogin.value = true;
}
data = localStorage.getItem("LOGIN_FORM_PASS");
if (data) {
data = JSON.parse(data) as any;
formInline.username = data.username;
formInline.password = data.password;
formInline.enterprisecode = data.enterprisecode;
autoLogin.value = true;
}
});
function handleSmsSubmit(e) {
e.preventDefault();
formRefSms.value.validate(async (errors) => {
@ -113,10 +196,17 @@ function handleSmsSubmit(e) {
phonecode,
});
const { code, message: msg } = res;
loginRejectMessge.value = msg;
if (code === ResultEnum.SUCCESS) {
//
if (autoLogin.value) {
localStorage.setItem("LOGIN_FORM_SMS", JSON.stringify(formSms));
} else {
localStorage.removeItem("LOGIN_FORM_SMS");
}
loginSuccess.value = true;
// const { code, message: msg } = await userStore.login(params)
await userStore.getInformation();
message.destroyAll();
const toPath = decodeURIComponent((route.query?.redirect || "/") as string);
message.success("登录成功,即将进入系统");
@ -125,7 +215,9 @@ function handleSmsSubmit(e) {
} else {
message.destroyAll();
message.info(msg || "登录失败");
loginSuccess.value = false;
}
} catch (e) {
} finally {
loading.value = false;
}
@ -146,18 +238,23 @@ function switchTab(type: number) {
}
function computedForm() {
return !formInline.enterprisecode || !formInline.username || !formInline.password;
if (tab.value == 0) {
return !formInline.enterprisecode || !formInline.username || !formInline.password;
}
if (tab.value == 1) {
return !formSms.agentcode || !formSms.phone || !formSms.phonecode;
}
}
async function sendCode(value) {
if (!formSms.phonecode) return;
if (!formSms.phone) return;
if (!flag.value) return;
flag.value = false;
const res = await getCode({
phone: formSms.phone,
agentcode: "",
agentcode: formSms.agentcode,
});
startCount();
}
@ -215,6 +312,7 @@ function forget() {
v-model:value="formInline.enterprisecode"
class="item-input"
placeholder="请输入企业编码"
maxlength="20"
>
<template #prefix>
<svg-icon size="20" name="enterprise" />
@ -226,6 +324,7 @@ function forget() {
v-model:value="formInline.username"
class="item-input"
placeholder="请输入用户名"
maxlength="16"
>
<template #prefix>
<svg-icon size="20" name="account" />
@ -239,6 +338,7 @@ function forget() {
type="password"
show-password-on="click"
placeholder="请输入密码"
maxlength="16"
>
<template #prefix>
<svg-icon size="20" name="password" />
@ -254,6 +354,7 @@ function forget() {
:loading="loading"
block
@click="handleSubmit"
:disabled="computedForm()"
>
登录
</n-button>
@ -266,7 +367,7 @@ function forget() {
</n-checkbox>
</div>
<div class="flex-initial order-last" @click="forget">
<a href="javascript:">忘记密码</a>
<a href="javascript:">忘记密码</a>
</div>
</div>
</n-form-item>
@ -296,6 +397,7 @@ function forget() {
v-model:value="formSms.phone"
class="item-input"
placeholder="请输入手机号"
maxlength="11"
>
<template #prefix>
<img
@ -325,7 +427,10 @@ function forget() {
</template>
<template #suffix>
<div
:class="{ 'code-count': countTime !== '获取验证码' }"
:class="{
'code-count':
countTime !== '获取验证码' || !(formSms.phone.length == 11),
}"
class="code"
@click="sendCode"
>
@ -343,6 +448,7 @@ function forget() {
:loading="loading"
block
@click="handleSmsSubmit"
:disabled="computedForm()"
>
登录
</n-button>
@ -355,7 +461,7 @@ function forget() {
</n-checkbox>
</div>
<div class="flex-initial order-last" @click="forget">
<a href="javascript:">忘记密码</a>
<a href="javascript:">忘记密码</a>
</div>
</div>
</n-form-item>
@ -402,6 +508,7 @@ function forget() {
color: #666666;
line-height: 33px;
margin-right: 24px;
cursor: pointer;
&-active {
width: 96px;
@ -475,6 +582,7 @@ function forget() {
font-weight: Regular;
color: #507afd;
margin-left: 12px;
cursor: pointer;
&-count {
font-size: 14px;

@ -1,18 +1,18 @@
<script lang="ts" setup>
import { ref } from 'vue'
import Login from './components/Login.vue'
import Forget from './components/Forget.vue'
import { ref } from "vue";
import Login from "./components/Login.vue";
import Forget from "./components/Forget.vue";
const show = ref(false)
const ifLogin = ref(true)
const show = ref(false);
const ifLogin = ref(true);
function showLogin() {
show.value = true
show.value = true;
}
function close() {
show.value = false
ifLogin.value = true
show.value = false;
ifLogin.value = true;
}
</script>
@ -20,87 +20,59 @@ function close() {
<div class="wrap-login">
<div class="content">
<div class="header f-c-b">
<img class="img-logo" src="@/assets/images/login/logo.png" alt="">
<div class="btn-login f-c-c" @click="showLogin">
登录
</div>
<img class="img-logo" src="@/assets/images/login/logo.png" alt="" />
<div class="btn-login f-c-c" @click="showLogin"></div>
</div>
<div class="img-wrap f-s">
<img class="img-ai" src="../../assets/images/login/ai.png" alt="">
<img class="img-ai" src="../../assets/images/login/ai.png" alt="" />
<div class="right">
<div class="f-c">
<img class="img-item" src="../../assets/images/login/img-item-1.png" alt="">
<img class="img-item" src="../../assets/images/login/img-item-2.png" alt="">
<img class="img-item" src="../../assets/images/login/img-item-3.png" alt="">
<img class="img-item" src="../../assets/images/login/img-item-4.png" alt="">
<img class="img-item" src="../../assets/images/login/img-item-5.png" alt="">
</div>
<div class="img-task">
Task approval
<img class="img-item" src="../../assets/images/login/img-item-1.png" alt="" />
<img class="img-item" src="../../assets/images/login/img-item-2.png" alt="" />
<img class="img-item" src="../../assets/images/login/img-item-3.png" alt="" />
<img class="img-item" src="../../assets/images/login/img-item-4.png" alt="" />
<img class="img-item" src="../../assets/images/login/img-item-5.png" alt="" />
</div>
<div class="img-task">Task approval</div>
</div>
</div>
<div class="center-text f-c-b">
<img class="img-ip" src="../../assets/images/login/img-ip.png" alt="">
<img class="img-text" src="../../assets/images/login/img-text.png" alt="">
<img class="img-icon-1" src="../../assets/images/login/img-icon-1.png" alt="">
</div>
<div class="text">
企业级 SaaS 智能审批解决方案
</div>
<img class="img-icon-2" src="../../assets/images/login/img-icon-2.png" alt="">
<div class="btn-login-2 f-c-c" @click="showLogin">
立即登录 ->
<img class="img-ip" src="../../assets/images/login/img-ip.png" alt="" />
<img class="img-text" src="../../assets/images/login/img-text.png" alt="" />
<img class="img-icon-1" src="../../assets/images/login/img-icon-1.png" alt="" />
</div>
<div class="text">企业级 SaaS 智能审批解决方案</div>
<img class="img-icon-2" src="../../assets/images/login/img-icon-2.png" alt="" />
<div class="btn-login-2 f-c-c" @click="showLogin"> -></div>
<div class="item-wrap f-c">
<div class="item">
<img class="item-img" src="../../assets/images/login/item-1.png" alt="">
<div class="title">
AI一键查重
</div>
<div class="subtitle">
一键查重生成任务包
</div>
<img class="item-img" src="../../assets/images/login/item-1.png" alt="" />
<div class="title">AI一键查重</div>
<div class="subtitle">一键查重生成任务包</div>
</div>
<div class="item">
<img class="item-img" src="../../assets/images/login/item-2.png" alt="">
<div class="title">
AI工单管理
</div>
<div class="subtitle">
智能批量辨识真假假图快速审批
</div>
<img class="item-img" src="../../assets/images/login/item-2.png" alt="" />
<div class="title">AI工单管理</div>
<div class="subtitle">智能批量辨识真假假图快速审批</div>
</div>
<div class="item">
<img class="item-img" src="../../assets/images/login/item-3.png" alt="">
<div class="title">
AI快速审批
</div>
<div class="subtitle">
智能图片比对批量审批一键确认
</div>
<img class="item-img" src="../../assets/images/login/item-3.png" alt="" />
<div class="title">AI快速审批</div>
<div class="subtitle">智能图片比对批量审批一键确认</div>
</div>
<div class="item">
<img class="item-img" src="../../assets/images/login/item-4.png" alt="">
<div class="title">
OCR
</div>
<div class="subtitle">
图片自动识别文档图片版面解析
</div>
<img class="item-img" src="../../assets/images/login/item-4.png" alt="" />
<div class="title">OCR</div>
<div class="subtitle">图片自动识别文档图片版面解析</div>
</div>
<div class="item">
<img class="item-img" src="../../assets/images/login/item-5.png" alt="">
<div class="title">
更多功能
</div>
<div class="subtitle">
探索更多功能
</div>
<img class="item-img" src="../../assets/images/login/item-5.png" alt="" />
<div class="title">更多功能</div>
<div class="subtitle">探索更多功能</div>
</div>
</div>
<img class="item-footer" src="../../assets/images/login/footer.png" alt="">
<img class="item-footer" src="../../assets/images/login/footer.png" alt="" />
</div>
<n-modal v-model:show="show" :mask-closable="false">
<Login v-if="ifLogin" @close="close" @forget="ifLogin = !ifLogin" />
@ -111,54 +83,54 @@ function close() {
<style lang="less" scoped>
.wrap-login {
background-image: url('../../assets/images/login/bg.png');
background-image: url("../../assets/images/login/bg.png");
background-repeat: no-repeat;
background-size: cover;
height: 100vh;
.f-c-c{
.f-c-c {
display: flex;
align-items: center;
justify-content: center;
}
.f-c-b{
.f-c-b {
display: flex;
align-items: center;
justify-content: space-between;
}
.f-c{
.f-c {
display: flex;
align-items: center;
}
.f-s{
.f-s {
display: flex;
align-items: flex-start;
}
.img-logo{
.img-logo {
width: 121px;
height: 35px;
}
.img-ai{
.img-ai {
width: 97px;
height: 90px;
}
.img-item{
.img-item {
width: 53px;
height: 52px;
margin-left: -10px;
}
.img-task{
.img-task {
width: 138px;
height: 54px;
border-radius: 6px;
background-image: url('../../assets/images/login/img-task.png');
background-image: url("../../assets/images/login/img-task.png");
background-repeat: no-repeat;
background-size: cover;
font-size: 14px;
@ -173,38 +145,38 @@ function close() {
text-align: center;
}
.img-ip{
.img-ip {
width: 80px;
height: 80px;
}
.img-text{
.img-text {
width: 600px;
height: 65px;
margin-top: 43px;
}
.img-icon-1{
.img-icon-1 {
width: 54px;
height: 54px;
}
.img-icon-2{
.img-icon-2 {
width: 54px;
height: 54px;
margin-left: 830px;
}
.content{
.content {
width: 1300px;
margin: 0 auto;
padding-top: 27px;
}
.header{
.header {
margin-bottom: 44px;
.btn-login{
.btn-login {
width: 76px;
height: 40px;
border: 1px solid #666666;
@ -217,16 +189,16 @@ function close() {
}
}
.img-wrap{
.img-wrap {
padding-left: 174px;
}
.center-text{
.center-text {
margin: 0 auto;
width: 776px;
}
.text{
.text {
font-size: 20px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
@ -236,12 +208,12 @@ function close() {
margin-top: 32px;
}
.btn-login-2{
.btn-login-2 {
width: 138px;
height: 44px;
background: linear-gradient(136deg,#3258e8, #786efc 100%);
background: linear-gradient(136deg, #3258e8, #786efc 100%);
border-radius: 8px;
box-shadow: 0px 2px 6px 0px rgba(116,153,253,0.30);
box-shadow: 0px 2px 6px 0px rgba(116, 153, 253, 0.3);
font-size: 16px;
font-family: PingFang SC, PingFang SC-Medium;
font-weight: Medium;
@ -252,12 +224,12 @@ function close() {
cursor: pointer;
}
.item-wrap{
.item-wrap {
margin-top: 78px;
.item{
.item {
width: 258px;
height: 132px;
background-image: url('../../assets/images/login/item-bg.png');
background-image: url("../../assets/images/login/item-bg.png");
background-repeat: no-repeat;
background-size: cover;
position: relative;
@ -266,7 +238,7 @@ function close() {
box-sizing: border-box;
}
.item-img{
.item-img {
width: 66px;
height: 76px;
position: absolute;
@ -274,7 +246,7 @@ function close() {
left: 20px;
}
.title{
.title {
font-size: 16px;
font-family: PingFang SC, PingFang SC-Medium;
font-weight: Medium;
@ -283,7 +255,7 @@ function close() {
margin-bottom: 8px;
}
.subtitle{
.subtitle {
font-size: 12px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
@ -292,13 +264,29 @@ function close() {
}
}
.item-footer{
width: 970px;
height: 119px;
position: fixed;
left: 50%;
bottom: 0;
margin-left: -485px;
@media screen and (min-width: 1440px) {
.item-footer {
max-width: 970px;
max-height: 119px;
width: 50%;
height: 10vh;
position: fixed;
left: 50%;
bottom: 0;
margin-left: -485px;
}
}
@media screen and (min-width:1440) {
.item-footer {
max-width: 970px;
max-height: 119px;
width: 50%;
height: 10vh;
position: fixed;
left: 60%;
bottom: 0;
margin-left: -485px;
}
}
}
</style>

@ -17,7 +17,7 @@ interface FormState {
const formRef = ref()
const message = useMessage()
const loading = ref(false)
const autoLogin = ref(true)
const autoLogin = ref(false)
const LOGIN_NAME = PageEnum.BASE_LOGIN_NAME
const userStore = useUserStore()
const router = useRouter()
@ -127,7 +127,7 @@ function handleSubmit(e) {
</n-button>
</n-form-item>
<n-form-item class="default-color">
<div class="w-full flex justify-between">
<div class="flex justify-between w-full">
<div class="flex-initial">
<n-checkbox v-model:checked="autoLogin">
记住账号
@ -162,7 +162,7 @@ function handleSubmit(e) {
</n-button>
</n-form-item>
<n-form-item class="default-color">
<div class="w-full flex justify-between">
<div class="flex justify-between w-full">
<div class="flex-initial">
<n-checkbox v-model:checked="autoLogin">
记住账号

@ -497,4 +497,10 @@ onMounted(async () => {
--n-padding-top: 0px;
--n-padding-bottom: 12px;
}
::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important;
}
::v-deep(.n-scrollbar){
border-top: none !important;
}
</style>

@ -483,4 +483,10 @@ onMounted(async () => {
--n-padding-top: 0px;
--n-padding-bottom: 12px;
}
::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important;
}
::v-deep(.n-scrollbar){
border-top: none !important;
}
</style>

@ -497,4 +497,10 @@ onMounted(async () => {
--n-padding-top: 0px;
--n-padding-bottom: 12px;
}
::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important;
}
::v-deep(.n-scrollbar){
border-top: none !important;
}
</style>

Loading…
Cancel
Save