version: v4.6.4-beta1.1

This commit is contained in:
XiaoDaiGua-Ray 2024-02-28 10:31:25 +08:00
parent 0c1842cbbd
commit 8db423a018
21 changed files with 1128 additions and 1224 deletions

View File

@ -24,6 +24,7 @@
"datetimerange",
"domtoimage",
"EDITMSG",
"iife",
"macarons",
"menutag",
"ndata",

View File

@ -1,5 +1,19 @@
# CHANGE LOG
## 4.6.4-beta1.1
更新了一大波的开发依赖。
## Feats
- 更新 `vue` 版本至 `3.4.20`
- 更新 `vite` 版本至 `5.1.4`
- 更新了开发依赖
- 移除 `utils/xlsx` 工具包与 `xlsx` 依赖
- 更新了 `viteCDNPlugin` 配置形式,现在会自动读取版本号
- 更新 `vue-hooks-plus` 版本至 `1.8.8`
- 更改 `vite-plugins` 包名称为 `vite-helper`
## 4.6.4-beta1.0
更新了核心依赖插件:`vite`, `vue`

View File

@ -1,7 +1,7 @@
{
"name": "ray-template",
"private": false,
"version": "4.6.4-beta1.0",
"version": "4.6.4-beta1.1",
"type": "module",
"engines": {
"node": "^18.0.0 || >=20.0.0",
@ -13,7 +13,7 @@
"preview": "vite preview",
"test": "vue-tsc --noEmit && vite build --mode test",
"dev-build": "vue-tsc --noEmit && vite build --mode development",
"report": "vue-tsc --noEmit && vite build --mode report",
"report": "vite build --mode report",
"prepare": "husky install"
},
"husky": {
@ -40,7 +40,7 @@
"currency.js": "^2.0.4",
"dayjs": "^1.11.10",
"dom-to-image": "2.6.0",
"echarts": "^5.4.3",
"echarts": "^5.5.0",
"interactjs": "1.10.26",
"lodash-es": "^4.17.21",
"mockjs": "1.1.0",
@ -48,62 +48,62 @@
"pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.0",
"print-js": "^1.6.0",
"vue": "^3.4.19",
"vue-hooks-plus": "1.8.5",
"vue": "^3.4.20",
"vue-demi": "0.14.6",
"vue-hooks-plus": "1.8.8",
"vue-i18n": "^9.9.0",
"vue-router": "^4.2.5",
"xlsx": "^0.18.5"
"vue-router": "^4.2.5"
},
"devDependencies": {
"@babel/core": "^7.23.2",
"@babel/eslint-parser": "^7.22.11",
"@babel/core": "^7.23.9",
"@babel/eslint-parser": "^7.23.3",
"@commitlint/cli": "^17.7.1",
"@commitlint/config-conventional": "^17.7.0",
"@interactjs/types": "1.10.21",
"@intlify/unplugin-vue-i18n": "^1.5.0",
"@intlify/unplugin-vue-i18n": "^2.0.0",
"@types/crypto-js": "^4.1.1",
"@types/dom-to-image": "2.6.7",
"@types/lodash-es": "^4.17.11",
"@types/mockjs": "1.0.7",
"@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.5.0",
"@vitejs/plugin-vue": "^5.0.3",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue-hooks-plus/resolvers": "1.2.4",
"@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^12.0.0",
"autoprefixer": "^10.4.15",
"depcheck": "^1.4.5",
"eslint": "^8.52.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-standard-with-typescript": "^39.0.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-standard-with-typescript": "^43.0.0",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-n": "^16.2.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-vue": "^9.18.1",
"husky": "8.0.3",
"lint-staged": "^15.1.0",
"postcss": "^8.4.31",
"postcss-px-to-viewport-8-plugin": "1.2.2",
"prettier": "^3.0.3",
"rollup-plugin-visualizer": "^5.9.2",
"sass": "1.69.5",
"postcss-px-to-viewport-8-plugin": "1.2.3",
"prettier": "^3.2.5",
"rollup-plugin-visualizer": "^5.12.0",
"sass": "1.71.1",
"svg-sprite-loader": "^6.0.11",
"typescript": "^5.2.2",
"unplugin-auto-import": "^0.16.6",
"unplugin-vue-components": "^0.25.2",
"vite": "^5.1.3",
"vite-plugin-cdn2": "0.15.2",
"unplugin-auto-import": "^0.17.5",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.1.4",
"vite-plugin-cdn2": "0.15.4",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-ejs": "^1.7.0",
"vite-plugin-eslint": "1.8.1",
"vite-plugin-imp": "^2.4.0",
"vite-plugin-inspect": "^0.7.38",
"vite-plugin-mock-dev-server": "1.3.4",
"vite-plugin-inspect": "^0.8.3",
"vite-plugin-mock-dev-server": "1.4.7",
"vite-plugin-svg-icons": "^2.0.1",
"vite-svg-loader": "^4.0.0",
"vue-tsc": "^1.8.8"
"vue-tsc": "^1.8.27"
},
"description": "<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->",
"main": "index.ts",

1866
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,8 @@
import { getAppDefaultLanguage } from '@/locales/helper'
import { colorToRgba, setStorage } from '@/utils'
import { useI18n, useDayjs } from '@/hooks'
import { APP_CATCH_KEY } from '@/app-config'
import { watchOnce } from '@vueuse/core'
import { APP_THEME } from '@/app-config'
import { APP_CATCH_KEY, APP_THEME } from '@/app-config'
import type { SettingState } from '@/store/modules/setting/type'
import type { LocalKey } from '@/hooks'

View File

@ -77,8 +77,8 @@ export type DeepMutable<T> = {
-readonly [P in keyof T]: T[P] extends ReadonlyArray<infer U>
? Array<DeepMutable<U>>
: T[P] extends object
? DeepMutable<T[P]>
: T[P]
? DeepMutable<T[P]>
: T[P]
}
/**
@ -89,8 +89,5 @@ export type DeepMutable<T> = {
* ReturnPromiseType<Promise<string>> // string
* ReturnPromiseType<Promise<string> | Promise<number>> // string | number
*/
export type ReturnPromiseType<T extends Promise<any>> = T extends Promise<
infer U
>
? U
: never
export type ReturnPromiseType<T extends Promise<any>> =
T extends Promise<infer U> ? U : never

View File

@ -14,10 +14,10 @@ export type RemoveStorageFC = <T extends RemoveStorageKey>(
storageType: T extends '__all__'
? 'all'
: T extends '__all_sessionStorage__'
? 'sessionStorage'
: T extends '__all_localStorage__'
? 'localStorage'
: StorageLike,
? 'sessionStorage'
: T extends '__all_localStorage__'
? 'localStorage'
: StorageLike,
options?: StorageOptions,
) => void

1
src/utils/app/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './prefix-cache-key'

View File

@ -0,0 +1,23 @@
import { APP_CATCH_KEY_PREFIX } from '@/app-config'
/**
*
* @param key pinia key
*
* @returns key
*
* @description
* key 便 key
*
* @example
* // 假设 APP_CATCH_KEY_PREFIX = 'ray-template:'
*
* prefixCacheKey('signing') // 返回 'ray-template:signing'
*/
export const prefixCacheKey = (key: string) => {
if (['', false, null, void 0].includes(key)) {
return key
}
return `${APP_CATCH_KEY_PREFIX}${key}`
}

View File

@ -20,8 +20,12 @@ import type { StorageLike, StorageOptions, RemoveStorageFC } from '@/types'
* @param options
*
* @description
* key
* sessionStorage
* key
*
* sessionStorage
*
* @example
* hasStorage('signing') // 查找 session 中 signing 缓存字段
*/
function hasStorage(
key: string,
@ -43,7 +47,14 @@ function hasStorage(
* @param options
*
* @description
* sessionStorage
* sessionStorage
*
* key
*
* @example
* setStorage('demo', 'hi') // 设置 session 中 demo 缓存字段
* setStorage('demo', 'hi', 'localStorage') // 设置 local 中 demo 缓存字段
* setStorage('demo', 'hi', 'sessionStorage', { prefix: true, prefixKey: 'ray' }) // 设置 session 中 ray_demo 缓存字段
*/
function setStorage<T = unknown>(
key: string,
@ -95,7 +106,16 @@ function getStorage<T = unknown>(
* @param options
*
* @description
* sessionStorage
*
*
* sessionStorage
*
* key
*
* @example
* getStorage('demo') // 获取 session 中 demo 缓存字段
* getStorage('demo', 'localStorage') // 获取 local 中 demo 缓存字段
* getStorage('demo', 'sessionStorage', { prefix: true, prefixKey: 'ray' }) // 获取 session 中 ray_demo 缓存字段
*/
function getStorage<T = unknown>(
key: string,
@ -133,10 +153,12 @@ function getStorage<T = unknown>(
* @param options
*
* @description
* sessionStorage
*
*
* __all____all_sessionStorage____all_localStorage__ key
* sessionStorage localStorage
* sessionStorage
*
* __all____all_sessionStorage____all_localStorage__ key
* sessionStorage localStorage
*
* @example
* removeStorage('__all__', 'all') // 清空所有缓存
@ -161,8 +183,8 @@ const removeStorage: RemoveStorageFC = (key, storageType, options) => {
const keys = isAll
? [...sessionStorageKeys, ...localStorageKeys]
: removeType === 'localStorage'
? localStorageKeys
: sessionStorageKeys
? localStorageKeys
: sessionStorageKeys
keys.forEach((curr) => {
if (key === '__all__') {
window.sessionStorage.removeItem(_prefix + curr)

View File

@ -3,5 +3,5 @@ export * from './cache'
export * from './dom'
export * from './element'
export * from './precision'
export * from './xlsx'
export * from './vue'
export * from './app'

View File

@ -1,104 +0,0 @@
/**
*
* @author Ray <https://github.com/XiaoDaiGua-Ray>
*
* @date 2023-01-15
*
* @workspace ray-template
*
* @remark
*/
import { utils, writeFileXLSX } from 'xlsx'
import dayjs from 'dayjs'
import type { DataTableBaseColumn } from 'naive-ui'
import type { Range, WorkSheet } from 'xlsx'
export interface ExportExcelHeader extends DataTableBaseColumn {}
export type RowData = Record<string, unknown>
export interface ExportXLSXConfig {
filename?: string
}
/**
*
* @param columns table columns
* @returns
*/
const setupSheetHeader = (columns: ExportExcelHeader[]) => {
const header = columns.reduce((pre, curr) => {
pre[curr.key] = curr.title
return pre
}, {} as ExportExcelHeader)
return header
}
/**
*
* @param range table range
* @param sheetData sheet data
* @param sheetHeader table header
*
* @remark
* @remark ,
*/
const transformSheetHeader = (
range: Range,
sheetData: WorkSheet,
sheetHeader: ExportExcelHeader,
) => {
for (let c = range.s.c; c <= range.e.c; c++) {
const header = utils.encode_col(c) + '1'
sheetData[header].v = sheetHeader[sheetData[header].v]
}
}
/**
*
* @param dataSource
* @param columns
* @param config xlsx
*
* @remark xlsx
* @remark , 使 dataSource
*/
export const exportFileToXLSX = async (
dataSource: RowData[],
columns?: ExportExcelHeader[],
config: ExportXLSXConfig = {},
) => {
await new Promise<void>((resolve, reject) => {
if (Array.isArray(dataSource)) {
if (dataSource.length) {
const sheetHeader = setupSheetHeader(columns ?? []) // 获取所有列(设置为 `excel` 表头)
const sheetData = utils.json_to_sheet(dataSource) // 将所有数据转换为表格数据类型
const workBook = utils.book_new()
const filename = config.filename
? config.filename + '.xlsx'
: dayjs().format('YYYY-MM-DD') + '导出表格.xlsx'
utils.book_append_sheet(workBook, sheetData, 'Data')
const range = utils.decode_range(sheetData['!ref'] as string) // 获取所有单元格
if (columns?.length) {
transformSheetHeader(range, sheetData, sheetHeader)
}
writeFileXLSX(workBook, filename) // 输出表格
resolve()
} else {
resolve()
}
} else {
reject()
}
})
}

View File

@ -34,8 +34,8 @@
},
"include": [
"vite.config.ts",
"vite-plugins/index.ts",
"vite-plugins/type.ts",
"vite-helper/index.ts",
"vite-helper/type.ts",
"vite.custom.config.ts",
"package.json",
"vite-env.d.ts",

View File

@ -81,6 +81,9 @@
"watchEffect": true,
"watchPostEffect": true,
"watchSyncEffect": true,
"NEllipsis": true
"NEllipsis": true,
"ExtractDefaultPropTypes": true,
"ExtractPropTypes": true,
"ExtractPublicPropTypes": true
}
}

View File

@ -83,5 +83,6 @@ declare global {
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
import('vue')
}

66
vite-helper/index.ts Normal file
View File

@ -0,0 +1,66 @@
import pkg from '../package.json'
/**
*
* @param title title
*/
export const htmlTitlePlugin = (title: string) => {
return {
name: 'html-transform',
transformIndexHtml: (html: string) => {
return html.replace(/<title>(.*?)<\/title>/, `<title>${title}</title>`)
},
}
}
/**
*
* @param options css
* @returns additionalData string
*
* @description
* css
*/
export const mixinCSSPlugin = (options?: string[]) => {
if (!Array.isArray(options)) {
throw TypeError(
'mixinCSSPlugin: The mixinCSSPlugin argument must be an array!',
)
}
const mixinString = options.reduce((pre, curr) => {
const temp = `@import "${curr}";`
return (pre += temp)
}, '')
return mixinString as string
}
/**
*
* @param dependenciesKey
*
* @returns
*
* @description
* package.json
*
* @example
* const vueVersion = getDependenciesVersion('vue') // vue version
* const unknownVersion = getDependenciesVersion('unknown package') // Error
*/
export const getDependenciesVersion = (
dependenciesKey: keyof typeof pkg.dependencies,
) => {
const { dependencies } = pkg
const result = dependencies[dependenciesKey]
if (!result) {
throw Error(
`[getDependenciesVersion]: The ${dependenciesKey} does not exist in the package.json file!`,
)
}
return result.replace(/^[^\w\s]+/, '')
}

View File

@ -1,35 +0,0 @@
/**
*
* @param title title
*/
export const htmlTitlePlugin = (title: string) => {
return {
name: 'html-transform',
transformIndexHtml: (html: string) => {
return html.replace(/<title>(.*?)<\/title>/, `<title>${title}</title>`)
},
}
}
/**
*
* @param options css
* @returns additionalData string
*
* @remark css ,
*/
export const mixinCSSPlugin = (options?: string[]) => {
if (!Array.isArray(options)) {
throw TypeError(
'mixinCSSPlugin: The mixinCSSPlugin argument must be an array!',
)
}
const mixinString = options.reduce((pre, curr) => {
const temp = `@import "${curr}";`
return (pre += temp)
}, '')
return mixinString as string
}

View File

@ -45,10 +45,8 @@ export default defineConfig(({ mode }) => {
'vue-i18n',
'naive-ui',
'@vueuse/core',
'vue-demi',
'dayjs',
'echarts',
'xlsx',
'axios',
'print-js',
'clipboard',

View File

@ -38,7 +38,7 @@
import path from 'node:path'
import { htmlTitlePlugin, mixinCSSPlugin } from './vite-plugins/index'
import { htmlTitlePlugin, mixinCSSPlugin } from './vite-helper/index'
import { APP_THEME } from './src/app-config/designConfig'
import { PRE_LOADING_CONFIG, SIDE_BAR_LOGO } from './src/app-config/appConfig'

View File

@ -26,12 +26,14 @@ import mockDevServerPlugin from 'vite-plugin-mock-dev-server'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import unpluginViteComponents from 'unplugin-vue-components/vite'
import { cdn as viteCDNPlugin } from 'vite-plugin-cdn2'
import { getDependenciesVersion } from './vite-helper'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
import config from './vite.custom.config'
import type { PluginOption } from 'vite'
import type pkg from './package.json'
// 仅适用于报告模式report
function onlyReportOptions(mode: string) {
@ -48,65 +50,55 @@ function onlyReportOptions(mode: string) {
// 仅适用于构建模式任何构建模式preview、build、report...
function onlyBuildOptions(mode: string) {
// cdn 列表
const cdnOptions: Array<{
name: keyof typeof pkg.dependencies
global: string
}> = [
{
name: 'vue',
global: 'Vue',
},
{
name: 'vue-demi',
global: 'VueDemi',
},
{
name: 'naive-ui',
global: 'naive',
},
{
name: 'pinia',
global: 'Pinia',
},
{
name: 'vue-router',
global: 'VueRouter',
},
{
name: 'vue-i18n',
global: 'VueI18n',
},
{
name: 'echarts',
global: 'echarts',
},
{
name: 'axios',
global: 'axios',
},
]
return [
viteCDNPlugin({
// modules 顺序 vue, vue-demi 必须保持当前顺序加载,否则会出现加载错误问题
modules: [
{
name: 'vue',
global: 'Vue',
resolve:
'https://cdnjs.cloudflare.com/ajax/libs/vue/3.4.14/vue.global.min.js',
},
{
name: 'vue-demi',
global: 'VueDemi',
resolve:
'https://cdnjs.cloudflare.com/ajax/libs/vue-demi/0.14.6/index.iife.min.js',
},
{
name: 'naive-ui',
global: 'naive',
resolve:
'https://cdnjs.cloudflare.com/ajax/libs/naive-ui/2.37.3/index.prod.js',
},
{
name: 'pinia',
global: 'Pinia',
resolve:
'https://cdnjs.cloudflare.com/ajax/libs/pinia/2.1.7/pinia.iife.min.js',
},
{
name: 'vue-router',
global: 'VueRouter',
resolve:
'https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.2.5/vue-router.global.min.js',
},
{
name: 'vue-i18n',
global: 'VueI18n',
resolve:
'https://cdnjs.cloudflare.com/ajax/libs/vue-i18n/9.9.0/vue-i18n.global.min.js',
},
{
name: 'echarts',
global: 'echarts',
resolve:
'https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js',
},
{
name: 'xlsx',
global: 'XLSX',
resolve:
'https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js',
},
{
name: 'axios',
global: 'axios',
resolve:
'https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.7/axios.min.js',
},
],
modules: cdnOptions.map((curr) => {
return {
name: curr.name,
global: curr.global,
resolve: `https://cdnjs.cloudflare.com/ajax/libs/${curr.name}/${getDependenciesVersion(curr.name)}/${curr.name}.min.js`,
}
}),
}),
]
}