Compare commits

...

7 Commits

Author SHA1 Message Date
6f45facc1b bug修复+请求拦截 2024-12-26 20:16:59 +08:00
夕阳微笑1
58a0257c30 图片管理小修改 2024-12-26 19:13:09 +08:00
夕阳微笑1
4b04a694e3 角色权限的完善 2024-12-26 19:12:44 +08:00
夕阳微笑1
b5bdf3b548 图片可以上传gif 2024-12-24 15:08:44 +08:00
夕阳微笑1
e69d5528ad 登录页修改 2024-12-24 15:08:33 +08:00
夕阳微笑1
03827e11ce 图片管理样式修改 2024-12-23 21:49:47 +08:00
夕阳微笑1
f4c273bf4e 修改角色管理 2024-12-23 21:49:38 +08:00
12 changed files with 161 additions and 70 deletions

View File

@ -11,7 +11,7 @@ const downloadPhoto = (imgSrc:any) => {
const url = window.URL.createObjectURL(res.data);
const a = document.createElement('a');
a.href = url;
a.download = '下载图片.jpg';
a.download = '下载图片.'+ imgSrc.substr(imgSrc.lastIndexOf('.')+1) || 'jpg';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);

View File

@ -1,3 +1,4 @@
import { baseUrlHost } from '../baseUrlHost';
import request from '/@/utils/request';
/**
@ -12,11 +13,11 @@ import request from '/@/utils/request';
*/
export function useMenuApi() {
return {
getAdminMenu: (params?: object) => {
getAdminMenu: (id: number) => {
return request({
url: '/gitee/lyt-top/vue-next-admin-images/raw/master/menu/adminMenu.json',
// url: '/gitee/lyt-top/vue-next-admin-images/raw/master/menu/adminMenu.json',
url:baseUrlHost + `/acGrouptype/findByUserMenu/${id}`,
method: 'get',
params,
});
},
getTestMenu: (params?: object) => {

View File

@ -3,19 +3,23 @@
<el-aside class="layout-aside" :class="setCollapseStyle">
<Logo v-if="setShowLogo" />
<el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef" @mouseenter="onAsideEnterLeave(true)" @mouseleave="onAsideEnterLeave(false)">
<Vertical :menuList="state.menuList" />
<div v-if="isDataReady">
<Vertical :menuList="Menulist" />
</div>
</el-scrollbar>
</el-aside>
</div>
</template>
<script setup lang="ts" name="layoutAside">
import { defineAsyncComponent, reactive, computed, watch, onBeforeMount, ref } from 'vue';
import { defineAsyncComponent, reactive, computed, watch, onBeforeMount, ref, onMounted } from 'vue';
import { storeToRefs } from 'pinia';
import { useRoutesList } from '/@/stores/routesList';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import mittBus from '/@/utils/mitt';
import {useMenuApi} from '/@/api/menu'
//
const Logo = defineAsyncComponent(() => import('/@/layout/logo/index.vue'));
@ -34,6 +38,10 @@ const state = reactive<AsideState>({
clientWidth: 0,
});
const useMenuapi = useMenuApi();
const isDataReady = ref(false)
// /
const setCollapseStyle = computed(() => {
const { layout, isCollapse, menuBar } = themeConfig.value;
@ -87,6 +95,23 @@ const setFilterRoutes = () => {
if (themeConfig.value.layout === 'columns') return false;
state.menuList = filterRoutesFun(routesList.value);
};
let Menulist = ref([]);
// const defaultOpeneds =reactive([])
const getmenulist = async() =>{
try{
const res = await useMenuapi.getAdminMenu(1);
// console.log('',res);
Menulist.value = res.data;
isDataReady.value = true
// for(let i = 0; i < Menulist.value.length; i++){
// defaultOpeneds.push(i + '')
// }
}catch(error){
console.error(error)
}
};
//
const filterRoutesFun = <T extends RouteItem>(arr: T[]): T[] => {
return arr
@ -97,6 +122,7 @@ const filterRoutesFun = <T extends RouteItem>(arr: T[]): T[] => {
return item;
});
};
//
const initMenuFixed = (clientWidth: number) => {
state.clientWidth = clientWidth;
@ -113,6 +139,7 @@ const onAsideEnterLeave = (bool: Boolean) => {
onBeforeMount(() => {
initMenuFixed(document.body.clientWidth);
setFilterRoutes();
// await getmenulist();
// (mittBus.off('setSendColumnsChildren))
// 使
mittBus.on('setSendColumnsChildren', (res: MittMenu) => {
@ -138,6 +165,11 @@ onBeforeMount(() => {
closeLayoutAsideMobileMode();
});
});
onMounted(async() =>{
await getmenulist();
})
// themeConfig el-scrollbar
watch(
() => [themeConfig.value.isShowLogoChange, themeConfig.value.isShowLogo, themeConfig.value.layout, themeConfig.value.isClassicSplitMenu],

View File

@ -6,8 +6,9 @@
:collapse="state.isCollapse"
:unique-opened="getThemeConfig.isUniqueOpened"
:collapse-transition="false"
:default-openeds="defaultOpeneds"
>
<template v-for="val in menuLists">
<!-- <template v-for="val in menuLists">
<el-sub-menu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
<template #title>
<SvgIcon :name="val.meta.icon" />
@ -26,16 +27,31 @@
</template>
</el-menu-item>
</template>
</template>
</template> -->
<el-sub-menu :index="index.toString()" v-for="(item,index) in menuLists" :key="index" >
<template #title>
<span>{{ item.modulename }}</span>
</template>
<el-menu-item-group>
<font-awesome-icon :icon="['fas',item.actions[0].icon]" size="lg" class="edtIcon" />
<el-menu-item :index="item1.link" v-for="(item1, index1) in item.actions" :key="index1">
<SvgIcon :name="item1.icon" />
{{ item1.actionname }}
</el-menu-item>
</el-menu-item-group>
</el-sub-menu>
</el-menu>
</template>
<script setup lang="ts" name="navMenuVertical">
import { defineAsyncComponent, reactive, computed, onMounted, watch } from 'vue';
import { defineAsyncComponent, reactive, computed, onMounted, watch,ref ,onBeforeMount} from 'vue';
import { useRoute, onBeforeRouteUpdate, RouteRecordRaw } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import other from '/@/utils/other';
import {useMenuApi} from '/@/api/menu'
//
const SubItem = defineAsyncComponent(() => import('/@/layout/navMenu/subItem.vue'));
@ -61,12 +77,25 @@ const state = reactive({
//
const menuLists = computed(() => {
return <RouteItems>props.menuList;
return props.menuList || [];
});
//
const getThemeConfig = computed(() => {
return themeConfig.value;
});
//
// const defaultOpeneds = computed(() => {
// if (menuLists.value.length === 0) {
// console.log(111111111111);
// return []; //
// }
// console.log(22222222222);
// return menuLists.value.map((_, index) => index.toString());
// });
const defaultOpeneds = ref<string[]>([]);
//
const setParentHighlight = (currentRoute: RouteToFrom) => {
const { path, meta } = currentRoute;
@ -78,9 +107,18 @@ const setParentHighlight = (currentRoute: RouteToFrom) => {
const onALinkClick = (val: RouteItem) => {
other.handleOpenLink(val);
};
//
onMounted(() => {
state.defaultActive = setParentHighlight(route);
//
// const storedOpeneds = localStorage.getItem('defaultOpeneds');
// if (storedOpeneds) {
// console.log('Loaded from localStorage:', JSON.parse(storedOpeneds));
// } else {
// //
// localStorage.setItem('defaultOpeneds', JSON.stringify(defaultOpeneds.value));
// }
});
//
onBeforeRouteUpdate((to) => {
@ -99,4 +137,21 @@ watch(
immediate: true,
}
);
// // localStorage
// // localStorage
// watch(defaultOpeneds, (newVal) => {
// localStorage.setItem('defaultOpeneds', JSON.stringify(newVal));
// });
// props defaultOpeneds
watch(
() => props.menuList,
(newMenuList) => {
defaultOpeneds.value = newMenuList.map((_, index) => index.toString());
},
{
immediate: true,
deep: true,
}
);
</script>

View File

@ -38,14 +38,21 @@ service.interceptors.response.use(
const res = response.data;
if (res.code && res.code !== 0) {
// `token` 过期或者账号已在别处登录
if (res.code === 401 || res.code === 4001) {
Session.clear(); // 清除浏览器全部临时缓存
window.location.href = '/'; // 去登录页
if (res.code === 401 || res.code === 4001 || (res.code === 502 && res.errorMsg==='只有登录成功后才可访问')) {
// ElMessage.error('该账户已在其它地方登录,请重新登录');
ElMessageBox.alert('你已被登出,请重新登录', '提示', {})
.then(() => {})
.catch(() => {});
.then(() => {
Session.clear(); // 清除浏览器全部临时缓存
window.location.href = '/'; // 去登录页
})
.catch(() => {
Session.clear(); // 清除浏览器全部临时缓存
window.location.href = '/'; // 去登录页
});
}
// else if(res.code === 502 && res.errorMsg){
// console.log(res.errorMsg);
// return res;
// }
return Promise.reject(service.interceptors.response);

View File

@ -106,7 +106,8 @@ const onSignIn = async () => {
// token
Session.set('token', res.data.token);
// usertype
Cookies.set('userName', res.data.user.usertype === 1 ? 'admin' : 'user');
// Cookies.set('userName', res.data.user.usertype === 1 ? 'admin' : 'user');
Cookies.set('userName', 'admin');
if (!themeConfig.value.isRequestRoutes) {
// 2
const isNoPower = await initFrontEndControlRoutes();
@ -116,7 +117,13 @@ const onSignIn = async () => {
// router No match found for location with path "/"
const isNoPower = await initBackEndControlRoutes();
// initBackEndControlRoutes signInSuccess
signInSuccess(isNoPower);
// signInSuccess(isNoPower);
if (isNoPower) {
//
signInSuccess(false); // signInSuccess
} else {
throw new Error('权限不足或路由加载失败');
}
}
}else{
ElMessage.error(res.errorMsg||res.message);

View File

@ -5,7 +5,7 @@
<img :src="logoMini" />
<div class="login-left-logo-text">
<span>{{ getThemeConfig.globalTitle }}</span>
<span class="login-left-logo-text-msg">{{ getThemeConfig.globalViceTitleMsg }}</span>
<!-- <span class="login-left-logo-text-msg">{{ getThemeConfig.globalViceTitleMsg }}</span> -->
</div>
</div>
<div class="login-left-img">

View File

@ -49,9 +49,9 @@
<el-image lazy :src="jpgFormatter(scope.row)" preview-teleported="true" :preview-src-list="[jpgFormatter(scope.row)]"/>
</template>
</el-table-column>
<el-table-column prop="moduleName" label="模块" show-overflow-tooltip width="200px" align="center"></el-table-column>
<el-table-column prop="moduleName" label="模块" show-overflow-tooltip width="220px" align="center"></el-table-column>
<el-table-column prop="labelName" label="标签" show-overflow-tooltip width="200px" align="center"></el-table-column>
<el-table-column prop="uploadName" label="上传者" show-overflow-tooltip width="200px" align="center"></el-table-column>
<el-table-column prop="uploadName" label="上传者" show-overflow-tooltip width="210px" align="center"></el-table-column>
<el-table-column prop="createtime" label="创建时间" :formatter="dateFormatter" show-overflow-tooltip width="200px" align="center"></el-table-column>
<el-table-column label="操作" width="250" align="center">
<template #default="scope">
@ -322,15 +322,14 @@ const viteUrl = import.meta.env.VITE_API_URL;
//
const jpgFormatter = (row: any) => {
let newPath;
if (row?.data) {
newPath = row.data.path.replaceAll('\\', '/')
} else {
newPath = row.path.replaceAll('\\\\', '/')
}
newPath = newPath.includes('http://8.138.171.103/')||newPath.includes('http://guojunjie.oss-cn-hangzhou.aliyuncs.com/') ?
newPath : encodeURI(viteUrl + newPath)
console.log(newPath);
let newPath = row?.data ? row.data.path : row.path;
// if (row?.data) {
// newPath = row.data.path.replaceAll('\\', '/')
// } else {
// newPath = row.path.replaceAll('\\\\', '/')
// }
newPath = newPath.includes(viteUrl)||newPath.includes('http://8.138.171.103/')||newPath.includes('http://guojunjie.oss-cn-hangzhou.aliyuncs.com/') ?
newPath : encodeURI(newPath)
return `${newPath}`;
}
@ -420,7 +419,7 @@ const disabled = ref(false)
const handleChange: UploadProps['onChange'] = async (file: uploadFile, uploadFiles) => {
state.formData.loading = true;
if (file.raw.type === 'image/png' || file.raw.type === 'image/jpeg' || file.raw.type === 'image/jpg') {
if (file.raw.type === 'image/png' || file.raw.type === 'image/jpeg' || file.raw.type === 'image/jpg' || file.raw.type === 'image/gif') {
state.formData.fileList = uploadFiles;
uploadDisabled.value = true;
try {
@ -475,13 +474,16 @@ const handleRemove = (file: UploadFile, uploadFiles) => {
//
const download = async(row:any) =>{
state.formData.loading = true;
let newPath;
if (row?.data) {
newPath = row.data.path.replaceAll('\\', '/')
} else {
newPath = row.path.replaceAll('\\\\', '/')
}
newPath = newPath.includes('http://localhost:8888/') ? newPath : viteUrl + newPath
// let newPath;
// if (row?.data) {
// newPath = row.data.path.replaceAll('\\', '/')
// } else {
// newPath = row.path.replaceAll('\\\\', '/')
// }
// newPath = newPath.includes('http://localhost:8888/') ? newPath : viteUrl + newPath
let newPath = row?.data ? row.data.path : row.path;
newPath = newPath.includes(viteUrl)||newPath.includes('http://8.138.171.103/')||newPath.includes('http://guojunjie.oss-cn-hangzhou.aliyuncs.com/') ?
newPath : encodeURI(newPath);
try{
await downloadPhoto(newPath);
}catch(error){

View File

@ -34,18 +34,19 @@
<!-- <el-table-column prop="type" label="类型" show-overflow-tooltip></el-table-column> -->
<el-table-column prop="reviewStatus" align="center" label="审核结果" show-overflow-tooltip>
<template #default="scope">
<el-tag v-if="scope.row.reviewStatus === 0">未发布</el-tag>
<el-tag v-else-if="scope.row.reviewStatus === 1" type="warning">审核中</el-tag>
<el-tag v-if="scope.row.reviewStatus === 1" type="warning">审核中</el-tag>
<el-tag v-else-if="scope.row.reviewStatus === 2" type="success">通过</el-tag>
<el-tag v-else-if="scope.row.reviewStatus === 3" type="danger">未通过</el-tag>
<el-tag v-else>未发布</el-tag>
</template>
</el-table-column>
<el-table-column prop="createtime" align="center" label="时间" :formatter="dateFormatter" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="200" align="center">
<template #default="scope">
<!-- <el-button size="small" text type="primary" @click="toShowDetail(scope.row.id)">查看详情</el-button> -->
<el-button size="small" v-if="scope.row.reviewStatus === 0" text type="primary" @click="audit(scope.row)">审核</el-button>
<el-button size="small" v-else-if="scope.row.reviewStatus === 0" text type="primary" @click="toPublic(scope.row)">发布</el-button>
<el-button size="small" v-if="scope.row.reviewStatus === 1" text type="primary" @click="audit(scope.row)">审核</el-button>
<el-button size="small" v-else-if="scope.row.reviewStatus === null" text type="primary" @click="toPublic(scope.row)">发布</el-button>
<el-button size="small" v-else text type="primary" @click="audit(scope.row)">重新审核</el-button>
</template>
</el-table-column>
</el-table>
@ -63,7 +64,7 @@
>
</el-pagination>
</el-card>
<MessageDialog ref="messageDialogRef" />
<!-- <MessageDialog ref="messageDialogRef" /> -->
<!-- 回复弹窗 -->
<el-dialog style="height: 200px;" :title="state.auditDialog.title" v-model="state.auditDialog.show" width="400px">
<div class="dialog-content">
@ -88,8 +89,8 @@ import { sharesApi } from '/@/api/service/shares';
import { ElMessage, ElMessageBox, TableColumnCtx } from 'element-plus';
//
const MessageDialog = defineAsyncComponent(() => import('/@/views/message/dialog.vue'));
const messageDialogRef = ref();
// const MessageDialog = defineAsyncComponent(() => import('/@/views/message/dialog.vue'));
// const messageDialogRef = ref();
//
const state = reactive({
@ -117,7 +118,7 @@ const state = reactive({
//
const statusList = ref([
{label: '未发布', value: 0},
// {label: '', value: ''},
{label: '审核中', value: 1},
{label: '通过', value: 2},
{label: '未通过', value: 3},
@ -154,9 +155,9 @@ const reset = () =>{
}
//
const toShowDetail = (id: any) => {
messageDialogRef.value.openDialog(id);
}
// const toShowDetail = (id: any) => {
// messageDialogRef.value.openDialog(id);
// }
const replayFormRef = ref();

View File

@ -197,10 +197,6 @@ const onSubmit = async() => {
if(valid){
state.ruleForm.show = state.ruleForm.show ? 1 : 0;
state.ruleForm.grouptypeid = 1;
let body = {
actions:tree.value.getCheckedKeys(true, false),
groupid:state.ruleForm.id
}
if (state.dialog.type === 'add') {
try{
const param = {
@ -209,12 +205,7 @@ const onSubmit = async() => {
}
const res = await roleapi.addRole(param);
if (res?.success) {
try{
const data = await roleactionapi.setUprolePermission(body)
console.log(5555555,data);
}catch(error){
console.error(error)
}
emit('reset');
closeDialog();
ElMessage.success('角色新建成功!');
@ -234,6 +225,10 @@ const onSubmit = async() => {
ElMessage.error('角色新建失败!')
}
} else {
let body = {
actions:tree.value.getCheckedKeys(true, false),
groupid:state.ruleForm.id
}
try{
const res = await roleapi.updateRole(state.ruleForm);
if(res?.success){

View File

@ -30,10 +30,10 @@
<el-table-column prop="createtime" label="创建时间" :formatter="dateFormatter" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="100">
<template #default="scope">
<el-button :disabled="scope.row.name === '管理员'" size="small" text type="primary" @click="onOpenEditRole('edit', scope.row)"
<el-button size="small" text type="primary" @click="onOpenEditRole('edit', scope.row)"
>修改</el-button
>
<el-button :disabled="scope.row.name === '管理员'" size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>
<el-button size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
@ -125,15 +125,6 @@ const getTableData = async() => {
}
};
//
const getroleDetail = async() =>{
try{
const res = await roleapi.getRoleDetail();
}catch(error){
console.error(error)
}
};
//
const onOpenAddRole = (type: string) => {

View File

@ -169,7 +169,7 @@ const getVideoDetail = async () => {
// 01truefalse
// ts
if (state.data.path) {
const never: any = [{ name: state.data.name, url: viteUrl + state.data.path }];
const never: any = [{ name: state.data.name, url: state.data.path }];
state.fileArray = never;
state.coverHide = true;
}