feat: add a new feature
This commit is contained in:
parent
1ffc4237ca
commit
b44e90451d
29
.vscode/launch.json
vendored
Normal file
29
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Filename: /Users/kurosago/Code/Self/uniViteTemplate/.vscode/launch.json
|
||||||
|
* Path: /Users/kurosago/Code/Self/uniViteTemplate
|
||||||
|
* Created Date: Thursday, June 20th 2024, 9:26:43 pm
|
||||||
|
* Author: KuroSago
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 self.
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Vue Debugger",
|
||||||
|
"url": "http://localhost:9527",
|
||||||
|
"webRoot": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "TS Debugger",
|
||||||
|
"runtimeExecutable": "tsx",
|
||||||
|
"skipFiles": ["<node_internals>/**", "${workspaceFolder}/node_modules/**"],
|
||||||
|
"program": "${file}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -4,7 +4,6 @@
|
|||||||
"source.fixAll.eslint": "explicit",
|
"source.fixAll.eslint": "explicit",
|
||||||
"source.organizeImports": "never"
|
"source.organizeImports": "never"
|
||||||
},
|
},
|
||||||
"eslint.experimental.useFlatConfig": true,
|
|
||||||
"editor.formatOnSave": false,
|
"editor.formatOnSave": false,
|
||||||
"prettier.enable": false,
|
"prettier.enable": false,
|
||||||
"unocss.root": ["./"],
|
"unocss.root": ["./"],
|
||||||
|
|||||||
@ -39,7 +39,7 @@ export default antfu({
|
|||||||
'./dist/*',
|
'./dist/*',
|
||||||
'./.vscode/*',
|
'./.vscode/*',
|
||||||
'./.idea/*',
|
'./.idea/*',
|
||||||
'**/androidPrivacy.json',
|
'./src/androidPrivacy.json',
|
||||||
'README.md',
|
'README.md',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
"message": "__请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款, 包括但不限于:为了更好的向你提供服务, 我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>__你可阅读<a href=\"\">《服务协议》</a>和<a href=\"\">《隐私政策》</a>了解详细信息。如果你同意, 请点击下面按钮开始接受我们的服务。",
|
"message": "__请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款, 包括但不限于:为了更好的向你提供服务, 我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>__你可阅读<a href=\"\">《服务协议》</a>和<a href=\"\">《隐私政策》</a>了解详细信息。如果你同意, 请点击下面按钮开始接受我们的服务。",
|
||||||
"buttonAccept": "同意并接受",
|
"buttonAccept": "同意并接受",
|
||||||
"buttonRefuse": "暂不同意",
|
"buttonRefuse": "暂不同意",
|
||||||
// HX 3.4.13之后版本新增, system 使用系统webview 打开隐私协议链接, 默认使用uni-app内置web组件
|
|
||||||
"hrefLoader": "default",
|
"hrefLoader": "default",
|
||||||
"second": {
|
"second": {
|
||||||
"title": "确认提示",
|
"title": "确认提示",
|
||||||
|
|||||||
23
src/enums/UI.ts
Normal file
23
src/enums/UI.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// S、M、L、XL、XXL、XXXL
|
||||||
|
// S: Small 小 ;M: Middle 中;L: Large 大;XL: extra large 加大;多个X则代表多重加大码,X越多,码数越大。
|
||||||
|
export enum Size {
|
||||||
|
S = 's',
|
||||||
|
M = 'm',
|
||||||
|
L = 'l',
|
||||||
|
XL = 'xl',
|
||||||
|
XXl = 'xxl',
|
||||||
|
XXXL = 'xxxl',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum UNOCSS_THEME_TYPE {
|
||||||
|
SCREENS = 'screens',
|
||||||
|
COLORS = 'colors',
|
||||||
|
SPACING = 'spacing',
|
||||||
|
BORDERRADIUS = 'borderRadius',
|
||||||
|
FONTFAMILY = 'fontFamily',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum THEME_MODEL {
|
||||||
|
LIGHT = 'light',
|
||||||
|
DARK = 'dark',
|
||||||
|
}
|
||||||
10
src/enums/apiEnum.ts
Normal file
10
src/enums/apiEnum.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export enum ApiVersionEnum {
|
||||||
|
V1 = 'v1',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ApiPathEnum {
|
||||||
|
ADMIN = 'admin',
|
||||||
|
USERS = 'users',
|
||||||
|
PORTAL = 'portal',
|
||||||
|
RIDERS = 'riders',
|
||||||
|
}
|
||||||
@ -1,5 +0,0 @@
|
|||||||
// token key
|
|
||||||
export const TOKEN_KEY = 'TOKEN__';
|
|
||||||
|
|
||||||
// user info key
|
|
||||||
export const USER_INFO_KEY = 'USER__INFO__';
|
|
||||||
112
src/enums/platformEnum.ts
Normal file
112
src/enums/platformEnum.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/**
|
||||||
|
* 平台
|
||||||
|
*/
|
||||||
|
export enum PLATFORMS {
|
||||||
|
DEFAULT = 'DEFAULT' /* 默认 */,
|
||||||
|
VUE3 = 'VUE3' /* HBuilderX 3.2.0+ */,
|
||||||
|
APP_PLUS = 'APP-PLUS' /* App */,
|
||||||
|
APP_PLUS_NVUE = 'APP-PLUS-NVUE' /* App nvue 页面 */,
|
||||||
|
APP_NVUE = 'APP-NVUE' /* App nvue 页面 */,
|
||||||
|
H5 = 'H5' /* H5 */,
|
||||||
|
MP_WEIXIN = 'MP-WEIXIN' /* 微信小程序 */,
|
||||||
|
MP_ALIPAY = 'MP-ALIPAY' /* 支付宝小程序 */,
|
||||||
|
MP_BAIDU = 'MP_BAIDU' /* 百度小程序 */,
|
||||||
|
MP_TOUTIAO = 'MP-TOUTIAO' /* 字节跳动小程序 */,
|
||||||
|
MP_LARK = 'MP-LARK' /* 飞书小程序 */,
|
||||||
|
MP_QQ = 'MP-QQ' /* QQ小程序 */,
|
||||||
|
MP_KUAISHOU = 'MP-KUAISHOU' /* 快手小程序 */,
|
||||||
|
MP_JD = 'MP-JD' /* 京东小程序 */,
|
||||||
|
MP_360 = 'MP-360' /* 360小程序 */,
|
||||||
|
MP = 'MP' /* 微信小程序/支付宝小程序/百度小程序/字节跳动小程序/飞书小程序/QQ小程序/360小程序 */,
|
||||||
|
QUICKAPP_WEBVIEW = 'QUICKAPP-WEBVIEW' /* 快应用通用(包含联盟、华为) */,
|
||||||
|
QUICKAPP_WEBVIEW_UNION = 'QUICKAPP-WEBVIEW-UNION' /* 快应用联盟 */,
|
||||||
|
QUICKAPP_WEBVIEW_HUAWEI = 'QUICKAPP-WEBVIEW-HUAWEI' /* 快应用华为 */,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台环境
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function PLATFORM_ENV() {
|
||||||
|
let platform = PLATFORMS.DEFAULT;
|
||||||
|
|
||||||
|
/* #ifdef VUE3 */
|
||||||
|
platform = PLATFORMS.VUE3;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
platform = PLATFORMS.APP_PLUS;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef APP-PLUS-NVUE */
|
||||||
|
platform = PLATFORMS.APP_PLUS_NVUE;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
platform = PLATFORMS.APP_NVUE;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef H5 */
|
||||||
|
platform = PLATFORMS.H5;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP */
|
||||||
|
platform = PLATFORMS.MP;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
platform = PLATFORMS.MP_WEIXIN;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP-ALIPAY */
|
||||||
|
platform = PLATFORMS.MP_ALIPAY;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP_BAIDU */
|
||||||
|
platform = PLATFORMS.MP_BAIDU;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP-TOUTIAO */
|
||||||
|
platform = PLATFORMS.MP_TOUTIAO;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP-LARK */
|
||||||
|
platform = PLATFORMS.MP_LARK;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP-QQ */
|
||||||
|
platform = PLATFORMS.MP_QQ;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP-KUAISHOU */
|
||||||
|
platform = PLATFORMS.MP_KUAISHOU;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP-JD */
|
||||||
|
platform = PLATFORMS.MP_JD;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP-360 */
|
||||||
|
platform = PLATFORMS.MP_360;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef QUICKAPP-WEBVIEW */
|
||||||
|
platform = PLATFORMS.QUICKAPP_WEBVIEW;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef QUICKAPP-WEBVIEW-UNION */
|
||||||
|
platform = PLATFORMS.QUICKAPP_WEBVIEW_UNION;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef QUICKAPP-WEBVIEW-HUAWEI */
|
||||||
|
platform = PLATFORMS.QUICKAPP_WEBVIEW_HUAWEI;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前平台
|
||||||
|
* 在微信小程序中 "process.env['UNI_PLATFORM']" 无效
|
||||||
|
*/
|
||||||
|
export const CURRENT_PLATFORM = PLATFORM_ENV();
|
||||||
31
src/enums/protocolsEnum.ts
Normal file
31
src/enums/protocolsEnum.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
[
|
||||||
|
{"key":"userService","value":"用户服务协议"},
|
||||||
|
{"key":"privacyPolicy","value":"个人信息保护政策"},
|
||||||
|
{"key":"userPrivacy","value":"用户隐私政策"}
|
||||||
|
{"key":"platformRules","value":"平台规则"},
|
||||||
|
{"key":"platformQualification","value":"平台资质"}
|
||||||
|
{"key":"personalInformation","value":"个人信息收集清单"},
|
||||||
|
{"key":"thirdPartyInformation","value":"第三方信息共享清单"}
|
||||||
|
]
|
||||||
|
*/
|
||||||
|
|
||||||
|
export enum ProtocolsEnum {
|
||||||
|
userService = '用户服务协议',
|
||||||
|
privacyPolicy = '个人信息保护政策',
|
||||||
|
userPrivacy = '用户隐私政策',
|
||||||
|
platformRules = '平台规则',
|
||||||
|
platformQualification = '平台资质',
|
||||||
|
personalInformation = '个人信息收集清单',
|
||||||
|
thirdPartyInformation = '第三方信息共享清单',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ProtocolsKey {
|
||||||
|
userService = 'user_service',
|
||||||
|
privacyPolicy = 'privacy_policy',
|
||||||
|
userPrivacy = 'user_privacy',
|
||||||
|
platformRules = 'platform_rules',
|
||||||
|
platformQualification = 'platform_qualification',
|
||||||
|
personalInformation = 'personal_information',
|
||||||
|
thirdPartyInformation = 'third_party_information',
|
||||||
|
}
|
||||||
13
src/enums/routerEnum.ts
Normal file
13
src/enums/routerEnum.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export enum NAVIGATE_TYPE {
|
||||||
|
NAVIGATE_TO = 'navigateTo',
|
||||||
|
REDIRECT_TO = 'redirectTo',
|
||||||
|
RE_LAUNCH = 'reLaunch',
|
||||||
|
SWITCH_TAB = 'switchTab',
|
||||||
|
NAVIGATE_BACK = 'navigateBack',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NAVIGATE_TYPE_LIST = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'];
|
||||||
|
|
||||||
|
export const HOME_PAGE = '/pages/index/index';
|
||||||
|
export const LOGIN_PAGE = '/pages/login/index';
|
||||||
|
export const NOT_FOUND_PAGE = '/pages/notFound/404';
|
||||||
14
src/layout/AppProvider.vue
Normal file
14
src/layout/AppProvider.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!-- //@ts-nocheck -->
|
||||||
|
<template>
|
||||||
|
<view
|
||||||
|
id="layout"
|
||||||
|
:class="{
|
||||||
|
dark: __themeModel === 'dark',
|
||||||
|
}"
|
||||||
|
class="bg-page flex flex-col"
|
||||||
|
:style="__theme"
|
||||||
|
style="min-height: 100vh; transition-duration: 1000ms; transition: all"
|
||||||
|
>
|
||||||
|
<!-- template -->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
18
src/mixins/theme.ts
Normal file
18
src/mixins/theme.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// 混入主题
|
||||||
|
import { useSystemInfoStore } from '@/stores/modules/system';
|
||||||
|
|
||||||
|
export const themeMixin = {
|
||||||
|
computed: {
|
||||||
|
__themeModel() {
|
||||||
|
const themeStore = storeToRefs(useSystemInfoStore());
|
||||||
|
return themeStore.themeModel.value;
|
||||||
|
},
|
||||||
|
__theme() {
|
||||||
|
const themeStore = storeToRefs(useSystemInfoStore());
|
||||||
|
const theme = themeStore.theme.value;
|
||||||
|
return Object.keys(theme)
|
||||||
|
.map(key => `${key}:${theme[key]};`)
|
||||||
|
.join('');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
46
src/model/theme.ts
Normal file
46
src/model/theme.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
export interface ThemeCfg {
|
||||||
|
'--colors-primary': string
|
||||||
|
'--colors-secondary': string
|
||||||
|
'--colors-accent': string
|
||||||
|
'--colors-success': string
|
||||||
|
'--colors-warning': string
|
||||||
|
'--colors-error': string
|
||||||
|
'--colors-disable': string
|
||||||
|
'--colors-danger': string
|
||||||
|
'--colors-mark': string
|
||||||
|
'--colors-title': string
|
||||||
|
'--colors-subtitle': string
|
||||||
|
'--colors-paragraph': string
|
||||||
|
'--colors-fontColorblack': string
|
||||||
|
'--colors-fontColorPrimary': string
|
||||||
|
'--colors-fontColorInverse': string
|
||||||
|
'--colors-fontColorGrey': string
|
||||||
|
'--colors-fontColorPlaceholder': string
|
||||||
|
'--colors-fontColorDisable': string
|
||||||
|
'--colors-fontColorBottomText': string
|
||||||
|
'--colors-container': string
|
||||||
|
'--colors-page': string
|
||||||
|
'--colors-containerInverse': string
|
||||||
|
'--colors-containerHover': string
|
||||||
|
'--colors-containerMask': string
|
||||||
|
'--colors-iconButton': string
|
||||||
|
'--colors-borderColor': string
|
||||||
|
'--fontSize-sm': string
|
||||||
|
'--fontSize-base': string
|
||||||
|
'--fontSize-lg': string
|
||||||
|
'--fontSize-title': string
|
||||||
|
'--fontSize-subtitle': string
|
||||||
|
'--fontSize-paragraph': string
|
||||||
|
'--borderRadius-sm': string
|
||||||
|
'--borderRadius-base': string
|
||||||
|
'--borderRadius-lg': string
|
||||||
|
'--borderRadius-circle': string
|
||||||
|
'--spacing-rowSm': string
|
||||||
|
'--spacing-rowBase': string
|
||||||
|
'--spacing-rowLg': string
|
||||||
|
'--spacing-colSm': string
|
||||||
|
'--spacing-colBase': string
|
||||||
|
'--spacing-colLg': string
|
||||||
|
'--opacity-disabled': string
|
||||||
|
[propName: string]: string
|
||||||
|
}
|
||||||
47
src/stores/modules/system.ts
Normal file
47
src/stores/modules/system.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { THEME_MODEL } from '@/enums/UI';
|
||||||
|
import type { ThemeCfg } from '@/model/theme';
|
||||||
|
import { theme as _theme } from '@/theme/theme';
|
||||||
|
|
||||||
|
interface SystemInfo {
|
||||||
|
theme: ThemeCfg
|
||||||
|
themeModel: THEME_MODEL
|
||||||
|
systemInfo: UniApp.GetSystemInfoResult
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useSystemInfoStore = defineStore({
|
||||||
|
id: 'system',
|
||||||
|
state: (): SystemInfo => ({
|
||||||
|
// 主题
|
||||||
|
// theme: <ThemeCfg>Object.assign(_theme.light),
|
||||||
|
theme: <ThemeCfg>{ ..._theme.light },
|
||||||
|
|
||||||
|
// 当前主题模式
|
||||||
|
themeModel: THEME_MODEL.LIGHT as THEME_MODEL,
|
||||||
|
|
||||||
|
// 系统信息
|
||||||
|
systemInfo: {
|
||||||
|
statusBarHeight: 0,
|
||||||
|
} as UniApp.GetSystemInfoResult,
|
||||||
|
}),
|
||||||
|
getters: {},
|
||||||
|
actions: {
|
||||||
|
// 获取系统信息
|
||||||
|
async getSystemInfo() {
|
||||||
|
const res = (await uni.getSystemInfoSync()) as UniApp.GetSystemInfoResult;
|
||||||
|
this.systemInfo = res;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 切换主题
|
||||||
|
changeThemeModel({ model = THEME_MODEL.DARK as THEME_MODEL }) {
|
||||||
|
this.themeModel = model;
|
||||||
|
this.theme = { ..._theme[model] };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
persist: {
|
||||||
|
storage: {
|
||||||
|
setItem: uni.setStorageSync,
|
||||||
|
getItem: uni.getStorageSync,
|
||||||
|
},
|
||||||
|
paths: ['theme', 'themeModel', 'systemInfo'],
|
||||||
|
},
|
||||||
|
});
|
||||||
205
src/theme/theme.ts
Normal file
205
src/theme/theme.ts
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/**
|
||||||
|
* 主题根文件
|
||||||
|
* @note 命名规则: ( key )
|
||||||
|
* -- 变量标志符
|
||||||
|
* colors 变量类型
|
||||||
|
* primary 变量标识符
|
||||||
|
* 在本文件的各种定义主题中 key 名应当保持完全统一
|
||||||
|
* 按照此格式书写的 key 名完全路径禁止有重叠,否则会引发 bug
|
||||||
|
*/
|
||||||
|
// container {
|
||||||
|
// // ThemeColor
|
||||||
|
// '--source': '#00bdd4',
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* secondary :通常用于表示次要的、补充的元素,例如按钮的边框颜色、图标的颜色等。
|
||||||
|
* accent :通常用于表示强调的、突出的元素,例如链接的颜色、高亮的颜色等。
|
||||||
|
* tertiary :通常用于表示第三级的、较为次要的元素,例如表格的边框颜色、分割线的颜色等。
|
||||||
|
* neutral :通常用于表示中性的、不带有情感色彩的元素,例如背景色、文本颜色等。
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const theme = {
|
||||||
|
light: {
|
||||||
|
/* light */
|
||||||
|
|
||||||
|
/* 颜色 */
|
||||||
|
'--colors-primary': '#FFE274', // 主色
|
||||||
|
'--colors-secondary': '#5A7767', // 次要
|
||||||
|
'--colors-accent': '#FB9300', // 强调
|
||||||
|
|
||||||
|
'--colors-success': '#4cd964',
|
||||||
|
'--colors-warning': '#f0ad4e',
|
||||||
|
'--colors-error': '#dd524d',
|
||||||
|
'--colors-disable': '#ddd',
|
||||||
|
'--colors-danger': '#FF6843',
|
||||||
|
'--colors-mark': 'rgba(0,0,0,0.4)',
|
||||||
|
|
||||||
|
/* 文章场景相关 */
|
||||||
|
'--colors-title': '#2c405a', // 文章标题颜色
|
||||||
|
'--colors-subtitle': '#555555', // 二级标题颜色
|
||||||
|
'--colors-paragraph': '#3f536e', // 文章段落颜色
|
||||||
|
|
||||||
|
/* 文字基本颜色 */
|
||||||
|
'--colors-fontColorblack': '#333', // 基本色 - 不切换
|
||||||
|
'--colors-fontColorPrimary': '#333', // 基本色
|
||||||
|
'--colors-fontColorInverse': '#fff', // 反色
|
||||||
|
'--colors-fontColorGrey': '#999', // 辅助灰色,如加载更多的提示信息
|
||||||
|
'--colors-fontColorPlaceholder': '#808080',
|
||||||
|
'--colors-fontColorDisable': '#c0c0c0',
|
||||||
|
'--colors-fontColorBottomText': '#6F6E80', // 底部tabbar文字颜色
|
||||||
|
|
||||||
|
/* 背景颜色 */
|
||||||
|
'--colors-container': '#ffffff',
|
||||||
|
'--colors-page': '#F6F4F0',
|
||||||
|
'--colors-containerInverse': '#000000', // 背景反色
|
||||||
|
'--colors-containerHover': 'rgba(255, 226, 116, .5)', // 点击状态颜色
|
||||||
|
'--colors-secondaryHover': 'rgba(90,119,103, .5)', // 点击状态颜色
|
||||||
|
'--colors-containerMask': 'rgba(0, 0, 0, 0.4)', // 遮罩颜色
|
||||||
|
// '--colors-iconButton': '#F5F5EC',
|
||||||
|
'--colors-iconButton': '#E4E4E4', // ICON 按钮背景色
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
'--colors-borderColor': '#c8c7cc',
|
||||||
|
|
||||||
|
/* 文字尺寸 */
|
||||||
|
'--fontSize-sm': '24rpx',
|
||||||
|
'--fontSize-base': '28rpx',
|
||||||
|
'--fontSize-lg': '32rpx',
|
||||||
|
/* 文章场景相关 */
|
||||||
|
'--fontSize-title': '40rpx',
|
||||||
|
'--fontSize-subtitle': '36rpx',
|
||||||
|
'--fontSize-paragraph': '32rpx',
|
||||||
|
|
||||||
|
/* Border Radius */
|
||||||
|
'--borderRadius-sm': '4rpx',
|
||||||
|
'--borderRadius-base': '6rpx',
|
||||||
|
'--borderRadius-lg': '12rpx',
|
||||||
|
'--borderRadius-circle': '50%',
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
'--spacing-rowSm': '12px',
|
||||||
|
'--spacing-rowBase': '24rpx',
|
||||||
|
'--spacing-rowLg': '32rpx',
|
||||||
|
|
||||||
|
/* 垂直间距 */
|
||||||
|
'--spacing-colSm': '8rpx',
|
||||||
|
'--spacing-colBase': '16rpx',
|
||||||
|
'--spacing-colLg': '24rpx',
|
||||||
|
|
||||||
|
/* 透明度 */
|
||||||
|
'--opacity-disabled': '0.3', // 组件禁用态的透明度
|
||||||
|
},
|
||||||
|
dark: {
|
||||||
|
/* dark */
|
||||||
|
|
||||||
|
/* 颜色 */
|
||||||
|
'--colors-primary': '#FFE274',
|
||||||
|
'--colors-secondary': '#5A7767', // 次要
|
||||||
|
'--colors-accent': '#FB9300', // 强调
|
||||||
|
|
||||||
|
'--colors-success': '#4cd964',
|
||||||
|
'--colors-warning': '#f0ad4e',
|
||||||
|
'--colors-error': '#dd524d',
|
||||||
|
'--colors-disable': '#ddd',
|
||||||
|
'--colors-danger': '#FF6843',
|
||||||
|
'--colors-mark': 'rgba(26, 26, 26,0.4)',
|
||||||
|
|
||||||
|
/* 文章场景相关 */
|
||||||
|
'--colors-title': '#2c405a', // 文章标题颜色
|
||||||
|
'--colors-subtitle': '#555555', // 二级标题颜色
|
||||||
|
'--colors-paragraph': '#3f536e', // 文章段落颜色
|
||||||
|
|
||||||
|
/* 文字基本颜色 */
|
||||||
|
'--colors-fontColorblack': '#333', // 基本色 - 不切换
|
||||||
|
'--colors-fontColorPrimary': '#999', // 基本色
|
||||||
|
'--colors-fontColorInverse': '#333', // 反色
|
||||||
|
'--colors-fontColorGrey': '#666', // 辅助灰色,如加载更多的提示信息
|
||||||
|
'--colors-fontColorPlaceholder': '#808080',
|
||||||
|
'--colors-fontColorDisable': '#c0c0c0',
|
||||||
|
'--colors-fontColorBottomText': '#6F6E80', // 底部tabbar文字颜色
|
||||||
|
|
||||||
|
/* 背景颜色 */
|
||||||
|
'--colors-container': '#000000',
|
||||||
|
'--colors-page': '#191919',
|
||||||
|
'--colors-containerInverse': '#ffffff', // 背景反色
|
||||||
|
'--colors-containerHover': 'rgba(255, 226, 116, .5)', // 点击状态颜色
|
||||||
|
'--colors-secondaryHover': 'rgba(90,119,103, .5)', // 点击状态颜色
|
||||||
|
'--colors-containerMask': 'rgba(0, 0, 0, 0.4)', // 遮罩颜色
|
||||||
|
'--colors-iconButton': '#808080', // ICON 按钮背景色
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
'--colors-borderColor': '#c8c7cc',
|
||||||
|
|
||||||
|
/* 文字尺寸 */
|
||||||
|
'--fontSize-sm': '24rpx',
|
||||||
|
'--fontSize-base': '28rpx',
|
||||||
|
'--fontSize-lg': '32rpx',
|
||||||
|
|
||||||
|
/* 文章场景相关 */
|
||||||
|
'--fontSize-title': '40rpx',
|
||||||
|
'--fontSize-subtitle': '36rpx',
|
||||||
|
'--fontSize-paragraph': '32rpx',
|
||||||
|
|
||||||
|
/* Border Radius */
|
||||||
|
'--borderRadius-sm': '4rpx',
|
||||||
|
'--borderRadius-base': '6rpx',
|
||||||
|
'--borderRadius-lg': '12rpx',
|
||||||
|
'--borderRadius-circle': '50%',
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
'--spacing-rowSm': '12px',
|
||||||
|
'--spacing-rowBase': '24rpx',
|
||||||
|
'--spacing-rowLg': '32rpx',
|
||||||
|
|
||||||
|
/* 垂直间距 */
|
||||||
|
'--spacing-colSm': '8rpx',
|
||||||
|
'--spacing-colBase': '16rpx',
|
||||||
|
'--spacing-colLg': '24rpx',
|
||||||
|
|
||||||
|
/* 透明度 */
|
||||||
|
'--opacity-disabled': '0.3', // 组件禁用态的透明度
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ExtendStyle {
|
||||||
|
SPACING = 'spacing',
|
||||||
|
// BORDERRADIUS = 'borderRadius' ,
|
||||||
|
// FONTSIZE = 'fontSize',
|
||||||
|
OPACITY = 'opacity',
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建 theme
|
||||||
|
export function buildTheme() {
|
||||||
|
const _theme: any = {
|
||||||
|
extend: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const flattenedObj: Map<string, any> = new Map([]);
|
||||||
|
for (const [_, themeItem] of Object.entries(theme)) {
|
||||||
|
for (const [key, _] of Object.entries(themeItem)) {
|
||||||
|
flattenedObj.set(key, _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const extendList = [ExtendStyle.OPACITY];
|
||||||
|
|
||||||
|
flattenedObj.forEach((_v: string, k: string) => {
|
||||||
|
// const [_, key, value] = k.match(/^--(.+?)-(.+)$/) || [0, 'key', 'value'];
|
||||||
|
const [_, key, value] = k.match(/^--([^-]+)-(.+)$/) || [0, 'key', 'value'];
|
||||||
|
|
||||||
|
if (extendList.includes(key as ExtendStyle)) {
|
||||||
|
if (!_theme.extend[key]) {
|
||||||
|
_theme.extend[key] = {};
|
||||||
|
}
|
||||||
|
_theme.extend[key][value] = `var(${k})`;
|
||||||
|
} else {
|
||||||
|
if (!_theme[key]) {
|
||||||
|
_theme[key] = {};
|
||||||
|
}
|
||||||
|
_theme[key][value] = `var(${k})`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// console.log('_theme ===>>>', _theme);
|
||||||
|
return _theme;
|
||||||
|
}
|
||||||
16
src/types/import-components.d.ts
vendored
Normal file
16
src/types/import-components.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
export {}
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
AppProvider: typeof import('./../components/AppProvider/index.vue')['default']
|
||||||
|
BasicButton: typeof import('./../components/BasicButton/index.vue')['default']
|
||||||
|
BasicInput: typeof import('./../components/BasicInput/index.vue')['default']
|
||||||
|
Iconify: typeof import('./../components/Iconify/index.vue')['default']
|
||||||
|
Test: typeof import('./../components/Test/index.vue')['default']
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import { getCache, setCache } from '@/utils/cache';
|
|
||||||
import { TOKEN_KEY } from '@/enums/cacheEnum';
|
|
||||||
|
|
||||||
const authenticationScheme = 'Bearer';
|
|
||||||
|
|
||||||
export function getToken() {
|
|
||||||
return getCache<string>(TOKEN_KEY) || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAuthorization() {
|
|
||||||
const token = getToken();
|
|
||||||
return token ? `${authenticationScheme} ${token}` : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setToken(token: string) {
|
|
||||||
return setCache(TOKEN_KEY, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function removeToken() {
|
|
||||||
return setCache(TOKEN_KEY, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否登录
|
|
||||||
export function isLogin() {
|
|
||||||
return !!getToken();
|
|
||||||
}
|
|
||||||
29
src/utils/cache/index.ts
vendored
29
src/utils/cache/index.ts
vendored
@ -1,29 +0,0 @@
|
|||||||
import type { CreateStorageParams } from './storageCache';
|
|
||||||
import { createStorage } from './storageCache';
|
|
||||||
import { DEFAULT_CACHE_TIME, DEFAULT_PREFIX_KEY, cacheCipher, enableStorageEncryption } from '@/settings/encryptionSetting';
|
|
||||||
|
|
||||||
const options: Partial<CreateStorageParams> = {
|
|
||||||
prefixKey: DEFAULT_PREFIX_KEY,
|
|
||||||
key: cacheCipher.key,
|
|
||||||
iv: cacheCipher.iv,
|
|
||||||
hasEncrypt: enableStorageEncryption,
|
|
||||||
timeout: DEFAULT_CACHE_TIME,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const storage = createStorage(options);
|
|
||||||
|
|
||||||
export function setCache(key: string, value: any, expire?: number | null): void {
|
|
||||||
storage.set(key, value, expire);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getCache<T = any>(key: string): T {
|
|
||||||
return storage.get<T>(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function removeCache(key: string): void {
|
|
||||||
return storage.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearCache(): void {
|
|
||||||
return storage.clear();
|
|
||||||
}
|
|
||||||
110
src/utils/cache/storageCache.ts
vendored
110
src/utils/cache/storageCache.ts
vendored
@ -1,110 +0,0 @@
|
|||||||
import { cacheCipher } from '@/settings/encryptionSetting';
|
|
||||||
import type { EncryptionParams } from '@/utils/cipher';
|
|
||||||
import { AesEncryption } from '@/utils/cipher';
|
|
||||||
import { isNullOrUnDef } from '@/utils/is';
|
|
||||||
|
|
||||||
export interface CreateStorageParams extends EncryptionParams {
|
|
||||||
prefixKey: string
|
|
||||||
hasEncrypt: boolean
|
|
||||||
timeout?: number | null
|
|
||||||
}
|
|
||||||
export function createStorage({
|
|
||||||
prefixKey = '',
|
|
||||||
key = cacheCipher.key,
|
|
||||||
iv = cacheCipher.iv,
|
|
||||||
timeout = null,
|
|
||||||
hasEncrypt = true,
|
|
||||||
}: Partial<CreateStorageParams> = {}) {
|
|
||||||
if (hasEncrypt && [key.length, iv.length].some(item => item !== 16)) {
|
|
||||||
throw new Error('When hasEncrypt is true, the key or iv must be 16 bits!');
|
|
||||||
}
|
|
||||||
|
|
||||||
const encryption = new AesEncryption({ key, iv });
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cache class
|
|
||||||
* Construction parameters can be passed into sessionStorage, localStorage,
|
|
||||||
* @class Cache
|
|
||||||
* @example
|
|
||||||
*/
|
|
||||||
class Storage {
|
|
||||||
private prefixKey?: string;
|
|
||||||
|
|
||||||
private encryption: AesEncryption;
|
|
||||||
|
|
||||||
private hasEncrypt: boolean;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.prefixKey = prefixKey;
|
|
||||||
this.encryption = encryption;
|
|
||||||
this.hasEncrypt = hasEncrypt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getKey(key: string) {
|
|
||||||
return `${this.prefixKey}${key}`.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set cache
|
|
||||||
* @param {string} key
|
|
||||||
* @param {*} value
|
|
||||||
* @param {*} expire Expiration time in seconds
|
|
||||||
* @memberof Cache
|
|
||||||
*/
|
|
||||||
set(key: string, value: any, expire: number | null = timeout) {
|
|
||||||
try {
|
|
||||||
const stringData = JSON.stringify({
|
|
||||||
value,
|
|
||||||
time: Date.now(),
|
|
||||||
expire: !isNullOrUnDef(expire) ? new Date().getTime() + expire * 1000 : null,
|
|
||||||
});
|
|
||||||
const stringifyValue = this.hasEncrypt ? this.encryption.encryptByAES(stringData) : stringData;
|
|
||||||
uni.setStorageSync(this.getKey(key), stringifyValue);
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(`setStorageSync error: ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read cache
|
|
||||||
* @param {string} key
|
|
||||||
* @param {*} def
|
|
||||||
* @memberof Cache
|
|
||||||
*/
|
|
||||||
get<T = any>(key: string, def: any = null): T {
|
|
||||||
const val = uni.getStorageSync(this.getKey(key));
|
|
||||||
if (!val)
|
|
||||||
return def;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const decVal = this.hasEncrypt ? this.encryption.decryptByAES(val) : val;
|
|
||||||
const data = JSON.parse(decVal);
|
|
||||||
const { value, expire } = data;
|
|
||||||
if (isNullOrUnDef(expire) || expire < new Date().getTime()) {
|
|
||||||
this.remove(key);
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
} catch (e) {
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete cache based on key
|
|
||||||
* @param {string} key
|
|
||||||
* @memberof Cache
|
|
||||||
*/
|
|
||||||
remove(key: string) {
|
|
||||||
uni.removeStorageSync(this.getKey(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all caches of this instance
|
|
||||||
*/
|
|
||||||
clear(): void {
|
|
||||||
uni.clearStorageSync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Storage();
|
|
||||||
}
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
/**
|
|
||||||
* unocss defineConfig
|
|
||||||
* @link unocss: https://github.com/unocss/unocss
|
|
||||||
* @type {import('unocss').UserConfig}
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { defineConfig, presetIcons } from 'unocss';
|
|
||||||
import presetWeapp from 'unocss-preset-weapp';
|
|
||||||
import { transformerAttributify, transformerClass } from 'unocss-preset-weapp/transformer';
|
|
||||||
|
|
||||||
const transformRules = {
|
|
||||||
'.': '-d2e-',
|
|
||||||
'/': '-s2f-',
|
|
||||||
':': '-c3a-',
|
|
||||||
'%': '-p25-',
|
|
||||||
'!': '-e21-',
|
|
||||||
'#': '-w23-',
|
|
||||||
'(': '-b28-',
|
|
||||||
')': '-b29-',
|
|
||||||
'[': '-f4b-',
|
|
||||||
']': '-f5d-',
|
|
||||||
'$': '-r24-',
|
|
||||||
',': '-r2c-',
|
|
||||||
};
|
|
||||||
|
|
||||||
const prefix = '';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
presets: [
|
|
||||||
// https://github.com/MellowCo/unocss-preset-weapp
|
|
||||||
presetWeapp({
|
|
||||||
nonValuedAttribute: true,
|
|
||||||
prefix,
|
|
||||||
whRpx: true,
|
|
||||||
transform: true,
|
|
||||||
platform: 'uniapp',
|
|
||||||
transformRules,
|
|
||||||
}),
|
|
||||||
presetIcons({
|
|
||||||
scale: 1.2,
|
|
||||||
warn: true,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
shortcuts: [
|
|
||||||
{
|
|
||||||
center: 'flex justify-center items-center',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
theme: {
|
|
||||||
colors: {
|
|
||||||
primary: '#007AFF',
|
|
||||||
secondary: '#4CD964',
|
|
||||||
danger: '#FF3B30',
|
|
||||||
warning: '#FF9500',
|
|
||||||
info: '#5AC8FA',
|
|
||||||
light: '#F0F0F0',
|
|
||||||
dark: '#1A1A1A',
|
|
||||||
},
|
|
||||||
fontSize: {
|
|
||||||
mini: ['20rpx', '26rpx'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
transformers: [
|
|
||||||
transformerAttributify({
|
|
||||||
classPrefix: prefix,
|
|
||||||
transformRules,
|
|
||||||
nonValuedAttribute: true,
|
|
||||||
}),
|
|
||||||
transformerClass({
|
|
||||||
transformRules,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
97
unocss.config.ts
Normal file
97
unocss.config.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* unocss defineConfig
|
||||||
|
* @link unocss: https://github.com/unocss/unocss
|
||||||
|
* @link unocss-preset-weapp: https://github.com/MellowCo/unocss-preset-weapp
|
||||||
|
*/
|
||||||
|
import presetWeapp from 'unocss-preset-weapp';
|
||||||
|
import { extractorAttributify, transformerClass } from 'unocss-preset-weapp/transformer';
|
||||||
|
import { presetIcons } from 'unocss';
|
||||||
|
|
||||||
|
import transformerDirectives from '@unocss/transformer-directives';
|
||||||
|
|
||||||
|
const { presetWeappAttributify, transformerAttributify } = extractorAttributify();
|
||||||
|
|
||||||
|
export default {
|
||||||
|
presets: [
|
||||||
|
// https://github.com/MellowCo/unocss-preset-weapp
|
||||||
|
presetWeapp(),
|
||||||
|
// attributify autocomplete
|
||||||
|
presetWeappAttributify(),
|
||||||
|
presetIcons(),
|
||||||
|
],
|
||||||
|
shortcuts: [
|
||||||
|
{
|
||||||
|
'border-base': 'border border-gray-500_10',
|
||||||
|
'center': 'flex justify-center items-center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
transformers: [
|
||||||
|
transformerDirectives({
|
||||||
|
enforce: 'pre',
|
||||||
|
}),
|
||||||
|
|
||||||
|
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerAttributify
|
||||||
|
transformerAttributify(),
|
||||||
|
|
||||||
|
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerClass
|
||||||
|
transformerClass(),
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
opacity: {
|
||||||
|
disabled: 'var(--opacity-disabled)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
primary: 'var(--colors-primary)',
|
||||||
|
secondary: 'var(--colors-secondary)',
|
||||||
|
accent: 'var(--colors-accent)',
|
||||||
|
success: 'var(--colors-success)',
|
||||||
|
warning: 'var(--colors-warning)',
|
||||||
|
error: 'var(--colors-error)',
|
||||||
|
disable: 'var(--colors-disable)',
|
||||||
|
danger: 'var(--colors-danger)',
|
||||||
|
mark: 'var(--colors-mark)',
|
||||||
|
title: 'var(--colors-title)',
|
||||||
|
subtitle: 'var(--colors-subtitle)',
|
||||||
|
paragraph: 'var(--colors-paragraph)',
|
||||||
|
fontColorblack: 'var(--colors-fontColorblack)',
|
||||||
|
fontColorPrimary: 'var(--colors-fontColorPrimary)',
|
||||||
|
fontColorInverse: 'var(--colors-fontColorInverse)',
|
||||||
|
fontColorGrey: 'var(--colors-fontColorGrey)',
|
||||||
|
fontColorPlaceholder: 'var(--colors-fontColorPlaceholder)',
|
||||||
|
fontColorDisable: 'var(--colors-fontColorDisable)',
|
||||||
|
fontColorBottomText: 'var(--colors-fontColorBottomText)',
|
||||||
|
container: 'var(--colors-container)',
|
||||||
|
page: 'var(--colors-page)',
|
||||||
|
containerInverse: 'var(--colors-containerInverse)',
|
||||||
|
containerHover: 'var(--colors-containerHover)',
|
||||||
|
secondaryHover: 'var(--colors-secondaryHover)',
|
||||||
|
containerMask: 'var(--colors-containerMask)',
|
||||||
|
iconButton: 'var(--colors-iconButton)',
|
||||||
|
borderColor: 'var(--colors-borderColor)',
|
||||||
|
},
|
||||||
|
fontSize: {
|
||||||
|
sm: 'var(--fontSize-sm)',
|
||||||
|
base: 'var(--fontSize-base)',
|
||||||
|
lg: 'var(--fontSize-lg)',
|
||||||
|
title: 'var(--fontSize-title)',
|
||||||
|
subtitle: 'var(--fontSize-subtitle)',
|
||||||
|
paragraph: 'var(--fontSize-paragraph)',
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
sm: 'var(--borderRadius-sm)',
|
||||||
|
base: 'var(--borderRadius-base)',
|
||||||
|
lg: 'var(--borderRadius-lg)',
|
||||||
|
circle: 'var(--borderRadius-circle)',
|
||||||
|
},
|
||||||
|
spacing: {
|
||||||
|
rowSm: 'var(--spacing-rowSm)',
|
||||||
|
rowBase: 'var(--spacing-rowBase)',
|
||||||
|
rowLg: 'var(--spacing-rowLg)',
|
||||||
|
colSm: 'var(--spacing-colSm)',
|
||||||
|
colBase: 'var(--spacing-colBase)',
|
||||||
|
colLg: 'var(--spacing-colLg)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
57
vite/plugins/appProvider.ts
Normal file
57
vite/plugins/appProvider.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import * as fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
import * as process from 'node:process';
|
||||||
|
import normallize from 'normalize-path';
|
||||||
|
import type { PluginOption } from 'vite';
|
||||||
|
|
||||||
|
// export const defaultPagesRE = /src[/\\]pages(.*)[/\\](.*)[/\\](.*)\.vue$/;
|
||||||
|
export const defaultPagesRE = /src[/\\]pages([^/\\]*)[/\\]([^/\\]*)[/\\](.*)\.vue$/;
|
||||||
|
|
||||||
|
export interface Options {
|
||||||
|
pagesRE: RegExp
|
||||||
|
name: string
|
||||||
|
configPath: string
|
||||||
|
pluginName: string
|
||||||
|
DEBUG: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function (options: Partial<Options> = {}) {
|
||||||
|
const {
|
||||||
|
pagesRE = defaultPagesRE,
|
||||||
|
name = './src/layout/AppProvider.vue',
|
||||||
|
pluginName = 'AppProvider',
|
||||||
|
// DEBUG = process.env.DEBUG,
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
const template = fs.readFileSync(normalizePagePathFromBase(name), 'utf-8');
|
||||||
|
|
||||||
|
return <PluginOption>{
|
||||||
|
name: pluginName,
|
||||||
|
enforce: 'pre',
|
||||||
|
transform(code, id) {
|
||||||
|
id = normalizePagePathFromBase(id);
|
||||||
|
const regResult = pagesRE.exec(id);
|
||||||
|
if (regResult && (regResult[2] === regResult[3] || regResult[3] === 'index')) {
|
||||||
|
const oldTempleate = /<template>([\s\S]*)<\/template>/.exec(code);
|
||||||
|
const tmp_string = oldTempleate != null ? oldTempleate[1] : '';
|
||||||
|
const newTemplate = template.replace('<!-- template -->', tmp_string as string);
|
||||||
|
code = code.replace(/<template>([\s\S]*)<\/template>/, newTemplate);
|
||||||
|
}
|
||||||
|
return { code, map: null };
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function normalizePagePathFromBase(file: string) {
|
||||||
|
return normallize(path.relative(process.cwd(), file));
|
||||||
|
}
|
||||||
|
|
||||||
|
// function debug(...args) {
|
||||||
|
// DEBUG &&
|
||||||
|
// console.log(
|
||||||
|
// c.dim(new Date().toLocaleTimeString()),
|
||||||
|
// c.bold(c.red(`[debug:${pluginName}]`)),
|
||||||
|
// ...args,
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
}
|
||||||
82
vite/plugins/build.unocss.config.ts
Normal file
82
vite/plugins/build.unocss.config.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import * as fs from 'node:fs';
|
||||||
|
import { buildTheme } from '../../src/theme/theme';
|
||||||
|
|
||||||
|
export default function buildThemeConfig() {
|
||||||
|
const _data = buildTheme();
|
||||||
|
// 写入时会先清空文件
|
||||||
|
fs.writeFile('./unocss.config.ts', `${createFileByTemplate(_data)}`, (err: any) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else {
|
||||||
|
console.log('构建 css 提示文件完成');
|
||||||
|
console.table(flatten(_data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 写完文件后使用编辑器格式化一下
|
||||||
|
}
|
||||||
|
|
||||||
|
function flatten(obj: any, parentKey = ''): any {
|
||||||
|
let result: any = {};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(obj)) {
|
||||||
|
const newKey = parentKey ? `${parentKey}.${key}` : key;
|
||||||
|
|
||||||
|
if (typeof value === 'object' && value !== null) {
|
||||||
|
const flattened = flatten(value, newKey);
|
||||||
|
result = { ...result, ...flattened };
|
||||||
|
} else {
|
||||||
|
result[newKey] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过模版生成文件
|
||||||
|
function createFileByTemplate(theme: any) {
|
||||||
|
const fileString = `
|
||||||
|
/**
|
||||||
|
* unocss defineConfig
|
||||||
|
* @link unocss: https://github.com/unocss/unocss
|
||||||
|
* @link unocss-preset-weapp: https://github.com/MellowCo/unocss-preset-weapp
|
||||||
|
* */
|
||||||
|
import presetWeapp from 'unocss-preset-weapp'
|
||||||
|
import { extractorAttributify, transformerClass } from 'unocss-preset-weapp/transformer'
|
||||||
|
import { presetIcons } from 'unocss'
|
||||||
|
|
||||||
|
import transformerDirectives from '@unocss/transformer-directives'
|
||||||
|
|
||||||
|
const { presetWeappAttributify, transformerAttributify } = extractorAttributify()
|
||||||
|
|
||||||
|
export default {
|
||||||
|
presets: [
|
||||||
|
// https://github.com/MellowCo/unocss-preset-weapp
|
||||||
|
presetWeapp(),
|
||||||
|
// attributify autocomplete
|
||||||
|
presetWeappAttributify(),
|
||||||
|
presetIcons(),
|
||||||
|
],
|
||||||
|
shortcuts: [
|
||||||
|
{
|
||||||
|
'border-base': 'border border-gray-500_10',
|
||||||
|
'center': 'flex justify-center items-center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
transformers: [
|
||||||
|
transformerDirectives({
|
||||||
|
enforce: 'pre',
|
||||||
|
}),
|
||||||
|
|
||||||
|
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerAttributify
|
||||||
|
transformerAttributify(),
|
||||||
|
|
||||||
|
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerClass
|
||||||
|
transformerClass(),
|
||||||
|
],
|
||||||
|
theme: ${JSON.stringify(theme, null, 2)}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
return fileString;
|
||||||
|
}
|
||||||
16
vite/plugins/components.ts
Normal file
16
vite/plugins/components.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import type { Options } from 'unplugin-vue-components/types';
|
||||||
|
import Components from 'unplugin-vue-components/vite';
|
||||||
|
|
||||||
|
export default function createComponents(options?: Options | undefined) {
|
||||||
|
return Components({
|
||||||
|
// 指定组件位置,默认是src/components
|
||||||
|
dirs: ['src/components'],
|
||||||
|
deep: true, // search for subdirectories
|
||||||
|
// ui库解析器
|
||||||
|
// resolvers: [ElementPlusResolver()],
|
||||||
|
extensions: ['vue'],
|
||||||
|
// 配置文件生成位置
|
||||||
|
dts: 'src/types/import-components.d.ts',
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
}
|
||||||
5
vite/plugins/index.ts
Normal file
5
vite/plugins/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import appProvider from './appProvider';
|
||||||
|
import buildThemeConfig from './build.unocss.config';
|
||||||
|
import createComponents from './components';
|
||||||
|
|
||||||
|
export { appProvider, buildThemeConfig, createComponents };
|
||||||
Loading…
x
Reference in New Issue
Block a user