refactor: ♻️ 完善 typescript 类型,重构代码
This commit is contained in:
parent
14e64324f7
commit
5ac4e273aa
|
|
@ -18,8 +18,8 @@ export default [
|
|||
return {
|
||||
code: "00000",
|
||||
data: {
|
||||
verifyCodeKey: "534b8ef2b0a24121bec76391ddd159f9",
|
||||
verifyCodeBase64:
|
||||
captchaKey: "534b8ef2b0a24121bec76391ddd159f9",
|
||||
captchaBase64:
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAAkCAIAAADNSmkJAAAFKUlEQVR4Xu2ZXUwcVRiGV70wMWo08V5NvPXCrDbFaGpMaZW2hqQxaoiJTRsaMBCNSYtpa2JTKiFSelFa+Q/QZcMWqEhBlh+htbEpZhMrBQrlJ0hBywLLyrJ0WZbje3bqOvPNLHPWrDvdOE9ONmfe78zkzMs335wzWJhJQrBQweS/wTQ6QWgYHdoIOcecOe05O+t2WkutO+p2ZF3Ksg/YV9ZW6FATYajR3nveg60H9327r3O8c35lHgp+r05dPdJzBL73TPSQ8SaCKIxGLsPlop+K0JHrEkPuoT31e5qGmmjARACF0agYyGVNlyVm/pzZXrN9fHGcBkz0UBid+31u93i3XFFT80vN8cvHqWqih8Lo1NpUqS5vwh3vnd223VQ10UNh9NbyrcFQUK6oCawHUipSqGqiB83oBf+CXFGDMp1mS6OqiR4Ko7FexkpOrqhpHGw82nOUqiZ6KIzGrkRuorW0dJMmOy+hOCfYGzb2RBFv6HRO0gEJw/U7y+pgL1bwmTxexN6sZ31TdEwEhdG+gA+7EqyXpUO1uZH20cWL8hMTRt1N9tBXzCJrOIRoCPJpSO2RAp4HmtCdIfZ+2JWgEBN9LbR28seTGU0Zue1tMLp+YIAMSADzfvbkKX4/eb28j4YODiGin3heqmIlLja5hAUCu+nmGY3JWKvpMAlqNGgebsauBOvlqSX+JEx7p7EbTLen53XlzfmWUioqXikrc68Y8N2juJ/fyVsNChGHEE//rBANYWaZz+TRQqpLaBgNsPfDrgSpbS21YtV87IdjrlkX9JZbt5DOma2t9ITo5F+5glN22WwL/n+yDv00mw06orKxOqQ5+J04hhViwzAXETIcJDVm8uxZqktoGx2Nj9t43Wgaul/ERQiGQvtbWnDWgZYW9CXlQFjZ/7ciyHNn+Z2MexTimIeLz59TiIln0M1e+IbPpOAaDUnEYPTi6iqKxpbycs/qKo1tCslfKcffPn9enuMiPPY1vxO/ckeFQ4h46cdGqUWoidE/y54q5tPY5WDrGzQqIXot4BgchEE57e00IMCw2/1qZSVO/7SjA78o9INzcxsbrL+fnTnDDh9mmZn8F30oG1Hm+nABv5mQMopDS/h1HxtqTzWbABMe9sxpPoe9zezeOo1GELqWhPS8t46M0IAYHbdvR1aHbaOjbjfLz2eFhez6dba4yAfgF30o0BFVE8+Mjh/wFxPI+I5mAEHU6Ls+38vhTFwOBGhMDF8gkFpbC5ffsdv/uBs6dIj19dExEtARVXv9YNbop8NFY3aZ6gRRo+tu3IBHnzmdNCBMXldXJKPfL74WzWUJRE+coDUknqsOdZXQbAJYwluVTbOZI3Qt8GFzMwxyjo3RgBiN4fr+elXVpZGRLWXl6PdOTtJBSlBDUK/lnIrjOlrtqWYTQDJaF6FrTXu9sOa1ysrVoM5HVE1GFxZQcyJ/p+xzv6K/rbr6N6+XDpUBl0tKFIrbz78qWB6YnWFMCBld4XLBms+7df75ook/GNzb0GCV7U1Qfz9p64TyQWNjYD3qe9rj4SMJtQP3MyjSDPzWIRHPjH7X4YAvfXoPuyZf9Pbi3PcuXIh4mp3NllYC6XY79C+jl2o8PBipxjnBttn4MgMNnWgfcRJGPI2OL8hTj3LloIlmRicvBhiNykvecpqoa3RSY4DRcLAwyicuOepVR1JjgNFYHWONHL04czTX0UmNAUYD7Pr+xc4wqTHGaBb2OtZvHUmNYUazcA2J6etdUmOk0f8rTKMTxF91RG0D1SwYGwAAAABJRU5ErkJggg==",
|
||||
},
|
||||
msg: "一切ok",
|
||||
|
|
|
|||
|
|
@ -1,88 +0,0 @@
|
|||
import request from "@/utils/request";
|
||||
|
||||
export interface ArticleQuery {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
sort?: string;
|
||||
title?: string;
|
||||
type?: string;
|
||||
importance?: number;
|
||||
}
|
||||
|
||||
export interface ArticleDetail {
|
||||
id: number;
|
||||
timestamp: number;
|
||||
title: string;
|
||||
type: string;
|
||||
status: string;
|
||||
importance: number;
|
||||
content?: string;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface ArticleCreate {
|
||||
type: string;
|
||||
timestamp: Date;
|
||||
title: string;
|
||||
status?: string;
|
||||
importance?: number;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface ArticleUpdate {
|
||||
id: number;
|
||||
type?: string;
|
||||
timestamp?: Date;
|
||||
title?: string;
|
||||
status?: string;
|
||||
importance?: number;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export function fetchList(query: ArticleQuery) {
|
||||
return request({
|
||||
url: "/api/v1/article/list",
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchArticle(id: number) {
|
||||
return request({
|
||||
url: "/api/v1/article/detail",
|
||||
method: "get",
|
||||
params: { id },
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchPv(id: number) {
|
||||
return request({
|
||||
url: "/api/v1/article/pv",
|
||||
method: "get",
|
||||
params: { id },
|
||||
});
|
||||
}
|
||||
|
||||
export function createArticle(data: ArticleCreate) {
|
||||
return request({
|
||||
url: "/api/v1/article/create",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateArticle(data: ArticleUpdate) {
|
||||
return request({
|
||||
url: "/api/v1/article/update",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteArticle(id: number) {
|
||||
return request({
|
||||
url: "/api/v1/article/delete",
|
||||
method: "post",
|
||||
data: { id },
|
||||
});
|
||||
}
|
||||
|
|
@ -12,8 +12,8 @@ export function loginApi(data: LoginData): AxiosPromise<LoginResult> {
|
|||
const formData = new FormData();
|
||||
formData.append("username", data.username);
|
||||
formData.append("password", data.password);
|
||||
formData.append("verifyCodeKey", data.verifyCodeKey || "");
|
||||
formData.append("verifyCode", data.verifyCode || "");
|
||||
formData.append("captchaKey", data.captchaKey || "");
|
||||
formData.append("captchaCode", data.captchaCode || "");
|
||||
return request({
|
||||
url: "/api/v1/auth/login",
|
||||
method: "post",
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ export interface LoginData {
|
|||
/**
|
||||
* 验证码缓存key
|
||||
*/
|
||||
verifyCodeKey?: string;
|
||||
captchaKey?: string;
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
verifyCode?: string;
|
||||
captchaCode?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -51,9 +51,9 @@ export interface CaptchaResult {
|
|||
/**
|
||||
* 验证码缓存key
|
||||
*/
|
||||
verifyCodeKey: string;
|
||||
captchaKey: string;
|
||||
/**
|
||||
* 验证码图片Base64字符串
|
||||
*/
|
||||
captchaImgBase64: string;
|
||||
captchaBase64: string;
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512"><path d="M400 148l-21.12-24.57A191.43 191.43 0 0 0 240 64C134 64 48 150 48 256s86 192 192 192a192.09 192.09 0 0 0 181.07-128" fill="none" stroke="currentColor" stroke-linecap="square" stroke-miterlimit="10" stroke-width="32"></path><path d="M464 68.45V220a4 4 0 0 1-4 4H308.45a4 4 0 0 1-2.83-6.83L457.17 65.62a4 4 0 0 1 6.83 2.83z" fill="currentColor"></path></svg>
|
||||
|
After Width: | Height: | Size: 562 B |
|
|
@ -9,7 +9,7 @@ export default {
|
|||
username: "Username",
|
||||
password: "Password",
|
||||
login: "Login",
|
||||
verifyCode: "Verify Code",
|
||||
captchaCode: "Verify Code",
|
||||
},
|
||||
// 导航栏国际化
|
||||
navbar: {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export default {
|
|||
username: "用户名",
|
||||
password: "密码",
|
||||
login: "登 录",
|
||||
verifyCode: "验证码",
|
||||
captchaCode: "验证码",
|
||||
},
|
||||
// 导航栏国际化
|
||||
navbar: {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ const tagsViewStore = useTagsViewStore();
|
|||
const appStore = useAppStore();
|
||||
|
||||
const { visitedViews } = storeToRefs(tagsViewStore);
|
||||
console.log("visitedViews", visitedViews);
|
||||
const settingsStore = useSettingsStore();
|
||||
const layout = computed(() => settingsStore.layout);
|
||||
|
||||
|
|
@ -141,11 +142,14 @@ function filterAffixTags(routes: RouteRecordRaw[], basePath = "/") {
|
|||
let tags: TagView[] = [];
|
||||
routes.forEach(processRoute);
|
||||
|
||||
console.log("filterAffixTags", tags);
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
function initTags() {
|
||||
const tags: TagView[] = filterAffixTags(permissionStore.routes);
|
||||
console.log("initTags", tags);
|
||||
affixTags.value = tags;
|
||||
for (const tag of tags) {
|
||||
// Must have tag name
|
||||
|
|
@ -156,6 +160,7 @@ function initTags() {
|
|||
}
|
||||
|
||||
function addTags() {
|
||||
console.log("addTags", visitedViews);
|
||||
if (route.meta.title) {
|
||||
tagsViewStore.addView({
|
||||
name: route.name as string,
|
||||
|
|
@ -169,13 +174,14 @@ function addTags() {
|
|||
}
|
||||
|
||||
function moveToCurrentTag() {
|
||||
console.log("moveToCurrentTag", visitedViews);
|
||||
// 使用 nextTick() 的目的是确保在更新 tagsView 组件之前,scrollPaneRef 对象已经滚动到了正确的位置。
|
||||
nextTick(() => {
|
||||
for (const tag of visitedViews.value) {
|
||||
if (tag.path === route.path) {
|
||||
scrollPaneRef.value.moveToTarget(tag);
|
||||
// when query is different then update
|
||||
route.query = { ...route.query, ...tag.query };
|
||||
// route.query = { ...route.query, ...tag.query };
|
||||
if (tag.fullPath !== route.fullPath) {
|
||||
tagsViewStore.updateVisitedView({
|
||||
name: route.name as string,
|
||||
|
|
|
|||
|
|
@ -80,31 +80,30 @@ function toggleSideBar() {
|
|||
|
||||
<template>
|
||||
<div :class="classObj" class="app-wrapper">
|
||||
<el-watermark content="vue3-element-admin">
|
||||
<!-- 手机设备侧边栏打开遮罩层 -->
|
||||
<div
|
||||
v-if="classObj.mobile && classObj.openSidebar"
|
||||
class="drawer-bg"
|
||||
@click="handleOutsideClick"
|
||||
></div>
|
||||
<!-- 手机设备侧边栏打开遮罩层 -->
|
||||
<div
|
||||
v-if="classObj.mobile && classObj.openSidebar"
|
||||
class="drawer__background"
|
||||
@click="handleOutsideClick"
|
||||
></div>
|
||||
|
||||
<Sidebar class="sidebar-container" />
|
||||
<template v-if="layout === 'mix'">
|
||||
<div class="mix-wrap">
|
||||
<div class="left-wrap">
|
||||
<LeftMenu :menu-list="mixLeftMenu" :base-path="activeTopMenu" />
|
||||
<div class="menu-action">
|
||||
<hamburger
|
||||
:is-active="appStore.sidebar.opened"
|
||||
@toggle-click="toggleSideBar"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Main />
|
||||
<Sidebar class="sidebar-container" />
|
||||
|
||||
<div v-if="layout === 'mix'" class="mix-wrapper">
|
||||
<div class="mix-wrapper__left">
|
||||
<LeftMenu :menu-list="mixLeftMenu" :base-path="activeTopMenu" />
|
||||
<!-- 展开/收缩侧边栏菜单 -->
|
||||
<div class="toggle-sidebar">
|
||||
<hamburger
|
||||
:is-active="appStore.sidebar.opened"
|
||||
@toggle-click="toggleSideBar"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<Main v-else />
|
||||
</el-watermark>
|
||||
</div>
|
||||
<Main />
|
||||
</div>
|
||||
|
||||
<Main v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -126,7 +125,7 @@ function toggleSideBar() {
|
|||
}
|
||||
}
|
||||
|
||||
.drawer-bg {
|
||||
.drawer__background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
|
|
@ -177,12 +176,12 @@ function toggleSideBar() {
|
|||
margin-left: 0;
|
||||
}
|
||||
|
||||
.mix-wrap {
|
||||
.mix-wrapper {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding-top: 50px;
|
||||
|
||||
.left-wrap {
|
||||
.mix-wrapper__left {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
|
|
@ -190,7 +189,7 @@ function toggleSideBar() {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.menu-action {
|
||||
.toggle-sidebar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
|
|
@ -219,8 +218,8 @@ function toggleSideBar() {
|
|||
}
|
||||
|
||||
.openSidebar {
|
||||
.mix-wrap {
|
||||
.left-wrap {
|
||||
.mix-wrapper {
|
||||
.mix-wrapper__left {
|
||||
width: $sideBarWidth;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@ export const useTagsViewStore = defineStore("tagsView", () => {
|
|||
const visitedViews = ref<TagView[]>([]);
|
||||
const cachedViews = ref<string[]>([]);
|
||||
|
||||
console.log("first visitedViews", visitedViews, "cachedViews", cachedViews);
|
||||
|
||||
/**
|
||||
* 添加已访问视图到已访问视图列表中
|
||||
*/
|
||||
function addVisitedView(view: TagView) {
|
||||
console.log("addVisitedView", visitedViews, view);
|
||||
// 如果已经存在于已访问的视图列表中,则不再添加
|
||||
if (visitedViews.value.some((v) => v.path === view.path)) {
|
||||
if (visitedViews.value.some((v) => v.fullPath === view.fullPath)) {
|
||||
return;
|
||||
}
|
||||
// 如果视图是固定的(affix),则在已访问的视图列表的开头添加
|
||||
|
|
@ -25,6 +28,7 @@ export const useTagsViewStore = defineStore("tagsView", () => {
|
|||
* 添加缓存视图到缓存视图列表中
|
||||
*/
|
||||
function addCachedView(view: TagView) {
|
||||
console.log("addCachedView", visitedViews, view);
|
||||
const viewName = view.name;
|
||||
// 如果缓存视图名称已经存在于缓存视图列表中,则不再添加
|
||||
if (cachedViews.value.includes(viewName)) {
|
||||
|
|
@ -86,6 +90,7 @@ export const useTagsViewStore = defineStore("tagsView", () => {
|
|||
}
|
||||
|
||||
function updateVisitedView(view: TagView) {
|
||||
console.log("updateVisitedView", visitedViews, view);
|
||||
for (let v of visitedViews.value) {
|
||||
if (v.path === view.path) {
|
||||
v = Object.assign(v, view);
|
||||
|
|
@ -95,6 +100,7 @@ export const useTagsViewStore = defineStore("tagsView", () => {
|
|||
}
|
||||
|
||||
function addView(view: TagView) {
|
||||
console.log("addView", visitedViews, view);
|
||||
addVisitedView(view);
|
||||
addCachedView(view);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@
|
|||
}
|
||||
|
||||
.hideSidebar {
|
||||
.left-wrap {
|
||||
.mix-wrapper__left {
|
||||
width: 54px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ orderCount.value = 2000;
|
|||
<el-statistic :value="99">
|
||||
<template #title>
|
||||
<div class="flex items-center">
|
||||
<svg-icon icon-class="message" :size="20" />
|
||||
<svg-icon icon-class="message" size="20px" />
|
||||
<span class="text-[16px] ml-1">消息</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -96,7 +96,7 @@ orderCount.value = 2000;
|
|||
<el-statistic :value="50">
|
||||
<template #title>
|
||||
<div class="flex items-center">
|
||||
<svg-icon icon-class="todolist" :size="20" />
|
||||
<svg-icon icon-class="todolist" size="20px" />
|
||||
<span class="text-[16px] ml-1">待办</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -106,7 +106,7 @@ orderCount.value = 2000;
|
|||
<el-statistic :value="10">
|
||||
<template #title>
|
||||
<div class="flex items-center">
|
||||
<svg-icon icon-class="project" :size="20" />
|
||||
<svg-icon icon-class="project" size="20px" />
|
||||
<span class="text-[16px] ml-1">项目</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -70,15 +70,15 @@
|
|||
</el-tooltip>
|
||||
|
||||
<!-- 验证码 -->
|
||||
<el-form-item prop="verifyCode">
|
||||
<el-form-item prop="captchaCode">
|
||||
<span class="p-2">
|
||||
<svg-icon icon-class="verify-code" />
|
||||
<svg-icon icon-class="captcha" />
|
||||
</span>
|
||||
|
||||
<el-input
|
||||
v-model="loginData.verifyCode"
|
||||
v-model="loginData.captchaCode"
|
||||
auto-complete="off"
|
||||
:placeholder="$t('login.verifyCode')"
|
||||
:placeholder="$t('login.captchaCode')"
|
||||
class="w-[60%]"
|
||||
@keyup.enter="handleLogin"
|
||||
/>
|
||||
|
|
@ -211,11 +211,11 @@ const loginRules = computed(() => {
|
|||
message: `${prefix}${t("login.password")}`,
|
||||
},
|
||||
],
|
||||
verifyCode: [
|
||||
captchaCode: [
|
||||
{
|
||||
required: true,
|
||||
trigger: "blur",
|
||||
message: `${prefix}${t("login.verifyCode")}`,
|
||||
message: `${prefix}${t("login.captchaCode")}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -234,9 +234,8 @@ function checkCapslock(e: any) {
|
|||
*/
|
||||
function getCaptcha() {
|
||||
getCaptchaApi().then(({ data }) => {
|
||||
const { captchaImgBase64, verifyCodeKey } = data;
|
||||
loginData.value.verifyCodeKey = verifyCodeKey;
|
||||
captchaBase64.value = captchaImgBase64;
|
||||
loginData.value.captchaKey = data.captchaKey;
|
||||
captchaBase64.value = data.captchaBase64;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
|
|||
},
|
||||
vueTemplate: true,
|
||||
// 配置文件生成位置(false:关闭自动生成)
|
||||
//dts: false,
|
||||
dts: "src/types/auto-imports.d.ts",
|
||||
dts: false,
|
||||
// dts: "src/types/auto-imports.d.ts",
|
||||
}),
|
||||
|
||||
Components({
|
||||
|
|
@ -94,8 +94,8 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
|
|||
// 指定自定义组件位置(默认:src/components)
|
||||
dirs: ["src/components", "src/**/components"],
|
||||
// 配置文件位置 (false:关闭自动生成)
|
||||
// dts: false,
|
||||
dts: "src/types/components.d.ts",
|
||||
dts: false,
|
||||
// dts: "src/types/components.d.ts",
|
||||
}),
|
||||
|
||||
Icons({
|
||||
|
|
|
|||
Loading…
Reference in New Issue