后台前端
This commit is contained in:
parent
aec7b928f5
commit
5a4d9181cb
2
.env
2
.env
@ -8,4 +8,4 @@ VITE_OPEN = false
|
|||||||
VITE_OPEN_CDN = false
|
VITE_OPEN_CDN = false
|
||||||
|
|
||||||
# public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可
|
# public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可
|
||||||
VITE_PUBLIC_PATH = /vue-next-admin-preview/
|
VITE_PUBLIC_PATH = ./
|
@ -2,4 +2,5 @@
|
|||||||
ENV = production
|
ENV = production
|
||||||
|
|
||||||
# 线上环境接口地址
|
# 线上环境接口地址
|
||||||
VITE_API_URL = https://lyt-top.gitee.io/vue-next-admin-preview/
|
# VITE_API_URL = https://lyt-top.gitee.io/vue-next-admin-preview/
|
||||||
|
VITE_API_URL = http://8.138.171.103/
|
4694
package-lock.json
generated
4694
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -47,6 +47,7 @@
|
|||||||
"@typescript-eslint/parser": "^7.2.0",
|
"@typescript-eslint/parser": "^7.2.0",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vue/compiler-sfc": "^3.4.21",
|
"@vue/compiler-sfc": "^3.4.21",
|
||||||
|
"code-inspector-plugin": "^0.17.6",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-vue": "^9.23.0",
|
"eslint-plugin-vue": "^9.23.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
|
50
src/api/article/index.ts
Normal file
50
src/api/article/index.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import request from '/@/utils/request';
|
||||||
|
import { baseUrlHost } from '../baseUrlHost';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (不建议写成 request.post(xxx),因为这样 post 时,无法 params 与 data 同时传参)
|
||||||
|
* 注意在写get请求时,参数是params,而不是data,要标注好
|
||||||
|
*
|
||||||
|
* 登录api接口集合
|
||||||
|
* @method getArticleList 获取文章列表
|
||||||
|
* @method getModuleList 获取模块列表
|
||||||
|
* @method getLabelList 获取标签列表
|
||||||
|
* @method deleteArticle 删除文章
|
||||||
|
* @method getArticleDetail 获取文章详情
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function articleApi() {
|
||||||
|
return {
|
||||||
|
getArticleList: (params: object) => {
|
||||||
|
return request({
|
||||||
|
url: baseUrlHost + '/cpArticle',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getModuleList: () => {
|
||||||
|
return request({
|
||||||
|
url: baseUrlHost + '/cpModule/all',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getLabelList: (moduleid: Number) => {
|
||||||
|
return request({
|
||||||
|
url: baseUrlHost + `/cpLabel/moduleid/${moduleid}`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteArticle: (id: Number) => {
|
||||||
|
return request({
|
||||||
|
url: baseUrlHost + `/cpArticle/${id}`,
|
||||||
|
method: 'delete',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getArticleDetail: (id: Number) => {
|
||||||
|
return request({
|
||||||
|
url: baseUrlHost + `/cpArticle/${id}`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
1
src/api/baseUrlHost.ts
Normal file
1
src/api/baseUrlHost.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const baseUrlHost = "/vueAdminApi";
|
@ -1,12 +1,16 @@
|
|||||||
import request from '/@/utils/request';
|
import request from '/@/utils/request';
|
||||||
|
import { baseUrlHost } from '../baseUrlHost';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (不建议写成 request.post(xxx),因为这样 post 时,无法 params 与 data 同时传参)
|
* (不建议写成 request.post(xxx),因为这样 post 时,无法 params 与 data 同时传参)
|
||||||
*
|
* 注意在写get请求时,参数是params,而不是data,要标注好
|
||||||
* 登录api接口集合
|
* 登录api接口集合
|
||||||
* @method signIn 用户登录
|
* @method signIn 用户登录
|
||||||
* @method signOut 用户退出登录
|
* @method signOut 用户退出登录
|
||||||
|
* @method login 登录
|
||||||
|
* @method loginOut 登出
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function useLoginApi() {
|
export function useLoginApi() {
|
||||||
return {
|
return {
|
||||||
signIn: (data: object) => {
|
signIn: (data: object) => {
|
||||||
@ -23,5 +27,18 @@ export function useLoginApi() {
|
|||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
login: (data: object) => {
|
||||||
|
return request({
|
||||||
|
url: baseUrlHost+'/acUser/login',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
loginOut: () => {
|
||||||
|
return request({
|
||||||
|
url: baseUrlHost+'/acUser/logout',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
:prop="item.key"
|
:prop="item.key"
|
||||||
:width="item.colWidth"
|
:width="item.colWidth"
|
||||||
:label="item.title"
|
:label="item.title"
|
||||||
|
:formatter="item.formatter"
|
||||||
>
|
>
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<template v-if="item.type === 'image'">
|
<template v-if="item.type === 'image'">
|
||||||
|
@ -8,6 +8,10 @@ export default {
|
|||||||
systemUser: 'systemUser',
|
systemUser: 'systemUser',
|
||||||
systemDept: 'systemDept',
|
systemDept: 'systemDept',
|
||||||
systemDic: 'systemDic',
|
systemDic: 'systemDic',
|
||||||
|
article: 'article',
|
||||||
|
articleDetail: 'articleDetail',
|
||||||
|
addArticle: 'addArticle',
|
||||||
|
editArticle: 'editArticle',
|
||||||
limits: 'limits',
|
limits: 'limits',
|
||||||
limitsFrontEnd: 'FrontEnd',
|
limitsFrontEnd: 'FrontEnd',
|
||||||
limitsFrontEndPage: 'FrontEndPage',
|
limitsFrontEndPage: 'FrontEndPage',
|
||||||
|
@ -8,6 +8,10 @@ export default {
|
|||||||
systemUser: '用户管理',
|
systemUser: '用户管理',
|
||||||
systemDept: '部门管理',
|
systemDept: '部门管理',
|
||||||
systemDic: '字典管理',
|
systemDic: '字典管理',
|
||||||
|
article: '文章管理',
|
||||||
|
articleDetail: '文章详情',
|
||||||
|
addArticle: '新增文章',
|
||||||
|
editArticle: '编辑文章',
|
||||||
limits: '权限管理',
|
limits: '权限管理',
|
||||||
limitsFrontEnd: '前端控制',
|
limitsFrontEnd: '前端控制',
|
||||||
limitsFrontEndPage: '页面权限',
|
limitsFrontEndPage: '页面权限',
|
||||||
|
@ -8,6 +8,10 @@ export default {
|
|||||||
systemUser: '用戶管理',
|
systemUser: '用戶管理',
|
||||||
systemDept: '部門管理',
|
systemDept: '部門管理',
|
||||||
systemDic: '字典管理',
|
systemDic: '字典管理',
|
||||||
|
article: '文章管理',
|
||||||
|
articleDetail: '文章詳情',
|
||||||
|
addArticle: '文章新增',
|
||||||
|
editArticle: '文章編輯',
|
||||||
limits: '許可權管理',
|
limits: '許可權管理',
|
||||||
limitsFrontEnd: '前端控制',
|
limitsFrontEnd: '前端控制',
|
||||||
limitsFrontEndPage: '頁面許可權',
|
limitsFrontEndPage: '頁面許可權',
|
||||||
|
@ -97,11 +97,15 @@ import { useThemeConfig } from '/@/stores/themeConfig';
|
|||||||
import other from '/@/utils/other';
|
import other from '/@/utils/other';
|
||||||
import mittBus from '/@/utils/mitt';
|
import mittBus from '/@/utils/mitt';
|
||||||
import { Session, Local } from '/@/utils/storage';
|
import { Session, Local } from '/@/utils/storage';
|
||||||
|
import { useLoginApi } from '/@/api/login';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/topBar/userNews.vue'));
|
const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/topBar/userNews.vue'));
|
||||||
const Search = defineAsyncComponent(() => import('/@/layout/navBars/topBar/search.vue'));
|
const Search = defineAsyncComponent(() => import('/@/layout/navBars/topBar/search.vue'));
|
||||||
|
|
||||||
|
// 引入 api 请求接口
|
||||||
|
const loginApi = useLoginApi();
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const userNewsRef = ref();
|
const userNewsRef = ref();
|
||||||
const userNewsBadgeRef = ref();
|
const userNewsBadgeRef = ref();
|
||||||
@ -159,16 +163,17 @@ const onHandleCommandClick = (path: string) => {
|
|||||||
confirmButtonText: t('message.user.logOutConfirm'),
|
confirmButtonText: t('message.user.logOutConfirm'),
|
||||||
cancelButtonText: t('message.user.logOutCancel'),
|
cancelButtonText: t('message.user.logOutCancel'),
|
||||||
buttonSize: 'default',
|
buttonSize: 'default',
|
||||||
beforeClose: (action, instance, done) => {
|
beforeClose: async (action, instance, done) => {
|
||||||
if (action === 'confirm') {
|
if (action === 'confirm') {
|
||||||
|
try {
|
||||||
instance.confirmButtonLoading = true;
|
instance.confirmButtonLoading = true;
|
||||||
instance.confirmButtonText = t('message.user.logOutExit');
|
instance.confirmButtonText = t('message.user.logOutExit');
|
||||||
setTimeout(() => {
|
await loginApi.loginOut();
|
||||||
|
} catch (error) {
|
||||||
|
} finally {
|
||||||
done();
|
done();
|
||||||
setTimeout(() => {
|
|
||||||
instance.confirmButtonLoading = false;
|
instance.confirmButtonLoading = false;
|
||||||
}, 300);
|
}
|
||||||
}, 700);
|
|
||||||
} else {
|
} else {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
@ -176,6 +181,7 @@ const onHandleCommandClick = (path: string) => {
|
|||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
// 清除缓存/token等
|
// 清除缓存/token等
|
||||||
|
console.log('清除缓存/token等');
|
||||||
Session.clear();
|
Session.clear();
|
||||||
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
|
@ -155,6 +155,68 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/article',
|
||||||
|
name: 'article',
|
||||||
|
component: () => import('/@/views/article/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'message.router.article',
|
||||||
|
isLink: '',
|
||||||
|
isHide: false,
|
||||||
|
isKeepAlive: true,
|
||||||
|
isAffix: false,
|
||||||
|
isIframe: false,
|
||||||
|
roles: ['admin', 'common'],
|
||||||
|
icon: 'iconfont icon-jiliandongxuanzeqi',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/article/detail',
|
||||||
|
name: 'articleDetail',
|
||||||
|
component: () => import('/@/views/article/component/detail.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'message.router.articleDetail',
|
||||||
|
isLink: '',
|
||||||
|
isHide: true,
|
||||||
|
isKeepAlive: false,
|
||||||
|
isAffix: false,
|
||||||
|
isIframe: false,
|
||||||
|
roles: ['admin','common'],
|
||||||
|
icon: 'ele-Document',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/article/add',
|
||||||
|
name: 'addArticle',
|
||||||
|
component: () => import('/@/views/article/component/upload.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'message.router.addArticle',
|
||||||
|
isLink: '',
|
||||||
|
isHide: true,
|
||||||
|
isKeepAlive: false,
|
||||||
|
isAffix: false,
|
||||||
|
isIframe: false,
|
||||||
|
roles: ['admin','common'],
|
||||||
|
icon: 'ele-Document',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/article/edit',
|
||||||
|
name: 'editArticle',
|
||||||
|
component: () => import('/@/views/article/component/upload.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'message.router.editArticle',
|
||||||
|
isLink: '',
|
||||||
|
isHide: true,
|
||||||
|
isKeepAlive: false,
|
||||||
|
isAffix: false,
|
||||||
|
isIframe: false,
|
||||||
|
roles: ['admin','common'],
|
||||||
|
icon: 'ele-Document',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/limits',
|
path: '/limits',
|
||||||
name: 'limits',
|
name: 'limits',
|
||||||
|
@ -21,6 +21,7 @@ service.interceptors.request.use(
|
|||||||
// 在发送请求之前做些什么 token
|
// 在发送请求之前做些什么 token
|
||||||
if (Session.get('token')) {
|
if (Session.get('token')) {
|
||||||
config.headers!['Authorization'] = `${Session.get('token')}`;
|
config.headers!['Authorization'] = `${Session.get('token')}`;
|
||||||
|
config.headers!['token'] = `${Session.get('token')}`;
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
|
143
src/views/article/component/detail.vue
Normal file
143
src/views/article/component/detail.vue
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
<template>
|
||||||
|
<div class="layout-pd">
|
||||||
|
<el-card v-loading="state.loading" shadow="hover" header="文章详情">
|
||||||
|
<el-form :model="state.data" size="large" label-width="100px" class="mt20 mb20">
|
||||||
|
<el-row :gutter="35">
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="封面:">
|
||||||
|
<el-image
|
||||||
|
style="width: 100px;height: 100px;border-radius: 4px;"
|
||||||
|
:src="state.data.photo"
|
||||||
|
:zoom-rate="1.2"
|
||||||
|
:preview-src-list="[state.data.photo]"
|
||||||
|
preview-teleported
|
||||||
|
fit="cover"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="模块名称:">
|
||||||
|
{{ state.data.moduleName }}
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="标签名称:">
|
||||||
|
{{ state.data.labelName }}
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="标题:">
|
||||||
|
{{ state.data.title }}
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="文章类型:">
|
||||||
|
图文
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="是否置顶:">
|
||||||
|
<el-tag type="success" v-if="state.data.top===1">是</el-tag>
|
||||||
|
<el-tag type="error" v-else>否</el-tag>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="浏览数:">
|
||||||
|
{{ state.data.view }}
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="创建日期:">
|
||||||
|
{{ dateFormatter() }}
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<!-- <div class="mt5 mb20 ml10">文章内容:</div> -->
|
||||||
|
<Editor v-model:get-html="state.data.text" v-model:get-text="state.data.text" :disable="true" />
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="articleDetail">
|
||||||
|
import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
|
||||||
|
import { articleApi } from '/@/api/article';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
// 引入组件
|
||||||
|
const Editor = defineAsyncComponent(() => import('/@/components/editor/index.vue'));
|
||||||
|
|
||||||
|
// 引入 api 请求接口
|
||||||
|
const artApi = articleApi();
|
||||||
|
|
||||||
|
// 模块列表
|
||||||
|
const moduleList = ref([]);
|
||||||
|
|
||||||
|
// 获取模块名称和标签名称
|
||||||
|
const route = useRoute();
|
||||||
|
const moduleName:any = route.query.moduleName;
|
||||||
|
const labelName:any = route.query.labelName;
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
data: {
|
||||||
|
labelName: '',
|
||||||
|
moduleName: '',
|
||||||
|
title: '',
|
||||||
|
articletype: 0,
|
||||||
|
createtime: '',
|
||||||
|
photo: '',
|
||||||
|
text: '',
|
||||||
|
top: 0,
|
||||||
|
view: 0,
|
||||||
|
},
|
||||||
|
loading: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取文章详情
|
||||||
|
const getArticleDetail = async() => {
|
||||||
|
try {
|
||||||
|
state.loading = true;
|
||||||
|
let res = await artApi.getArticleList({
|
||||||
|
moduleName: moduleName,
|
||||||
|
labelName: labelName,
|
||||||
|
size: 1,
|
||||||
|
current: 1
|
||||||
|
});
|
||||||
|
if(res?.success) {
|
||||||
|
state.data = res.data.records[0];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取文章详情失败');
|
||||||
|
} finally {
|
||||||
|
state.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取模块列表
|
||||||
|
const getModuleList = async() => {
|
||||||
|
try {
|
||||||
|
let res = await artApi.getModuleList();
|
||||||
|
if(res?.success){
|
||||||
|
moduleList.value = res.data;
|
||||||
|
}else{
|
||||||
|
ElMessage.error('模块列表获取失败!');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('模块列表获取失败!');
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日期格式化
|
||||||
|
function dateFormatter(){
|
||||||
|
if(!state.data.createtime) return '';
|
||||||
|
let date = new Date(state.data.createtime);
|
||||||
|
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getArticleDetail();
|
||||||
|
getModuleList();
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
234
src/views/article/component/upload.vue
Normal file
234
src/views/article/component/upload.vue
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
<template>
|
||||||
|
<div class="layout-pd">
|
||||||
|
<el-card v-loading="state.loading" shadow="hover" header="文章详情">
|
||||||
|
<el-form ref="articleFormRef" :model="state.data" :rules="state.rules" size="large" label-width="100px" class="mt20 mb20">
|
||||||
|
<el-row :gutter="35">
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="封面:" class="coverImg">
|
||||||
|
<!-- 上传文件 -->
|
||||||
|
<el-upload ref="uploadRef" class="h100 personal-user-left-upload" action="#" list-type="picture-card"
|
||||||
|
:auto-upload="false" :limit="1" :class="{ hide: state.coverHide }" @change="handleUploadChange">
|
||||||
|
<template #default>
|
||||||
|
<el-icon><Plus /></el-icon>
|
||||||
|
</template>
|
||||||
|
<template #file="{ file }">
|
||||||
|
<div>
|
||||||
|
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
|
||||||
|
<span class="el-upload-list__item-actions">
|
||||||
|
<span
|
||||||
|
class="el-upload-list__item-preview"
|
||||||
|
@click="handlePictureCardPreview(file)"
|
||||||
|
>
|
||||||
|
<el-icon><zoom-in /></el-icon>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-if="!disabled"
|
||||||
|
class="el-upload-list__item-delete"
|
||||||
|
@click="handleDownload(file)"
|
||||||
|
>
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-if="!disabled"
|
||||||
|
class="el-upload-list__item-delete"
|
||||||
|
@click="handleRemove(file)"
|
||||||
|
>
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="模块名称:" prop="moduleName">
|
||||||
|
<el-select size="default" v-model="state.data.moduleName" placeholder="请选择模块" clearable>
|
||||||
|
<el-option :data-op="item.id" v-for="(item,index) in moduleList" :key="index" :label="item.moduleName" :value="item.moduleName"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="标签名称:" prop="labelName">
|
||||||
|
<el-input v-model="state.data.labelName" placeholder="请输入标签名称" clearable></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="标题:" prop="title">
|
||||||
|
<el-input v-model="state.data.title" placeholder="请输入标题" clearable></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="文章类型:" prop="articletype">
|
||||||
|
<el-select size="default" v-model="state.data.articletype" placeholder="请选择文章类型" clearable>
|
||||||
|
<el-option label="图文" :value="0"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||||
|
<el-form-item label="是否置顶:" prop="top">
|
||||||
|
<el-switch v-model="state.data.top" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item prop="text" label-width="0px">
|
||||||
|
<Editor v-model:get-html="state.data.text" v-model:get-text="state.data.text" :disable="true" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-row class="flex mt15">
|
||||||
|
<div class="flex-margin" style="width: 100%;display: flex;justify-content: flex-end;">
|
||||||
|
<el-button size="larger" type="primary" @click="onSubmitForm">
|
||||||
|
<SvgIcon name="iconfont icon-shuxing" />
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<!-- 封面预览弹窗 -->
|
||||||
|
<el-dialog v-model="dialogVisible">
|
||||||
|
<img w-full :src="dialogImageUrl" alt="预览" />
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="articleDetail">
|
||||||
|
import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
|
||||||
|
import { articleApi } from '/@/api/article';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { ElMessage, UploadFile, UploadFiles } from 'element-plus';
|
||||||
|
import { Delete, Download, Plus, ZoomIn } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
// 引入组件
|
||||||
|
const Editor = defineAsyncComponent(() => import('/@/components/editor/index.vue'));
|
||||||
|
|
||||||
|
// 引入 api 请求接口
|
||||||
|
const artApi = articleApi();
|
||||||
|
|
||||||
|
// 模块列表
|
||||||
|
const moduleList = ref([]);
|
||||||
|
|
||||||
|
// 获取文章id
|
||||||
|
const route = useRoute();
|
||||||
|
const moduleName:any = route.query.moduleName;
|
||||||
|
const labelName:any = route.query.labelName;
|
||||||
|
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
data: {
|
||||||
|
labelName: '',
|
||||||
|
moduleName: '',
|
||||||
|
title: '',
|
||||||
|
articletype: '',
|
||||||
|
photo: '',
|
||||||
|
text: '',
|
||||||
|
top: false,// 是否置顶,这里提交的时候要换成0或1
|
||||||
|
},
|
||||||
|
loading: false,
|
||||||
|
rules: {
|
||||||
|
moduleName: { required: true, message: '请选择模块', trigger: 'blur' },
|
||||||
|
labelName: { required: true, message: '请输入标签名称', trigger: 'blur' },
|
||||||
|
title: { required: true, message: '请输入标题', trigger: 'blur' },
|
||||||
|
articletype: { required: true, message: '请选择文章类型', trigger: 'blur' },
|
||||||
|
photo: { required: true, message: '请上传图片', trigger: 'blur' },
|
||||||
|
top: { required: true, message: '请选择是否置顶', trigger: 'blur' },
|
||||||
|
text: { required: true, message: '请输入文章内容', trigger: 'blur' },
|
||||||
|
},
|
||||||
|
coverFile: {},
|
||||||
|
coverHide: false
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取文章详情
|
||||||
|
const getArticleDetail = async() => {
|
||||||
|
try {
|
||||||
|
state.loading = true;
|
||||||
|
let res = await artApi.getArticleList({
|
||||||
|
moduleName: moduleName,
|
||||||
|
labelName: labelName,
|
||||||
|
size: 1,
|
||||||
|
current: 1
|
||||||
|
});
|
||||||
|
if(res?.success) {
|
||||||
|
state.data = res.data.records[0];
|
||||||
|
// 下面这里处理一下,因为后端返回的是0和1,而前端需要的是true和false,到时候提交的时候再转换回来
|
||||||
|
// 这个报错没关系的,只是ts的语法检查,不影响运行
|
||||||
|
state.data.top = state.data.top === 1;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取文章详情失败');
|
||||||
|
} finally {
|
||||||
|
state.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取模块列表
|
||||||
|
const getModuleList = async() => {
|
||||||
|
try {
|
||||||
|
let res = await artApi.getModuleList();
|
||||||
|
if(res?.success){
|
||||||
|
moduleList.value = res.data;
|
||||||
|
}else{
|
||||||
|
ElMessage.error('模块列表获取失败!');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('模块列表获取失败!');
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const articleFormRef = ref();
|
||||||
|
|
||||||
|
// 保存文章
|
||||||
|
const onSubmitForm = () => {
|
||||||
|
articleFormRef.value.validate((valid: boolean) => {
|
||||||
|
if (valid){
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 封面上传禁用
|
||||||
|
const disabled = ref(false);
|
||||||
|
// 封面弹窗
|
||||||
|
const dialogImageUrl = ref('');
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
|
||||||
|
const uploadRef = ref();
|
||||||
|
|
||||||
|
// 封面删除
|
||||||
|
const handleRemove = (file: UploadFile) => {
|
||||||
|
state.coverFile = {};
|
||||||
|
state.coverHide = false;
|
||||||
|
uploadRef.value.clearFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 封面预览
|
||||||
|
const handlePictureCardPreview = (file: UploadFile) => {
|
||||||
|
dialogImageUrl.value = file.url!
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 封面下载
|
||||||
|
const handleDownload = (file: UploadFile) => {
|
||||||
|
console.log(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 封面图片更改
|
||||||
|
const handleUploadChange = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
||||||
|
const file:any = uploadFile.raw;
|
||||||
|
state.coverFile = file;
|
||||||
|
state.coverHide = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if(moduleName && labelName && route.path == '/article/edit')
|
||||||
|
getArticleDetail();
|
||||||
|
getModuleList();
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.coverImg :deep(.hide .el-upload--picture-card) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
244
src/views/article/index.vue
Normal file
244
src/views/article/index.vue
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
<template>
|
||||||
|
<div class="system-dept-container layout-padding">
|
||||||
|
<el-card shadow="hover" class="layout-padding-auto">
|
||||||
|
<div class="system-dept-search mb15">
|
||||||
|
<el-select @change="handleChangeModule" size="default" v-model="state.tableData.param.moduleName" placeholder="请选择模块" clearable style="max-width: 180px">
|
||||||
|
<el-option :data-op="item.id" v-for="(item,index) in moduleList" :key="index" :label="item.moduleName" :value="item.moduleName"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-select size="default" v-model="state.tableData.param.labelName" placeholder="请选择标签" clearable class="ml10" style="max-width: 180px">
|
||||||
|
<el-option v-for="(item,index) in labelList" :key="index" :label="item.name" :value="item.name"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-input size="default" placeholder="请输入标题" v-model="state.tableData.param.title" class="ml10" style="max-width: 180px"> </el-input>
|
||||||
|
<el-button @click="getTableData" size="default" type="primary" class="ml10">
|
||||||
|
<el-icon>
|
||||||
|
<ele-Search />
|
||||||
|
</el-icon>
|
||||||
|
查询
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="reset" size="default" type="primary" class="ml10">
|
||||||
|
<el-icon>
|
||||||
|
<ele-RefreshRight />
|
||||||
|
</el-icon>
|
||||||
|
重置
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="toAddArticle" size="default" type="success" class="ml10">
|
||||||
|
<el-icon>
|
||||||
|
<ele-FolderAdd />
|
||||||
|
</el-icon>
|
||||||
|
新增文章
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table :data="state.tableData.data" v-loading="state.tableData.loading" style="width: 100%">
|
||||||
|
<el-table-column type="index" label="序号" width="100"/>
|
||||||
|
<el-table-column prop="moduleName" label="模块名称" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="labelName" label="标签名称" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="title" label="标题" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="articletype" label="文章类型" :formatter="typeFormatter" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="置顶" show-overflow-tooltip>
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag type="success" v-if="scope.row.top===1">是</el-tag>
|
||||||
|
<el-tag type="error" v-else>否</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createtime" label="创建时间" :formatter="dateFormatter" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="操作" width="200">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button size="small" text type="primary" @click="toShowDetail(scope.row)">查看详情</el-button>
|
||||||
|
<el-button size="small" text type="primary" @click="toEditArticle(scope.row)">修改</el-button>
|
||||||
|
<el-button size="small" text type="primary" @click="deleteArticle(scope.row.id)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="onHandleSizeChange"
|
||||||
|
@current-change="onHandleCurrentChange"
|
||||||
|
class="mt15"
|
||||||
|
:pager-count="5"
|
||||||
|
:page-sizes="[10, 20, 30]"
|
||||||
|
v-model:current-page="state.tableData.param.current"
|
||||||
|
background
|
||||||
|
v-model:page-size="state.tableData.param.size"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="state.tableData.total"
|
||||||
|
>
|
||||||
|
</el-pagination>
|
||||||
|
</el-card>
|
||||||
|
<!-- <DeptDialog ref="deptDialogRef" @refresh="getTableData()" /> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="articleIndex">
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
import { articleApi } from '/@/api/article';
|
||||||
|
import { ElMessage, ElMessageBox, TableColumnCtx } from 'element-plus';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const state = reactive({
|
||||||
|
tableData: {
|
||||||
|
data: [],
|
||||||
|
total: 0,
|
||||||
|
loading: false,
|
||||||
|
param: {
|
||||||
|
labelName: '',
|
||||||
|
moduleName: '',
|
||||||
|
title: '',
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 模块列表
|
||||||
|
const moduleList = ref([]);
|
||||||
|
|
||||||
|
// 标签列表
|
||||||
|
const labelList = ref([]);
|
||||||
|
|
||||||
|
// 引入 api 请求接口
|
||||||
|
const artApi = articleApi();
|
||||||
|
|
||||||
|
// 获取表格数据
|
||||||
|
const getTableData = async() => {
|
||||||
|
try {
|
||||||
|
state.tableData.loading = true;
|
||||||
|
let res = await artApi.getArticleList(state.tableData.param);
|
||||||
|
if(res?.success){
|
||||||
|
state.tableData.data = res.data.records;
|
||||||
|
state.tableData.total = res.data.total;
|
||||||
|
}else{
|
||||||
|
ElMessage.error('文章列表获取失败!');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
} finally {
|
||||||
|
state.tableData.loading = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getModuleList = async() => {
|
||||||
|
try {
|
||||||
|
let res = await artApi.getModuleList();
|
||||||
|
if(res?.success){
|
||||||
|
moduleList.value = res.data;
|
||||||
|
}else{
|
||||||
|
ElMessage.error('模块列表获取失败!');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('模块列表获取失败!');
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模块选择
|
||||||
|
const handleChangeModule = async(val: any) => {
|
||||||
|
try {
|
||||||
|
state.tableData.param.labelName = '';
|
||||||
|
if(!val){labelList.value=[]; return;}
|
||||||
|
const op:any = event?.currentTarget;
|
||||||
|
let res = await artApi.getLabelList(op.dataset.op);
|
||||||
|
if(res?.success){
|
||||||
|
labelList.value = res.data;
|
||||||
|
}else{
|
||||||
|
ElMessage.error('标签列表获取失败!');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('标签列表获取失败!');
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const reset = () =>{
|
||||||
|
state.tableData.param = {
|
||||||
|
labelName: '',
|
||||||
|
moduleName: '',
|
||||||
|
title: '',
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
}
|
||||||
|
getTableData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加文章
|
||||||
|
const toAddArticle = () => {
|
||||||
|
router.push({ path: '/article/add' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加文章
|
||||||
|
const toEditArticle = (row: any) => {
|
||||||
|
router.push({ path: '/article/edit', query: { moduleName: row.moduleName, labelName: row.labelName } });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文章详情
|
||||||
|
const toShowDetail = (row: any) => {
|
||||||
|
router.push({ path: '/article/detail' , query: { moduleName: row.moduleName, labelName: row.labelName } });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文章删除
|
||||||
|
const deleteArticle = (id: number) => {
|
||||||
|
ElMessageBox.confirm('确定要删除该文章吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
.then(async() => {
|
||||||
|
try {
|
||||||
|
state.tableData.loading = true;
|
||||||
|
let res = await artApi.deleteArticle(id);
|
||||||
|
if(res?.success){
|
||||||
|
await getTableData();
|
||||||
|
ElMessage.success('文章删除成功!');
|
||||||
|
} else ElMessage.error('文章删除失败!');
|
||||||
|
} catch(e) {
|
||||||
|
ElMessage.error('处理失败!');
|
||||||
|
} finally {
|
||||||
|
state.tableData.loading = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日期格式化
|
||||||
|
const dateFormatter = (row: any, column: TableColumnCtx<String>) => {
|
||||||
|
let date = new Date(row.createtime);
|
||||||
|
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文章类型格式化
|
||||||
|
const typeFormatter = (row: any, column: TableColumnCtx<String>) => {
|
||||||
|
return row.articletype === 1 ? '外链' : '图文';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页改变
|
||||||
|
const onHandleSizeChange = (val: number) => {
|
||||||
|
state.tableData.param.size = val;
|
||||||
|
getTableData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 分页改变
|
||||||
|
const onHandleCurrentChange = (val: number) => {
|
||||||
|
state.tableData.param.current = val;
|
||||||
|
getTableData();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTableData();
|
||||||
|
getModuleList();
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.system-dept-container {
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
.el-table {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form size="large" class="login-content-form">
|
<el-form size="large" class="login-content-form">
|
||||||
<el-form-item class="login-animation1">
|
<el-form-item class="login-animation1">
|
||||||
<el-input text :placeholder="$t('message.account.accountPlaceholder1')" v-model="state.ruleForm.userName" clearable autocomplete="off">
|
<el-input text :placeholder="$t('message.account.accountPlaceholder1')" v-model="state.ruleForm.username" clearable autocomplete="off">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon class="el-input__icon"><ele-User /></el-icon>
|
<el-icon class="el-input__icon"><ele-User /></el-icon>
|
||||||
</template>
|
</template>
|
||||||
@ -68,6 +68,7 @@ import { initBackEndControlRoutes } from '/@/router/backEnd';
|
|||||||
import { Session } from '/@/utils/storage';
|
import { Session } from '/@/utils/storage';
|
||||||
import { formatAxis } from '/@/utils/formatTime';
|
import { formatAxis } from '/@/utils/formatTime';
|
||||||
import { NextLoading } from '/@/utils/loading';
|
import { NextLoading } from '/@/utils/loading';
|
||||||
|
import { useLoginApi } from '/@/api/login';
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@ -78,14 +79,17 @@ const router = useRouter();
|
|||||||
const state = reactive({
|
const state = reactive({
|
||||||
isShowPassword: false,
|
isShowPassword: false,
|
||||||
ruleForm: {
|
ruleForm: {
|
||||||
userName: 'admin',
|
username: 'admin1',
|
||||||
password: '123456',
|
password: '123456',
|
||||||
code: '1234',
|
code: '1234',
|
||||||
|
usertype: 1
|
||||||
},
|
},
|
||||||
loading: {
|
loading: {
|
||||||
signIn: false,
|
signIn: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
// 引入 api 请求接口
|
||||||
|
const loginApi = useLoginApi();
|
||||||
|
|
||||||
// 时间获取
|
// 时间获取
|
||||||
const currentTime = computed(() => {
|
const currentTime = computed(() => {
|
||||||
@ -93,11 +97,14 @@ const currentTime = computed(() => {
|
|||||||
});
|
});
|
||||||
// 登录
|
// 登录
|
||||||
const onSignIn = async () => {
|
const onSignIn = async () => {
|
||||||
|
try {
|
||||||
state.loading.signIn = true;
|
state.loading.signIn = true;
|
||||||
|
let res = await loginApi.login(state.ruleForm);
|
||||||
|
if(res?.success){
|
||||||
// 存储 token 到浏览器缓存
|
// 存储 token 到浏览器缓存
|
||||||
Session.set('token', Math.random().toString(36).substr(0));
|
Session.set('token', 'fbc545a91cc94fe89296828a25a7e08e@9085553879028596738');
|
||||||
// 模拟数据,对接接口时,记得删除多余代码及对应依赖的引入。用于 `/src/stores/userInfo.ts` 中不同用户登录判断(模拟数据)
|
// 模拟数据,对接接口时,记得删除多余代码及对应依赖的引入。用于 `/src/stores/userInfo.ts` 中不同用户登录判断(模拟数据)
|
||||||
Cookies.set('userName', state.ruleForm.userName);
|
Cookies.set('userName', res.data.user.realname);
|
||||||
if (!themeConfig.value.isRequestRoutes) {
|
if (!themeConfig.value.isRequestRoutes) {
|
||||||
// 前端控制路由,2、请注意执行顺序
|
// 前端控制路由,2、请注意执行顺序
|
||||||
const isNoPower = await initFrontEndControlRoutes();
|
const isNoPower = await initFrontEndControlRoutes();
|
||||||
@ -109,6 +116,11 @@ const onSignIn = async () => {
|
|||||||
// 执行完 initBackEndControlRoutes,再执行 signInSuccess
|
// 执行完 initBackEndControlRoutes,再执行 signInSuccess
|
||||||
signInSuccess(isNoPower);
|
signInSuccess(isNoPower);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
} finally {
|
||||||
|
state.loading.signIn = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// 登录成功后的跳转
|
// 登录成功后的跳转
|
||||||
const signInSuccess = (isNoPower: boolean | undefined) => {
|
const signInSuccess = (isNoPower: boolean | undefined) => {
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
/* Module Resolution Options */
|
/* Module Resolution Options */
|
||||||
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
|
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
|
||||||
"baseUrl": "." /* Base directory to resolve non-absolute module names. */,
|
"baseUrl": "http://8.138.171.103:8081" /* Base directory to resolve non-absolute module names. */,
|
||||||
"paths": {
|
"paths": {
|
||||||
"/@/*": ["src/*"]
|
"/@/*": ["src/*"]
|
||||||
} /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,
|
} /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,
|
||||||
|
@ -4,6 +4,7 @@ import { defineConfig, loadEnv, ConfigEnv } from 'vite';
|
|||||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus';
|
import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus';
|
||||||
import viteCompression from 'vite-plugin-compression';
|
import viteCompression from 'vite-plugin-compression';
|
||||||
import { buildConfig } from './src/utils/build';
|
import { buildConfig } from './src/utils/build';
|
||||||
|
import { codeInspectorPlugin } from 'code-inspector-plugin';
|
||||||
|
|
||||||
const pathResolve = (dir: string) => {
|
const pathResolve = (dir: string) => {
|
||||||
return resolve(__dirname, '.', dir);
|
return resolve(__dirname, '.', dir);
|
||||||
@ -16,8 +17,9 @@ const alias: Record<string, string> = {
|
|||||||
|
|
||||||
const viteConfig = defineConfig((mode: ConfigEnv) => {
|
const viteConfig = defineConfig((mode: ConfigEnv) => {
|
||||||
const env = loadEnv(mode.mode, process.cwd());
|
const env = loadEnv(mode.mode, process.cwd());
|
||||||
|
|
||||||
return {
|
return {
|
||||||
plugins: [vue(), vueSetupExtend(), viteCompression(), JSON.parse(env.VITE_OPEN_CDN) ? buildConfig.cdn() : null],
|
plugins: [vue(), vueSetupExtend(), viteCompression(), JSON.parse(env.VITE_OPEN_CDN) ? buildConfig.cdn() : null, codeInspectorPlugin({bundler: 'vite'})],
|
||||||
root: process.cwd(),
|
root: process.cwd(),
|
||||||
resolve: { alias },
|
resolve: { alias },
|
||||||
base: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH,
|
base: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH,
|
||||||
@ -28,6 +30,12 @@ const viteConfig = defineConfig((mode: ConfigEnv) => {
|
|||||||
open: JSON.parse(env.VITE_OPEN),
|
open: JSON.parse(env.VITE_OPEN),
|
||||||
hmr: true,
|
hmr: true,
|
||||||
proxy: {
|
proxy: {
|
||||||
|
'/vueAdminApi': {
|
||||||
|
target: 'http://8.138.171.103:8081',
|
||||||
|
ws: true,
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path) => path.replace(/^\/vueAdminApi/, ''),
|
||||||
|
},
|
||||||
'/gitee': {
|
'/gitee': {
|
||||||
target: 'https://gitee.com',
|
target: 'https://gitee.com',
|
||||||
ws: true,
|
ws: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user