feat: 全局筛选弹框样式适配,登录逻辑修补

pull/1/head
刘释隆 1 year ago
parent 547314a591
commit 97bd8a6fe2

@ -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','/api/web/smslogin/login']
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>

@ -52,7 +52,17 @@ const formSms: FormSms = reactive({
const tab = ref(0);
const countTime = ref("获取验证码");
const rules = {
enterprisecode: { 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" },
phone: { required: true, message: "请输入手机号", trigger: "blur" },
phonecode: [
@ -84,7 +94,6 @@ function handleSubmit(e) {
const { username, password, enterprisecode } = formInline;
message.loading("登录中...");
loading.value = true;
const params = {
username,
password,
@ -94,15 +103,17 @@ function handleSubmit(e) {
try {
const { code, message: msg } = await userStore.login(params);
loginRejectMessge.value = msg;
if (code === ResultEnum.SUCCESS) {
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 || "登录失败");
}
@ -145,8 +156,7 @@ function handleSmsSubmit(e) {
message.info(msg || "登录失败");
loginSuccess.value = false;
}
}
catch(e){
} catch (e) {
} finally {
loading.value = false;
}
@ -167,18 +177,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();
}
@ -236,6 +251,7 @@ function forget() {
v-model:value="formInline.enterprisecode"
class="item-input"
placeholder="请输入企业编码"
maxlength="20"
>
<template #prefix>
<svg-icon size="20" name="enterprise" />
@ -247,6 +263,7 @@ function forget() {
v-model:value="formInline.username"
class="item-input"
placeholder="请输入用户名"
maxlength="16"
>
<template #prefix>
<svg-icon size="20" name="account" />
@ -260,6 +277,7 @@ function forget() {
type="password"
show-password-on="click"
placeholder="请输入密码"
maxlength="16"
>
<template #prefix>
<svg-icon size="20" name="password" />
@ -275,6 +293,7 @@ function forget() {
:loading="loading"
block
@click="handleSubmit"
:disabled="computedForm()"
>
登录
</n-button>
@ -287,7 +306,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>
@ -346,7 +365,10 @@ function forget() {
</template>
<template #suffix>
<div
:class="{ 'code-count': countTime !== '获取验证码' }"
:class="{
'code-count':
countTime !== '获取验证码' || !(formSms.phone.length == 11),
}"
class="code"
@click="sendCode"
>
@ -364,6 +386,7 @@ function forget() {
:loading="loading"
block
@click="handleSmsSubmit"
:disabled="computedForm()"
>
登录
</n-button>
@ -376,7 +399,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>

@ -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