mirror of
https://github.com/Tencent/tdesign-vue-next-starter.git
synced 2024-12-23 03:22:32 +08:00
Merge pull request #75 from Tencent/reafactor/pinia
refactor(pinia): use pinia refactor store
This commit is contained in:
commit
20d059ce54
|
@ -21,15 +21,15 @@
|
||||||
"echarts": "~5.1.2",
|
"echarts": "~5.1.2",
|
||||||
"hex-to-hsl": "^1.0.2",
|
"hex-to-hsl": "^1.0.2",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
"pinia": "^2.0.11",
|
||||||
"qrcode.vue": "^3.2.2",
|
"qrcode.vue": "^3.2.2",
|
||||||
"tdesign-icons-vue-next": "^0.0.6",
|
"tdesign-icons-vue-next": "^0.0.6",
|
||||||
"tdesign-vue-next": "0.8.1",
|
"tdesign-vue-next": "0.9.2",
|
||||||
"tvision-color": "^1.3.1",
|
"tvision-color": "^1.3.1",
|
||||||
"vue": "^3.2.31",
|
"vue": "^3.2.31",
|
||||||
"vue-color-kit": "^1.0.5",
|
"vue-color-kit": "^1.0.5",
|
||||||
"vue-router": "^4.0.11",
|
"vue-router": "^4.0.11",
|
||||||
"vue3-clipboard": "^1.0.0",
|
"vue3-clipboard": "^1.0.0"
|
||||||
"vuex": "^4.0.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^15.0.0",
|
"@commitlint/cli": "^15.0.0",
|
||||||
|
|
|
@ -3,17 +3,17 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted } from 'vue';
|
import { computed, onMounted } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
import config from '@/config/style';
|
import config from '@/config/style';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
|
|
||||||
const store = useStore();
|
const store = useSettingStore();
|
||||||
|
|
||||||
const mode = computed(() => {
|
const mode = computed(() => {
|
||||||
return store.getters['setting/mode'];
|
return store.displayMode;
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
store.dispatch('setting/changeTheme', { ...config });
|
store.updateConfig({ ...config });
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
import { getBrandColor } from '@/config/color';
|
import { getBrandColor } from '@/config/color';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
|
|
||||||
|
const store = useSettingStore();
|
||||||
|
|
||||||
const panelColor =
|
const panelColor =
|
||||||
'conic-gradient(from 90deg at 50% 50%, #FF0000 -19.41deg, #FF0000 18.76deg, #FF8A00 59.32deg, #FFE600 99.87deg, #14FF00 141.65deg, #00A3FF 177.72deg, #0500FF 220.23deg, #AD00FF 260.13deg, #FF00C7 300.69deg, #FF0000 340.59deg, #FF0000 378.76deg)';
|
'conic-gradient(from 90deg at 50% 50%, #FF0000 -19.41deg, #FF0000 18.76deg, #FF8A00 59.32deg, #FFE600 99.87deg, #14FF00 141.65deg, #00A3FF 177.72deg, #0500FF 220.23deg, #AD00FF 260.13deg, #FF00C7 300.69deg, #FF0000 340.59deg, #FF0000 378.76deg)';
|
||||||
|
@ -15,11 +17,9 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const store = useStore();
|
|
||||||
|
|
||||||
const style = computed(() => {
|
const style = computed(() => {
|
||||||
const { value } = props;
|
const { value } = props;
|
||||||
const { colorList } = store.state.setting;
|
const { colorList } = store;
|
||||||
return {
|
return {
|
||||||
background: value !== 'dynamic' ? getBrandColor(value, colorList)['@brand-color'] : panelColor,
|
background: value !== 'dynamic' ? getBrandColor(value, colorList)['@brand-color'] : panelColor,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import hexToHsl from 'hex-to-hsl';
|
import hexToHsl from 'hex-to-hsl';
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
export type ColorToken = Record<string, string>;
|
export type TColorToken = Record<string, string>;
|
||||||
export type ColorSeries = Record<string, ColorToken>;
|
export type TColorSeries = Record<string, TColorToken>;
|
||||||
|
|
||||||
export const defaultLightColor = [
|
export const defaultLightColor = [
|
||||||
'#0052d9',
|
'#0052d9',
|
||||||
|
@ -24,7 +24,7 @@ export const defaultDarkColor = [
|
||||||
'#ab87d5',
|
'#ab87d5',
|
||||||
];
|
];
|
||||||
|
|
||||||
export const BACKGROUND_TOKEN: ColorSeries = {
|
export const BACKGROUND_TOKEN: TColorSeries = {
|
||||||
BLUE_GREY: {
|
BLUE_GREY: {
|
||||||
'@gray-color-1': '#F1F2F5',
|
'@gray-color-1': '#F1F2F5',
|
||||||
'@gray-color-2': '#EBEDF1',
|
'@gray-color-2': '#EBEDF1',
|
||||||
|
@ -60,7 +60,7 @@ export const BACKGROUND_TOKEN: ColorSeries = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
export const NEUTRAL_GREY_TOKEN: ColorToken = {
|
export const NEUTRAL_GREY_TOKEN: TColorToken = {
|
||||||
'@gray-color-1': '#F3F3F3',
|
'@gray-color-1': '#F3F3F3',
|
||||||
'@gray-color-2': '#EEEEEE',
|
'@gray-color-2': '#EEEEEE',
|
||||||
'@gray-color-3': '#E7E7E7',
|
'@gray-color-3': '#E7E7E7',
|
||||||
|
@ -77,7 +77,7 @@ export const NEUTRAL_GREY_TOKEN: ColorToken = {
|
||||||
'@gray-color-14': '#181818',
|
'@gray-color-14': '#181818',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const COLOR_TOKEN: ColorSeries = {
|
export const COLOR_TOKEN: TColorSeries = {
|
||||||
DEFAULT: {
|
DEFAULT: {
|
||||||
'@brand-color': '#0052D9',
|
'@brand-color': '#0052D9',
|
||||||
'@brand-color-1': '#e0ebff',
|
'@brand-color-1': '#e0ebff',
|
||||||
|
@ -185,35 +185,37 @@ export const COLOR_TOKEN: ColorSeries = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LIGHT_CHART_COLORS: ColorToken = {
|
export const LIGHT_CHART_COLORS = {
|
||||||
textColor: 'rgba(0, 0, 0, 0.9)',
|
textColor: 'rgba(0, 0, 0, 0.9)',
|
||||||
placeholderColor: 'rgba(0, 0, 0, 0.35)',
|
placeholderColor: 'rgba(0, 0, 0, 0.35)',
|
||||||
borderColor: '#dcdcdc',
|
borderColor: '#dcdcdc',
|
||||||
containerColor: '#fff',
|
containerColor: '#fff',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DARK_CHART_COLORS: ColorToken = {
|
export const DARK_CHART_COLORS = {
|
||||||
textColor: 'rgba(255, 255, 255, 0.9)',
|
textColor: 'rgba(255, 255, 255, 0.9)',
|
||||||
placeholderColor: 'rgba(255, 255, 255, 0.35)',
|
placeholderColor: 'rgba(255, 255, 255, 0.35)',
|
||||||
borderColor: '#5e5e5e',
|
borderColor: '#5e5e5e',
|
||||||
containerColor: '#242424',
|
containerColor: '#242424',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TChartColor = typeof LIGHT_CHART_COLORS;
|
||||||
|
|
||||||
function toUnderline(name: string): string {
|
function toUnderline(name: string): string {
|
||||||
return name.replace(/([A-Z])/g, '_$1').toUpperCase();
|
return name.replace(/([A-Z])/g, '_$1').toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getGreyColor(type: string): ColorToken {
|
export function getGreyColor(type: string): TColorToken {
|
||||||
const name = toUnderline(type);
|
const name = toUnderline(type);
|
||||||
return BACKGROUND_TOKEN[name] || {};
|
return BACKGROUND_TOKEN[name] || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBrandColor(type: string, colorList: ColorSeries): ColorToken {
|
export function getBrandColor(type: string, colorList: TColorSeries): TColorToken {
|
||||||
const name = /^#[A-F\d]{6}$/i.test(type) ? type : toUnderline(type);
|
const name = /^#[A-F\d]{6}$/i.test(type) ? type : toUnderline(type);
|
||||||
return colorList[name || 'DEFAULT'];
|
return colorList[name || 'DEFAULT'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getColorList(colorArray: Array<ColorToken>): Array<string> {
|
export function getColorList(colorArray: Array<TColorToken>): Array<string> {
|
||||||
const pureColorList = [];
|
const pureColorList = [];
|
||||||
colorArray.map((colorToken) => Object.keys(colorToken).map((key) => pureColorList.push(colorToken[key])));
|
colorArray.map((colorToken) => Object.keys(colorToken).map((key) => pureColorList.push(colorToken[key])));
|
||||||
|
|
||||||
|
@ -262,7 +264,7 @@ export function generateColorMap(theme: string, colorPalette: Array<string>, mod
|
||||||
};
|
};
|
||||||
return colorMap;
|
return colorMap;
|
||||||
}
|
}
|
||||||
export function insertThemeStylesheet(theme: string, colorMap: ColorToken, mode: 'light' | 'dark') {
|
export function insertThemeStylesheet(theme: string, colorMap: TColorToken, mode: 'light' | 'dark') {
|
||||||
const isDarkMode = mode === 'dark';
|
const isDarkMode = mode === 'dark';
|
||||||
const root = !isDarkMode ? `:root[theme-color='${theme}']` : `:root[theme-color='${theme}'][theme-mode='dark']`;
|
const root = !isDarkMode ? `:root[theme-color='${theme}']` : `:root[theme-color='${theme}'][theme-mode='dark']`;
|
||||||
|
|
||||||
|
|
|
@ -35,5 +35,5 @@ export interface NotificationItem {
|
||||||
status: boolean;
|
status: boolean;
|
||||||
collected: boolean;
|
collected: boolean;
|
||||||
date: string;
|
date: string;
|
||||||
quality: 'high' | 'low' | 'middle';
|
quality: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<search :layout="layout" />
|
<search :layout="layout" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<menu-content v-show="layout !== 'side'" class="header-menu" :nav-data="menu" />
|
<MenuContent v-show="layout !== 'side'" class="header-menu" :nav-data="menu" />
|
||||||
<template #operations>
|
<template #operations>
|
||||||
<div class="operations-container">
|
<div class="operations-container">
|
||||||
<!-- 搜索框 -->
|
<!-- 搜索框 -->
|
||||||
|
@ -65,9 +65,8 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PropType, computed } from 'vue';
|
import { PropType, computed } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
import { prefix } from '@/config/global';
|
import { prefix } from '@/config/global';
|
||||||
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
||||||
import { MenuRoute } from '@/interface';
|
import { MenuRoute } from '@/interface';
|
||||||
|
@ -107,11 +106,13 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const store = useStore();
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
|
||||||
const toggleSettingPanel = () => {
|
const toggleSettingPanel = () => {
|
||||||
store.commit('setting/toggleSettingPanel', true);
|
settingStore.updateConfig({
|
||||||
|
showSettingPanel: true,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const active = computed(() => {
|
const active = computed(() => {
|
||||||
|
@ -141,7 +142,9 @@ const menuCls = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const changeCollapsed = () => {
|
const changeCollapsed = () => {
|
||||||
store.commit('setting/toggleSidebarCompact');
|
settingStore.updateConfig({
|
||||||
|
isSidebarCompact: !settingStore.isSidebarCompact,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNav = (url) => {
|
const handleNav = (url) => {
|
||||||
|
|
|
@ -46,31 +46,29 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useStore } from 'vuex';
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useNotificationStore } from '@/store';
|
||||||
import { NotificationItem } from '@/interface';
|
import { NotificationItem } from '@/interface';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const store = useStore();
|
const store = useNotificationStore();
|
||||||
const { msgData } = store.state.notification;
|
const { msgData, unreadMsg } = storeToRefs(store);
|
||||||
|
|
||||||
const unreadMsg = computed(() => store.getters['notification/unreadMsg']);
|
|
||||||
|
|
||||||
const setRead = (type: string, item?: NotificationItem) => {
|
const setRead = (type: string, item?: NotificationItem) => {
|
||||||
const changeMsg = msgData;
|
const changeMsg = msgData.value;
|
||||||
if (type === 'all') {
|
if (type === 'all') {
|
||||||
changeMsg.forEach((e: NotificationItem) => {
|
changeMsg.forEach((e) => {
|
||||||
e.status = false;
|
e.status = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
changeMsg.forEach((e: NotificationItem) => {
|
changeMsg.forEach((e) => {
|
||||||
if (e.id === item?.id) {
|
if (e.id === item?.id) {
|
||||||
e.status = false;
|
e.status = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
store.commit('notification/setMsgData', changeMsg);
|
store.setMsgData(changeMsg);
|
||||||
};
|
};
|
||||||
|
|
||||||
const goDetail = () => {
|
const goDetail = () => {
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
const layout = defineProps({
|
defineProps({
|
||||||
type: String,
|
layout: String,
|
||||||
});
|
});
|
||||||
|
|
||||||
const isSearchFocus = ref(false);
|
const isSearchFocus = ref(false);
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
import { defineComponent, PropType, computed, onMounted } from 'vue';
|
import { defineComponent, PropType, computed, onMounted } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
import { prefix } from '@/config/global';
|
import { prefix } from '@/config/global';
|
||||||
import pgk from '../../../package.json';
|
import pgk from '../../../package.json';
|
||||||
import MenuContent from './MenuContent';
|
import MenuContent from './MenuContent';
|
||||||
import tLogo from '@/assets/assets-t-logo.svg?component';
|
import tLogo from '@/assets/assets-t-logo.svg?component';
|
||||||
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
|
|
||||||
const MIN_POINT = 992 - 1;
|
const MIN_POINT = 992 - 1;
|
||||||
|
|
||||||
const useComputed = (props) => {
|
const useComputed = (props) => {
|
||||||
const store = useStore();
|
const collapsed = computed(() => useSettingStore().isSidebarCompact);
|
||||||
|
|
||||||
const collapsed = computed(() => store.state.setting.isSidebarCompact);
|
|
||||||
|
|
||||||
const sideNavCls = computed(() => {
|
const sideNavCls = computed(() => {
|
||||||
const { isCompact } = props;
|
const { isCompact } = props;
|
||||||
|
@ -87,16 +85,20 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const store = useStore();
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
|
||||||
const changeCollapsed = () => {
|
const changeCollapsed = () => {
|
||||||
store.commit('setting/toggleSidebarCompact');
|
settingStore.updateConfig({
|
||||||
|
isSidebarCompact: !settingStore.isSidebarCompact,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const autoCollapsed = () => {
|
const autoCollapsed = () => {
|
||||||
const isCompact = window.innerWidth <= MIN_POINT;
|
const isCompact = window.innerWidth <= MIN_POINT;
|
||||||
store.commit('setting/showSidebarCompact', isCompact);
|
settingStore.updateConfig({
|
||||||
|
isSidebarCompact: isCompact,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent, computed } from 'vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { usePermissionStore, useSettingStore } from '@/store';
|
||||||
|
|
||||||
import TDesignHeader from './components/Header.vue';
|
import TDesignHeader from './components/Header.vue';
|
||||||
import TDesignBreadcrumb from './components/Breadcrumb.vue';
|
import TDesignBreadcrumb from './components/Breadcrumb.vue';
|
||||||
import TDesignFooter from './components/Footer.vue';
|
import TDesignFooter from './components/Footer.vue';
|
||||||
|
@ -8,112 +11,111 @@ import TDesignContent from './components/Content.vue';
|
||||||
|
|
||||||
import { prefix } from '@/config/global';
|
import { prefix } from '@/config/global';
|
||||||
import TdesignSetting from './setting.vue';
|
import TdesignSetting from './setting.vue';
|
||||||
import { SettingType } from '@/interface';
|
|
||||||
import '@/style/layout.less';
|
import '@/style/layout.less';
|
||||||
|
|
||||||
const name = `${prefix}-base-layout`;
|
const name = `${prefix}-base-layout`;
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name,
|
name,
|
||||||
computed: {
|
setup() {
|
||||||
...mapGetters({
|
const route = useRoute();
|
||||||
showSidebar: 'setting/showSidebar',
|
const permissionStore = usePermissionStore();
|
||||||
showHeader: 'setting/showHeader',
|
const settingStore = useSettingStore();
|
||||||
showHeaderLogo: 'setting/showHeaderLogo',
|
const { routers: menuRouters } = storeToRefs(permissionStore);
|
||||||
showSidebarLogo: 'setting/showSidebarLogo',
|
const setting = storeToRefs(settingStore);
|
||||||
showFooter: 'setting/showFooter',
|
|
||||||
mode: 'setting/mode',
|
const mainLayoutCls = computed(() => [
|
||||||
menuRouters: 'permission/routers',
|
{
|
||||||
}),
|
't-layout--with-sider': settingStore.showSidebar,
|
||||||
setting(): SettingType {
|
},
|
||||||
return this.$store.state.setting;
|
]);
|
||||||
},
|
|
||||||
mainLayoutCls() {
|
const headerMenu = computed(() => {
|
||||||
return [
|
if (settingStore.layout === 'mix') {
|
||||||
{
|
if (settingStore.splitMenu) {
|
||||||
't-layout--with-sider': this.showSidebar,
|
console.log(menuRouters);
|
||||||
},
|
return menuRouters.value.map((menu) => ({
|
||||||
];
|
|
||||||
},
|
|
||||||
headerMenu() {
|
|
||||||
const { layout, splitMenu } = this.$store.state.setting;
|
|
||||||
const { menuRouters } = this;
|
|
||||||
if (layout === 'mix') {
|
|
||||||
if (splitMenu) {
|
|
||||||
return menuRouters.map((menu) => ({
|
|
||||||
...menu,
|
...menu,
|
||||||
children: [],
|
children: [],
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return menuRouters;
|
return menuRouters.value;
|
||||||
},
|
});
|
||||||
sideMenu() {
|
|
||||||
const { layout, splitMenu } = this.$store.state.setting;
|
const sideMenu = computed(() => {
|
||||||
let { menuRouters } = this;
|
const { layout, splitMenu } = settingStore;
|
||||||
|
let newMenuRouters = menuRouters.value;
|
||||||
if (layout === 'mix' && splitMenu) {
|
if (layout === 'mix' && splitMenu) {
|
||||||
menuRouters.forEach((menu) => {
|
newMenuRouters.forEach((menu) => {
|
||||||
if (this.$route.path.indexOf(menu.path) === 0) {
|
if (route.path.indexOf(menu.path) === 0) {
|
||||||
menuRouters = menu.children.map((subMenu) => ({ ...subMenu, path: `${menu.path}/${subMenu.path}` }));
|
newMenuRouters = menu.children.map((subMenu) => ({ ...subMenu, path: `${menu.path}/${subMenu.path}` }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return menuRouters;
|
return newMenuRouters;
|
||||||
},
|
});
|
||||||
},
|
|
||||||
methods: {
|
const renderSidebar = () => {
|
||||||
renderSidebar() {
|
|
||||||
return (
|
return (
|
||||||
this.showSidebar && (
|
settingStore.showSidebar && (
|
||||||
<TDesignSideNav
|
<TDesignSideNav
|
||||||
showLogo={this.showSidebarLogo}
|
showLogo={settingStore.showSidebarLogo}
|
||||||
layout={this.setting.layout}
|
layout={settingStore.layout}
|
||||||
isFixed={this.setting.isSidebarFixed}
|
isFixed={settingStore.isSidebarFixed}
|
||||||
menu={this.sideMenu}
|
menu={sideMenu.value}
|
||||||
theme={this.mode}
|
theme={settingStore.displayMode}
|
||||||
isCompact={this.setting.isSidebarCompact}
|
isCompact={settingStore.isSidebarCompact}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
};
|
||||||
renderHeader() {
|
|
||||||
|
const renderHeader = () => {
|
||||||
return (
|
return (
|
||||||
this.showHeader && (
|
settingStore.showHeader && (
|
||||||
<TDesignHeader
|
<TDesignHeader
|
||||||
showLogo={this.showHeaderLogo}
|
showLogo={settingStore.showHeaderLogo}
|
||||||
theme={this.mode}
|
theme={settingStore.displayMode}
|
||||||
layout={this.setting.layout}
|
layout={settingStore.layout}
|
||||||
isFixed={this.setting.isHeaderFixed}
|
isFixed={settingStore.isHeaderFixed}
|
||||||
menu={this.headerMenu}
|
menu={headerMenu.value}
|
||||||
isCompact={this.setting.isSidebarCompact}
|
isCompact={settingStore.isSidebarCompact}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
};
|
||||||
renderContent() {
|
|
||||||
const { showBreadcrumb } = this.setting;
|
const renderFooter = () => {
|
||||||
const { showFooter } = this;
|
return (
|
||||||
|
<t-footer class={`${prefix}-footer-layout`}>
|
||||||
|
<TDesignFooter />
|
||||||
|
</t-footer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderContent = () => {
|
||||||
|
const { showBreadcrumb, showFooter } = settingStore;
|
||||||
return (
|
return (
|
||||||
<t-layout class={[`${prefix}-layout`]}>
|
<t-layout class={[`${prefix}-layout`]}>
|
||||||
<t-content class={`${prefix}-content-layout`}>
|
<t-content class={`${prefix}-content-layout`}>
|
||||||
{showBreadcrumb && <TDesignBreadcrumb />}
|
{showBreadcrumb && <TDesignBreadcrumb />}
|
||||||
<TDesignContent />
|
<TDesignContent />
|
||||||
</t-content>
|
</t-content>
|
||||||
{showFooter && this.renderFooter()}
|
{showFooter && renderFooter()}
|
||||||
</t-layout>
|
</t-layout>
|
||||||
);
|
);
|
||||||
},
|
};
|
||||||
|
|
||||||
renderFooter() {
|
return {
|
||||||
return (
|
setting,
|
||||||
<t-footer class={`${prefix}-footer-layout`}>
|
mainLayoutCls,
|
||||||
<TDesignFooter />
|
renderSidebar,
|
||||||
</t-footer>
|
renderHeader,
|
||||||
);
|
renderContent,
|
||||||
},
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { layout } = this.setting;
|
const { layout } = this.setting;
|
||||||
const header = this.renderHeader();
|
const header = this.renderHeader();
|
||||||
|
|
|
@ -92,24 +92,23 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch, onMounted, watchEffect } from 'vue';
|
import { ref, computed, watch, onMounted, watchEffect } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
import { ColorPicker } from 'vue-color-kit';
|
import { ColorPicker } from 'vue-color-kit';
|
||||||
import { MessagePlugin, PopupVisibleChangeContext } from 'tdesign-vue-next';
|
import { MessagePlugin, PopupVisibleChangeContext } from 'tdesign-vue-next';
|
||||||
import { Color } from 'tvision-color';
|
import { Color } from 'tvision-color';
|
||||||
import useClipboard from 'vue-clipboard3';
|
import useClipboard from 'vue-clipboard3';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
|
|
||||||
import 'vue-color-kit/dist/vue-color-kit.css';
|
import 'vue-color-kit/dist/vue-color-kit.css';
|
||||||
|
|
||||||
import STYLE_CONFIG from '@/config/style';
|
import STYLE_CONFIG from '@/config/style';
|
||||||
import { insertThemeStylesheet, generateColorMap } from '@/config/color';
|
import { insertThemeStylesheet, generateColorMap } from '@/config/color';
|
||||||
|
|
||||||
import Thumbnail from '@/components/thumbnail/index.vue';
|
|
||||||
import ColorContainer from '@/components/color/index.vue';
|
|
||||||
|
|
||||||
import SettingDarkIcon from '@/assets/assets-setting-dark.svg';
|
import SettingDarkIcon from '@/assets/assets-setting-dark.svg';
|
||||||
import SettingLightIcon from '@/assets/assets-setting-light.svg';
|
import SettingLightIcon from '@/assets/assets-setting-light.svg';
|
||||||
import SettingAutoIcon from '@/assets/assets-setting-auto.svg';
|
import SettingAutoIcon from '@/assets/assets-setting-auto.svg';
|
||||||
|
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
|
||||||
const LAYOUT_OPTION = ['side', 'top', 'mix'];
|
const LAYOUT_OPTION = ['side', 'top', 'mix'];
|
||||||
const COLOR_OPTIONS = ['default', 'cyan', 'green', 'yellow', 'orange', 'red', 'pink', 'purple', 'dynamic'];
|
const COLOR_OPTIONS = ['default', 'cyan', 'green', 'yellow', 'orange', 'red', 'pink', 'purple', 'dynamic'];
|
||||||
const MODE_OPTIONS = [
|
const MODE_OPTIONS = [
|
||||||
|
@ -119,61 +118,63 @@ const MODE_OPTIONS = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const formData = ref({ ...STYLE_CONFIG });
|
const formData = ref({ ...STYLE_CONFIG });
|
||||||
const store = useStore();
|
|
||||||
const colors = ref();
|
const colors = ref();
|
||||||
const isColoPickerDisplay = ref(false);
|
const isColoPickerDisplay = ref(false);
|
||||||
|
|
||||||
const showSettingPanel = computed({
|
const showSettingPanel = computed({
|
||||||
get() {
|
get() {
|
||||||
return store.state.setting.showSettingPanel;
|
return settingStore.showSettingPanel;
|
||||||
},
|
},
|
||||||
set(newVal) {
|
set(newVal: boolean) {
|
||||||
store.commit('setting/toggleSettingPanel', newVal);
|
settingStore.updateConfig({
|
||||||
|
showSettingPanel: newVal,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mode = computed(() => {
|
const mode = computed(() => {
|
||||||
return store.getters['setting/mode'];
|
return settingStore.displayMode;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => colors.value,
|
() => colors.value,
|
||||||
(newColor) => {
|
(newColor) => {
|
||||||
const { hex } = newColor;
|
const { hex } = newColor;
|
||||||
const { setting } = store.state;
|
|
||||||
|
|
||||||
// hex 主题色
|
// hex 主题色
|
||||||
const newPalette = Color.getPaletteByGradation({
|
const newPalette = Color.getPaletteByGradation({
|
||||||
colors: [hex],
|
colors: [hex],
|
||||||
step: 10,
|
step: 10,
|
||||||
})[0];
|
})[0];
|
||||||
const { mode } = store.state.setting;
|
const { mode } = settingStore;
|
||||||
const colorMap = generateColorMap(hex, newPalette, mode);
|
const colorMap = generateColorMap(hex, newPalette, mode as 'light' | 'dark');
|
||||||
|
|
||||||
store.commit('setting/addColor', { [hex]: colorMap });
|
insertThemeStylesheet(hex, colorMap, mode as 'light' | 'dark');
|
||||||
|
|
||||||
insertThemeStylesheet(hex, colorMap, mode);
|
settingStore.updateConfig({
|
||||||
|
[hex]: colorMap,
|
||||||
store.dispatch('setting/changeTheme', { ...setting, brandTheme: hex });
|
});
|
||||||
|
settingStore.changeBrandTheme(hex);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const changeColor = (val) => {
|
const changeColor = (val) => {
|
||||||
const { hex } = val;
|
const { hex } = val;
|
||||||
const { setting } = store.state;
|
|
||||||
// hex 主题色
|
// hex 主题色
|
||||||
const newPalette = Color.getPaletteByGradation({
|
const newPalette = Color.getPaletteByGradation({
|
||||||
colors: [hex],
|
colors: [hex],
|
||||||
step: 10,
|
step: 10,
|
||||||
})[0];
|
})[0];
|
||||||
const { mode } = store.state.setting;
|
const { mode } = settingStore;
|
||||||
const colorMap = generateColorMap(hex, newPalette, mode);
|
const colorMap = generateColorMap(hex, newPalette, mode as 'light' | 'dark');
|
||||||
|
|
||||||
store.commit('setting/addColor', { [hex]: colorMap });
|
settingStore.updateConfig({
|
||||||
|
[hex]: colorMap,
|
||||||
|
});
|
||||||
|
|
||||||
insertThemeStylesheet(hex, colorMap, mode);
|
insertThemeStylesheet(hex, colorMap, mode as 'light' | 'dark');
|
||||||
|
|
||||||
store.dispatch('setting/changeTheme', { ...setting, brandTheme: hex });
|
settingStore.changeBrandTheme(hex);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -212,7 +213,9 @@ const getModeIcon = (mode: string) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCloseDrawer = () => {
|
const handleCloseDrawer = () => {
|
||||||
store.commit('setting/toggleSettingPanel', false);
|
settingStore.updateConfig({
|
||||||
|
showSettingPanel: false,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getThumbnailUrl = (name: string): string => {
|
const getThumbnailUrl = (name: string): string => {
|
||||||
|
@ -220,7 +223,7 @@ const getThumbnailUrl = (name: string): string => {
|
||||||
};
|
};
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
store.dispatch('setting/changeTheme', formData.value);
|
settingStore.updateConfig(formData.value);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|
|
@ -3,11 +3,11 @@ import { createApp } from 'vue';
|
||||||
import TDesign from 'tdesign-vue-next';
|
import TDesign from 'tdesign-vue-next';
|
||||||
import 'tdesign-vue-next/es/style/index.css';
|
import 'tdesign-vue-next/es/style/index.css';
|
||||||
import VueClipboard from 'vue3-clipboard';
|
import VueClipboard from 'vue3-clipboard';
|
||||||
|
|
||||||
import { store } from './store';
|
import { store } from './store';
|
||||||
import router from './router';
|
import router from './router';
|
||||||
import '@/style/index.less';
|
import '@/style/index.less';
|
||||||
import './permission';
|
import './permission';
|
||||||
|
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import { Color } from 'tvision-color';
|
import { Color } from 'tvision-color';
|
||||||
import { getBrandColor, defaultLightColor, defaultDarkColor } from '@/config/color';
|
import { getBrandColor, defaultLightColor, defaultDarkColor, TChartColor } from '@/config/color';
|
||||||
import store from '@/store';
|
import { getSettingStore } from '@/store';
|
||||||
|
|
||||||
const { state } = store;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 依据主题类型获取颜色
|
* 依据主题类型获取颜色
|
||||||
|
@ -14,8 +12,8 @@ const { state } = store;
|
||||||
* @returns {}
|
* @returns {}
|
||||||
*/
|
*/
|
||||||
export function getColorFromTheme(theme: string) {
|
export function getColorFromTheme(theme: string) {
|
||||||
const { setting } = state as any;
|
const settingStore = getSettingStore();
|
||||||
const { colorList, mode } = setting;
|
const { colorList, mode } = settingStore;
|
||||||
const isDarkMode = mode === 'dark';
|
const isDarkMode = mode === 'dark';
|
||||||
let themeColorList = [];
|
let themeColorList = [];
|
||||||
const themeColor = getBrandColor(theme, colorList);
|
const themeColor = getBrandColor(theme, colorList);
|
||||||
|
@ -41,8 +39,9 @@ export function getColorFromTheme(theme: string) {
|
||||||
|
|
||||||
/** 图表颜色 */
|
/** 图表颜色 */
|
||||||
function chartListColor(): Array<string> {
|
function chartListColor(): Array<string> {
|
||||||
const { setting } = state as any;
|
const settingStore = getSettingStore();
|
||||||
const res = getColorFromTheme(setting.brandTheme);
|
const { brandTheme } = settingStore;
|
||||||
|
const res = getColorFromTheme(brandTheme);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -178,7 +177,7 @@ export function constructInitDataset({
|
||||||
dateTime = [],
|
dateTime = [],
|
||||||
placeholderColor,
|
placeholderColor,
|
||||||
borderColor,
|
borderColor,
|
||||||
}: { dateTime: Array<string> } & Record<string, string>) {
|
}: { dateTime: Array<string> } & TChartColor) {
|
||||||
// const dataset: Array<Array<string>> = [['时间'], ['入库'], ['出库']];
|
// const dataset: Array<Array<string>> = [['时间'], ['入库'], ['出库']];
|
||||||
const divideNum = 10;
|
const divideNum = 10;
|
||||||
const timeArray = [];
|
const timeArray = [];
|
||||||
|
@ -276,7 +275,7 @@ export function getSmoothLineDataSet({
|
||||||
dateTime = [],
|
dateTime = [],
|
||||||
placeholderColor,
|
placeholderColor,
|
||||||
borderColor,
|
borderColor,
|
||||||
}: { dateTime?: Array<string> } & Record<string, string>) {
|
}: { dateTime?: Array<string> } & TChartColor) {
|
||||||
let dateArray: Array<string> = ['00:00', '02:00', '04:00', '06:00'];
|
let dateArray: Array<string> = ['00:00', '02:00', '04:00', '06:00'];
|
||||||
if (dateTime.length > 0) {
|
if (dateTime.length > 0) {
|
||||||
const divideNum = 7;
|
const divideNum = 7;
|
||||||
|
@ -383,7 +382,7 @@ export function getFolderLineDataSet({
|
||||||
dateTime = [],
|
dateTime = [],
|
||||||
placeholderColor,
|
placeholderColor,
|
||||||
borderColor,
|
borderColor,
|
||||||
}: { dateTime?: Array<string> } & Record<string, string>) {
|
}: { dateTime?: Array<string> } & TChartColor) {
|
||||||
let dateArray: Array<string> = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
|
let dateArray: Array<string> = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
|
||||||
if (dateTime.length > 0) {
|
if (dateTime.length > 0) {
|
||||||
const divideNum = 7;
|
const divideNum = 7;
|
||||||
|
@ -543,7 +542,7 @@ export function getLineChartDataSet({
|
||||||
dateTime = [],
|
dateTime = [],
|
||||||
placeholderColor,
|
placeholderColor,
|
||||||
borderColor,
|
borderColor,
|
||||||
}: { dateTime?: Array<string> } & Record<string, string>) {
|
}: { dateTime?: Array<string> } & TChartColor) {
|
||||||
const divideNum = 10;
|
const divideNum = 10;
|
||||||
const timeArray = [];
|
const timeArray = [];
|
||||||
const inArray = [];
|
const inArray = [];
|
||||||
|
@ -679,7 +678,7 @@ export function getScatterDataSet({
|
||||||
dateTime = [],
|
dateTime = [],
|
||||||
placeholderColor,
|
placeholderColor,
|
||||||
borderColor,
|
borderColor,
|
||||||
}: { dateTime?: Array<string> } & Record<string, string>): any {
|
}: { dateTime?: Array<string> } & TChartColor): any {
|
||||||
const divideNum = 40;
|
const divideNum = 40;
|
||||||
const timeArray = [];
|
const timeArray = [];
|
||||||
const inArray = [];
|
const inArray = [];
|
||||||
|
@ -975,7 +974,7 @@ export function get2ColBarChartDataSet({
|
||||||
isMonth = false,
|
isMonth = false,
|
||||||
placeholderColor,
|
placeholderColor,
|
||||||
borderColor,
|
borderColor,
|
||||||
}: { isMonth?: boolean } & Record<string, string>) {
|
}: { isMonth?: boolean } & TChartColor) {
|
||||||
let lastYearListCopy = lastYearList.concat([]);
|
let lastYearListCopy = lastYearList.concat([]);
|
||||||
let thisYearListCopy = lastYearList.concat([]);
|
let thisYearListCopy = lastYearList.concat([]);
|
||||||
|
|
||||||
|
@ -1078,7 +1077,7 @@ export function getPieChartDataSet({
|
||||||
textColor,
|
textColor,
|
||||||
placeholderColor,
|
placeholderColor,
|
||||||
containerColor,
|
containerColor,
|
||||||
}: { radius: number } & Record<string, string>) {
|
}: { radius?: number } & Record<string, string>) {
|
||||||
return {
|
return {
|
||||||
color: chartListColor(),
|
color: chartListColor(),
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div>
|
<div>
|
||||||
<t-row :gutter="[16, 16]">
|
<t-row :gutter="[16, 16]">
|
||||||
<t-col v-for="(item, index) in PANE_LIST" :key="item.title" :xs="6" :xl="3">
|
<t-col v-for="(item, index) in PANE_LIST" :key="item.title" :xs="6" :xl="3">
|
||||||
<card :subtitle="item.title" :style="{ height: '168px' }" :class="{ 'main-color': index == 0 }">
|
<card :subtitle="item.title" size="small" :style="{ height: '168px' }" :class="{ 'main-color': index == 0 }">
|
||||||
<div class="dashboard-item">
|
<div class="dashboard-item">
|
||||||
<div class="dashboard-item-top">
|
<div class="dashboard-item-top">
|
||||||
<span :style="{ fontSize: `${resizeTime * 36}px` }">{{ item.number }}</span>
|
<span :style="{ fontSize: `${resizeTime * 36}px` }">{{ item.number }}</span>
|
||||||
|
@ -204,12 +204,12 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, watch, ref, onUnmounted, nextTick, computed } from 'vue';
|
import { onMounted, watch, ref, onUnmounted, nextTick, computed } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
|
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import { TooltipComponent, LegendComponent, GridComponent } from 'echarts/components';
|
import { TooltipComponent, LegendComponent, GridComponent } from 'echarts/components';
|
||||||
import { PieChart, LineChart, BarChart } from 'echarts/charts';
|
import { PieChart, LineChart, BarChart } from 'echarts/charts';
|
||||||
import { CanvasRenderer } from 'echarts/renderers';
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
import { LAST_7_DAYS } from '@/utils/date';
|
import { LAST_7_DAYS } from '@/utils/date';
|
||||||
|
|
||||||
// 导入样式
|
// 导入样式
|
||||||
|
@ -241,10 +241,10 @@ const getThisMonth = (checkedValues?: string[]) => {
|
||||||
return `${date.getFullYear()}-${startMonth} 至 ${date2.getFullYear()}-${endMonth}`;
|
return `${date.getFullYear()}-${startMonth} 至 ${date2.getFullYear()}-${endMonth}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const store = useStore();
|
const store = useSettingStore();
|
||||||
const resizeTime = ref(1);
|
const resizeTime = ref(1);
|
||||||
|
|
||||||
const chartColors = computed(() => store.state.setting.chartColors);
|
const chartColors = computed(() => store.chartColors);
|
||||||
|
|
||||||
// moneyCharts
|
// moneyCharts
|
||||||
let moneyContainer: HTMLElement;
|
let moneyContainer: HTMLElement;
|
||||||
|
@ -355,14 +355,14 @@ onUnmounted(() => {
|
||||||
const currentMonth = ref(getThisMonth());
|
const currentMonth = ref(getThisMonth());
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => store.state.setting.brandTheme,
|
() => store.brandTheme,
|
||||||
() => {
|
() => {
|
||||||
changeChartsTheme([refundChart, stokeChart, monitorChart, countChart]);
|
changeChartsTheme([refundChart, stokeChart, monitorChart, countChart]);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => store.state.setting.mode,
|
() => store.mode,
|
||||||
() => {
|
() => {
|
||||||
[moneyChart, refundChart, stokeChart, monitorChart, countChart].forEach((item) => {
|
[moneyChart, refundChart, stokeChart, monitorChart, countChart].forEach((item) => {
|
||||||
item.dispose();
|
item.dispose();
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
|
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components';
|
import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components';
|
||||||
|
@ -70,14 +69,16 @@ import ProductCard from '@/components/card/Card.vue';
|
||||||
import { changeChartsTheme, getFolderLineDataSet, getScatterDataSet } from '../base/index';
|
import { changeChartsTheme, getFolderLineDataSet, getScatterDataSet } from '../base/index';
|
||||||
import { PANE_LIST_DATA, PRODUCT_LIST } from './constants';
|
import { PANE_LIST_DATA, PRODUCT_LIST } from './constants';
|
||||||
import { LAST_7_DAYS } from '@/utils/date';
|
import { LAST_7_DAYS } from '@/utils/date';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
|
|
||||||
import Trend from '@/components/trend/index.vue';
|
import Trend from '@/components/trend/index.vue';
|
||||||
import Card from '@/components/card/index.vue';
|
import Card from '@/components/card/index.vue';
|
||||||
|
|
||||||
echarts.use([GridComponent, LegendComponent, TooltipComponent, LineChart, ScatterChart, CanvasRenderer]);
|
echarts.use([GridComponent, LegendComponent, TooltipComponent, LineChart, ScatterChart, CanvasRenderer]);
|
||||||
|
|
||||||
const store = useStore();
|
const store = useSettingStore();
|
||||||
const chartColors = computed(() => store.state.setting.chartColors);
|
const chartColors = computed(() => store.chartColors);
|
||||||
|
|
||||||
// lineChart logic
|
// lineChart logic
|
||||||
let lineContainer: HTMLElement;
|
let lineContainer: HTMLElement;
|
||||||
let lineChart: echarts.ECharts;
|
let lineChart: echarts.ECharts;
|
||||||
|
@ -126,14 +127,14 @@ onUnmounted(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => store.state.setting.mode,
|
() => store.mode,
|
||||||
() => {
|
() => {
|
||||||
renderCharts();
|
renderCharts();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => store.state.setting.brandTheme,
|
() => store.brandTheme,
|
||||||
() => {
|
() => {
|
||||||
changeChartsTheme([lineChart, scatterChart]);
|
changeChartsTheme([lineChart, scatterChart]);
|
||||||
},
|
},
|
||||||
|
@ -144,7 +145,7 @@ const onSatisfyChange = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMaterialChange = (value: string[]) => {
|
const onMaterialChange = (value: string[]) => {
|
||||||
const chartColors = computed(() => store.state.setting.chartColors);
|
const chartColors = computed(() => store.chartColors);
|
||||||
lineChart.setOption(getFolderLineDataSet({ dateTime: value, ...chartColors.value }));
|
lineChart.setOption(getFolderLineDataSet({ dateTime: value, ...chartColors.value }));
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -70,12 +70,12 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, ref, watch, computed } from 'vue';
|
import { onMounted, onUnmounted, ref, watch, computed } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
|
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import { TitleComponent, ToolboxComponent, TooltipComponent, GridComponent, LegendComponent } from 'echarts/components';
|
import { TitleComponent, ToolboxComponent, TooltipComponent, GridComponent, LegendComponent } from 'echarts/components';
|
||||||
import { BarChart, LineChart } from 'echarts/charts';
|
import { BarChart, LineChart } from 'echarts/charts';
|
||||||
import { CanvasRenderer } from 'echarts/renderers';
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
|
|
||||||
import { changeChartsTheme, getSmoothLineDataSet, get2ColBarChartDataSet } from '../../dashboard/base/index';
|
import { changeChartsTheme, getSmoothLineDataSet, get2ColBarChartDataSet } from '../../dashboard/base/index';
|
||||||
import { BASE_INFO_DATA, TABLE_COLUMNS as columns } from './constants';
|
import { BASE_INFO_DATA, TABLE_COLUMNS as columns } from './constants';
|
||||||
|
@ -96,9 +96,9 @@ echarts.use([
|
||||||
CanvasRenderer,
|
CanvasRenderer,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const store = useStore();
|
const store = useSettingStore();
|
||||||
|
|
||||||
const chartColors = computed(() => store.state.setting.chartColors);
|
const chartColors = computed(() => store.chartColors);
|
||||||
const data = ref([]);
|
const data = ref([]);
|
||||||
const pagination = ref({
|
const pagination = ref({
|
||||||
defaultPageSize: 10,
|
defaultPageSize: 10,
|
||||||
|
@ -173,7 +173,7 @@ onMounted(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => store.state.setting.brandTheme,
|
() => store.brandTheme,
|
||||||
() => {
|
() => {
|
||||||
changeChartsTheme([monitorChart, dataChart]);
|
changeChartsTheme([monitorChart, dataChart]);
|
||||||
},
|
},
|
||||||
|
|
|
@ -50,11 +50,12 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, ComputedRef } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
import { storeToRefs } from 'pinia';
|
||||||
import { NOTIFICATION_TYPES } from '@/constants';
|
import { NOTIFICATION_TYPES } from '@/constants';
|
||||||
import { NotificationItem } from '@/interface';
|
import { NotificationItem } from '@/interface';
|
||||||
import EmptyIcon from '@/assets/assets-empty.svg?component';
|
import EmptyIcon from '@/assets/assets-empty.svg?component';
|
||||||
|
import { useNotificationStore } from '@/store';
|
||||||
|
|
||||||
const TAB_LIST = [
|
const TAB_LIST = [
|
||||||
{
|
{
|
||||||
|
@ -76,14 +77,13 @@ const tabValue = ref('msgData');
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const selectedItem = ref<NotificationItem>();
|
const selectedItem = ref<NotificationItem>();
|
||||||
|
|
||||||
const store = useStore();
|
const store = useNotificationStore();
|
||||||
|
const { msgData, unreadMsg, readMsg } = storeToRefs(store);
|
||||||
|
|
||||||
const { msgData } = store.state.notification;
|
const msgDataList = computed(() => {
|
||||||
|
if (tabValue.value === 'msgData') return msgData.value;
|
||||||
const msgDataList: ComputedRef<NotificationItem[]> = computed(() => {
|
if (tabValue.value === 'unreadMsg') return unreadMsg.value;
|
||||||
if (tabValue.value === 'msgData') return msgData;
|
if (tabValue.value === 'readMsg') return readMsg.value;
|
||||||
if (tabValue.value === 'unreadMsg') return store.getters['notification/unreadMsg'];
|
|
||||||
if (tabValue.value === 'readMsg') return store.getters['notification/readMsg'];
|
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,25 +93,25 @@ const handleClickDeleteBtn = (item: NotificationItem) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const setReadStatus = (item: NotificationItem) => {
|
const setReadStatus = (item: NotificationItem) => {
|
||||||
const changeMsg = msgData;
|
const changeMsg = msgData.value;
|
||||||
changeMsg.forEach((e: NotificationItem) => {
|
changeMsg.forEach((e: NotificationItem) => {
|
||||||
if (e.id === item.id) {
|
if (e.id === item.id) {
|
||||||
if (e.status) e.status = false;
|
if (e.status) e.status = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
store.commit('notification/setMsgData', changeMsg);
|
store.setMsgData(changeMsg);
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteMsg = () => {
|
const deleteMsg = () => {
|
||||||
const item = selectedItem.value;
|
const item = selectedItem.value;
|
||||||
const changeMsg = msgData;
|
const changeMsg = msgData.value;
|
||||||
changeMsg.forEach((e: NotificationItem, index: number) => {
|
changeMsg.forEach((e: NotificationItem, index: number) => {
|
||||||
if (e.id === item?.id) {
|
if (e.id === item?.id) {
|
||||||
changeMsg.splice(index, 1);
|
changeMsg.splice(index, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
store.commit('notification/setMsgData', changeMsg);
|
store.setMsgData(changeMsg);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -16,12 +16,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useStore } from 'vuex';
|
|
||||||
import LogoFullIcon from '@/assets/assets-logo-full.svg?component';
|
import LogoFullIcon from '@/assets/assets-logo-full.svg?component';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
|
|
||||||
const store = useStore();
|
const settingStore = useSettingStore();
|
||||||
const toggleSettingPanel = () => {
|
const toggleSettingPanel = () => {
|
||||||
store.commit('setting/toggleSettingPanel', true);
|
settingStore.updateConfig({
|
||||||
|
showSettingPanel: true,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const navToGitHub = () => {
|
const navToGitHub = () => {
|
||||||
|
|
|
@ -73,10 +73,12 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
import QrcodeVue from 'qrcode.vue';
|
import QrcodeVue from 'qrcode.vue';
|
||||||
import { MessagePlugin } from 'tdesign-vue-next';
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import { useCounter } from '@/hooks';
|
import { useCounter } from '@/hooks';
|
||||||
|
import { useUserStore } from '@/store';
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const INITIAL_DATA = {
|
const INITIAL_DATA = {
|
||||||
phone: '',
|
phone: '',
|
||||||
|
@ -105,12 +107,12 @@ const switchType = (val: string) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const store = useStore();
|
|
||||||
|
|
||||||
const onSubmit = async ({ validateResult }) => {
|
const onSubmit = async ({ validateResult }) => {
|
||||||
if (validateResult === true) {
|
if (validateResult === true) {
|
||||||
try {
|
try {
|
||||||
await store.dispatch('user/login', formData.value);
|
await userStore.login(formData.value);
|
||||||
|
|
||||||
MessagePlugin.success('登陆成功');
|
MessagePlugin.success('登陆成功');
|
||||||
router.push({
|
router.push({
|
||||||
path: '/dashboard/base',
|
path: '/dashboard/base',
|
||||||
|
|
|
@ -91,11 +91,11 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components';
|
import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components';
|
||||||
import { LineChart } from 'echarts/charts';
|
import { LineChart } from 'echarts/charts';
|
||||||
import { CanvasRenderer } from 'echarts/renderers';
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
|
import { useSettingStore } from '@/store';
|
||||||
|
|
||||||
import { LAST_7_DAYS } from '@/utils/date';
|
import { LAST_7_DAYS } from '@/utils/date';
|
||||||
import { USER_INFO_LIST, TEAM_MEMBERS, PRODUCT_LIST } from './constants';
|
import { USER_INFO_LIST, TEAM_MEMBERS, PRODUCT_LIST } from './constants';
|
||||||
|
@ -111,8 +111,8 @@ echarts.use([GridComponent, TooltipComponent, LineChart, CanvasRenderer, LegendC
|
||||||
|
|
||||||
let lineContainer: HTMLElement;
|
let lineContainer: HTMLElement;
|
||||||
let lineChart: echarts.ECharts;
|
let lineChart: echarts.ECharts;
|
||||||
const store = useStore();
|
const store = useSettingStore();
|
||||||
const chartColors = computed(() => store.state.setting.chartColors);
|
const chartColors = computed(() => store.chartColors);
|
||||||
|
|
||||||
const onLineChange = (value) => {
|
const onLineChange = (value) => {
|
||||||
lineChart.setOption(getFolderLineDataSet(value));
|
lineChart.setOption(getFolderLineDataSet(value));
|
||||||
|
@ -166,7 +166,7 @@ const getIcon = (type) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => store.state.setting.brandTheme,
|
() => store.brandTheme,
|
||||||
() => {
|
() => {
|
||||||
changeChartsTheme([lineChart]);
|
changeChartsTheme([lineChart]);
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,42 +2,47 @@ import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import NProgress from 'nprogress'; // progress bar
|
import NProgress from 'nprogress'; // progress bar
|
||||||
import 'nprogress/nprogress.css'; // progress bar style
|
import 'nprogress/nprogress.css'; // progress bar style
|
||||||
|
|
||||||
import store from '@/store';
|
import { getPermissionStore, getUserStore } from '@/store';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
|
|
||||||
|
const permissionStore = getPermissionStore();
|
||||||
|
const userStore = getUserStore();
|
||||||
|
|
||||||
NProgress.configure({ showSpinner: false });
|
NProgress.configure({ showSpinner: false });
|
||||||
|
|
||||||
const whiteListRouters = store.getters['permission/whiteListRouters'];
|
const { whiteListRouters } = permissionStore;
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
NProgress.start();
|
NProgress.start();
|
||||||
|
|
||||||
const token = store.getters['user/token'];
|
const { token } = userStore;
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
store.dispatch('user/logout');
|
userStore.logout();
|
||||||
store.dispatch('permission/restore');
|
permissionStore.restore();
|
||||||
});
|
});
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const roles = store.getters['user/roles'];
|
const { roles } = userStore;
|
||||||
|
|
||||||
if (roles && roles.length > 0) {
|
if (roles && roles.length > 0) {
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
await store.dispatch('user/getUserInfo');
|
await userStore.getUserInfo();
|
||||||
|
|
||||||
await store.dispatch('permission/initRoutes', store.getters['user/roles']);
|
const { roles } = userStore;
|
||||||
|
|
||||||
|
await permissionStore.initRoutes(roles);
|
||||||
|
|
||||||
next({ ...to });
|
next({ ...to });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
|
||||||
MessagePlugin.error(error);
|
MessagePlugin.error(error);
|
||||||
await store.commit('user/removeToken');
|
await userStore.removeToken();
|
||||||
next(`/login?redirect=${to.path}`);
|
next(`/login?redirect=${to.path}`);
|
||||||
NProgress.done();
|
NProgress.done();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import baseRouters from './modules/base';
|
||||||
import componentsRouters from './modules/components';
|
import componentsRouters from './modules/components';
|
||||||
import othersRouters from './modules/others';
|
import othersRouters from './modules/others';
|
||||||
|
|
||||||
|
// 关于单层路由,meta 中设置 { single: true } 即可为单层路由,{ hidden: true } 即可在侧边栏隐藏该路由
|
||||||
|
|
||||||
// 存放动态路由
|
// 存放动态路由
|
||||||
export const asyncRouterList: Array<RouteRecordRaw> = [...baseRouters, ...componentsRouters, ...othersRouters];
|
export const asyncRouterList: Array<RouteRecordRaw> = [...baseRouters, ...componentsRouters, ...othersRouters];
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
import { createStore } from 'vuex';
|
import { createPinia } from 'pinia';
|
||||||
import user from './modules/user';
|
|
||||||
import notification from './modules/notification';
|
|
||||||
import setting from './modules/setting';
|
|
||||||
import permission from './modules/permission';
|
|
||||||
|
|
||||||
export const store = createStore({
|
const store = createPinia();
|
||||||
modules: {
|
|
||||||
user,
|
export { store };
|
||||||
setting,
|
|
||||||
notification,
|
export * from './modules/notification';
|
||||||
permission,
|
export * from './modules/permission';
|
||||||
},
|
export * from './modules/user';
|
||||||
});
|
export * from './modules/setting';
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
|
|
@ -1,85 +1,76 @@
|
||||||
// 定义的state初始值
|
import { defineStore } from 'pinia';
|
||||||
import { NotificationItem } from '@/interface';
|
import { NotificationItem } from '@/interface';
|
||||||
|
|
||||||
const state = {
|
const msgData = [
|
||||||
msgData: [
|
{
|
||||||
{
|
id: '123',
|
||||||
id: '123',
|
content: '腾讯大厦一楼改造施工项目 已通过审核!',
|
||||||
content: '腾讯大厦一楼改造施工项目 已通过审核!',
|
type: '合同动态',
|
||||||
type: '合同动态',
|
status: true,
|
||||||
status: true,
|
collected: false,
|
||||||
collected: false,
|
date: '2021-01-01 08:00',
|
||||||
date: '2021-01-01 08:00',
|
quality: 'high',
|
||||||
quality: 'high',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '124',
|
|
||||||
content: '三季度生产原材料采购项目 开票成功!',
|
|
||||||
type: '票务动态',
|
|
||||||
status: true,
|
|
||||||
collected: false,
|
|
||||||
date: '2021-01-01 08:00',
|
|
||||||
quality: 'low',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '125',
|
|
||||||
content: '2021-01-01 10:00的【国家电网线下签约】会议即将开始,请提前10分钟前往 会议室1 进行签到!',
|
|
||||||
type: '会议通知',
|
|
||||||
status: true,
|
|
||||||
collected: false,
|
|
||||||
date: '2021-01-01 08:00',
|
|
||||||
quality: 'middle',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '126',
|
|
||||||
content: '一季度生产原材料采购项目 开票成功!',
|
|
||||||
type: '票务动态',
|
|
||||||
status: true,
|
|
||||||
collected: false,
|
|
||||||
date: '2021-01-01 08:00',
|
|
||||||
quality: 'low',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '127',
|
|
||||||
content: '二季度生产原材料采购项目 开票成功!',
|
|
||||||
type: '票务动态',
|
|
||||||
status: true,
|
|
||||||
collected: false,
|
|
||||||
date: '2021-01-01 08:00',
|
|
||||||
quality: 'low',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '128',
|
|
||||||
content: '三季度生产原材料采购项目 开票成功!',
|
|
||||||
type: '票务动态',
|
|
||||||
status: true,
|
|
||||||
collected: false,
|
|
||||||
date: '2021-01-01 08:00',
|
|
||||||
quality: 'low',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
type NotificationStateType = typeof state;
|
|
||||||
type MsgDataType = typeof state.msgData;
|
|
||||||
|
|
||||||
const mutations = {
|
|
||||||
setMsgData(state: NotificationStateType, data: MsgDataType) {
|
|
||||||
state.msgData = data;
|
|
||||||
},
|
},
|
||||||
};
|
{
|
||||||
|
id: '124',
|
||||||
|
content: '三季度生产原材料采购项目 开票成功!',
|
||||||
|
type: '票务动态',
|
||||||
|
status: true,
|
||||||
|
collected: false,
|
||||||
|
date: '2021-01-01 08:00',
|
||||||
|
quality: 'low',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '125',
|
||||||
|
content: '2021-01-01 10:00的【国家电网线下签约】会议即将开始,请提前10分钟前往 会议室1 进行签到!',
|
||||||
|
type: '会议通知',
|
||||||
|
status: true,
|
||||||
|
collected: false,
|
||||||
|
date: '2021-01-01 08:00',
|
||||||
|
quality: 'middle',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '126',
|
||||||
|
content: '一季度生产原材料采购项目 开票成功!',
|
||||||
|
type: '票务动态',
|
||||||
|
status: true,
|
||||||
|
collected: false,
|
||||||
|
date: '2021-01-01 08:00',
|
||||||
|
quality: 'low',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '127',
|
||||||
|
content: '二季度生产原材料采购项目 开票成功!',
|
||||||
|
type: '票务动态',
|
||||||
|
status: true,
|
||||||
|
collected: false,
|
||||||
|
date: '2021-01-01 08:00',
|
||||||
|
quality: 'low',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '128',
|
||||||
|
content: '三季度生产原材料采购项目 开票成功!',
|
||||||
|
type: '票务动态',
|
||||||
|
status: true,
|
||||||
|
collected: false,
|
||||||
|
date: '2021-01-01 08:00',
|
||||||
|
quality: 'low',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const getters = {
|
type MsgDataType = typeof msgData;
|
||||||
unreadMsg: (state: NotificationStateType) => state.msgData.filter((item: NotificationItem) => item.status),
|
|
||||||
readMsg: (state: NotificationStateType) => state.msgData.filter((item: NotificationItem) => !item.status),
|
|
||||||
};
|
|
||||||
|
|
||||||
const actions = {};
|
export const useNotificationStore = defineStore('notification', {
|
||||||
|
state: () => ({
|
||||||
export default {
|
msgData,
|
||||||
namespaced: true,
|
}),
|
||||||
state,
|
getters: {
|
||||||
mutations,
|
unreadMsg: (state) => state.msgData.filter((item: NotificationItem) => item.status),
|
||||||
actions,
|
readMsg: (state) => state.msgData.filter((item: NotificationItem) => !item.status),
|
||||||
getters,
|
},
|
||||||
};
|
actions: {
|
||||||
|
setMsgData(data: MsgDataType) {
|
||||||
|
this.msgData = data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
import router, { asyncRouterList, page404 } from '@/router';
|
import router, { asyncRouterList, page404 } from '@/router';
|
||||||
|
import { store } from '@/store';
|
||||||
|
|
||||||
function filterPermissionsRouters(routes, roles) {
|
function filterPermissionsRouters(routes: Array<RouteRecordRaw>, roles: Array<unknown>) {
|
||||||
const res = [];
|
const res = [];
|
||||||
routes.forEach((route) => {
|
routes.forEach((route) => {
|
||||||
const children = [];
|
const children = [];
|
||||||
|
@ -18,57 +21,38 @@ function filterPermissionsRouters(routes, roles) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = {
|
export const usePermissionStore = defineStore('permission', {
|
||||||
whiteListRouters: ['/login'],
|
state: () => ({
|
||||||
routers: [],
|
whiteListRouters: ['/login'],
|
||||||
};
|
routers: [],
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
async initRoutes(roles: Array<unknown>) {
|
||||||
|
let accessedRouters;
|
||||||
|
|
||||||
const mutations = {
|
// special token
|
||||||
setRouters: (state, routers) => {
|
if (roles.includes('ALL_ROUTERS')) {
|
||||||
state.routers = routers;
|
accessedRouters = asyncRouterList;
|
||||||
|
} else {
|
||||||
|
accessedRouters = filterPermissionsRouters(asyncRouterList, roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.routers = accessedRouters;
|
||||||
|
|
||||||
|
// register routers
|
||||||
|
accessedRouters.concat(page404).forEach((item: RouteRecordRaw) => {
|
||||||
|
router.addRoute(item);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async restore() {
|
||||||
|
this.routers.concat(page404).forEach((item: RouteRecordRaw) => {
|
||||||
|
if (router.hasRoute(item.name)) router.removeRoute(item.name);
|
||||||
|
});
|
||||||
|
this.routers = [];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
const getters = {
|
export function getPermissionStore() {
|
||||||
routers: (state) => {
|
return usePermissionStore(store);
|
||||||
return state.routers;
|
}
|
||||||
},
|
|
||||||
whiteListRouters: (state) => {
|
|
||||||
return state.whiteListRouters;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
async initRoutes({ commit }, roles) {
|
|
||||||
let accessedRouters;
|
|
||||||
|
|
||||||
// special token
|
|
||||||
if (roles.includes('ALL_ROUTERS')) {
|
|
||||||
accessedRouters = asyncRouterList;
|
|
||||||
} else {
|
|
||||||
accessedRouters = filterPermissionsRouters(asyncRouterList, roles);
|
|
||||||
}
|
|
||||||
|
|
||||||
commit('setRouters', accessedRouters);
|
|
||||||
|
|
||||||
// register routers
|
|
||||||
state.routers.concat(page404).forEach((item) => {
|
|
||||||
router.addRoute(item);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
async restore({ commit, state }) {
|
|
||||||
// remove routers
|
|
||||||
state.routers.concat(page404).forEach((item) => {
|
|
||||||
router.removeRoute(item.name);
|
|
||||||
});
|
|
||||||
commit('setRouters', []);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
mutations,
|
|
||||||
actions,
|
|
||||||
getters,
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { COLOR_TOKEN, LIGHT_CHART_COLORS, DARK_CHART_COLORS } from '@/config/color';
|
||||||
import STYLE_CONFIG from '@/config/style';
|
import STYLE_CONFIG from '@/config/style';
|
||||||
import { COLOR_TOKEN, ColorSeries, ColorToken, LIGHT_CHART_COLORS, DARK_CHART_COLORS } from '@/config/color';
|
import { store } from '@/store';
|
||||||
|
|
||||||
// 定义的state初始值
|
|
||||||
const state = {
|
const state = {
|
||||||
...STYLE_CONFIG,
|
...STYLE_CONFIG,
|
||||||
showSettingPanel: false,
|
showSettingPanel: false,
|
||||||
|
@ -9,98 +10,62 @@ const state = {
|
||||||
chartColors: LIGHT_CHART_COLORS,
|
chartColors: LIGHT_CHART_COLORS,
|
||||||
};
|
};
|
||||||
|
|
||||||
type IInitStateType = typeof state;
|
export type TState = typeof state;
|
||||||
|
|
||||||
interface IStateType extends IInitStateType {
|
export const useSettingStore = defineStore('setting', {
|
||||||
isAsideFooter: boolean;
|
state: () => state,
|
||||||
showSettingPanel: boolean;
|
getters: {
|
||||||
|
showSidebar: (state) => state.layout !== 'top',
|
||||||
|
showSidebarLogo: (state) => state.layout === 'side',
|
||||||
|
showHeaderLogo: (state) => state.layout !== 'side',
|
||||||
|
displayMode: (state) => {
|
||||||
|
if (state.mode === 'auto') {
|
||||||
|
const media = window.matchMedia('(prefers-color-scheme:dark)');
|
||||||
|
if (media.matches) {
|
||||||
|
return 'dark';
|
||||||
|
}
|
||||||
|
return 'light';
|
||||||
|
}
|
||||||
|
return state.mode;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
async changeMode(mode: 'dark' | 'light' | 'auto') {
|
||||||
|
let theme = mode;
|
||||||
|
|
||||||
|
if (mode === 'auto') {
|
||||||
|
const media = window.matchMedia('(prefers-color-scheme:dark)');
|
||||||
|
if (media.matches) {
|
||||||
|
theme = 'dark';
|
||||||
|
} else {
|
||||||
|
theme = 'light';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const isDarkMode = theme === 'dark';
|
||||||
|
|
||||||
|
document.documentElement.setAttribute('theme-mode', isDarkMode ? 'dark' : '');
|
||||||
|
|
||||||
|
this.chartColor = isDarkMode ? DARK_CHART_COLORS : LIGHT_CHART_COLORS;
|
||||||
|
},
|
||||||
|
changeBrandTheme(brandTheme: string) {
|
||||||
|
document.documentElement.setAttribute('theme-color', brandTheme);
|
||||||
|
},
|
||||||
|
updateConfig(payload: Partial<TState>) {
|
||||||
|
for (const key in payload) {
|
||||||
|
if (payload[key] !== undefined) {
|
||||||
|
this[key] = payload[key];
|
||||||
|
}
|
||||||
|
if (key === 'mode') {
|
||||||
|
this.changeMode(payload[key]);
|
||||||
|
}
|
||||||
|
if (key === 'brandTheme') {
|
||||||
|
this.changeBrandTheme(payload[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function getSettingStore() {
|
||||||
|
return useSettingStore(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mutations = {
|
|
||||||
update(state: IStateType, payload: IStateType) {
|
|
||||||
state.showBreadcrumb = payload.showBreadcrumb;
|
|
||||||
state.mode = payload.mode;
|
|
||||||
state.layout = payload.layout;
|
|
||||||
state.isSidebarCompact = payload.isSidebarCompact;
|
|
||||||
state.splitMenu = payload.splitMenu;
|
|
||||||
state.isFooterAside = payload.isFooterAside;
|
|
||||||
state.isSidebarFixed = payload.isSidebarFixed;
|
|
||||||
state.isHeaderFixed = payload.isHeaderFixed;
|
|
||||||
state.showHeader = payload.showHeader;
|
|
||||||
state.showFooter = payload.showFooter;
|
|
||||||
state.backgroundTheme = payload.backgroundTheme;
|
|
||||||
state.brandTheme = payload.brandTheme;
|
|
||||||
},
|
|
||||||
toggleSidebarCompact(state: IStateType) {
|
|
||||||
state.isSidebarCompact = !state.isSidebarCompact;
|
|
||||||
},
|
|
||||||
showSidebarCompact(state: IStateType, payload: boolean) {
|
|
||||||
state.isSidebarCompact = payload;
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleSettingPanel(state: IStateType, payload: boolean) {
|
|
||||||
state.showSettingPanel = payload;
|
|
||||||
},
|
|
||||||
addColor(state: IStateType, payload: ColorSeries) {
|
|
||||||
state.colorList = { ...state.colorList, ...payload };
|
|
||||||
},
|
|
||||||
changeChartColor(state: IStateType, payload: ColorToken) {
|
|
||||||
state.chartColors = { ...payload };
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const getters = {
|
|
||||||
showHeader: (state: IStateType) => state.showHeader,
|
|
||||||
showSidebar: (state: IStateType) => state.layout !== 'top',
|
|
||||||
showSidebarLogo: (state: IStateType) => state.layout === 'side',
|
|
||||||
showHeaderLogo: (state: IStateType) => state.layout !== 'side',
|
|
||||||
showFooter: (state: IStateType) => state.showFooter,
|
|
||||||
mode: (state: IStateType) => {
|
|
||||||
if (state.mode === 'auto') {
|
|
||||||
const media = window.matchMedia('(prefers-color-scheme:dark)');
|
|
||||||
if (media.matches) {
|
|
||||||
return 'dark';
|
|
||||||
}
|
|
||||||
return 'light';
|
|
||||||
}
|
|
||||||
return state.mode;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
async changeTheme({ commit, dispatch }, payload) {
|
|
||||||
dispatch('changeMode', payload);
|
|
||||||
dispatch('changeBrandTheme', payload);
|
|
||||||
commit('update', payload);
|
|
||||||
},
|
|
||||||
async changeMode({ commit }, payload: IStateType) {
|
|
||||||
let theme = payload.mode;
|
|
||||||
|
|
||||||
if (payload.mode === 'auto') {
|
|
||||||
const media = window.matchMedia('(prefers-color-scheme:dark)');
|
|
||||||
if (media.matches) {
|
|
||||||
theme = 'dark';
|
|
||||||
} else {
|
|
||||||
theme = 'light';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const isDarkMode = theme === 'dark';
|
|
||||||
|
|
||||||
document.documentElement.setAttribute('theme-mode', isDarkMode ? 'dark' : '');
|
|
||||||
|
|
||||||
commit('changeChartColor', isDarkMode ? DARK_CHART_COLORS : LIGHT_CHART_COLORS);
|
|
||||||
},
|
|
||||||
changeBrandTheme(_: { state: IStateType }, payload: IStateType) {
|
|
||||||
const { brandTheme } = payload;
|
|
||||||
|
|
||||||
document.documentElement.setAttribute('theme-color', brandTheme);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
mutations,
|
|
||||||
actions,
|
|
||||||
getters,
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,102 +1,86 @@
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
import { TOKEN_NAME } from '@/config/global';
|
import { TOKEN_NAME } from '@/config/global';
|
||||||
|
import { store } from '@/store';
|
||||||
|
|
||||||
const InitUserInfo = {
|
const InitUserInfo = {
|
||||||
roles: [],
|
roles: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
// 定义的state初始值
|
export const useUserStore = defineStore('user', {
|
||||||
const state = {
|
state: () => ({
|
||||||
token: localStorage.getItem(TOKEN_NAME) || 'main_token', // 默认token不走权限
|
token: localStorage.getItem(TOKEN_NAME) || 'main_token', // 默认token不走权限
|
||||||
userInfo: InitUserInfo,
|
userInfo: InitUserInfo,
|
||||||
};
|
}),
|
||||||
|
getters: {
|
||||||
const mutations = {
|
roles: (state) => {
|
||||||
setToken(state, token) {
|
return state.userInfo?.roles;
|
||||||
localStorage.setItem(TOKEN_NAME, token);
|
},
|
||||||
state.token = token;
|
|
||||||
},
|
},
|
||||||
removeToken(state) {
|
actions: {
|
||||||
localStorage.removeItem(TOKEN_NAME);
|
async login(userInfo: Record<string, unknown>) {
|
||||||
state.token = '';
|
const mockLogin = async (userInfo: Record<string, unknown>) => {
|
||||||
},
|
// 登录请求流程
|
||||||
setUserInfo(state, userInfo) {
|
console.log(userInfo);
|
||||||
state.userInfo = userInfo;
|
// const { account, password } = userInfo;
|
||||||
},
|
// if (account !== 'td') {
|
||||||
};
|
// return {
|
||||||
|
// code: 401,
|
||||||
const getters = {
|
// message: '账号不存在',
|
||||||
token: (state) => {
|
// };
|
||||||
return state.token;
|
// }
|
||||||
},
|
// if (['main_', 'dev_'].indexOf(password) === -1) {
|
||||||
roles: (state) => {
|
// return {
|
||||||
return state.userInfo?.roles;
|
// code: 401,
|
||||||
},
|
// message: '密码错误',
|
||||||
};
|
// };
|
||||||
|
// }
|
||||||
const actions = {
|
// const token = {
|
||||||
async login({ commit }, userInfo) {
|
// main_: 'main_token',
|
||||||
const mockLogin = async (userInfo) => {
|
// dev_: 'dev_token',
|
||||||
// 登录请求流程
|
// }[password];
|
||||||
console.log(userInfo);
|
|
||||||
// const { account, password } = userInfo;
|
|
||||||
// if (account !== 'td') {
|
|
||||||
// return {
|
|
||||||
// code: 401,
|
|
||||||
// message: '账号不存在',
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// if (['main_', 'dev_'].indexOf(password) === -1) {
|
|
||||||
// return {
|
|
||||||
// code: 401,
|
|
||||||
// message: '密码错误',
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// const token = {
|
|
||||||
// main_: 'main_token',
|
|
||||||
// dev_: 'dev_token',
|
|
||||||
// }[password];
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
message: '登陆成功',
|
|
||||||
data: 'main_token',
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const res = await mockLogin(userInfo);
|
|
||||||
if (res.code === 200) {
|
|
||||||
commit('setToken', res.data);
|
|
||||||
} else {
|
|
||||||
throw res;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getUserInfo({ commit, state }) {
|
|
||||||
const mockRemoteUserInfo = async (token) => {
|
|
||||||
if (token === 'main_token') {
|
|
||||||
return {
|
return {
|
||||||
name: 'td_main',
|
code: 200,
|
||||||
roles: ['ALL_ROUTERS'],
|
message: '登陆成功',
|
||||||
|
data: 'main_token',
|
||||||
};
|
};
|
||||||
}
|
|
||||||
return {
|
|
||||||
name: 'td_dev',
|
|
||||||
roles: ['userIndex', 'dashboardBase', 'login'],
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
const res = await mockRemoteUserInfo(state.token);
|
const res = await mockLogin(userInfo);
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.token = res.data;
|
||||||
|
} else {
|
||||||
|
throw res;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getUserInfo() {
|
||||||
|
const mockRemoteUserInfo = async (token: string) => {
|
||||||
|
if (token === 'main_token') {
|
||||||
|
return {
|
||||||
|
name: 'td_main',
|
||||||
|
roles: ['ALL_ROUTERS'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name: 'td_dev',
|
||||||
|
roles: ['userIndex', 'dashboardBase', 'login'],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
commit('setUserInfo', res);
|
const res = await mockRemoteUserInfo(this.token);
|
||||||
|
|
||||||
|
this.userInfo = res;
|
||||||
|
},
|
||||||
|
async logout() {
|
||||||
|
localStorage.removeItem(TOKEN_NAME);
|
||||||
|
this.token = '';
|
||||||
|
this.userInfo = InitUserInfo;
|
||||||
|
},
|
||||||
|
async removeToken() {
|
||||||
|
this.token = '';
|
||||||
|
},
|
||||||
},
|
},
|
||||||
async logout({ commit }) {
|
});
|
||||||
commit('removeToken');
|
|
||||||
commit('setUserInfo', InitUserInfo);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
export function getUserStore() {
|
||||||
namespaced: true,
|
return useUserStore(store);
|
||||||
state,
|
}
|
||||||
mutations,
|
|
||||||
actions,
|
|
||||||
getters,
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user