!68 修复升级依赖带来的问题

* Merge remote-tracking branch 'origin/dev' into dev
* 升级依赖
* Merge remote-tracking branch 'origin/ts' into ts
* 升级依赖
* Merge branch 'dev' of gitee.com:JavaLionLi/plus-ui into ts
* 升级依赖
* !61 fix: 删除重复环境变量ElUploadInstance
* fix: 删除重复环境变量ElUploadInstance
This commit is contained in:
ahaos 2023-12-13 10:35:55 +00:00
parent b06f6a316b
commit f32a7105c3
22 changed files with 172 additions and 203 deletions

View File

@ -4,7 +4,7 @@
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"quoteProps": "preserve",
"jsxSingleQuote": false,
"bracketSameLine": false,
"trailingComma": "none",

View File

@ -18,19 +18,19 @@
"url": "https://gitee.com/JavaLionLi/plus-ui.git"
},
"dependencies": {
"@element-plus/icons-vue": "2.1.0",
"@element-plus/icons-vue": "2.3.1",
"@vueup/vue-quill": "1.2.0",
"@vueuse/core": "10.7.0",
"animate.css": "4.1.1",
"await-to-js": "^3.0.0",
"axios": "^1.3.4",
"crypto-js": "^4.1.1",
"echarts": "5.4.0",
"echarts": "5.4.3",
"element-plus": "2.4.3",
"file-saver": "2.0.5",
"fuse.js": "6.6.2",
"js-cookie": "3.0.1",
"jsencrypt": "3.3.1",
"js-cookie": "3.0.5",
"jsencrypt": "3.3.2",
"nprogress": "0.2.0",
"path-browserify": "1.0.1",
"path-to-regexp": "6.2.0",
@ -38,14 +38,14 @@
"screenfull": "6.0.0",
"vform3-builds": "3.0.8",
"vue": "3.3.11",
"vue-cropper": "1.0.3",
"vue-cropper": "1.1.1",
"vue-i18n": "9.2.2",
"vue-router": "4.2.5",
"vue-types": "5.1.1"
},
"devDependencies": {
"@iconify/json": "^2.2.40",
"@intlify/unplugin-vue-i18n": "0.8.2",
"@iconify/json": "^2.2.157",
"@intlify/unplugin-vue-i18n": "1.6.0",
"@types/crypto-js": "^4.1.1",
"@types/file-saver": "2.0.5",
"@types/js-cookie": "3.0.3",
@ -57,7 +57,7 @@
"@unocss/preset-attributify": "^0.58.0",
"@unocss/preset-icons": "^0.58.0",
"@unocss/preset-uno": "^0.58.0",
"@vue/compiler-sfc": "3.2.45",
"@vue/compiler-sfc": "3.3.9",
"@vitejs/plugin-vue": "4.5.2",
"autoprefixer": "10.4.14",
"eslint": "8.55.0",
@ -72,13 +72,13 @@
"husky": "7.0.4",
"postcss": "^8.4.21",
"prettier": "3.1.1",
"sass": "1.56.1",
"sass": "1.69.5",
"typescript": "5.2.2",
"unocss": "^0.58.0",
"unplugin-auto-import": "0.17.2",
"unplugin-icons": "0.18.1",
"unplugin-vue-components": "0.26.0",
"unplugin-vue-setup-extend-plus": "0.4.9",
"unplugin-vue-setup-extend-plus": "1.0.0",
"vite-plugin-compression": "0.5.1",
"vite-plugin-svg-icons": "2.0.1",
"vitest": "^0.29.7",

View File

@ -10,7 +10,7 @@ import { handleThemeStyle } from '@/utils/theme';
import useAppStore from '@/store/modules/app';
const appStore = useAppStore();
const size = computed(() => appStore.size as any);
const size = computed(() => appStore.size);
onMounted(() => {
nextTick(() => {

View File

@ -18,7 +18,7 @@ const props = withDefaults(defineProps<Props>(), {
isView: false
});
const vFormRef = ref(null);
const vFormRef = ref();
// -
const getFormData = () => {
return vFormRef.value.getFormData();
@ -29,7 +29,7 @@ const getFormData = () => {
* @param {表单配置} formConf
* formConfig{ formTemplate表单模板formData表单数据hiddenField需要隐藏的字段字符串集合disabledField需要禁用的自读字符串集合}
*/
const initForm = (formConf) => {
const initForm = (formConf: any) => {
const { formTemplate, formData, hiddenField, disabledField } = toRaw(formConf);
if (formTemplate) {
vFormRef.value.setFormJson(formTemplate);

View File

@ -1,5 +1,5 @@
<template>
<div class="relative" :style="{ width: width }">
<div class="relative" :style="{ 'width': width }">
<el-input v-model="modelValue" readonly placeholder="点击选择图标" @click="visible = !visible">
<template #prepend>
<svg-icon :icon-class="modelValue" />

View File

@ -37,7 +37,7 @@ const realSrcList = computed(() => {
}
let real_src_list = props.src.split(',');
let srcList: string[] = [];
real_src_list.forEach((item) => {
real_src_list.forEach((item: string) => {
return srcList.push(item);
});
return srcList;

View File

@ -27,7 +27,7 @@ const sizeOptions = ref([
{ label: '稍小', value: 'small' }
]);
const handleSetSize = (size: string) => {
const handleSetSize = (size: 'large' | 'default' | 'small') => {
appStore.setSize(size);
};
</script>

View File

@ -0,0 +1,5 @@
export enum LanguageEnum {
zh_CN = 'zh_CN',
en_US = 'en_US'
}

View File

@ -4,6 +4,7 @@ import { createI18n } from 'vue-i18n';
// 本地语言包
import enUSLocale from './en_US';
import zhCNLocale from './zh_CN';
import { LanguageEnum } from '@/enums/LanguageEnum';
const messages = {
zh_CN: {
@ -18,12 +19,12 @@ const messages = {
*
* @returns zh-cn|en ...
*/
export const getLanguage = () => {
const language = useStorage('language', 'zh_CN');
export const getLanguage = (): LanguageEnum => {
const language = useStorage<LanguageEnum>('language', LanguageEnum.zh_CN);
if (language.value) {
return language.value;
}
return 'zh_CN';
return LanguageEnum.zh_CN;
};
const i18n = createI18n({

View File

@ -48,35 +48,35 @@
<div class="drawer-item">
<span>开启 TopNav</span>
<span class="comp-style">
<el-switch v-model="topNav" class="drawer-switch" />
<el-switch v-model="settingsStore.topNav" class="drawer-switch" @change="topNavChange" />
</span>
</div>
<div class="drawer-item">
<span>开启 Tags-Views</span>
<span class="comp-style">
<el-switch v-model="tagsView" class="drawer-switch" />
<el-switch v-model="settingsStore.tagsView" class="drawer-switch" />
</span>
</div>
<div class="drawer-item">
<span>固定 Header</span>
<span class="comp-style">
<el-switch v-model="fixedHeader" class="drawer-switch" />
<el-switch v-model="settingsStore.fixedHeader" class="drawer-switch" />
</span>
</div>
<div class="drawer-item">
<span>显示 Logo</span>
<span class="comp-style">
<el-switch v-model="sidebarLogo" class="drawer-switch" />
<el-switch v-model="settingsStore.sidebarLogo" class="drawer-switch" />
</span>
</div>
<div class="drawer-item">
<span>动态标题</span>
<span class="comp-style">
<el-switch v-model="dynamicTitle" class="drawer-switch" />
<el-switch v-model="settingsStore.dynamicTitle" class="drawer-switch" @change="dynamicTitleChange" />
</span>
</div>
@ -93,8 +93,8 @@ import useAppStore from '@/store/modules/app';
import useSettingsStore from '@/store/modules/settings';
import usePermissionStore from '@/store/modules/permission';
import { handleThemeStyle } from '@/utils/theme';
import { SettingTypeEnum } from '@/enums/SettingTypeEnum';
import { SideThemeEnum } from '@/enums/SideThemeEnum';
import defaultSettings from '@/settings';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const appStore = useAppStore();
@ -113,92 +113,58 @@ const isDark = useDark({
valueDark: 'dark',
valueLight: 'light'
});
//
watch(isDark, () => {
if (isDark.value) {
settingsStore.changeSetting({ key: SettingTypeEnum.SIDE_THEME, value: SideThemeEnum.DARK });
settingsStore.sideTheme = SideThemeEnum.DARK;
} else {
settingsStore.changeSetting({ key: SettingTypeEnum.SIDE_THEME, value: sideTheme.value });
settingsStore.sideTheme = sideTheme.value;
}
});
const toggleDark = () => useToggle(isDark);
/** 是否需要topNav */
const topNav = computed({
get: () => storeSettings.value.topNav,
set: (val) => {
settingsStore.changeSetting({ key: SettingTypeEnum.TOP_NAV, value: val });
const topNavChange = (val) => {
if (!val) {
appStore.toggleSideBarHide(false);
permissionStore.setSidebarRouters(permissionStore.defaultRoutes);
}
}
});
/** 是否需要tagview */
const tagsView = computed({
get: () => storeSettings.value.tagsView,
set: (val) => {
settingsStore.changeSetting({ key: SettingTypeEnum.TAGS_VIEW, value: val });
}
});
/**是否需要固定头部 */
const fixedHeader = computed({
get: () => storeSettings.value.fixedHeader,
set: (val) => {
settingsStore.changeSetting({ key: SettingTypeEnum.FIXED_HEADER, value: val });
}
});
/**是否需要侧边栏的logo */
const sidebarLogo = computed({
get: () => storeSettings.value.sidebarLogo,
set: (val) => {
settingsStore.changeSetting({ key: SettingTypeEnum.SIDEBAR_LOGO, value: val });
}
});
/**是否需要侧边栏的动态网页的title */
const dynamicTitle = computed({
get: () => storeSettings.value.dynamicTitle,
set: (val) => {
settingsStore.changeSetting({ key: SettingTypeEnum.DYNAMIC_TITLE, value: val });
};
const dynamicTitleChange = () => {
//
useDynamicTitle();
}
});
};
const themeChange = (val: string) => {
settingsStore.changeSetting({ key: SettingTypeEnum.THEME, value: val });
theme.value = val;
if (val) {
settingsStore.theme = val;
handleThemeStyle(val);
}
};
const handleTheme = (val: string) => {
sideTheme.value = val;
if (isDark.value && val === SideThemeEnum.LIGHT) {
//
settingsStore.changeSetting({ key: SettingTypeEnum.SIDE_THEME, value: SideThemeEnum.DARK });
settingsStore.sideTheme = SideThemeEnum.DARK;
return;
}
settingsStore.changeSetting({ key: SettingTypeEnum.SIDE_THEME, value: val });
settingsStore.sideTheme = val;
};
const saveSetting = () => {
proxy?.$modal.loading('正在保存到本地,请稍候...');
let layoutSetting = {
topNav: storeSettings.value.topNav,
tagsView: storeSettings.value.tagsView,
fixedHeader: storeSettings.value.fixedHeader,
sidebarLogo: storeSettings.value.sidebarLogo,
dynamicTitle: storeSettings.value.dynamicTitle,
sideTheme: storeSettings.value.sideTheme,
theme: storeSettings.value.theme
};
localStorage.setItem('layout-setting', JSON.stringify(layoutSetting));
const settings = useStorage<LayoutSetting>('layout-setting', defaultSettings);
settings.value.topNav = storeSettings.value.topNav;
settings.value.tagsView = storeSettings.value.tagsView;
settings.value.fixedHeader = storeSettings.value.fixedHeader;
settings.value.sidebarLogo = storeSettings.value.sidebarLogo;
settings.value.dynamicTitle = storeSettings.value.dynamicTitle;
settings.value.sideTheme = storeSettings.value.sideTheme;
settings.value.theme = storeSettings.value.theme;
setTimeout(() => {
proxy?.$modal.closeLoading();
}, 1000);
};
const resetSetting = () => {
proxy?.$modal.loading('正在清除设置缓存并刷新,请稍候...');
localStorage.removeItem('layout-setting');
useStorage<any>('layout-setting', null).value = null;
setTimeout('window.location.reload()', 1000);
};
const openSetting = () => {

View File

@ -14,10 +14,6 @@ import directive from './directive';
// 注册插件
import plugins from './plugins/index'; // plugins
import { download } from '@/utils/request';
// 预设动画
import animate from './animate';
// svg图标
import 'virtual:svg-icons-register';
@ -26,25 +22,10 @@ import ElementIcons from '@/plugins/svgicon';
// permission control
import './permission';
import { useDict } from '@/utils/dict';
import { getConfigKey, updateConfigByKey } from '@/api/system/config';
import { parseTime, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi';
// 国际化
import i18n from '@/lang/index';
const app = createApp(App);
// 全局方法挂载
app.config.globalProperties.useDict = useDict;
app.config.globalProperties.getConfigKey = getConfigKey;
app.config.globalProperties.updateConfigByKey = updateConfigByKey;
app.config.globalProperties.download = download;
app.config.globalProperties.parseTime = parseTime;
app.config.globalProperties.handleTree = handleTree;
app.config.globalProperties.addDateRange = addDateRange;
app.config.globalProperties.selectDictLabel = selectDictLabel;
app.config.globalProperties.selectDictLabels = selectDictLabels;
app.config.globalProperties.animate = animate;
app.use(ElementIcons);
app.use(router);

View File

@ -16,13 +16,13 @@ const whiteList = ['/login', '/register', '/social-callback'];
router.beforeEach(async (to, from, next) => {
NProgress.start();
if (getToken()) {
to.meta.title && useSettingsStore().setTitle(to.meta.title as string);
to.meta.title && useSettingsStore().setTitle(to.meta.title);
/* has token*/
if (to.path === '/login') {
next({ path: '/' });
NProgress.done();
} else if (whiteList.indexOf(to.path) !== -1) {
next()
} else if (whiteList.indexOf(to.path as string) !== -1) {
next();
} else {
if (useUserStore().roles.length === 0) {
isRelogin.show = true;

View File

@ -3,6 +3,13 @@ import tab from './tab';
import download from './download';
import cache from './cache';
import auth from './auth';
// 预设动画
import animate from '@/animate';
import { download as dl } from '@/utils/request';
import { useDict } from '@/utils/dict';
import { getConfigKey, updateConfigByKey } from '@/api/system/config';
import { parseTime, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi';
import { App } from 'vue';
@ -21,4 +28,16 @@ export default function installPlugin(app: App) {
// 认证对象
app.config.globalProperties.$auth = auth;
// 全局方法挂载
app.config.globalProperties.useDict = useDict;
app.config.globalProperties.getConfigKey = getConfigKey;
app.config.globalProperties.updateConfigByKey = updateConfigByKey;
app.config.globalProperties.download = dl;
app.config.globalProperties.parseTime = parseTime;
app.config.globalProperties.handleTree = handleTree;
app.config.globalProperties.addDateRange = addDateRange;
app.config.globalProperties.selectDictLabel = selectDictLabel;
app.config.globalProperties.selectDictLabels = selectDictLabels;
app.config.globalProperties.animate = animate;
}

View File

@ -1,3 +1,5 @@
import { LanguageEnum } from '@/enums/LanguageEnum';
const setting: DefaultSettings = {
/**
*
@ -50,6 +52,11 @@ const setting: DefaultSettings = {
animationEnable: false,
dark: false
dark: false,
language: LanguageEnum.zh_CN,
size: 'default',
layout: ''
};
export default setting;

View File

@ -9,7 +9,7 @@ export const useAppStore = defineStore('app', () => {
hide: false
});
const device = ref<string>('desktop');
const size = useStorage('size', 'default');
const size = useStorage<'large' | 'default' | 'small'>('size', 'default');
// 语言
const language = useStorage('language', 'zh_CN');
@ -43,7 +43,7 @@ export const useAppStore = defineStore('app', () => {
const toggleDevice = (d: string): void => {
device.value = d;
};
const setSize = (s: string): void => {
const setSize = (s: 'large' | 'default' | 'small'): void => {
size.value = s;
};
const toggleSideBarHide = (status: boolean): void => {

View File

@ -1,43 +1,29 @@
import { defineStore } from 'pinia';
import defaultSettings from '@/settings';
import { SettingTypeEnum } from '@/enums/SettingTypeEnum';
import { useDynamicTitle } from '@/utils/dynamicTitle';
export const useSettingsStore = defineStore('setting', () => {
const storageSetting = JSON.parse(localStorage.getItem('layout-setting') || '{}');
const storageSetting = useStorage<LayoutSetting>('layout-setting', {
topNav: defaultSettings.topNav,
tagsView: defaultSettings.tagsView,
fixedHeader: defaultSettings.fixedHeader,
sidebarLogo: defaultSettings.sidebarLogo,
dynamicTitle: defaultSettings.dynamicTitle,
sideTheme: defaultSettings.sideTheme,
theme: defaultSettings.theme
});
const title = ref<string>(defaultSettings.title);
const theme = ref<string>(storageSetting.theme || defaultSettings.theme);
const sideTheme = ref<string>(storageSetting.sideTheme || defaultSettings.sideTheme);
const showSettings = ref<boolean>(storageSetting.showSettings || defaultSettings.showSettings);
const topNav = ref<boolean>(storageSetting.topNav === undefined ? defaultSettings.topNav : storageSetting.topNav);
const tagsView = ref<boolean>(storageSetting.tagsView === undefined ? defaultSettings.tagsView : storageSetting.tagsView);
const fixedHeader = ref<boolean>(storageSetting.fixedHeader === undefined ? defaultSettings.fixedHeader : storageSetting.fixedHeader);
const sidebarLogo = ref<boolean>(storageSetting.sidebarLogo === undefined ? defaultSettings.sidebarLogo : storageSetting.sidebarLogo);
const dynamicTitle = ref<boolean>(storageSetting.dynamicTitle === undefined ? defaultSettings.dynamicTitle : storageSetting.dynamicTitle);
const animationEnable = ref<boolean>(
storageSetting.animationEnable === undefined ? defaultSettings.animationEnable : storageSetting.animationEnable
);
const dark = ref<boolean>(storageSetting.dark || defaultSettings.dark);
const theme = ref<string>(storageSetting.value.theme);
const sideTheme = ref<string>(storageSetting.value.sideTheme);
const showSettings = ref<boolean>(defaultSettings.showSettings);
const topNav = ref<boolean>(storageSetting.value.topNav);
const tagsView = ref<boolean>(storageSetting.value.tagsView);
const fixedHeader = ref<boolean>(storageSetting.value.fixedHeader);
const sidebarLogo = ref<boolean>(storageSetting.value.sidebarLogo);
const dynamicTitle = ref<boolean>(storageSetting.value.dynamicTitle);
const animationEnable = ref<boolean>(defaultSettings.animationEnable);
const dark = ref<boolean>(defaultSettings.dark);
const prop: { [key: string]: Ref<any> } = {
theme,
sideTheme,
showSettings,
topNav,
tagsView,
fixedHeader,
sidebarLogo,
dynamicTitle,
animationEnable,
dark
};
// actions
const changeSetting = (param: { key: SettingTypeEnum; value: any }) => {
const { key, value } = param;
if (key in prop) {
prop[key].value = value;
}
};
const setTitle = (value: string) => {
title.value = value;
useDynamicTitle();
@ -54,7 +40,6 @@ export const useSettingsStore = defineStore('setting', () => {
dynamicTitle,
animationEnable,
dark,
changeSetting,
setTitle
};
});

82
src/types/global.d.ts vendored
View File

@ -1,4 +1,5 @@
import type { ComponentInternalInstance as ComponentInstance, PropType as VuePropType } from 'vue/runtime-core';
import { LanguageEnum } from '@/enums/LanguageEnum';
declare global {
/** vue Instance */
@ -49,6 +50,8 @@ declare global {
/** 是否禁用上传 */
isUploading: boolean;
updateSupport: number;
/** 其他参数 */
[key: string]: any;
}
@ -87,76 +90,77 @@ declare global {
pageNum: number;
pageSize: number;
}
declare interface LayoutSetting {
/**
*
*/
topNav: boolean;
declare type DefaultSettings = {
/**
*
*/
tagsView: boolean;
/**
*
*/
fixedHeader: boolean;
/**
* Logo
*/
sidebarLogo: boolean;
/**
*
*/
dynamicTitle: boolean;
/**
* theme-dark | theme-light
*/
sideTheme: string;
/**
*
*/
theme: string;
}
declare interface DefaultSettings extends LayoutSetting {
/**
*
*/
title: string;
/**
* theme-dark | theme-light
*/
sideTheme?: string;
/**
*
*/
showSettings?: boolean;
showSettings: boolean;
/**
*
*/
topNav?: boolean;
/**
*
*/
tagsView?: boolean;
/**
*
*/
fixedHeader?: boolean;
/**
* Logo
*/
sidebarLogo?: boolean;
/**
*
*/
layout?: string;
/**
*
*/
theme?: string;
layout: string;
/**
*
*/
size?: string;
size: 'large' | 'default' | 'small';
/**
*
*/
language?: string;
language: LanguageEnum;
/**
*
*/
dynamicTitle?: boolean;
/**
*
*/
animationEnable?: boolean;
animationEnable: boolean;
/**
*
*
* true:
* false:
*/
dark?: boolean;
dark: boolean;
errorLog?: string;
};
errorLog: string;
}
}
export {};

20
src/types/module.d.ts vendored
View File

@ -1,13 +1,13 @@
import type modal from '@/plugins/modal';
import type tab from '@/plugins/tab';
import type download from '@/plugins/download';
import type auth from '@/plugins/auth';
import type cache from '@/plugins/cache';
import type animate from '@/animate';
import type { useDict } from '@/utils/dict';
import type { addDateRange, handleTree, selectDictLabel, selectDictLabels, parseTime } from '@/utils/ruoyi';
import type { getConfigKey, updateConfigByKey } from '@/api/system/config';
import type { download as rd } from '@/utils/request';
import modal from '@/plugins/modal';
import tab from '@/plugins/tab';
import download from '@/plugins/download';
import auth from '@/plugins/auth';
import cache from '@/plugins/cache';
import animate from '@/animate';
import { useDict } from '@/utils/dict';
import handleTree, { addDateRange, selectDictLabel, selectDictLabels, parseTime } from '@/utils/ruoyi';
import { getConfigKey, updateConfigByKey } from '@/api/system/config';
import { download as rd } from '@/utils/request';
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {

View File

@ -245,3 +245,7 @@ export const getNormalPath = (p: string): string => {
export const blobValidate = (data: any) => {
return data.type !== 'application/json';
};
export default {
handleTree
};

View File

@ -306,9 +306,8 @@ import { to } from 'await-to-js';
import { globalHeaders } from '@/utils/request';
const router = useRouter();
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { proxy } = getCurrentInstance();
const { sys_normal_disable, sys_user_sex } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex'));
const userList = ref<UserVO[]>();
const loading = ref(true);
const showSearch = ref(true);
@ -512,7 +511,7 @@ const handleResetPwd = async (row: UserVO) => {
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间'
})
);
if (!err) {
if (!err && res) {
await api.resetUserPwd(row.userId, res.value);
proxy?.$modal.msgSuccess('修改成功,新密码是:' + res.value);
}

View File

@ -24,12 +24,10 @@
<script setup lang="ts">
import { updateUserProfile } from '@/api/system/user';
import { propTypes } from '@/utils/propTypes';
const props = defineProps({
user: {
type: Object as PropType<any>,
required: true
}
user: propTypes.any.isRequired
});
const userForm = computed(() => props.user);
const { proxy } = getCurrentInstance() as ComponentInternalInstance;

View File

@ -233,7 +233,7 @@ interface MenuOptionsType {
const subColumns = ref<any>([]);
const menuOptions = ref<Array<MenuOptionsType>>([]);
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { proxy } = getCurrentInstance();
const props = defineProps({
info: propTypes.any.def(null),