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 // eslint-disable-next-line ts/no-use-before-define
const instance = http.getAxios() const instance = http.getAxios()
const config = response.config 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) const expirationTime = storage.get(TOKEN_EXPIRATION_TIME)
// console.log('剩余失效时间(分):', (expirationTime - Date.now()) / 1000 / 60, config.url) // console.log('剩余失效时间(分):', (expirationTime - Date.now()) / 1000 / 60, config.url)
@ -264,7 +264,7 @@ const transform: AxiosTransform = {
if (err && err.includes('Network Error')) { if (err && err.includes('Network Error')) {
$dialog.info({ $dialog.info({
title: '网络异常', title: '网络异常',
content: '请检查您的网络连接是否正常', content: '网络错误,请重试!',
positiveText: '确定', positiveText: '确定',
// negativeText: '取消', // negativeText: '取消',
closable: false, closable: false,

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

@ -561,4 +561,10 @@ function removeHandler(id: string, type: "fix" | "unfix") {
--n-padding-top: 0px; --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> </style>

@ -433,6 +433,13 @@ onMounted(()=>{
::v-deep(.n-card > .n-card-header) { ::v-deep(.n-card > .n-card-header) {
--n-padding-top: 0px; --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> </style>

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

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

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

@ -497,4 +497,10 @@ onMounted(async () => {
--n-padding-top: 0px; --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> </style>

@ -483,4 +483,10 @@ onMounted(async () => {
--n-padding-top: 0px; --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> </style>

@ -497,4 +497,10 @@ onMounted(async () => {
--n-padding-top: 0px; --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> </style>

Loading…
Cancel
Save