feat: 重构主题管理并优化UI样式
重构主题管理逻辑,将useTheme composable迁移至pinia store中管理 更新页面布局和样式,调整边距和卡片样式 添加新的主题配置文件并移除旧的主题图片资源 优化登录页和设置页的UI交互 更新unocss配置添加更多flex快捷类
@@ -7,7 +7,7 @@ VITE_APP_ENV=development
|
|||||||
VITE_APP_TITLE=fastapiadmin
|
VITE_APP_TITLE=fastapiadmin
|
||||||
|
|
||||||
# 网络请求公用地址
|
# 网络请求公用地址
|
||||||
VITE_API_BASE_URL=http://localhost:8001
|
VITE_API_BASE_URL=https://service.fastapiadmin.com
|
||||||
|
|
||||||
# 代理前缀
|
# 代理前缀
|
||||||
VITE_APP_BASE_API=/api/v1
|
VITE_APP_BASE_API=/api/v1
|
||||||
|
|||||||
@@ -93,68 +93,6 @@
|
|||||||
"watchSyncEffect": true,
|
"watchSyncEffect": true,
|
||||||
"DirectiveBinding": true,
|
"DirectiveBinding": true,
|
||||||
"MaybeRef": true,
|
"MaybeRef": true,
|
||||||
"MaybeRefOrGetter": true,
|
"MaybeRefOrGetter": true
|
||||||
"CommonUtil": true,
|
|
||||||
"Storage": true,
|
|
||||||
"acceptHMRUpdate": true,
|
|
||||||
"applyThemeOnPageShow": true,
|
|
||||||
"applyThemeToMiniProgram": true,
|
|
||||||
"auth": true,
|
|
||||||
"checkLogin": true,
|
|
||||||
"clearAll": true,
|
|
||||||
"clearToken": true,
|
|
||||||
"clearTokens": true,
|
|
||||||
"clearUserInfo": true,
|
|
||||||
"createPinia": true,
|
|
||||||
"createRouter": true,
|
|
||||||
"debounce": true,
|
|
||||||
"defineStore": true,
|
|
||||||
"dept": true,
|
|
||||||
"dict": true,
|
|
||||||
"file": true,
|
|
||||||
"getAccessToken": true,
|
|
||||||
"getActivePinia": true,
|
|
||||||
"getDarkerColor": true,
|
|
||||||
"getLighterColor": true,
|
|
||||||
"getRefreshToken": true,
|
|
||||||
"getToken": true,
|
|
||||||
"getUserInfo": true,
|
|
||||||
"isLoggedIn": true,
|
|
||||||
"log": true,
|
|
||||||
"mapActions": true,
|
|
||||||
"mapGetters": true,
|
|
||||||
"mapState": true,
|
|
||||||
"mapStores": true,
|
|
||||||
"mapWritableState": true,
|
|
||||||
"menu": true,
|
|
||||||
"notice": true,
|
|
||||||
"request": true,
|
|
||||||
"requireLogin": true,
|
|
||||||
"role": true,
|
|
||||||
"setAccessToken": true,
|
|
||||||
"setActivePinia": true,
|
|
||||||
"setMapStoreSuffix": true,
|
|
||||||
"setRefreshToken": true,
|
|
||||||
"setToken": true,
|
|
||||||
"setUserInfo": true,
|
|
||||||
"setupStore": true,
|
|
||||||
"store": true,
|
|
||||||
"storeToRefs": true,
|
|
||||||
"useDictStore": true,
|
|
||||||
"useMessage": true,
|
|
||||||
"useNotify": true,
|
|
||||||
"useRoute": true,
|
|
||||||
"useRouter": true,
|
|
||||||
"useThemeStore": true,
|
|
||||||
"useToast": true,
|
|
||||||
"useUserStore": true,
|
|
||||||
"user": true,
|
|
||||||
"config": true,
|
|
||||||
"extendedColorOptions": true,
|
|
||||||
"themeColorOptions": true,
|
|
||||||
"useStomp": true,
|
|
||||||
"useTabbar": true,
|
|
||||||
"useTheme": true,
|
|
||||||
"useWechat": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
{
|
{
|
||||||
"extends": ["stylelint-config-recommended", "stylelint-config-recommended-scss", "stylelint-config-recommended-vue/scss", "stylelint-config-html/vue", "stylelint-config-recess-order"],
|
"extends": [
|
||||||
|
"stylelint-config-recommended",
|
||||||
|
"stylelint-config-recommended-scss",
|
||||||
|
"stylelint-config-recommended-vue/scss",
|
||||||
|
"stylelint-config-html/vue",
|
||||||
|
"stylelint-config-recess-order"
|
||||||
|
],
|
||||||
"plugins": ["stylelint-prettier"],
|
"plugins": ["stylelint-prettier"],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ declare module 'vue' {
|
|||||||
WdCell: typeof import('wot-design-uni/components/wd-cell/wd-cell.vue')['default']
|
WdCell: typeof import('wot-design-uni/components/wd-cell/wd-cell.vue')['default']
|
||||||
WdCellGroup: typeof import('wot-design-uni/components/wd-cell-group/wd-cell-group.vue')['default']
|
WdCellGroup: typeof import('wot-design-uni/components/wd-cell-group/wd-cell-group.vue')['default']
|
||||||
WdCheckbox: typeof import('wot-design-uni/components/wd-checkbox/wd-checkbox.vue')['default']
|
WdCheckbox: typeof import('wot-design-uni/components/wd-checkbox/wd-checkbox.vue')['default']
|
||||||
WdCollapse: typeof import('wot-design-uni/components/wd-collapse/wd-collapse.vue')['default']
|
|
||||||
WdCollapseItem: typeof import('wot-design-uni/components/wd-collapse-item/wd-collapse-item.vue')['default']
|
|
||||||
WdConfigProvider: typeof import('wot-design-uni/components/wd-config-provider/wd-config-provider.vue')['default']
|
WdConfigProvider: typeof import('wot-design-uni/components/wd-config-provider/wd-config-provider.vue')['default']
|
||||||
WdDivider: typeof import('wot-design-uni/components/wd-divider/wd-divider.vue')['default']
|
WdDivider: typeof import('wot-design-uni/components/wd-divider/wd-divider.vue')['default']
|
||||||
WdForm: typeof import('wot-design-uni/components/wd-form/wd-form.vue')['default']
|
WdForm: typeof import('wot-design-uni/components/wd-form/wd-form.vue')['default']
|
||||||
@@ -32,15 +30,12 @@ declare module 'vue' {
|
|||||||
WdGridItem: typeof import('wot-design-uni/components/wd-grid-item/wd-grid-item.vue')['default']
|
WdGridItem: typeof import('wot-design-uni/components/wd-grid-item/wd-grid-item.vue')['default']
|
||||||
WdIcon: typeof import('wot-design-uni/components/wd-icon/wd-icon.vue')['default']
|
WdIcon: typeof import('wot-design-uni/components/wd-icon/wd-icon.vue')['default']
|
||||||
WdImg: typeof import('wot-design-uni/components/wd-img/wd-img.vue')['default']
|
WdImg: typeof import('wot-design-uni/components/wd-img/wd-img.vue')['default']
|
||||||
WdImgCropper: typeof import('wot-design-uni/components/wd-img-cropper/wd-img-cropper.vue')['default']
|
|
||||||
WdInput: typeof import('wot-design-uni/components/wd-input/wd-input.vue')['default']
|
WdInput: typeof import('wot-design-uni/components/wd-input/wd-input.vue')['default']
|
||||||
WdLoading: typeof import('wot-design-uni/components/wd-loading/wd-loading.vue')['default']
|
WdLoading: typeof import('wot-design-uni/components/wd-loading/wd-loading.vue')['default']
|
||||||
WdMessageBox: typeof import('wot-design-uni/components/wd-message-box/wd-message-box.vue')['default']
|
WdMessageBox: typeof import('wot-design-uni/components/wd-message-box/wd-message-box.vue')['default']
|
||||||
WdNavbar: typeof import('wot-design-uni/components/wd-navbar/wd-navbar.vue')['default']
|
|
||||||
WdNoticeBar: typeof import('wot-design-uni/components/wd-notice-bar/wd-notice-bar.vue')['default']
|
WdNoticeBar: typeof import('wot-design-uni/components/wd-notice-bar/wd-notice-bar.vue')['default']
|
||||||
WdNotify: typeof import('wot-design-uni/components/wd-notify/wd-notify.vue')['default']
|
WdNotify: typeof import('wot-design-uni/components/wd-notify/wd-notify.vue')['default']
|
||||||
WdPopup: typeof import('wot-design-uni/components/wd-popup/wd-popup.vue')['default']
|
WdPopup: typeof import('wot-design-uni/components/wd-popup/wd-popup.vue')['default']
|
||||||
WdProgress: typeof import('wot-design-uni/components/wd-progress/wd-progress.vue')['default']
|
|
||||||
WdRadio: typeof import('wot-design-uni/components/wd-radio/wd-radio.vue')['default']
|
WdRadio: typeof import('wot-design-uni/components/wd-radio/wd-radio.vue')['default']
|
||||||
WdRadioGroup: typeof import('wot-design-uni/components/wd-radio-group/wd-radio-group.vue')['default']
|
WdRadioGroup: typeof import('wot-design-uni/components/wd-radio-group/wd-radio-group.vue')['default']
|
||||||
WdSwiper: typeof import('wot-design-uni/components/wd-swiper/wd-swiper.vue')['default']
|
WdSwiper: typeof import('wot-design-uni/components/wd-swiper/wd-swiper.vue')['default']
|
||||||
@@ -49,8 +44,6 @@ declare module 'vue' {
|
|||||||
WdTabbarItem: typeof import('wot-design-uni/components/wd-tabbar-item/wd-tabbar-item.vue')['default']
|
WdTabbarItem: typeof import('wot-design-uni/components/wd-tabbar-item/wd-tabbar-item.vue')['default']
|
||||||
WdTag: typeof import('wot-design-uni/components/wd-tag/wd-tag.vue')['default']
|
WdTag: typeof import('wot-design-uni/components/wd-tag/wd-tag.vue')['default']
|
||||||
WdText: typeof import('wot-design-uni/components/wd-text/wd-text.vue')['default']
|
WdText: typeof import('wot-design-uni/components/wd-text/wd-text.vue')['default']
|
||||||
WdTextarea: typeof import('wot-design-uni/components/wd-textarea/wd-textarea.vue')['default']
|
|
||||||
WdToast: typeof import('wot-design-uni/components/wd-toast/wd-toast.vue')['default']
|
WdToast: typeof import('wot-design-uni/components/wd-toast/wd-toast.vue')['default']
|
||||||
WdUpload: typeof import('wot-design-uni/components/wd-upload/wd-upload.vue')['default']
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ export default [
|
|||||||
"**/u-charts/**",
|
"**/u-charts/**",
|
||||||
"**/qiun-**/**",
|
"**/qiun-**/**",
|
||||||
"**/auto-imports.d.ts",
|
"**/auto-imports.d.ts",
|
||||||
// unplugin-auto-import 生成的类型文件,每次提交都改变,所以加入这里吧,与 .gitignore 配合使用
|
|
||||||
"src/types/auto-imports.d.ts",
|
|
||||||
// vite-plugin-uni-pages 生成的类型文件,每次切换分支都一堆不同的,所以直接 .gitignore
|
|
||||||
"uni-pages.d.ts",
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
// 检查文件的配置
|
// 检查文件的配置
|
||||||
@@ -47,15 +43,13 @@ export default [
|
|||||||
...{
|
...{
|
||||||
uni: "readonly", // uni-app 全局对象
|
uni: "readonly", // uni-app 全局对象
|
||||||
UniApp: "readonly", // uni-app 全局对象
|
UniApp: "readonly", // uni-app 全局对象
|
||||||
PageResult: "readonly", // 分页结果数据类型
|
|
||||||
PageQuery: "readonly", // 分页查询数据类型
|
|
||||||
OptionType: "readonly", // 选项类型
|
|
||||||
getCurrentPages: "readonly", // uni-app 全局 API
|
getCurrentPages: "readonly", // uni-app 全局 API
|
||||||
ApiResponse: "readonly", // 统一响应数据类型
|
ApiResponse: "readonly", // 统一响应数据类型
|
||||||
|
PageQuery: "readonly", // 分页查询数据类型
|
||||||
|
PageResult: "readonly", // 分页结果数据类型
|
||||||
|
OptionType: "readonly", // 选项类型
|
||||||
creatorType: "readonly", // 创建人类型
|
creatorType: "readonly", // 创建人类型
|
||||||
UploadFileResult: "readonly", // 上传文件返回类型
|
UploadFileResult: "readonly", // 上传文件返回类型
|
||||||
Todo: "readonly", // 待办事项
|
|
||||||
TodoState: "readonly", // 待办事项状态
|
|
||||||
plus: true, // HTML5+ 运行时环境
|
plus: true, // HTML5+ 运行时环境
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// pages.config.ts
|
||||||
|
import { defineUniPages } from "@uni-helper/vite-plugin-uni-pages";
|
||||||
|
|
||||||
|
export default defineUniPages({
|
||||||
|
// 你也可以定义 pages 字段,它具有最高的优先级。
|
||||||
|
pages: [],
|
||||||
|
globalStyle: {
|
||||||
|
navigationBarBackgroundColor: "@navBgColor",
|
||||||
|
navigationBarTextStyle: "@navTxtStyle",
|
||||||
|
navigationBarTitleText: "FastApp",
|
||||||
|
backgroundColor: "@bgColor",
|
||||||
|
backgroundTextStyle: "@bgTxtStyle",
|
||||||
|
backgroundColorTop: "@bgColorTop",
|
||||||
|
backgroundColorBottom: "@bgColorBottom",
|
||||||
|
enablePullDownRefresh: false,
|
||||||
|
onReachBottomDistance: 50,
|
||||||
|
animationType: "pop-in",
|
||||||
|
animationDuration: 300,
|
||||||
|
},
|
||||||
|
|
||||||
|
tabBar: {
|
||||||
|
custom: true,
|
||||||
|
customize: true,
|
||||||
|
overlay: true,
|
||||||
|
height: "0",
|
||||||
|
color: "@tabColor",
|
||||||
|
selectedColor: "@tabSelectedColor",
|
||||||
|
backgroundColor: "@tabBgColor",
|
||||||
|
borderStyle: "@tabBorderStyle",
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
pagePath: "pages/index/index",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pagePath: "pages/work/index",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pagePath: "pages/mine/index",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Before Width: | Height: | Size: 3.0 MiB |
@@ -1,48 +0,0 @@
|
|||||||
import { useThemeStore, ThemeMode, ThemeColorOption } from "@/store";
|
|
||||||
|
|
||||||
export function useTheme() {
|
|
||||||
const store = useThemeStore();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换暗黑模式
|
|
||||||
* @param mode 指定主题模式,不传则自动切换
|
|
||||||
*/
|
|
||||||
function toggleTheme(mode?: ThemeMode) {
|
|
||||||
store.toggleTheme(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置主题色
|
|
||||||
* @param option 主题色选项
|
|
||||||
*/
|
|
||||||
function setThemeColor(option: ThemeColorOption) {
|
|
||||||
store.setCurrentThemeColor(option);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化主题
|
|
||||||
*/
|
|
||||||
function initTheme() {
|
|
||||||
store.initTheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注意:全局主题管理已在App.vue中处理
|
|
||||||
// 包括:系统主题监听、导航栏颜色同步等
|
|
||||||
// 组件中一般不需要再调用initTheme(),除非有特殊需求
|
|
||||||
|
|
||||||
return {
|
|
||||||
// 状态
|
|
||||||
theme: computed(() => store.theme),
|
|
||||||
isDark: computed(() => store.isDark),
|
|
||||||
currentThemeColor: computed(() => store.currentThemeColor),
|
|
||||||
themeVars: computed(() => store.themeVars),
|
|
||||||
|
|
||||||
// 主题选项
|
|
||||||
themeColorOptions: computed(() => store.themeColorOptions),
|
|
||||||
|
|
||||||
// 方法
|
|
||||||
initTheme,
|
|
||||||
toggleTheme,
|
|
||||||
setThemeColor,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,16 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useTheme } from "@/composables/useTheme";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { useThemeStore } from "@/store/modules/theme.store";
|
||||||
|
|
||||||
const { theme, themeVars } = useTheme();
|
const useTheme = useThemeStore();
|
||||||
|
|
||||||
|
let theme = useTheme.theme;
|
||||||
|
let themeVars = useTheme.themeVars;
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
theme = useTheme.theme;
|
||||||
|
themeVars = useTheme.themeVars;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
@@ -26,12 +26,15 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRouter, useRoute } from "uni-mini-router";
|
import { useRouter, useRoute } from "uni-mini-router";
|
||||||
import { useTheme } from "@/composables/useTheme";
|
|
||||||
import { useTabbar } from "@/composables/useTabbar";
|
import { useTabbar } from "@/composables/useTabbar";
|
||||||
|
import { useThemeStore } from "@/store/modules/theme.store";
|
||||||
|
|
||||||
|
const useTheme = useThemeStore();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { themeVars, theme } = useTheme();
|
let theme = useTheme.theme;
|
||||||
|
let themeVars = useTheme.themeVars;
|
||||||
const { activeTabbar, getTabbarItemValue, setTabbarItemActive, tabbarList } = useTabbar();
|
const { activeTabbar, getTabbarItemValue, setTabbarItemActive, tabbarList } = useTabbar();
|
||||||
|
|
||||||
function handleTabbarChange({ value }: { value: string }) {
|
function handleTabbarChange({ value }: { value: string }) {
|
||||||
|
|||||||
@@ -1,12 +1,4 @@
|
|||||||
{
|
{
|
||||||
"easycom": {
|
|
||||||
"autoscan": true,
|
|
||||||
"custom": {
|
|
||||||
"^wd-(.*)": "wot-design-uni/components/wd-$1/wd-$1.vue",
|
|
||||||
"^cu-(.*)": "@/components/cu-$1/index.vue"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
"path": "pages/index/index",
|
"path": "pages/index/index",
|
||||||
@@ -19,7 +11,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/login/index",
|
"path": "pages/login/index",
|
||||||
"type": "page"
|
"type": "page",
|
||||||
|
"name": "login",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "登录"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/mine/index",
|
"path": "pages/mine/index",
|
||||||
@@ -127,20 +123,27 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarBackgroundColor": "@navBgColor",
|
||||||
|
"navigationBarTextStyle": "@navTxtStyle",
|
||||||
"navigationBarTitleText": "FastApp",
|
"navigationBarTitleText": "FastApp",
|
||||||
"navigationBarBackgroundColor": "#F8F8F8",
|
"backgroundColor": "@bgColor",
|
||||||
"backgroundColor": "#F8F8F8"
|
"backgroundTextStyle": "@bgTxtStyle",
|
||||||
|
"backgroundColorTop": "@bgColorTop",
|
||||||
|
"backgroundColorBottom": "@bgColorBottom",
|
||||||
|
"enablePullDownRefresh": false,
|
||||||
|
"onReachBottomDistance": 50,
|
||||||
|
"animationType": "pop-in",
|
||||||
|
"animationDuration": 300
|
||||||
},
|
},
|
||||||
"tabBar": {
|
"tabBar": {
|
||||||
"custom": true,
|
"custom": true,
|
||||||
"customize": true,
|
"customize": true,
|
||||||
"overlay": true,
|
"overlay": true,
|
||||||
"height": "0",
|
"height": "0",
|
||||||
"color": "#474747",
|
"color": "@tabColor",
|
||||||
"selectedColor": "#3B8DFF",
|
"selectedColor": "@tabSelectedColor",
|
||||||
"backgroundColor": "#F8F8F8",
|
"backgroundColor": "@tabBgColor",
|
||||||
"borderStyle": "black",
|
"borderStyle": "@tabBorderStyle",
|
||||||
"list": [
|
"list": [
|
||||||
{
|
{
|
||||||
"pagePath": "pages/index/index"
|
"pagePath": "pages/index/index"
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
</wd-grid-item>
|
</wd-grid-item>
|
||||||
</wd-grid>
|
</wd-grid>
|
||||||
|
|
||||||
<wd-card>
|
<wd-card type="rectangle">
|
||||||
<template #title>
|
<template #title>
|
||||||
<view class="flex-between">
|
<view class="flex-between">
|
||||||
<view>访问趋势</view>
|
<view>访问趋势</view>
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<view class="w-full h-360px mb-40rpx">
|
<view class="h-330px mb-2rpx">
|
||||||
<qiun-data-charts type="area" :chartData="chartData" :opts="chartOpts" />
|
<qiun-data-charts type="area" :chartData="chartData" :opts="chartOpts" />
|
||||||
</view>
|
</view>
|
||||||
</wd-card>
|
</wd-card>
|
||||||
@@ -135,11 +135,7 @@ const chartOpts = ref({
|
|||||||
// 日期范围
|
// 日期范围
|
||||||
const recentDaysRange = ref(7);
|
const recentDaysRange = ref(7);
|
||||||
|
|
||||||
const swiperList = ref([
|
const swiperList = ref(["/static/images/banner01.jpg", "/static/images/banner02.jpg"]);
|
||||||
"/static/images/banner02.jpg",
|
|
||||||
"/static/images/banner03.jpg",
|
|
||||||
"/static/images/banner01.png",
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 快捷导航列表
|
// 快捷导航列表
|
||||||
const navList = reactive([
|
const navList = reactive([
|
||||||
@@ -194,13 +190,6 @@ const generateStaticTrendData = (days: number) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleClick(e: any) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
function onChange(e: any) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载访问统计数据(使用静态数据)
|
// 加载访问统计数据(使用静态数据)
|
||||||
const loadVisitStatsData = async () => {
|
const loadVisitStatsData = async () => {
|
||||||
// 模拟异步加载
|
// 模拟异步加载
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<!-- Logo和标题区域 -->
|
<!-- Logo和标题区域 -->
|
||||||
<view class="header">
|
<view class="header">
|
||||||
<wd-img src="/static/logo.png" class="logo" mode="aspectFit" />
|
<wd-img src="./static/logo.png" class="logo" mode="aspectFit" />
|
||||||
<text class="title">FastApp管理系统</text>
|
<text class="title">FastApp管理系统</text>
|
||||||
<text class="subtitle">欢迎使用移动端管理平台</text>
|
<text class="subtitle">欢迎使用移动端管理平台</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -174,15 +174,17 @@
|
|||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
import { useUserStore } from "@/store";
|
import { useUserStore } from "@/store";
|
||||||
import { useToast } from "wot-design-uni";
|
import { useToast } from "wot-design-uni";
|
||||||
import { useTheme } from "@/composables/useTheme";
|
|
||||||
import AuthAPI, { type LoginFormData, type CaptchaInfo } from "@/api/auth";
|
import AuthAPI, { type LoginFormData, type CaptchaInfo } from "@/api/auth";
|
||||||
|
import { useThemeStore } from "@/store/modules/theme.store";
|
||||||
|
|
||||||
|
const useTheme = useThemeStore();
|
||||||
|
|
||||||
const loginFormRef = ref();
|
const loginFormRef = ref();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const loginType = ref<"account" | "phone">("account");
|
const loginType = ref<"account" | "phone">("account");
|
||||||
const { theme } = useTheme();
|
let theme = useTheme.theme;
|
||||||
|
|
||||||
// 登录表单数据
|
// 登录表单数据
|
||||||
const loginFormData = ref<LoginFormData>({
|
const loginFormData = ref<LoginFormData>({
|
||||||
@@ -281,7 +283,7 @@ const handleWechatLogin = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 是否暗黑模式
|
// 是否暗黑模式
|
||||||
const isDarkMode = computed(() => theme.value === "dark");
|
const isDarkMode = computed(() => theme === "dark");
|
||||||
|
|
||||||
// 导航函数
|
// 导航函数
|
||||||
const navigateToUserAgreement = () => {
|
const navigateToUserAgreement = () => {
|
||||||
@@ -314,14 +316,21 @@ onLoad((options) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<route lang="json">
|
||||||
|
{
|
||||||
|
"name": "login",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "登录"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.app-container {
|
.app-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: var(--wot-color-bg-container);
|
background-color: var(--wot-color-bg-container);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<wd-img
|
<wd-img
|
||||||
width="120rpx"
|
width="120rpx"
|
||||||
height="120rpx"
|
height="120rpx"
|
||||||
src="/static/logo.png"
|
src="./static/logo.png"
|
||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
class="about-logo"
|
class="about-logo"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -47,16 +47,24 @@
|
|||||||
<wd-collapse v-model="activeNames" accordion>
|
<wd-collapse v-model="activeNames" accordion>
|
||||||
<wd-collapse-item title="常见问题" name="faq">
|
<wd-collapse-item title="常见问题" name="faq">
|
||||||
<view class="faq-list">
|
<view class="faq-list">
|
||||||
<view v-for="(item, index) in faqList" :key="index" class="faq-item" :class="{
|
<view
|
||||||
active: currentFaq === index,
|
v-for="(item, index) in faqList"
|
||||||
}" @tap="toggleFaq(index)">
|
:key="index"
|
||||||
|
class="faq-item"
|
||||||
|
:class="{ active: currentFaq === index }"
|
||||||
|
@tap="toggleFaq(index)"
|
||||||
|
>
|
||||||
<view class="faq-header">
|
<view class="faq-header">
|
||||||
<view class="faq-question">
|
<view class="faq-question">
|
||||||
<wd-icon name="question-filled" size="28rpx" color="#ff9500" />
|
<wd-icon name="question-filled" size="28rpx" color="#ff9500" />
|
||||||
<text class="question-text">{{ item.question }}</text>
|
<text class="question-text">{{ item.question }}</text>
|
||||||
</view>
|
</view>
|
||||||
<wd-icon name="arrow-down-bold" size="24rpx" color="#999"
|
<wd-icon
|
||||||
:custom-class="currentFaq === index ? 'rotate-180' : ''" />
|
name="arrow-down-bold"
|
||||||
|
size="24rpx"
|
||||||
|
color="#999"
|
||||||
|
:custom-class="currentFaq === index ? 'rotate-180' : ''"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="currentFaq === index" class="faq-answer">
|
<view v-if="currentFaq === index" class="faq-answer">
|
||||||
<text class="answer-text">{{ item.answer }}</text>
|
<text class="answer-text">{{ item.answer }}</text>
|
||||||
|
|||||||
@@ -10,14 +10,32 @@
|
|||||||
</wd-radio>
|
</wd-radio>
|
||||||
</wd-radio-group>
|
</wd-radio-group>
|
||||||
|
|
||||||
<wd-textarea v-model="formData.description" label="问题描述" prop="description" placeholder="请详细描述您遇到的问题或建议..."
|
<wd-textarea
|
||||||
:maxlength="120" show-word-limit />
|
v-model="formData.description"
|
||||||
|
label="问题描述"
|
||||||
|
prop="description"
|
||||||
|
placeholder="请详细描述您遇到的问题或建议..."
|
||||||
|
:maxlength="120"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
|
||||||
<wd-upload v-model="formData.fileList" label="相关截图" prop="fileList" :max-count="3" :before-read="beforeRead"
|
<wd-upload
|
||||||
@delete="handleDelete" />
|
v-model="formData.fileList"
|
||||||
|
label="相关截图"
|
||||||
|
prop="fileList"
|
||||||
|
:max-count="3"
|
||||||
|
:before-read="beforeRead"
|
||||||
|
@delete="handleDelete"
|
||||||
|
/>
|
||||||
|
|
||||||
<wd-input v-model="formData.contact" label="联系方式" prop="contact" placeholder="请输入您的手机号或邮箱" clearable
|
<wd-input
|
||||||
:border="false" />
|
v-model="formData.contact"
|
||||||
|
label="联系方式"
|
||||||
|
prop="contact"
|
||||||
|
placeholder="请输入您的手机号或邮箱"
|
||||||
|
clearable
|
||||||
|
:border="false"
|
||||||
|
/>
|
||||||
<wd-text size="small">选填,便于我们与您联系</wd-text>
|
<wd-text size="small">选填,便于我们与您联系</wd-text>
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
|
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ watch(
|
|||||||
|
|
||||||
// 卡片容器
|
// 卡片容器
|
||||||
.card-container {
|
.card-container {
|
||||||
margin: 24rpx 30rpx;
|
margin: 24rpx 12rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
@@ -419,7 +419,7 @@ watch(
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 30rpx;
|
padding: 30rpx;
|
||||||
margin: 20rpx 30rpx;
|
margin: 24rpx 12rpx;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
box-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.1);
|
box-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.1);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="app-container">
|
<view class="app-container">
|
||||||
<wd-cell-group custom-style="margin-top: 20rpx">
|
<wd-cell-group>
|
||||||
<wd-cell v-if="isLogin" title="个人资料" icon="user" is-link @click="navigateToProfile" />
|
<wd-cell v-if="isLogin" title="个人资料" icon="user" is-link @click="navigateToProfile" />
|
||||||
<wd-cell v-if="isLogin" title="账号和安全" icon="secured" is-link @click="navigateToAccount" />
|
<wd-cell v-if="isLogin" title="账号和安全" icon="secured" is-link @click="navigateToAccount" />
|
||||||
<wd-cell title="主题设置" icon="setting1" is-link @click="navigateToTheme" />
|
<wd-cell title="主题设置" icon="setting1" is-link @click="navigateToTheme" />
|
||||||
@@ -8,9 +8,7 @@
|
|||||||
<wd-cell title="隐私政策" icon="folder" is-link @click="navigateToPrivacy" />
|
<wd-cell title="隐私政策" icon="folder" is-link @click="navigateToPrivacy" />
|
||||||
<wd-cell title="关于我们" icon="info-circle" is-link @click="navigateToAbout" />
|
<wd-cell title="关于我们" icon="info-circle" is-link @click="navigateToAbout" />
|
||||||
<wd-cell title="进入官网" icon="internet" is-link @click="navigateToOfficialWebsite" />
|
<wd-cell title="进入官网" icon="internet" is-link @click="navigateToOfficialWebsite" />
|
||||||
</wd-cell-group>
|
<wd-divider />
|
||||||
|
|
||||||
<wd-cell-group custom-style="margin-top:40rpx">
|
|
||||||
<wd-cell title="网络测试" icon="wifi" is-link @click="navigateToNetworkTest" />
|
<wd-cell title="网络测试" icon="wifi" is-link @click="navigateToNetworkTest" />
|
||||||
<wd-cell title="清空缓存" icon="delete1" :value="cacheSize" clickable @click="handleClearCache" />
|
<wd-cell title="清空缓存" icon="delete1" :value="cacheSize" clickable @click="handleClearCache" />
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
@@ -214,7 +212,7 @@ onLoad(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0 20rpx;
|
padding: 0 20rpx;
|
||||||
margin-top: 60rpx;
|
margin-top: 40rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logout-btn {
|
.logout-btn {
|
||||||
|
|||||||
@@ -29,10 +29,10 @@
|
|||||||
<text class="color-label">预设主题色</text>
|
<text class="color-label">预设主题色</text>
|
||||||
<view class="color-grid">
|
<view class="color-grid">
|
||||||
<view
|
<view
|
||||||
v-for="(color, index) in themeColorOptions"
|
v-for="(color, index) in useTheme.themeColorOptions"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="color-item"
|
class="color-item"
|
||||||
:class="{ active: currentThemeColor === color.primary }"
|
:class="{ active: color.primary }"
|
||||||
@click="handleSelectColor(color)"
|
@click="handleSelectColor(color)"
|
||||||
>
|
>
|
||||||
<view
|
<view
|
||||||
@@ -113,13 +113,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useTheme } from "@/composables/useTheme";
|
import { useThemeStore } from "@/store/modules/theme.store";
|
||||||
|
|
||||||
// 使用主题组合函数
|
const useTheme = useThemeStore();
|
||||||
const { isDark, themeVars, themeColorOptions, toggleTheme, setThemeColor } = useTheme();
|
|
||||||
|
|
||||||
// 创建响应式的计算属性
|
// 创建响应式的计算属性
|
||||||
const isDarkMode = computed(() => isDark.value);
|
const isDarkMode = computed(() => useTheme.isDark);
|
||||||
|
|
||||||
// 自定义颜色输入
|
// 自定义颜色输入
|
||||||
const customColor = ref("");
|
const customColor = ref("");
|
||||||
@@ -127,12 +126,12 @@ const showCustomColorInput = ref(false);
|
|||||||
|
|
||||||
// 当前选中的主题色
|
// 当前选中的主题色
|
||||||
const currentThemeColor = computed(() => {
|
const currentThemeColor = computed(() => {
|
||||||
return themeVars.value.colorTheme || themeColorOptions.value[0].primary;
|
return useTheme.themeVars.colorTheme || useTheme.themeColorOptions[0].primary;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 选择预设颜色
|
// 选择预设颜色
|
||||||
const handleSelectColor = (color: (typeof themeColorOptions.value)[0]) => {
|
const handleSelectColor = (color: (typeof useTheme.themeColorOptions)[0]) => {
|
||||||
setThemeColor(color);
|
useTheme.setCurrentThemeColor(color);
|
||||||
customColor.value = color.primary;
|
customColor.value = color.primary;
|
||||||
|
|
||||||
// 提示
|
// 提示
|
||||||
@@ -175,7 +174,7 @@ const applyCustomColor = () => {
|
|||||||
primary: color,
|
primary: color,
|
||||||
};
|
};
|
||||||
|
|
||||||
setThemeColor(customColorOption);
|
useTheme.setCurrentThemeColor(customColorOption);
|
||||||
showCustomColorInput.value = false;
|
showCustomColorInput.value = false;
|
||||||
|
|
||||||
// 提示
|
// 提示
|
||||||
@@ -193,8 +192,8 @@ const handleResetTheme = () => {
|
|||||||
content: "确定要重置为默认主题吗?",
|
content: "确定要重置为默认主题吗?",
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
setThemeColor(themeColorOptions.value[0]);
|
useTheme.setCurrentThemeColor(useTheme.themeColorOptions[0]);
|
||||||
customColor.value = themeColorOptions.value[0].primary;
|
customColor.value = useTheme.themeColorOptions[0].primary;
|
||||||
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: "已重置为默认主题",
|
title: "已重置为默认主题",
|
||||||
@@ -208,7 +207,7 @@ const handleResetTheme = () => {
|
|||||||
|
|
||||||
// 切换暗黑模式
|
// 切换暗黑模式
|
||||||
const handleToggleDarkMode = () => {
|
const handleToggleDarkMode = () => {
|
||||||
toggleTheme();
|
useTheme.toggleTheme();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: `已切换到${isDarkMode.value ? "暗黑" : "浅色"}模式`,
|
title: `已切换到${isDarkMode.value ? "暗黑" : "浅色"}模式`,
|
||||||
@@ -378,18 +377,6 @@ onShow(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-border {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 200rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: var(--wot-color-text-secondary, #666);
|
|
||||||
border: 2rpx solid;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自定义颜色弹窗
|
// 自定义颜色弹窗
|
||||||
.custom-color-popup {
|
.custom-color-popup {
|
||||||
padding: 40rpx 30rpx;
|
padding: 40rpx 30rpx;
|
||||||
|
|||||||
@@ -22,7 +22,12 @@
|
|||||||
<text class="section-subtitle">常用功能一键直达</text>
|
<text class="section-subtitle">常用功能一键直达</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="actions-grid">
|
<view class="actions-grid">
|
||||||
<view class="action-item" v-for="(action, index) in quickActions" :key="index" @tap="handleQuickAction(action)">
|
<view
|
||||||
|
v-for="(action, index) in quickActions"
|
||||||
|
:key="index"
|
||||||
|
class="action-item"
|
||||||
|
@tap="handleQuickAction(action)"
|
||||||
|
>
|
||||||
<view class="action-icon" :style="{ backgroundColor: action.color + '15' }">
|
<view class="action-icon" :style="{ backgroundColor: action.color + '15' }">
|
||||||
<wd-icon :name="action.icon" :color="action.color" size="28" />
|
<wd-icon :name="action.icon" :color="action.color" size="28" />
|
||||||
</view>
|
</view>
|
||||||
@@ -38,7 +43,12 @@
|
|||||||
<text class="section-subtitle">{{ pendingTodos.length }} 项待处理</text>
|
<text class="section-subtitle">{{ pendingTodos.length }} 项待处理</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="todo-list">
|
<view class="todo-list">
|
||||||
<view class="todo-item" v-for="(todo, index) in pendingTodos" :key="index" @tap="handleTodoItem(todo)">
|
<view
|
||||||
|
v-for="(todo, index) in pendingTodos"
|
||||||
|
:key="index"
|
||||||
|
class="todo-item"
|
||||||
|
@tap="handleTodoItem(todo)"
|
||||||
|
>
|
||||||
<view class="todo-priority" :class="'priority-' + todo.priority">
|
<view class="todo-priority" :class="'priority-' + todo.priority">
|
||||||
<view class="priority-dot"></view>
|
<view class="priority-dot"></view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ const router = createRouter({
|
|||||||
|
|
||||||
// 全局前置守卫
|
// 全局前置守卫
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
// 检查页面是否需要登录
|
|
||||||
if (to.meta && to.meta.requireAuth && !isLoggedIn()) {
|
if (to.meta && to.meta.requireAuth && !isLoggedIn()) {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: "提示",
|
title: "提示",
|
||||||
|
|||||||
|
After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 243 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 37 KiB |
@@ -1,31 +0,0 @@
|
|||||||
<svg width="100%" height="100%" viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<!-- 背景渐变 -->
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
||||||
<stop offset="0%" stop-color="#94BFFF" />
|
|
||||||
<stop offset="100%" stop-color="#165DFF" />
|
|
||||||
</linearGradient>
|
|
||||||
|
|
||||||
<!-- 图形渐变 -->
|
|
||||||
<linearGradient id="shapeGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
||||||
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.3" />
|
|
||||||
<stop offset="100%" stop-color="#ffffff" stop-opacity="0.15" />
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
|
|
||||||
<!-- 透明背景,不完全填充 -->
|
|
||||||
<rect width="100%" height="50%" fill="url(#bgGradient)" />
|
|
||||||
|
|
||||||
<!-- 左侧方块装饰 -->
|
|
||||||
<rect x="100" y="150" width="120" height="120" rx="15" fill="url(#shapeGradient)" transform="rotate(-10, 160, 210)" opacity="0.7" />
|
|
||||||
<rect x="190" y="90" width="80" height="80" rx="10" fill="url(#shapeGradient)" transform="rotate(15, 230, 130)" opacity="0.6" />
|
|
||||||
<rect x="60" y="250" width="100" height="100" rx="10" fill="url(#shapeGradient)" transform="rotate(-5, 110, 300)" opacity="0.5" />
|
|
||||||
|
|
||||||
<!-- 右侧圆形装饰 -->
|
|
||||||
<circle cx="750" cy="150" r="60" fill="url(#shapeGradient)" opacity="0.7" />
|
|
||||||
<circle cx="820" cy="230" r="90" fill="url(#shapeGradient)" opacity="0.5" />
|
|
||||||
<circle cx="690" cy="250" r="40" fill="url(#shapeGradient)" opacity="0.6" />
|
|
||||||
|
|
||||||
<!-- 底部波浪 -->
|
|
||||||
<path d="M0,900 C200,800 350,950 550,870 C750,790 850,900 1000,850 L1000,1000 L0,1000 Z" fill="#ffffff" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 2.5 MiB After Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
@@ -1,6 +1,7 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import type { ConfigProviderThemeVars } from "wot-design-uni";
|
|
||||||
import { useStorage } from "@uni-helper/uni-use";
|
import { useStorage } from "@uni-helper/uni-use";
|
||||||
|
import type { ConfigProviderThemeVars } from "wot-design-uni";
|
||||||
|
import { nextTick, reactive, computed } from "vue";
|
||||||
|
|
||||||
// 主题色选项接口
|
// 主题色选项接口
|
||||||
export interface ThemeColorOption {
|
export interface ThemeColorOption {
|
||||||
@@ -46,12 +47,6 @@ export const useThemeStore = defineStore("appTheme", () => {
|
|||||||
// 计算属性
|
// 计算属性
|
||||||
const isDark = computed(() => theme.value === "dark");
|
const isDark = computed(() => theme.value === "dark");
|
||||||
|
|
||||||
// 切换主题, 指定主题模式,不传则自动切换
|
|
||||||
const toggleTheme = (mode?: ThemeMode) => {
|
|
||||||
theme.value = mode || (theme.value === "light" ? "dark" : "light");
|
|
||||||
setNavigationBarColor();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置导航栏颜色
|
// 设置导航栏颜色
|
||||||
const setNavigationBarColor = () => {
|
const setNavigationBarColor = () => {
|
||||||
console.log("设置导航栏颜色", theme.value);
|
console.log("设置导航栏颜色", theme.value);
|
||||||
@@ -61,6 +56,12 @@ export const useThemeStore = defineStore("appTheme", () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 切换主题, 指定主题模式,不传则自动切换
|
||||||
|
const toggleTheme = (mode?: ThemeMode) => {
|
||||||
|
theme.value = mode || (theme.value === "light" ? "dark" : "light");
|
||||||
|
setNavigationBarColor();
|
||||||
|
};
|
||||||
|
|
||||||
// 设置主题色
|
// 设置主题色
|
||||||
const setCurrentThemeColor = (color: ThemeColorOption) => {
|
const setCurrentThemeColor = (color: ThemeColorOption) => {
|
||||||
currentThemeColor.value = color;
|
currentThemeColor.value = color;
|
||||||
@@ -79,6 +80,10 @@ export const useThemeStore = defineStore("appTheme", () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 注意:全局主题管理已在App.vue中处理
|
||||||
|
// 包括:系统主题监听、导航栏颜色同步等
|
||||||
|
// 组件中一般不需要再调用initTheme(),除非有特殊需求
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// 状态
|
// 状态
|
||||||
theme,
|
theme,
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"light": {
|
||||||
|
"bgColor": "#F8F8F8",
|
||||||
|
"bgColorBottom": "#F8F8F8",
|
||||||
|
"bgColorTop": "#F8F8F8",
|
||||||
|
"bgTxtStyle": "dark",
|
||||||
|
"navBgColor": "#FFF",
|
||||||
|
"navTxtStyle": "black",
|
||||||
|
"tabBgColor": "#ffffff",
|
||||||
|
"tabBorderStyle": "black",
|
||||||
|
"tabColor": "#bfbfbf",
|
||||||
|
"tabSelectedColor": "#0165FF"
|
||||||
|
},
|
||||||
|
"dark": {
|
||||||
|
"bgColor": "#000",
|
||||||
|
"bgColorBottom": "#000",
|
||||||
|
"bgColorTop": "#000",
|
||||||
|
"bgTxtStyle": "light",
|
||||||
|
"navBgColor": "#000000",
|
||||||
|
"navTxtStyle": "white",
|
||||||
|
"tabBgColor": "#1a1a1a",
|
||||||
|
"tabBorderStyle": "white",
|
||||||
|
"tabColor": "#bfbfbf",
|
||||||
|
"tabSelectedColor": "#0165FF"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -326,7 +326,6 @@ declare module 'vue' {
|
|||||||
readonly useStomp: UnwrapRef<typeof import('../composables/useStomp')['useStomp']>
|
readonly useStomp: UnwrapRef<typeof import('../composables/useStomp')['useStomp']>
|
||||||
readonly useTabbar: UnwrapRef<typeof import('../composables/useTabbar')['useTabbar']>
|
readonly useTabbar: UnwrapRef<typeof import('../composables/useTabbar')['useTabbar']>
|
||||||
readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
|
readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
|
||||||
readonly useTheme: UnwrapRef<typeof import('../composables/useTheme')['useTheme']>
|
|
||||||
readonly useThemeStore: UnwrapRef<typeof import('../store/modules/theme.store')['useThemeStore']>
|
readonly useThemeStore: UnwrapRef<typeof import('../store/modules/theme.store')['useThemeStore']>
|
||||||
readonly useToast: UnwrapRef<typeof import('wot-design-uni')['useToast']>
|
readonly useToast: UnwrapRef<typeof import('wot-design-uni')['useToast']>
|
||||||
readonly useUserStore: UnwrapRef<typeof import('../store/modules/user.store')['useUserStore']>
|
readonly useUserStore: UnwrapRef<typeof import('../store/modules/user.store')['useUserStore']>
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by vite-plugin-uni-pages
|
||||||
|
|
||||||
|
interface NavigateToOptions {
|
||||||
|
url: "/pages/index/index" |
|
||||||
|
"/pages/login/index" |
|
||||||
|
"/pages/mine/index" |
|
||||||
|
"/pages/work/index" |
|
||||||
|
"/pages/mine/about/index" |
|
||||||
|
"/pages/mine/faq/index" |
|
||||||
|
"/pages/mine/feedback/index" |
|
||||||
|
"/pages/mine/profile/complete-profile" |
|
||||||
|
"/pages/mine/profile/index" |
|
||||||
|
"/pages/mine/settings/index" |
|
||||||
|
"/pages/mine/settings/account/index" |
|
||||||
|
"/pages/mine/settings/agreement/index" |
|
||||||
|
"/pages/mine/settings/network/index" |
|
||||||
|
"/pages/mine/settings/theme/index";
|
||||||
|
}
|
||||||
|
interface RedirectToOptions extends NavigateToOptions {}
|
||||||
|
|
||||||
|
interface SwitchTabOptions {
|
||||||
|
url: "/pages/index/index" | "/pages/mine/index"
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReLaunchOptions = NavigateToOptions | SwitchTabOptions;
|
||||||
|
|
||||||
|
declare interface Uni {
|
||||||
|
navigateTo(options: UniNamespace.NavigateToOptions & NavigateToOptions): void;
|
||||||
|
redirectTo(options: UniNamespace.RedirectToOptions & RedirectToOptions): void;
|
||||||
|
switchTab(options: UniNamespace.SwitchTabOptions & SwitchTabOptions): void;
|
||||||
|
reLaunch(options: UniNamespace.ReLaunchOptions & ReLaunchOptions): void;
|
||||||
|
}
|
||||||
@@ -12,10 +12,20 @@ export default {
|
|||||||
],
|
],
|
||||||
shortcuts: [
|
shortcuts: [
|
||||||
{
|
{
|
||||||
"flex-center": "flex justify-center items-center flex-wrap",
|
"flex-center": "flex justify-center items-center",
|
||||||
|
|
||||||
"flex-start": "flex justify-start items-center",
|
"flex-start": "flex justify-start items-center",
|
||||||
"flex-end": "flex justify-end items-center",
|
"flex-end": "flex justify-end items-center",
|
||||||
"flex-between": "flex justify-between items-center",
|
"flex-between": "flex justify-between items-center",
|
||||||
|
"flex-around": "flex justify-around items-center",
|
||||||
|
"flex-evenly": "flex justify-evenly items-center",
|
||||||
|
"flex-stretch": "flex justify-stretch items-center",
|
||||||
|
"flex-baseline": "flex justify-baseline items-center",
|
||||||
|
"flex-column": "flex flex-col",
|
||||||
|
"flex-row": "flex flex-row",
|
||||||
|
|
||||||
|
// 垂直布局并居中对齐
|
||||||
|
"flex-col-center": "flex flex-col items-center",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import uni from "@dcloudio/vite-plugin-uni";
|
|||||||
import AutoImport from "unplugin-auto-import/vite";
|
import AutoImport from "unplugin-auto-import/vite";
|
||||||
import UniLayouts from "@uni-helper/vite-plugin-uni-layouts";
|
import UniLayouts from "@uni-helper/vite-plugin-uni-layouts";
|
||||||
import UniPages from "@uni-helper/vite-plugin-uni-pages";
|
import UniPages from "@uni-helper/vite-plugin-uni-pages";
|
||||||
|
|
||||||
import Components from "@uni-helper/vite-plugin-uni-components";
|
import Components from "@uni-helper/vite-plugin-uni-components";
|
||||||
import { WotResolver } from "@uni-helper/vite-plugin-uni-components/resolvers";
|
import { WotResolver } from "@uni-helper/vite-plugin-uni-components/resolvers";
|
||||||
|
|
||||||
|
|||||||
@@ -587,7 +587,6 @@ declare module 'vue' {
|
|||||||
readonly useThrottleFn: UnwrapRef<typeof import('@vueuse/core')['useThrottleFn']>
|
readonly useThrottleFn: UnwrapRef<typeof import('@vueuse/core')['useThrottleFn']>
|
||||||
readonly useThrottledRefHistory: UnwrapRef<typeof import('@vueuse/core')['useThrottledRefHistory']>
|
readonly useThrottledRefHistory: UnwrapRef<typeof import('@vueuse/core')['useThrottledRefHistory']>
|
||||||
readonly useTimeAgo: UnwrapRef<typeof import('@vueuse/core')['useTimeAgo']>
|
readonly useTimeAgo: UnwrapRef<typeof import('@vueuse/core')['useTimeAgo']>
|
||||||
readonly useTimeAgoIntl: UnwrapRef<typeof import('@vueuse/core')['useTimeAgoIntl']>
|
|
||||||
readonly useTimeout: UnwrapRef<typeof import('@vueuse/core')['useTimeout']>
|
readonly useTimeout: UnwrapRef<typeof import('@vueuse/core')['useTimeout']>
|
||||||
readonly useTimeoutFn: UnwrapRef<typeof import('@vueuse/core')['useTimeoutFn']>
|
readonly useTimeoutFn: UnwrapRef<typeof import('@vueuse/core')['useTimeoutFn']>
|
||||||
readonly useTimeoutPoll: UnwrapRef<typeof import('@vueuse/core')['useTimeoutPoll']>
|
readonly useTimeoutPoll: UnwrapRef<typeof import('@vueuse/core')['useTimeoutPoll']>
|
||||||
|
|||||||