mirror of
https://github.com/Tencent/tdesign-vue-next-starter.git
synced 2024-11-10 07:28:24 +08:00
refactor(pinia): use pinia refactor store
This commit is contained in:
parent
47d0edd888
commit
dd246e40b7
|
@ -21,15 +21,15 @@
|
|||
"echarts": "~5.1.2",
|
||||
"hex-to-hsl": "^1.0.2",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.11",
|
||||
"qrcode.vue": "^3.2.2",
|
||||
"tdesign-icons-vue-next": "^0.0.6",
|
||||
"tdesign-vue-next": "0.8.1",
|
||||
"tdesign-vue-next": "0.9.2",
|
||||
"tvision-color": "^1.3.1",
|
||||
"vue": "^3.2.31",
|
||||
"vue-color-kit": "^1.0.5",
|
||||
"vue-router": "^4.0.11",
|
||||
"vue3-clipboard": "^1.0.0",
|
||||
"vuex": "^4.0.2"
|
||||
"vue3-clipboard": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^15.0.0",
|
||||
|
|
|
@ -3,17 +3,17 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
import config from '@/config/style';
|
||||
import { useSettingStore } from '@/store';
|
||||
|
||||
const store = useStore();
|
||||
const store = useSettingStore();
|
||||
|
||||
const mode = computed(() => {
|
||||
return store.getters['setting/mode'];
|
||||
return store.displayMode;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
store.dispatch('setting/changeTheme', { ...config });
|
||||
store.updateConfig({ ...config });
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
import { getBrandColor } from '@/config/color';
|
||||
import { useSettingStore } from '@/store';
|
||||
|
||||
const store = useSettingStore();
|
||||
|
||||
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)';
|
||||
|
@ -15,11 +17,9 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const style = computed(() => {
|
||||
const { value } = props;
|
||||
const { colorList } = store.state.setting;
|
||||
const { colorList } = store;
|
||||
return {
|
||||
background: value !== 'dynamic' ? getBrandColor(value, colorList)['@brand-color'] : panelColor,
|
||||
};
|
||||
|
|
|
@ -35,5 +35,5 @@ export interface NotificationItem {
|
|||
status: boolean;
|
||||
collected: boolean;
|
||||
date: string;
|
||||
quality: 'high' | 'low' | 'middle';
|
||||
quality: string;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<search :layout="layout" />
|
||||
</div>
|
||||
</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>
|
||||
<div class="operations-container">
|
||||
<!-- 搜索框 -->
|
||||
|
@ -65,9 +65,8 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { PropType, computed } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
|
||||
import { useSettingStore } from '@/store';
|
||||
import { prefix } from '@/config/global';
|
||||
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
||||
import { MenuRoute } from '@/interface';
|
||||
|
@ -107,11 +106,13 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const store = useStore();
|
||||
const router = useRouter();
|
||||
const settingStore = useSettingStore();
|
||||
|
||||
const toggleSettingPanel = () => {
|
||||
store.commit('setting/toggleSettingPanel', true);
|
||||
settingStore.updateConfig({
|
||||
showSettingPanel: true,
|
||||
});
|
||||
};
|
||||
|
||||
const active = computed(() => {
|
||||
|
@ -141,7 +142,9 @@ const menuCls = computed(() => {
|
|||
});
|
||||
|
||||
const changeCollapsed = () => {
|
||||
store.commit('setting/toggleSidebarCompact');
|
||||
settingStore.updateConfig({
|
||||
isSidebarCompact: !settingStore.isSidebarCompact,
|
||||
});
|
||||
};
|
||||
|
||||
const handleNav = (url) => {
|
||||
|
|
|
@ -46,31 +46,29 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useStore } from 'vuex';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useNotificationStore } from '@/store';
|
||||
import { NotificationItem } from '@/interface';
|
||||
|
||||
const router = useRouter();
|
||||
const store = useStore();
|
||||
const { msgData } = store.state.notification;
|
||||
|
||||
const unreadMsg = computed(() => store.getters['notification/unreadMsg']);
|
||||
const store = useNotificationStore();
|
||||
const { msgData, unreadMsg } = storeToRefs(store);
|
||||
|
||||
const setRead = (type: string, item?: NotificationItem) => {
|
||||
const changeMsg = msgData;
|
||||
const changeMsg = msgData.value;
|
||||
if (type === 'all') {
|
||||
changeMsg.forEach((e: NotificationItem) => {
|
||||
changeMsg.forEach((e) => {
|
||||
e.status = false;
|
||||
});
|
||||
} else {
|
||||
changeMsg.forEach((e: NotificationItem) => {
|
||||
changeMsg.forEach((e) => {
|
||||
if (e.id === item?.id) {
|
||||
e.status = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
store.commit('notification/setMsgData', changeMsg);
|
||||
store.setMsgData(changeMsg);
|
||||
};
|
||||
|
||||
const goDetail = () => {
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
const layout = defineProps({
|
||||
type: String,
|
||||
defineProps({
|
||||
layout: String,
|
||||
});
|
||||
|
||||
const isSearchFocus = ref(false);
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
import { defineComponent, PropType, computed, onMounted } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useStore } from 'vuex';
|
||||
import { prefix } from '@/config/global';
|
||||
import pgk from '../../../package.json';
|
||||
import MenuContent from './MenuContent';
|
||||
import tLogo from '@/assets/assets-t-logo.svg?component';
|
||||
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
||||
import { useSettingStore } from '@/store';
|
||||
|
||||
const MIN_POINT = 992 - 1;
|
||||
|
||||
const useComputed = (props) => {
|
||||
const store = useStore();
|
||||
|
||||
const collapsed = computed(() => store.state.setting.isSidebarCompact);
|
||||
const collapsed = computed(() => useSettingStore().isSidebarCompact);
|
||||
|
||||
const sideNavCls = computed(() => {
|
||||
const { isCompact } = props;
|
||||
|
@ -87,16 +85,20 @@ export default defineComponent({
|
|||
},
|
||||
},
|
||||
setup(props) {
|
||||
const store = useStore();
|
||||
const router = useRouter();
|
||||
const settingStore = useSettingStore();
|
||||
|
||||
const changeCollapsed = () => {
|
||||
store.commit('setting/toggleSidebarCompact');
|
||||
settingStore.updateConfig({
|
||||
isSidebarCompact: !settingStore.isSidebarCompact,
|
||||
});
|
||||
};
|
||||
|
||||
const autoCollapsed = () => {
|
||||
const isCompact = window.innerWidth <= MIN_POINT;
|
||||
store.commit('setting/showSidebarCompact', isCompact);
|
||||
settingStore.updateConfig({
|
||||
isSidebarCompact: isCompact,
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { usePermissionStore, useSettingStore } from '@/store';
|
||||
|
||||
import TDesignHeader from './components/Header.vue';
|
||||
import TDesignBreadcrumb from './components/Breadcrumb.vue';
|
||||
import TDesignFooter from './components/Footer.vue';
|
||||
|
@ -8,112 +11,111 @@ import TDesignContent from './components/Content.vue';
|
|||
|
||||
import { prefix } from '@/config/global';
|
||||
import TdesignSetting from './setting.vue';
|
||||
import { SettingType } from '@/interface';
|
||||
import '@/style/layout.less';
|
||||
|
||||
const name = `${prefix}-base-layout`;
|
||||
|
||||
export default defineComponent({
|
||||
name,
|
||||
computed: {
|
||||
...mapGetters({
|
||||
showSidebar: 'setting/showSidebar',
|
||||
showHeader: 'setting/showHeader',
|
||||
showHeaderLogo: 'setting/showHeaderLogo',
|
||||
showSidebarLogo: 'setting/showSidebarLogo',
|
||||
showFooter: 'setting/showFooter',
|
||||
mode: 'setting/mode',
|
||||
menuRouters: 'permission/routers',
|
||||
}),
|
||||
setting(): SettingType {
|
||||
return this.$store.state.setting;
|
||||
},
|
||||
mainLayoutCls() {
|
||||
return [
|
||||
{
|
||||
't-layout--with-sider': this.showSidebar,
|
||||
},
|
||||
];
|
||||
},
|
||||
headerMenu() {
|
||||
const { layout, splitMenu } = this.$store.state.setting;
|
||||
const { menuRouters } = this;
|
||||
if (layout === 'mix') {
|
||||
if (splitMenu) {
|
||||
return menuRouters.map((menu) => ({
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const permissionStore = usePermissionStore();
|
||||
const settingStore = useSettingStore();
|
||||
const { routers: menuRouters } = storeToRefs(permissionStore);
|
||||
const setting = storeToRefs(settingStore);
|
||||
|
||||
const mainLayoutCls = computed(() => [
|
||||
{
|
||||
't-layout--with-sider': settingStore.showSidebar,
|
||||
},
|
||||
]);
|
||||
|
||||
const headerMenu = computed(() => {
|
||||
if (settingStore.layout === 'mix') {
|
||||
if (settingStore.splitMenu) {
|
||||
console.log(menuRouters);
|
||||
return menuRouters.value.map((menu) => ({
|
||||
...menu,
|
||||
children: [],
|
||||
}));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return menuRouters;
|
||||
},
|
||||
sideMenu() {
|
||||
const { layout, splitMenu } = this.$store.state.setting;
|
||||
let { menuRouters } = this;
|
||||
return menuRouters.value;
|
||||
});
|
||||
|
||||
const sideMenu = computed(() => {
|
||||
const { layout, splitMenu } = settingStore;
|
||||
let newMenuRouters = menuRouters.value;
|
||||
if (layout === 'mix' && splitMenu) {
|
||||
menuRouters.forEach((menu) => {
|
||||
if (this.$route.path.indexOf(menu.path) === 0) {
|
||||
menuRouters = menu.children.map((subMenu) => ({ ...subMenu, path: `${menu.path}/${subMenu.path}` }));
|
||||
newMenuRouters.forEach((menu) => {
|
||||
if (route.path.indexOf(menu.path) === 0) {
|
||||
newMenuRouters = menu.children.map((subMenu) => ({ ...subMenu, path: `${menu.path}/${subMenu.path}` }));
|
||||
}
|
||||
});
|
||||
}
|
||||
return menuRouters;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
renderSidebar() {
|
||||
return newMenuRouters;
|
||||
});
|
||||
|
||||
const renderSidebar = () => {
|
||||
return (
|
||||
this.showSidebar && (
|
||||
settingStore.showSidebar && (
|
||||
<TDesignSideNav
|
||||
showLogo={this.showSidebarLogo}
|
||||
layout={this.setting.layout}
|
||||
isFixed={this.setting.isSidebarFixed}
|
||||
menu={this.sideMenu}
|
||||
theme={this.mode}
|
||||
isCompact={this.setting.isSidebarCompact}
|
||||
showLogo={settingStore.showSidebarLogo}
|
||||
layout={settingStore.layout}
|
||||
isFixed={settingStore.isSidebarFixed}
|
||||
menu={sideMenu.value}
|
||||
theme={settingStore.displayMode}
|
||||
isCompact={settingStore.isSidebarCompact}
|
||||
/>
|
||||
)
|
||||
);
|
||||
},
|
||||
renderHeader() {
|
||||
};
|
||||
|
||||
const renderHeader = () => {
|
||||
return (
|
||||
this.showHeader && (
|
||||
settingStore.showHeader && (
|
||||
<TDesignHeader
|
||||
showLogo={this.showHeaderLogo}
|
||||
theme={this.mode}
|
||||
layout={this.setting.layout}
|
||||
isFixed={this.setting.isHeaderFixed}
|
||||
menu={this.headerMenu}
|
||||
isCompact={this.setting.isSidebarCompact}
|
||||
showLogo={settingStore.showHeaderLogo}
|
||||
theme={settingStore.displayMode}
|
||||
layout={settingStore.layout}
|
||||
isFixed={settingStore.isHeaderFixed}
|
||||
menu={headerMenu.value}
|
||||
isCompact={settingStore.isSidebarCompact}
|
||||
/>
|
||||
)
|
||||
);
|
||||
},
|
||||
renderContent() {
|
||||
const { showBreadcrumb } = this.setting;
|
||||
const { showFooter } = this;
|
||||
};
|
||||
|
||||
const renderFooter = () => {
|
||||
return (
|
||||
<t-footer class={`${prefix}-footer-layout`}>
|
||||
<TDesignFooter />
|
||||
</t-footer>
|
||||
);
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
const { showBreadcrumb, showFooter } = settingStore;
|
||||
return (
|
||||
<t-layout class={[`${prefix}-layout`]}>
|
||||
<t-content class={`${prefix}-content-layout`}>
|
||||
{showBreadcrumb && <TDesignBreadcrumb />}
|
||||
<TDesignContent />
|
||||
</t-content>
|
||||
{showFooter && this.renderFooter()}
|
||||
{showFooter && renderFooter()}
|
||||
</t-layout>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
renderFooter() {
|
||||
return (
|
||||
<t-footer class={`${prefix}-footer-layout`}>
|
||||
<TDesignFooter />
|
||||
</t-footer>
|
||||
);
|
||||
},
|
||||
return {
|
||||
setting,
|
||||
mainLayoutCls,
|
||||
renderSidebar,
|
||||
renderHeader,
|
||||
renderContent,
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
const { layout } = this.setting;
|
||||
const header = this.renderHeader();
|
||||
|
|
|
@ -92,11 +92,11 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted, watchEffect } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
import { ColorPicker } from 'vue-color-kit';
|
||||
import { MessagePlugin, PopupVisibleChangeContext } from 'tdesign-vue-next';
|
||||
import { Color } from 'tvision-color';
|
||||
import useClipboard from 'vue-clipboard3';
|
||||
import { useSettingStore } from '@/store';
|
||||
|
||||
import 'vue-color-kit/dist/vue-color-kit.css';
|
||||
|
||||
|
@ -110,6 +110,8 @@ import SettingDarkIcon from '@/assets/assets-setting-dark.svg';
|
|||
import SettingLightIcon from '@/assets/assets-setting-light.svg';
|
||||
import SettingAutoIcon from '@/assets/assets-setting-auto.svg';
|
||||
|
||||
const settingStore = useSettingStore();
|
||||
|
||||
const LAYOUT_OPTION = ['side', 'top', 'mix'];
|
||||
const COLOR_OPTIONS = ['default', 'cyan', 'green', 'yellow', 'orange', 'red', 'pink', 'purple', 'dynamic'];
|
||||
const MODE_OPTIONS = [
|
||||
|
@ -119,61 +121,63 @@ const MODE_OPTIONS = [
|
|||
];
|
||||
|
||||
const formData = ref({ ...STYLE_CONFIG });
|
||||
const store = useStore();
|
||||
const colors = ref();
|
||||
const isColoPickerDisplay = ref(false);
|
||||
|
||||
const showSettingPanel = computed({
|
||||
get() {
|
||||
return store.state.setting.showSettingPanel;
|
||||
return settingStore.showSettingPanel;
|
||||
},
|
||||
set(newVal) {
|
||||
store.commit('setting/toggleSettingPanel', newVal);
|
||||
settingStore.updateConfig({
|
||||
showSettingPanel: newVal,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const mode = computed(() => {
|
||||
return store.getters['setting/mode'];
|
||||
return settingStore.displayMode;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => colors.value,
|
||||
(newColor) => {
|
||||
const { hex } = newColor;
|
||||
const { setting } = store.state;
|
||||
|
||||
// hex 主题色
|
||||
const newPalette = Color.getPaletteByGradation({
|
||||
colors: [hex],
|
||||
step: 10,
|
||||
})[0];
|
||||
const { mode } = store.state.setting;
|
||||
const colorMap = generateColorMap(hex, newPalette, mode);
|
||||
const { mode } = settingStore;
|
||||
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);
|
||||
|
||||
store.dispatch('setting/changeTheme', { ...setting, brandTheme: hex });
|
||||
settingStore.updateConfig({
|
||||
[hex]: colorMap,
|
||||
});
|
||||
settingStore.changeBrandTheme(hex);
|
||||
},
|
||||
);
|
||||
|
||||
const changeColor = (val) => {
|
||||
const { hex } = val;
|
||||
const { setting } = store.state;
|
||||
// hex 主题色
|
||||
const newPalette = Color.getPaletteByGradation({
|
||||
colors: [hex],
|
||||
step: 10,
|
||||
})[0];
|
||||
const { mode } = store.state.setting;
|
||||
const colorMap = generateColorMap(hex, newPalette, mode);
|
||||
const { mode } = settingStore;
|
||||
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(() => {
|
||||
|
@ -212,7 +216,9 @@ const getModeIcon = (mode: string) => {
|
|||
};
|
||||
|
||||
const handleCloseDrawer = () => {
|
||||
store.commit('setting/toggleSettingPanel', false);
|
||||
settingStore.updateConfig({
|
||||
showSettingPanel: false,
|
||||
});
|
||||
};
|
||||
|
||||
const getThumbnailUrl = (name: string): string => {
|
||||
|
@ -220,7 +226,7 @@ const getThumbnailUrl = (name: string): string => {
|
|||
};
|
||||
|
||||
watchEffect(() => {
|
||||
store.dispatch('setting/changeTheme', formData.value);
|
||||
settingStore.updateConfig(formData.value);
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
|
|
|
@ -3,11 +3,11 @@ import { createApp } from 'vue';
|
|||
import TDesign from 'tdesign-vue-next';
|
||||
import 'tdesign-vue-next/es/style/index.css';
|
||||
import VueClipboard from 'vue3-clipboard';
|
||||
|
||||
import { store } from './store';
|
||||
import router from './router';
|
||||
import '@/style/index.less';
|
||||
import './permission';
|
||||
|
||||
import App from './App.vue';
|
||||
|
||||
const app = createApp(App);
|
||||
|
|
|
@ -2,9 +2,7 @@ import dayjs from 'dayjs';
|
|||
import * as echarts from 'echarts/core';
|
||||
import { Color } from 'tvision-color';
|
||||
import { getBrandColor, defaultLightColor, defaultDarkColor } from '@/config/color';
|
||||
import store from '@/store';
|
||||
|
||||
const { state } = store;
|
||||
import { getSettingStore } from '@/store';
|
||||
|
||||
/**
|
||||
* 依据主题类型获取颜色
|
||||
|
@ -14,8 +12,8 @@ const { state } = store;
|
|||
* @returns {}
|
||||
*/
|
||||
export function getColorFromTheme(theme: string) {
|
||||
const { setting } = state as any;
|
||||
const { colorList, mode } = setting;
|
||||
const settingStore = getSettingStore();
|
||||
const { colorList, mode } = settingStore;
|
||||
const isDarkMode = mode === 'dark';
|
||||
let themeColorList = [];
|
||||
const themeColor = getBrandColor(theme, colorList);
|
||||
|
@ -41,8 +39,9 @@ export function getColorFromTheme(theme: string) {
|
|||
|
||||
/** 图表颜色 */
|
||||
function chartListColor(): Array<string> {
|
||||
const { setting } = state as any;
|
||||
const res = getColorFromTheme(setting.brandTheme);
|
||||
const settingStore = getSettingStore();
|
||||
const { brandTheme } = settingStore;
|
||||
const res = getColorFromTheme(brandTheme);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -1078,7 +1077,7 @@ export function getPieChartDataSet({
|
|||
textColor,
|
||||
placeholderColor,
|
||||
containerColor,
|
||||
}: { radius: number } & Record<string, string>) {
|
||||
}: { radius?: number } & Record<string, string>) {
|
||||
return {
|
||||
color: chartListColor(),
|
||||
tooltip: {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<t-row :gutter="[16, 16]">
|
||||
<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-top">
|
||||
<span :style="{ fontSize: `${resizeTime * 36}px` }">{{ item.number }}</span>
|
||||
|
@ -204,12 +204,12 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onMounted, watch, ref, onUnmounted, nextTick, computed } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
|
||||
import * as echarts from 'echarts/core';
|
||||
import { TooltipComponent, LegendComponent, GridComponent } from 'echarts/components';
|
||||
import { PieChart, LineChart, BarChart } from 'echarts/charts';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { useSettingStore } from '@/store';
|
||||
import { LAST_7_DAYS } from '@/utils/date';
|
||||
|
||||
// 导入样式
|
||||
|
@ -241,10 +241,10 @@ const getThisMonth = (checkedValues?: string[]) => {
|
|||
return `${date.getFullYear()}-${startMonth} 至 ${date2.getFullYear()}-${endMonth}`;
|
||||
};
|
||||
|
||||
const store = useStore();
|
||||
const store = useSettingStore();
|
||||
const resizeTime = ref(1);
|
||||
|
||||
const chartColors = computed(() => store.state.setting.chartColors);
|
||||
const chartColors = computed(() => store.chartColors);
|
||||
|
||||
// moneyCharts
|
||||
let moneyContainer: HTMLElement;
|
||||
|
@ -276,7 +276,7 @@ const renderStokeChart = () => {
|
|||
stokeContainer = document.getElementById('stokeContainer');
|
||||
}
|
||||
stokeChart = echarts.init(stokeContainer);
|
||||
stokeChart.setOption(constructInitDataset({ dateTime: LAST_7_DAYS, ...chartColors.value }));
|
||||
stokeChart.setOption(constructInitDataset({ dateTime: LAST_7_DAYS, ...(chartColors.value as any) }));
|
||||
};
|
||||
|
||||
// monitorChart
|
||||
|
@ -355,14 +355,14 @@ onUnmounted(() => {
|
|||
const currentMonth = ref(getThisMonth());
|
||||
|
||||
watch(
|
||||
() => store.state.setting.brandTheme,
|
||||
() => store.brandTheme,
|
||||
() => {
|
||||
changeChartsTheme([refundChart, stokeChart, monitorChart, countChart]);
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => store.state.setting.mode,
|
||||
() => store.mode,
|
||||
() => {
|
||||
[moneyChart, refundChart, stokeChart, monitorChart, countChart].forEach((item) => {
|
||||
item.dispose();
|
||||
|
@ -374,10 +374,10 @@ watch(
|
|||
|
||||
const onCurrencyChange = (checkedValues: string[]) => {
|
||||
currentMonth.value = getThisMonth(checkedValues);
|
||||
monitorChart.setOption(getLineChartDataSet({ dateTime: checkedValues, ...chartColors.value }));
|
||||
monitorChart.setOption(getLineChartDataSet({ dateTime: checkedValues, ...(chartColors.value as any) }));
|
||||
};
|
||||
const onStokeDataChange = (checkedValues: string[]) => {
|
||||
stokeChart.setOption(constructInitDataset({ dateTime: checkedValues, ...chartColors.value }));
|
||||
stokeChart.setOption(constructInitDataset({ dateTime: checkedValues, ...(chartColors.value as any) }));
|
||||
};
|
||||
const rehandleClickOp = (val: MouseEvent) => {
|
||||
console.log(val);
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
|
||||
import * as echarts from 'echarts/core';
|
||||
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 { PANE_LIST_DATA, PRODUCT_LIST } from './constants';
|
||||
import { LAST_7_DAYS } from '@/utils/date';
|
||||
import { useSettingStore } from '@/store';
|
||||
|
||||
import Trend from '@/components/trend/index.vue';
|
||||
import Card from '@/components/card/index.vue';
|
||||
|
||||
echarts.use([GridComponent, LegendComponent, TooltipComponent, LineChart, ScatterChart, CanvasRenderer]);
|
||||
|
||||
const store = useStore();
|
||||
const chartColors = computed(() => store.state.setting.chartColors);
|
||||
const store = useSettingStore();
|
||||
const chartColors = computed(() => store.chartColors);
|
||||
|
||||
// lineChart logic
|
||||
let lineContainer: HTMLElement;
|
||||
let lineChart: echarts.ECharts;
|
||||
|
@ -126,14 +127,14 @@ onUnmounted(() => {
|
|||
});
|
||||
|
||||
watch(
|
||||
() => store.state.setting.mode,
|
||||
() => store.mode,
|
||||
() => {
|
||||
renderCharts();
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => store.state.setting.brandTheme,
|
||||
() => store.brandTheme,
|
||||
() => {
|
||||
changeChartsTheme([lineChart, scatterChart]);
|
||||
},
|
||||
|
@ -144,8 +145,8 @@ const onSatisfyChange = () => {
|
|||
};
|
||||
|
||||
const onMaterialChange = (value: string[]) => {
|
||||
const chartColors = computed(() => store.state.setting.chartColors);
|
||||
lineChart.setOption(getFolderLineDataSet({ dateTime: value, ...chartColors.value }));
|
||||
const chartColors = computed(() => store.chartColors);
|
||||
lineChart.setOption(getFolderLineDataSet({ dateTime: value, ...(chartColors.value as any) }));
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -70,12 +70,12 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref, watch, computed } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
|
||||
import * as echarts from 'echarts/core';
|
||||
import { TitleComponent, ToolboxComponent, TooltipComponent, GridComponent, LegendComponent } from 'echarts/components';
|
||||
import { BarChart, LineChart } from 'echarts/charts';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { useSettingStore } from '@/store';
|
||||
|
||||
import { changeChartsTheme, getSmoothLineDataSet, get2ColBarChartDataSet } from '../../dashboard/base/index';
|
||||
import { BASE_INFO_DATA, TABLE_COLUMNS as columns } from './constants';
|
||||
|
@ -96,9 +96,9 @@ echarts.use([
|
|||
CanvasRenderer,
|
||||
]);
|
||||
|
||||
const store = useStore();
|
||||
const store = useSettingStore();
|
||||
|
||||
const chartColors = computed(() => store.state.setting.chartColors);
|
||||
const chartColors = computed(() => store.chartColors);
|
||||
const data = ref([]);
|
||||
const pagination = ref({
|
||||
defaultPageSize: 10,
|
||||
|
@ -173,7 +173,7 @@ onMounted(() => {
|
|||
});
|
||||
|
||||
watch(
|
||||
() => store.state.setting.brandTheme,
|
||||
() => store.brandTheme,
|
||||
() => {
|
||||
changeChartsTheme([monitorChart, dataChart]);
|
||||
},
|
||||
|
|
|
@ -50,11 +50,12 @@
|
|||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, ComputedRef } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
import { ref, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { NOTIFICATION_TYPES } from '@/constants';
|
||||
import { NotificationItem } from '@/interface';
|
||||
import EmptyIcon from '@/assets/assets-empty.svg?component';
|
||||
import { useNotificationStore } from '@/store';
|
||||
|
||||
const TAB_LIST = [
|
||||
{
|
||||
|
@ -76,14 +77,13 @@ const tabValue = ref('msgData');
|
|||
const visible = ref(false);
|
||||
const selectedItem = ref<NotificationItem>();
|
||||
|
||||
const store = useStore();
|
||||
const store = useNotificationStore();
|
||||
const { msgData, unreadMsg, readMsg } = storeToRefs(store);
|
||||
|
||||
const { msgData } = store.state.notification;
|
||||
|
||||
const msgDataList: ComputedRef<NotificationItem[]> = computed(() => {
|
||||
if (tabValue.value === 'msgData') return msgData;
|
||||
if (tabValue.value === 'unreadMsg') return store.getters['notification/unreadMsg'];
|
||||
if (tabValue.value === 'readMsg') return store.getters['notification/readMsg'];
|
||||
const msgDataList = computed(() => {
|
||||
if (tabValue.value === 'msgData') return msgData.value;
|
||||
if (tabValue.value === 'unreadMsg') return unreadMsg.value;
|
||||
if (tabValue.value === 'readMsg') return readMsg.value;
|
||||
return [];
|
||||
});
|
||||
|
||||
|
@ -93,25 +93,25 @@ const handleClickDeleteBtn = (item: NotificationItem) => {
|
|||
};
|
||||
|
||||
const setReadStatus = (item: NotificationItem) => {
|
||||
const changeMsg = msgData;
|
||||
const changeMsg = msgData.value;
|
||||
changeMsg.forEach((e: NotificationItem) => {
|
||||
if (e.id === item.id) {
|
||||
if (e.status) e.status = false;
|
||||
}
|
||||
});
|
||||
store.commit('notification/setMsgData', changeMsg);
|
||||
store.setMsgData(changeMsg);
|
||||
};
|
||||
|
||||
const deleteMsg = () => {
|
||||
const item = selectedItem.value;
|
||||
const changeMsg = msgData;
|
||||
const changeMsg = msgData.value;
|
||||
changeMsg.forEach((e: NotificationItem, index: number) => {
|
||||
if (e.id === item?.id) {
|
||||
changeMsg.splice(index, 1);
|
||||
}
|
||||
});
|
||||
visible.value = false;
|
||||
store.commit('notification/setMsgData', changeMsg);
|
||||
store.setMsgData(changeMsg);
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from 'vuex';
|
||||
import LogoFullIcon from '@/assets/assets-logo-full.svg?component';
|
||||
import { useSettingStore } from '@/store';
|
||||
|
||||
const store = useStore();
|
||||
const settingStore = useSettingStore();
|
||||
const toggleSettingPanel = () => {
|
||||
store.commit('setting/toggleSettingPanel', true);
|
||||
settingStore.updateConfig({
|
||||
showSettingPanel: true,
|
||||
});
|
||||
};
|
||||
|
||||
const navToGitHub = () => {
|
||||
|
|
|
@ -73,10 +73,12 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useStore } from 'vuex';
|
||||
import QrcodeVue from 'qrcode.vue';
|
||||
import { MessagePlugin } from 'tdesign-vue-next';
|
||||
import { useCounter } from '@/hooks';
|
||||
import { useUserStore } from '@/store';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const INITIAL_DATA = {
|
||||
phone: '',
|
||||
|
@ -105,12 +107,12 @@ const switchType = (val: string) => {
|
|||
};
|
||||
|
||||
const router = useRouter();
|
||||
const store = useStore();
|
||||
|
||||
const onSubmit = async ({ validateResult }) => {
|
||||
if (validateResult === true) {
|
||||
try {
|
||||
await store.dispatch('user/login', formData.value);
|
||||
await userStore.login(formData.value);
|
||||
|
||||
MessagePlugin.success('登陆成功');
|
||||
router.push({
|
||||
path: '/dashboard/base',
|
||||
|
|
|
@ -91,11 +91,11 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
import * as echarts from 'echarts/core';
|
||||
import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { useSettingStore } from '@/store';
|
||||
|
||||
import { LAST_7_DAYS } from '@/utils/date';
|
||||
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 lineChart: echarts.ECharts;
|
||||
const store = useStore();
|
||||
const chartColors = computed(() => store.state.setting.chartColors);
|
||||
const store = useSettingStore();
|
||||
const chartColors = computed(() => store.chartColors);
|
||||
|
||||
const onLineChange = (value) => {
|
||||
lineChart.setOption(getFolderLineDataSet(value));
|
||||
|
@ -166,7 +166,7 @@ const getIcon = (type) => {
|
|||
};
|
||||
|
||||
watch(
|
||||
() => store.state.setting.brandTheme,
|
||||
() => store.brandTheme,
|
||||
() => {
|
||||
changeChartsTheme([lineChart]);
|
||||
},
|
||||
|
|
|
@ -2,42 +2,47 @@ import { MessagePlugin } from 'tdesign-vue-next';
|
|||
import NProgress from 'nprogress'; // progress bar
|
||||
import 'nprogress/nprogress.css'; // progress bar style
|
||||
|
||||
import store from '@/store';
|
||||
import { getPermissionStore, getUserStore } from '@/store';
|
||||
import router from '@/router';
|
||||
|
||||
const permissionStore = getPermissionStore();
|
||||
const userStore = getUserStore();
|
||||
|
||||
NProgress.configure({ showSpinner: false });
|
||||
|
||||
const whiteListRouters = store.getters['permission/whiteListRouters'];
|
||||
const { whiteListRouters } = permissionStore;
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
NProgress.start();
|
||||
|
||||
const token = store.getters['user/token'];
|
||||
const { token } = userStore;
|
||||
|
||||
if (token) {
|
||||
if (to.path === '/login') {
|
||||
setTimeout(() => {
|
||||
store.dispatch('user/logout');
|
||||
store.dispatch('permission/restore');
|
||||
userStore.logout();
|
||||
permissionStore.restore();
|
||||
});
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
const roles = store.getters['user/roles'];
|
||||
const { roles } = userStore;
|
||||
|
||||
if (roles && roles.length > 0) {
|
||||
next();
|
||||
} else {
|
||||
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 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
MessagePlugin.error(error);
|
||||
await store.commit('user/removeToken');
|
||||
await userStore.removeToken();
|
||||
next(`/login?redirect=${to.path}`);
|
||||
NProgress.done();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import baseRouters from './modules/base';
|
|||
import componentsRouters from './modules/components';
|
||||
import othersRouters from './modules/others';
|
||||
|
||||
// 关于单层路由,meta 中设置 { single: true } 即可为单层路由,{ hidden: true } 即可在侧边栏隐藏该路由
|
||||
|
||||
// 存放动态路由
|
||||
export const asyncRouterList: Array<RouteRecordRaw> = [...baseRouters, ...componentsRouters, ...othersRouters];
|
||||
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
import { createStore } from 'vuex';
|
||||
import user from './modules/user';
|
||||
import notification from './modules/notification';
|
||||
import setting from './modules/setting';
|
||||
import permission from './modules/permission';
|
||||
import { createPinia } from 'pinia';
|
||||
|
||||
export const store = createStore({
|
||||
modules: {
|
||||
user,
|
||||
setting,
|
||||
notification,
|
||||
permission,
|
||||
},
|
||||
});
|
||||
const store = createPinia();
|
||||
|
||||
export { store };
|
||||
|
||||
export * from './modules/notification';
|
||||
export * from './modules/permission';
|
||||
export * from './modules/user';
|
||||
export * from './modules/setting';
|
||||
|
||||
export default store;
|
||||
|
|
|
@ -1,85 +1,76 @@
|
|||
// 定义的state初始值
|
||||
import { defineStore } from 'pinia';
|
||||
import { NotificationItem } from '@/interface';
|
||||
|
||||
const state = {
|
||||
msgData: [
|
||||
{
|
||||
id: '123',
|
||||
content: '腾讯大厦一楼改造施工项目 已通过审核!',
|
||||
type: '合同动态',
|
||||
status: true,
|
||||
collected: false,
|
||||
date: '2021-01-01 08:00',
|
||||
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;
|
||||
const msgData = [
|
||||
{
|
||||
id: '123',
|
||||
content: '腾讯大厦一楼改造施工项目 已通过审核!',
|
||||
type: '合同动态',
|
||||
status: true,
|
||||
collected: false,
|
||||
date: '2021-01-01 08:00',
|
||||
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',
|
||||
},
|
||||
];
|
||||
|
||||
const getters = {
|
||||
unreadMsg: (state: NotificationStateType) => state.msgData.filter((item: NotificationItem) => item.status),
|
||||
readMsg: (state: NotificationStateType) => state.msgData.filter((item: NotificationItem) => !item.status),
|
||||
};
|
||||
type MsgDataType = typeof msgData;
|
||||
|
||||
const actions = {};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
getters,
|
||||
};
|
||||
export const useNotificationStore = defineStore('notification', {
|
||||
state: () => ({
|
||||
msgData,
|
||||
}),
|
||||
getters: {
|
||||
unreadMsg: (state) => state.msgData.filter((item: NotificationItem) => item.status),
|
||||
readMsg: (state) => state.msgData.filter((item: NotificationItem) => !item.status),
|
||||
},
|
||||
actions: {
|
||||
setMsgData(data: MsgDataType) {
|
||||
this.msgData = data;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { defineStore } from 'pinia';
|
||||
import router, { asyncRouterList, page404 } from '@/router';
|
||||
import { store } from '@/store';
|
||||
|
||||
function filterPermissionsRouters(routes, roles) {
|
||||
const res = [];
|
||||
|
@ -18,57 +20,38 @@ function filterPermissionsRouters(routes, roles) {
|
|||
return res;
|
||||
}
|
||||
|
||||
const state = {
|
||||
whiteListRouters: ['/login'],
|
||||
routers: [],
|
||||
};
|
||||
export const usePermissionStore = defineStore('permission', {
|
||||
state: () => ({
|
||||
whiteListRouters: ['/login'],
|
||||
routers: [],
|
||||
}),
|
||||
actions: {
|
||||
async initRoutes(roles) {
|
||||
let accessedRouters;
|
||||
|
||||
const mutations = {
|
||||
setRouters: (state, routers) => {
|
||||
state.routers = routers;
|
||||
// special token
|
||||
if (roles.includes('ALL_ROUTERS')) {
|
||||
accessedRouters = asyncRouterList;
|
||||
} else {
|
||||
accessedRouters = filterPermissionsRouters(asyncRouterList, roles);
|
||||
}
|
||||
|
||||
this.routers = accessedRouters;
|
||||
|
||||
// register routers
|
||||
accessedRouters.concat(page404).forEach((item) => {
|
||||
router.addRoute(item);
|
||||
});
|
||||
},
|
||||
async restore() {
|
||||
this.routers.concat(page404).forEach((item) => {
|
||||
if (router.hasRoute(item.name)) router.removeRoute(item.name);
|
||||
});
|
||||
this.routers = [];
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const getters = {
|
||||
routers: (state) => {
|
||||
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,
|
||||
};
|
||||
export function getPermissionStore() {
|
||||
return usePermissionStore(store);
|
||||
}
|
||||
|
|
|
@ -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 { COLOR_TOKEN, ColorSeries, ColorToken, LIGHT_CHART_COLORS, DARK_CHART_COLORS } from '@/config/color';
|
||||
import { store } from '@/store';
|
||||
|
||||
// 定义的state初始值
|
||||
const state = {
|
||||
...STYLE_CONFIG,
|
||||
showSettingPanel: false,
|
||||
|
@ -9,98 +10,60 @@ const state = {
|
|||
chartColors: LIGHT_CHART_COLORS,
|
||||
};
|
||||
|
||||
type IInitStateType = typeof state;
|
||||
export const useSettingStore = defineStore('setting', {
|
||||
state: () => state,
|
||||
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;
|
||||
|
||||
interface IStateType extends IInitStateType {
|
||||
isAsideFooter: boolean;
|
||||
showSettingPanel: boolean;
|
||||
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) {
|
||||
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 { store } from '@/store';
|
||||
|
||||
const InitUserInfo = {
|
||||
roles: [],
|
||||
};
|
||||
|
||||
// 定义的state初始值
|
||||
const state = {
|
||||
token: localStorage.getItem(TOKEN_NAME) || 'main_token', // 默认token不走权限
|
||||
userInfo: InitUserInfo,
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
setToken(state, token) {
|
||||
localStorage.setItem(TOKEN_NAME, token);
|
||||
state.token = token;
|
||||
export const useUserStore = defineStore('user', {
|
||||
state: () => ({
|
||||
token: localStorage.getItem(TOKEN_NAME) || 'main_token', // 默认token不走权限
|
||||
userInfo: InitUserInfo,
|
||||
}),
|
||||
getters: {
|
||||
roles: (state) => {
|
||||
return state.userInfo?.roles;
|
||||
},
|
||||
},
|
||||
removeToken(state) {
|
||||
localStorage.removeItem(TOKEN_NAME);
|
||||
state.token = '';
|
||||
},
|
||||
setUserInfo(state, userInfo) {
|
||||
state.userInfo = userInfo;
|
||||
},
|
||||
};
|
||||
|
||||
const getters = {
|
||||
token: (state) => {
|
||||
return state.token;
|
||||
},
|
||||
roles: (state) => {
|
||||
return state.userInfo?.roles;
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
async login({ commit }, userInfo) {
|
||||
const mockLogin = async (userInfo) => {
|
||||
// 登录请求流程
|
||||
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') {
|
||||
actions: {
|
||||
async login(userInfo) {
|
||||
const mockLogin = async (userInfo) => {
|
||||
// 登录请求流程
|
||||
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 {
|
||||
name: 'td_main',
|
||||
roles: ['ALL_ROUTERS'],
|
||||
code: 200,
|
||||
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) => {
|
||||
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 {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
getters,
|
||||
};
|
||||
export function getUserStore() {
|
||||
return useUserStore(store);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user