feat: 🚀 添加新的表格封装
This commit is contained in:
parent
b2fed0a09b
commit
71ba1bb264
|
@ -1,9 +1,39 @@
|
||||||
// @ts-check
|
// @see: https://www.prettier.cn
|
||||||
|
|
||||||
/** @type {import("prettier").Config} */
|
|
||||||
export default {
|
export default {
|
||||||
bracketSpacing: true,
|
// 超过最大值换行
|
||||||
singleQuote: false,
|
printWidth: 200,
|
||||||
arrowParens: "avoid",
|
// 缩进字节数
|
||||||
trailingComma: "none"
|
tabWidth: 1,
|
||||||
|
// 使用制表符而不是空格缩进行
|
||||||
|
useTabs: true,
|
||||||
|
// 结尾不用分号(true有,false没有)
|
||||||
|
semi: true,
|
||||||
|
// 使用单引号(true单引号,false双引号)
|
||||||
|
singleQuote: true,
|
||||||
|
// 更改引用对象属性的时间 可选值"<as-needed|consistent|preserve>"
|
||||||
|
quoteProps: 'as-needed',
|
||||||
|
// 在对象,数组括号与文字之间加空格 "{ foo: bar }"
|
||||||
|
bracketSpacing: true,
|
||||||
|
// 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"<none|es5|all>",默认none
|
||||||
|
trailingComma: 'all',
|
||||||
|
// 在JSX中使用单引号而不是双引号
|
||||||
|
jsxSingleQuote: true,
|
||||||
|
// (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid:省略括号 ,always:不省略括号
|
||||||
|
arrowParens: 'avoid',
|
||||||
|
// 如果文件顶部已经有一个 doclock,这个选项将新建一行注释,并打上@format标记。
|
||||||
|
insertPragma: false,
|
||||||
|
// 指定要使用的解析器,不需要写文件开头的 @prettier
|
||||||
|
requirePragma: false,
|
||||||
|
// 默认值。因为使用了一些折行敏感型的渲染器(如GitHub comment)而按照markdown文本样式进行折行
|
||||||
|
proseWrap: 'preserve',
|
||||||
|
// 在html中空格是否是敏感的 "css" - 遵守CSS显示属性的默认值, "strict" - 空格被认为是敏感的 ,"ignore" - 空格被认为是不敏感的
|
||||||
|
htmlWhitespaceSensitivity: 'css',
|
||||||
|
// 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
|
||||||
|
endOfLine: 'auto',
|
||||||
|
// 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
|
||||||
|
rangeStart: 0,
|
||||||
|
rangeEnd: Infinity,
|
||||||
|
|
||||||
|
vueIndentScriptAndStyle: false, // Vue文件脚本和样式标签缩进
|
||||||
};
|
};
|
||||||
|
|
20
Dockerfile
20
Dockerfile
|
@ -1,20 +0,0 @@
|
||||||
FROM node:20-alpine as build-stage
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
RUN corepack enable
|
|
||||||
RUN corepack prepare pnpm@latest --activate
|
|
||||||
|
|
||||||
RUN npm config set registry https://registry.npmmirror.com
|
|
||||||
|
|
||||||
COPY .npmrc package.json pnpm-lock.yaml ./
|
|
||||||
RUN pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
RUN pnpm build
|
|
||||||
|
|
||||||
FROM nginx:stable-alpine as production-stage
|
|
||||||
|
|
||||||
COPY --from=build-stage /app/dist /usr/share/nginx/html
|
|
||||||
EXPOSE 80
|
|
||||||
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
|
99
build/cdn.ts
99
build/cdn.ts
|
@ -1,4 +1,4 @@
|
||||||
import { Plugin as importToCDN } from "vite-plugin-cdn-import";
|
import { Plugin as importToCDN } from 'vite-plugin-cdn-import';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 打包时采用`cdn`模式,仅限外网使用(默认不采用,如果需要采用cdn模式,请在 .env.production 文件,将 VITE_CDN 设置成true)
|
* @description 打包时采用`cdn`模式,仅限外网使用(默认不采用,如果需要采用cdn模式,请在 .env.production 文件,将 VITE_CDN 设置成true)
|
||||||
|
@ -6,55 +6,50 @@ import { Plugin as importToCDN } from "vite-plugin-cdn-import";
|
||||||
* 注意:上面提到的仅限外网使用也不是完全肯定的,如果你们公司内网部署的有相关js、css文件,也可以将下面配置对应改一下,整一套内网版cdn
|
* 注意:上面提到的仅限外网使用也不是完全肯定的,如果你们公司内网部署的有相关js、css文件,也可以将下面配置对应改一下,整一套内网版cdn
|
||||||
*/
|
*/
|
||||||
export const cdn = importToCDN({
|
export const cdn = importToCDN({
|
||||||
//(prodUrl解释: name: 对应下面modules的name,version: 自动读取本地package.json中dependencies依赖中对应包的版本号,path: 对应下面modules的path,当然也可写完整路径,会替换prodUrl)
|
//(prodUrl解释: name: 对应下面modules的name,version: 自动读取本地package.json中dependencies依赖中对应包的版本号,path: 对应下面modules的path,当然也可写完整路径,会替换prodUrl)
|
||||||
prodUrl: "https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}",
|
prodUrl: 'https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}',
|
||||||
modules: [
|
modules: [
|
||||||
{
|
{
|
||||||
name: "vue",
|
name: 'vue',
|
||||||
var: "Vue",
|
var: 'Vue',
|
||||||
path: "vue.global.prod.min.js"
|
path: 'vue.global.prod.min.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "vue-router",
|
name: 'vue-router',
|
||||||
var: "VueRouter",
|
var: 'VueRouter',
|
||||||
path: "vue-router.global.min.js"
|
path: 'vue-router.global.min.js',
|
||||||
},
|
},
|
||||||
{
|
// 项目中没有直接安装vue-demi,但是pinia用到了,所以需要在引入pinia前引入vue-demi(https://github.com/vuejs/pinia/blob/v2/packages/pinia/package.json#L77)
|
||||||
name: "vue-i18n",
|
{
|
||||||
var: "VueI18n",
|
name: 'vue-demi',
|
||||||
path: "vue-i18n.runtime.global.prod.min.js"
|
var: 'VueDemi',
|
||||||
},
|
path: 'index.iife.min.js',
|
||||||
// 项目中没有直接安装vue-demi,但是pinia用到了,所以需要在引入pinia前引入vue-demi(https://github.com/vuejs/pinia/blob/v2/packages/pinia/package.json#L77)
|
},
|
||||||
{
|
{
|
||||||
name: "vue-demi",
|
name: 'pinia',
|
||||||
var: "VueDemi",
|
var: 'Pinia',
|
||||||
path: "index.iife.min.js"
|
path: 'pinia.iife.min.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pinia",
|
name: 'element-plus',
|
||||||
var: "Pinia",
|
var: 'ElementPlus',
|
||||||
path: "pinia.iife.min.js"
|
path: 'index.full.min.js',
|
||||||
},
|
css: 'index.min.css',
|
||||||
{
|
},
|
||||||
name: "element-plus",
|
{
|
||||||
var: "ElementPlus",
|
name: 'axios',
|
||||||
path: "index.full.min.js",
|
var: 'axios',
|
||||||
css: "index.min.css"
|
path: 'axios.min.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "axios",
|
name: 'dayjs',
|
||||||
var: "axios",
|
var: 'dayjs',
|
||||||
path: "axios.min.js"
|
path: 'dayjs.min.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "dayjs",
|
name: 'echarts',
|
||||||
var: "dayjs",
|
var: 'echarts',
|
||||||
path: "dayjs.min.js"
|
path: 'echarts.min.js',
|
||||||
},
|
},
|
||||||
{
|
],
|
||||||
name: "echarts",
|
|
||||||
var: "echarts",
|
|
||||||
path: "echarts.min.js"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,31 +4,12 @@
|
||||||
* 尤其当您禁用浏览器缓存时(这种情况只应该发生在调试阶段)必须将对应模块加入到 include里,否则会遇到开发环境切换页面卡顿的问题(vite 会认为它是一个新的依赖包会重新加载并强制刷新页面),因为它既无法使用浏览器缓存,又没有在本地 node_modules/.vite 里缓存
|
* 尤其当您禁用浏览器缓存时(这种情况只应该发生在调试阶段)必须将对应模块加入到 include里,否则会遇到开发环境切换页面卡顿的问题(vite 会认为它是一个新的依赖包会重新加载并强制刷新页面),因为它既无法使用浏览器缓存,又没有在本地 node_modules/.vite 里缓存
|
||||||
* 温馨提示:如果您使用的第三方库是全局引入,也就是引入到 src/main.ts 文件里,就不需要再添加到 include 里了,因为 vite 会自动将它们缓存到 node_modules/.vite
|
* 温馨提示:如果您使用的第三方库是全局引入,也就是引入到 src/main.ts 文件里,就不需要再添加到 include 里了,因为 vite 会自动将它们缓存到 node_modules/.vite
|
||||||
*/
|
*/
|
||||||
const include = [
|
const include = ['qs', 'mitt', 'dayjs', 'axios', 'pinia', 'vue-types', 'js-cookie', 'vue-tippy', 'pinyin-pro', 'sortablejs', '@vueuse/core', '@pureadmin/utils', 'responsive-storage'];
|
||||||
"qs",
|
|
||||||
"mitt",
|
|
||||||
"dayjs",
|
|
||||||
"axios",
|
|
||||||
"pinia",
|
|
||||||
"vue-i18n",
|
|
||||||
"vue-types",
|
|
||||||
"js-cookie",
|
|
||||||
"vue-tippy",
|
|
||||||
"pinyin-pro",
|
|
||||||
"sortablejs",
|
|
||||||
"@vueuse/core",
|
|
||||||
"@pureadmin/utils",
|
|
||||||
"responsive-storage"
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在预构建中强制排除的依赖项
|
* 在预构建中强制排除的依赖项
|
||||||
* 温馨提示:所有以 `@iconify-icons/` 开头引入的的本地图标模块,都应该加入到下面的 `exclude` 里,因为平台推荐的使用方式是哪里需要哪里引入而且都是单个的引入,不需要预构建,直接让浏览器加载就好
|
* 温馨提示:所有以 `@iconify-icons/` 开头引入的的本地图标模块,都应该加入到下面的 `exclude` 里,因为平台推荐的使用方式是哪里需要哪里引入而且都是单个的引入,不需要预构建,直接让浏览器加载就好
|
||||||
*/
|
*/
|
||||||
const exclude = [
|
const exclude = ['@iconify-icons/ep', '@iconify-icons/ri', '@pureadmin/theme/dist/browser-utils'];
|
||||||
"@iconify-icons/ep",
|
|
||||||
"@iconify-icons/ri",
|
|
||||||
"@pureadmin/theme/dist/browser-utils"
|
|
||||||
];
|
|
||||||
|
|
||||||
export { include, exclude };
|
export { include, exclude };
|
||||||
|
|
116
build/plugins.ts
116
build/plugins.ts
|
@ -1,66 +1,54 @@
|
||||||
import { cdn } from "./cdn";
|
import { cdn } from './cdn';
|
||||||
import vue from "@vitejs/plugin-vue";
|
import vue from '@vitejs/plugin-vue';
|
||||||
import { pathResolve } from "./utils";
|
import { viteBuildInfo } from './info';
|
||||||
import { viteBuildInfo } from "./info";
|
import svgLoader from 'vite-svg-loader';
|
||||||
import svgLoader from "vite-svg-loader";
|
import type { PluginOption } from 'vite';
|
||||||
import type { PluginOption } from "vite";
|
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||||
import vueJsx from "@vitejs/plugin-vue-jsx";
|
import Inspector from 'vite-plugin-vue-inspector';
|
||||||
import Inspector from "vite-plugin-vue-inspector";
|
import { configCompressPlugin } from './compress';
|
||||||
import { configCompressPlugin } from "./compress";
|
import removeNoMatch from 'vite-plugin-router-warn';
|
||||||
import removeNoMatch from "vite-plugin-router-warn";
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
import { visualizer } from "rollup-plugin-visualizer";
|
import removeConsole from 'vite-plugin-remove-console';
|
||||||
import removeConsole from "vite-plugin-remove-console";
|
import { themePreprocessorPlugin } from '@pureadmin/theme';
|
||||||
import { themePreprocessorPlugin } from "@pureadmin/theme";
|
import { genScssMultipleScopeVars } from '../src/layout/theme';
|
||||||
import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
|
import { vitePluginFakeServer } from 'vite-plugin-fake-server';
|
||||||
import { genScssMultipleScopeVars } from "../src/layout/theme";
|
|
||||||
import { vitePluginFakeServer } from "vite-plugin-fake-server";
|
|
||||||
|
|
||||||
export function getPluginsList(
|
export function getPluginsList(VITE_CDN: boolean, VITE_COMPRESSION: ViteCompression, VITE_PORT: number): PluginOption[] {
|
||||||
VITE_CDN: boolean,
|
const lifecycle = process.env.npm_lifecycle_event;
|
||||||
VITE_COMPRESSION: ViteCompression,
|
return [
|
||||||
VITE_PORT: number
|
vue(),
|
||||||
): PluginOption[] {
|
// jsx、tsx语法支持
|
||||||
const lifecycle = process.env.npm_lifecycle_event;
|
vueJsx(),
|
||||||
return [
|
// 按下Command(⌘)+Shift(⇧),然后点击页面元素会自动打开本地IDE并跳转到对应的代码位置
|
||||||
vue(),
|
Inspector(),
|
||||||
// jsx、tsx语法支持
|
viteBuildInfo(VITE_PORT),
|
||||||
vueJsx(),
|
/**
|
||||||
VueI18nPlugin({
|
* 开发环境下移除非必要的vue-router动态路由警告No match found for location with path
|
||||||
jitCompilation: false,
|
* 非必要具体看 https://github.com/vuejs/router/issues/521 和 https://github.com/vuejs/router/issues/359
|
||||||
include: [pathResolve("../locales/**")]
|
* vite-plugin-router-warn只在开发环境下启用,只处理vue-router文件并且只在服务启动或重启时运行一次,性能消耗可忽略不计
|
||||||
}),
|
*/
|
||||||
// 按下Command(⌘)+Shift(⇧),然后点击页面元素会自动打开本地IDE并跳转到对应的代码位置
|
removeNoMatch(),
|
||||||
Inspector(),
|
// mock支持
|
||||||
viteBuildInfo(VITE_PORT),
|
vitePluginFakeServer({
|
||||||
/**
|
logger: false,
|
||||||
* 开发环境下移除非必要的vue-router动态路由警告No match found for location with path
|
include: 'mock',
|
||||||
* 非必要具体看 https://github.com/vuejs/router/issues/521 和 https://github.com/vuejs/router/issues/359
|
infixName: false,
|
||||||
* vite-plugin-router-warn只在开发环境下启用,只处理vue-router文件并且只在服务启动或重启时运行一次,性能消耗可忽略不计
|
enableProd: true,
|
||||||
*/
|
}),
|
||||||
removeNoMatch(),
|
// 自定义主题
|
||||||
// mock支持
|
themePreprocessorPlugin({
|
||||||
vitePluginFakeServer({
|
scss: {
|
||||||
logger: false,
|
multipleScopeVars: genScssMultipleScopeVars(),
|
||||||
include: "mock",
|
extract: true,
|
||||||
infixName: false,
|
},
|
||||||
enableProd: true
|
}),
|
||||||
}),
|
// svg组件化支持
|
||||||
// 自定义主题
|
svgLoader(),
|
||||||
themePreprocessorPlugin({
|
VITE_CDN ? cdn : null,
|
||||||
scss: {
|
configCompressPlugin(VITE_COMPRESSION),
|
||||||
multipleScopeVars: genScssMultipleScopeVars(),
|
// 线上环境删除console
|
||||||
extract: true
|
removeConsole({ external: ['src/assets/iconfont/iconfont.js'] }),
|
||||||
}
|
// 打包分析
|
||||||
}),
|
lifecycle === 'report' ? visualizer({ open: true, brotliSize: true, filename: 'report.html' }) : (null as any),
|
||||||
// svg组件化支持
|
];
|
||||||
svgLoader(),
|
|
||||||
VITE_CDN ? cdn : null,
|
|
||||||
configCompressPlugin(VITE_COMPRESSION),
|
|
||||||
// 线上环境删除console
|
|
||||||
removeConsole({ external: ["src/assets/iconfont/iconfont.js"] }),
|
|
||||||
// 打包分析
|
|
||||||
lifecycle === "report"
|
|
||||||
? visualizer({ open: true, brotliSize: true, filename: "report.html" })
|
|
||||||
: (null as any)
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
351
eslint.config.js
351
eslint.config.js
|
@ -1,181 +1,176 @@
|
||||||
import js from "@eslint/js";
|
import js from '@eslint/js';
|
||||||
import pluginVue from "eslint-plugin-vue";
|
import pluginTypeScript from '@typescript-eslint/eslint-plugin';
|
||||||
import * as parserVue from "vue-eslint-parser";
|
import * as parserTypeScript from '@typescript-eslint/parser';
|
||||||
import configPrettier from "eslint-config-prettier";
|
import configPrettier from 'eslint-config-prettier';
|
||||||
import pluginPrettier from "eslint-plugin-prettier";
|
import { defineFlatConfig } from 'eslint-define-config';
|
||||||
import { defineFlatConfig } from "eslint-define-config";
|
import pluginPrettier from 'eslint-plugin-prettier';
|
||||||
import * as parserTypeScript from "@typescript-eslint/parser";
|
import pluginVue from 'eslint-plugin-vue';
|
||||||
import pluginTypeScript from "@typescript-eslint/eslint-plugin";
|
import * as parserVue from 'vue-eslint-parser';
|
||||||
|
|
||||||
export default defineFlatConfig([
|
export default defineFlatConfig([
|
||||||
{
|
{
|
||||||
...js.configs.recommended,
|
...js.configs.recommended,
|
||||||
ignores: [
|
ignores: ['**/.*', 'dist/*', '*.d.ts', 'public/*', 'src/assets/**', 'src/**/iconfont/**'],
|
||||||
"**/.*",
|
languageOptions: {
|
||||||
"dist/*",
|
globals: {
|
||||||
"*.d.ts",
|
// index.d.ts
|
||||||
"public/*",
|
RefType: 'readonly',
|
||||||
"src/assets/**",
|
EmitType: 'readonly',
|
||||||
"src/**/iconfont/**"
|
TargetContext: 'readonly',
|
||||||
],
|
ComponentRef: 'readonly',
|
||||||
languageOptions: {
|
ElRef: 'readonly',
|
||||||
globals: {
|
ForDataType: 'readonly',
|
||||||
// index.d.ts
|
AnyFunction: 'readonly',
|
||||||
RefType: "readonly",
|
PropType: 'readonly',
|
||||||
EmitType: "readonly",
|
Writable: 'readonly',
|
||||||
TargetContext: "readonly",
|
Nullable: 'readonly',
|
||||||
ComponentRef: "readonly",
|
NonNullable: 'readonly',
|
||||||
ElRef: "readonly",
|
Recordable: 'readonly',
|
||||||
ForDataType: "readonly",
|
ReadonlyRecordable: 'readonly',
|
||||||
AnyFunction: "readonly",
|
Indexable: 'readonly',
|
||||||
PropType: "readonly",
|
DeepPartial: 'readonly',
|
||||||
Writable: "readonly",
|
Without: 'readonly',
|
||||||
Nullable: "readonly",
|
Exclusive: 'readonly',
|
||||||
NonNullable: "readonly",
|
TimeoutHandle: 'readonly',
|
||||||
Recordable: "readonly",
|
IntervalHandle: 'readonly',
|
||||||
ReadonlyRecordable: "readonly",
|
Effect: 'readonly',
|
||||||
Indexable: "readonly",
|
ChangeEvent: 'readonly',
|
||||||
DeepPartial: "readonly",
|
WheelEvent: 'readonly',
|
||||||
Without: "readonly",
|
ImportMetaEnv: 'readonly',
|
||||||
Exclusive: "readonly",
|
Fn: 'readonly',
|
||||||
TimeoutHandle: "readonly",
|
PromiseFn: 'readonly',
|
||||||
IntervalHandle: "readonly",
|
ComponentElRef: 'readonly',
|
||||||
Effect: "readonly",
|
parseInt: 'readonly',
|
||||||
ChangeEvent: "readonly",
|
parseFloat: 'readonly',
|
||||||
WheelEvent: "readonly",
|
},
|
||||||
ImportMetaEnv: "readonly",
|
},
|
||||||
Fn: "readonly",
|
plugins: {
|
||||||
PromiseFn: "readonly",
|
prettier: pluginPrettier,
|
||||||
ComponentElRef: "readonly",
|
},
|
||||||
parseInt: "readonly",
|
rules: {
|
||||||
parseFloat: "readonly"
|
...configPrettier.rules,
|
||||||
}
|
...pluginPrettier.configs.recommended.rules,
|
||||||
},
|
'no-debugger': 'off',
|
||||||
plugins: {
|
|
||||||
prettier: pluginPrettier
|
'no-unused-vars': [
|
||||||
},
|
'error',
|
||||||
rules: {
|
{
|
||||||
...configPrettier.rules,
|
argsIgnorePattern: '^_',
|
||||||
...pluginPrettier.configs.recommended.rules,
|
varsIgnorePattern: '^_',
|
||||||
"no-debugger": "off",
|
},
|
||||||
"no-unused-vars": [
|
],
|
||||||
"error",
|
'prettier/prettier': [
|
||||||
{
|
'error',
|
||||||
argsIgnorePattern: "^_",
|
{
|
||||||
varsIgnorePattern: "^_"
|
endOfLine: 'auto',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"prettier/prettier": [
|
},
|
||||||
"error",
|
},
|
||||||
{
|
{
|
||||||
endOfLine: "auto"
|
files: ['**/*.?([cm])ts', '**/*.?([cm])tsx'],
|
||||||
}
|
languageOptions: {
|
||||||
]
|
parser: parserTypeScript,
|
||||||
}
|
parserOptions: {
|
||||||
},
|
sourceType: 'module',
|
||||||
{
|
},
|
||||||
files: ["**/*.?([cm])ts", "**/*.?([cm])tsx"],
|
},
|
||||||
languageOptions: {
|
plugins: {
|
||||||
parser: parserTypeScript,
|
'@typescript-eslint': pluginTypeScript,
|
||||||
parserOptions: {
|
},
|
||||||
sourceType: "module"
|
rules: {
|
||||||
}
|
...pluginTypeScript.configs.strict.rules,
|
||||||
},
|
'@typescript-eslint/ban-types': 'off',
|
||||||
plugins: {
|
'@typescript-eslint/no-redeclare': 'error',
|
||||||
"@typescript-eslint": pluginTypeScript
|
'@typescript-eslint/ban-ts-comment': 'off',
|
||||||
},
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
rules: {
|
'@typescript-eslint/prefer-as-const': 'warn',
|
||||||
...pluginTypeScript.configs.strict.rules,
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
"@typescript-eslint/ban-types": "off",
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
"@typescript-eslint/no-redeclare": "error",
|
'@typescript-eslint/no-import-type-side-effects': 'error',
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
'@typescript-eslint/consistent-type-imports': [
|
||||||
"@typescript-eslint/prefer-as-const": "warn",
|
'error',
|
||||||
"@typescript-eslint/no-empty-function": "off",
|
{
|
||||||
"@typescript-eslint/no-non-null-assertion": "off",
|
disallowTypeAnnotations: false,
|
||||||
"@typescript-eslint/no-import-type-side-effects": "error",
|
fixStyle: 'inline-type-imports',
|
||||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
},
|
||||||
"@typescript-eslint/consistent-type-imports": [
|
],
|
||||||
"error",
|
'@typescript-eslint/prefer-literal-enum-member': ['error', { allowBitwiseExpressions: true }],
|
||||||
{ disallowTypeAnnotations: false, fixStyle: "inline-type-imports" }
|
'@typescript-eslint/no-unused-vars': [
|
||||||
],
|
'error',
|
||||||
"@typescript-eslint/prefer-literal-enum-member": [
|
{
|
||||||
"error",
|
argsIgnorePattern: '^_',
|
||||||
{ allowBitwiseExpressions: true }
|
varsIgnorePattern: '^_',
|
||||||
],
|
},
|
||||||
"@typescript-eslint/no-unused-vars": [
|
],
|
||||||
"error",
|
},
|
||||||
{
|
},
|
||||||
argsIgnorePattern: "^_",
|
{
|
||||||
varsIgnorePattern: "^_"
|
files: ['**/*.d.ts'],
|
||||||
}
|
rules: {
|
||||||
]
|
'eslint-comments/no-unlimited-disable': 'off',
|
||||||
}
|
'import/no-duplicates': 'off',
|
||||||
},
|
'unused-imports/no-unused-vars': 'off',
|
||||||
{
|
},
|
||||||
files: ["**/*.d.ts"],
|
},
|
||||||
rules: {
|
{
|
||||||
"eslint-comments/no-unlimited-disable": "off",
|
files: ['**/*.?([cm])js'],
|
||||||
"import/no-duplicates": "off",
|
rules: {
|
||||||
"unused-imports/no-unused-vars": "off"
|
'@typescript-eslint/no-require-imports': 'off',
|
||||||
}
|
'@typescript-eslint/no-var-requires': 'off',
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
files: ["**/*.?([cm])js"],
|
{
|
||||||
rules: {
|
files: ['**/*.vue'],
|
||||||
"@typescript-eslint/no-require-imports": "off",
|
languageOptions: {
|
||||||
"@typescript-eslint/no-var-requires": "off"
|
globals: {
|
||||||
}
|
$: 'readonly',
|
||||||
},
|
$$: 'readonly',
|
||||||
{
|
$computed: 'readonly',
|
||||||
files: ["**/*.vue"],
|
$customRef: 'readonly',
|
||||||
languageOptions: {
|
$ref: 'readonly',
|
||||||
globals: {
|
$shallowRef: 'readonly',
|
||||||
$: "readonly",
|
$toRef: 'readonly',
|
||||||
$$: "readonly",
|
},
|
||||||
$computed: "readonly",
|
parser: parserVue,
|
||||||
$customRef: "readonly",
|
parserOptions: {
|
||||||
$ref: "readonly",
|
ecmaFeatures: {
|
||||||
$shallowRef: "readonly",
|
jsx: true,
|
||||||
$toRef: "readonly"
|
},
|
||||||
},
|
extraFileExtensions: ['.vue'],
|
||||||
parser: parserVue,
|
parser: '@typescript-eslint/parser',
|
||||||
parserOptions: {
|
sourceType: 'module',
|
||||||
ecmaFeatures: {
|
},
|
||||||
jsx: true
|
},
|
||||||
},
|
plugins: {
|
||||||
extraFileExtensions: [".vue"],
|
vue: pluginVue,
|
||||||
parser: "@typescript-eslint/parser",
|
},
|
||||||
sourceType: "module"
|
processor: pluginVue.processors['.vue'],
|
||||||
}
|
rules: {
|
||||||
},
|
...pluginVue.configs.base.rules,
|
||||||
plugins: {
|
...pluginVue.configs['vue3-essential'].rules,
|
||||||
vue: pluginVue
|
...pluginVue.configs['vue3-recommended'].rules,
|
||||||
},
|
'no-undef': 'off',
|
||||||
processor: pluginVue.processors[".vue"],
|
'no-unused-vars': 'off',
|
||||||
rules: {
|
'vue/no-v-html': 'off',
|
||||||
...pluginVue.configs.base.rules,
|
'vue/require-default-prop': 'off',
|
||||||
...pluginVue.configs["vue3-essential"].rules,
|
'vue/require-explicit-emits': 'off',
|
||||||
...pluginVue.configs["vue3-recommended"].rules,
|
'vue/no-useless-template-attributes': 'off',
|
||||||
"no-undef": "off",
|
'vue/multi-word-component-names': 'off',
|
||||||
"no-unused-vars": "off",
|
'vue/no-setup-props-reactivity-loss': 'off',
|
||||||
"vue/no-v-html": "off",
|
'vue/html-self-closing': [
|
||||||
"vue/require-default-prop": "off",
|
'error',
|
||||||
"vue/require-explicit-emits": "off",
|
{
|
||||||
"vue/multi-word-component-names": "off",
|
html: {
|
||||||
"vue/no-setup-props-reactivity-loss": "off",
|
void: 'always',
|
||||||
"vue/html-self-closing": [
|
normal: 'always',
|
||||||
"error",
|
component: 'always',
|
||||||
{
|
},
|
||||||
html: {
|
svg: 'always',
|
||||||
void: "always",
|
math: 'always',
|
||||||
normal: "always",
|
},
|
||||||
component: "always"
|
],
|
||||||
},
|
},
|
||||||
svg: "always",
|
},
|
||||||
math: "always"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
|
// @ts-check
|
||||||
export default {
|
export default {
|
||||||
"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
|
'*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
|
||||||
"{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [
|
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
|
||||||
"prettier --write--parser json"
|
'package.json': ['prettier --write'],
|
||||||
],
|
'*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'],
|
||||||
"package.json": ["prettier --write"],
|
'*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'],
|
||||||
"*.vue": ["eslint --fix", "prettier --write", "stylelint --fix"],
|
'*.md': ['prettier --write'],
|
||||||
"*.{scss,less,styl,html}": ["stylelint --fix", "prettier --write"],
|
|
||||||
"*.md": ["prettier --write"]
|
|
||||||
};
|
};
|
||||||
|
|
414
package.json
414
package.json
|
@ -1,210 +1,208 @@
|
||||||
{
|
{
|
||||||
"name": "bunny-admin-element",
|
"name": "bunny-admin-element",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"bunny-admin-element",
|
"bunny-admin-element",
|
||||||
"bunny-cli",
|
"bunny-cli",
|
||||||
"element-plus",
|
"element-plus",
|
||||||
"tailwindcss",
|
"tailwindcss",
|
||||||
"typescript",
|
"typescript",
|
||||||
"pinia",
|
"pinia",
|
||||||
"vue3",
|
"vue3",
|
||||||
"vite",
|
"vite",
|
||||||
"esm"
|
"esm"
|
||||||
],
|
],
|
||||||
"homepage": "https://gitee.com/BunnyBoss/bunny-admin-element-thin",
|
"homepage": "https://gitee.com/BunnyBoss/bunny-admin-element-thin",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitee.com/BunnyBoss/bunny-admin-element-thin"
|
"url": "https://gitee.com/BunnyBoss/bunny-admin-element-thin"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://gitee.com/BunnyBoss/bunny-admin-element-thin/issues"
|
"url": "https://gitee.com/BunnyBoss/bunny-admin-element-thin/issues"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Bunny0212",
|
"name": "Bunny0212",
|
||||||
"email": "1319900154@qq.com",
|
"email": "1319900154@qq.com",
|
||||||
"url": "https://github.com/xiaoxian521"
|
"url": "https://github.com/xiaoxian521"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
|
"dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
|
||||||
"serve": "pnpm vite",
|
"serve": "pnpm vite",
|
||||||
"start": "vite",
|
"start": "vite",
|
||||||
"build": "rimraf dist && NODE_OPTIONS=--max-old-space-size=8192 vite build && generate-version-file",
|
"build": "rimraf dist && NODE_OPTIONS=--max-old-space-size=8192 vite build && generate-version-file",
|
||||||
"build:staging": "rimraf dist && vite build --mode staging",
|
"build:staging": "rimraf dist && vite build --mode staging",
|
||||||
"report": "rimraf dist && vite build",
|
"report": "rimraf dist && vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"preview:build": "pnpm build && vite preview",
|
"preview:build": "pnpm build && vite preview",
|
||||||
"typecheck": "tsc --noEmit && vue-tsc --noEmit --skipLibCheck",
|
"typecheck": "tsc --noEmit && vue-tsc --noEmit --skipLibCheck",
|
||||||
"svgo": "svgo -f . -r",
|
"svgo": "svgo -f . -r",
|
||||||
"clean:cache": "rimraf .eslintcache && rimraf pnpm-lock.yaml && rimraf node_modules && pnpm store prune && pnpm install",
|
"clean:cache": "rimraf .eslintcache && rimraf pnpm-lock.yaml && rimraf node_modules && pnpm store prune && pnpm install",
|
||||||
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock,build}/**/*.{vue,js,ts,tsx}\" --fix",
|
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock,build}/**/*.{vue,js,ts,tsx}\" --fix",
|
||||||
"lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,scss,vue,html,md}\"",
|
"lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,scss,vue,html,md}\"",
|
||||||
"lint:stylelint": "stylelint --cache --fix \"**/*.{html,vue,css,scss}\" --cache-location node_modules/.cache/stylelint/",
|
"lint:stylelint": "stylelint --cache --fix \"**/*.{html,vue,css,scss}\" --cache-location node_modules/.cache/stylelint/",
|
||||||
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint",
|
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint",
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"preinstall": "npx only-allow pnpm",
|
"preinstall": "npx only-allow pnpm",
|
||||||
"commit": "git pull && git add -A && git-cz && git push"
|
"commit": "git pull && git add -A && git-cz && git push"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||||
"@howdyjs/mouse-menu": "^2.1.3",
|
"@howdyjs/mouse-menu": "^2.1.3",
|
||||||
"@infectoone/vue-ganttastic": "^2.3.2",
|
"@infectoone/vue-ganttastic": "^2.3.2",
|
||||||
"@logicflow/core": "^1.2.27",
|
"@logicflow/core": "^1.2.27",
|
||||||
"@logicflow/extension": "^1.2.27",
|
"@logicflow/extension": "^1.2.27",
|
||||||
"@pureadmin/descriptions": "^1.2.1",
|
"@pureadmin/descriptions": "^1.2.1",
|
||||||
"@pureadmin/table": "^3.1.2",
|
"@pureadmin/table": "^3.1.2",
|
||||||
"@pureadmin/utils": "^2.4.7",
|
"@pureadmin/utils": "^2.4.7",
|
||||||
"@vue-flow/background": "^1.3.0",
|
"@vue-flow/background": "^1.3.0",
|
||||||
"@vue-flow/core": "^1.33.6",
|
"@vue-flow/core": "^1.33.6",
|
||||||
"@vueuse/core": "^10.9.0",
|
"@vueuse/core": "^10.9.0",
|
||||||
"@vueuse/motion": "^2.1.0",
|
"@vueuse/motion": "^2.1.0",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
"@zxcvbn-ts/core": "^3.0.4",
|
"@zxcvbn-ts/core": "^3.0.4",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"china-area-data": "^5.0.1",
|
"china-area-data": "^5.0.1",
|
||||||
"cropperjs": "^1.6.2",
|
"commitlint": "^19.4.1",
|
||||||
"dayjs": "^1.11.11",
|
"cropperjs": "^1.6.2",
|
||||||
"echarts": "^5.5.0",
|
"dayjs": "^1.11.11",
|
||||||
"el-table-infinite-scroll": "^3.0.3",
|
"echarts": "^5.5.0",
|
||||||
"element-plus": "2.7.1",
|
"el-table-infinite-scroll": "^3.0.3",
|
||||||
"intro.js": "^7.2.0",
|
"element-plus": "2.7.1",
|
||||||
"js-cookie": "^3.0.5",
|
"intro.js": "^7.2.0",
|
||||||
"jsbarcode": "^3.11.6",
|
"js-cookie": "^3.0.5",
|
||||||
"localforage": "^1.10.0",
|
"jsbarcode": "^3.11.6",
|
||||||
"mint-filter": "^4.0.3",
|
"localforage": "^1.10.0",
|
||||||
"mitt": "^3.0.1",
|
"mint-filter": "^4.0.3",
|
||||||
"mqtt": "4.3.7",
|
"mitt": "^3.0.1",
|
||||||
"nprogress": "^0.2.0",
|
"mqtt": "4.3.7",
|
||||||
"path": "^0.12.7",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.1.7",
|
"path": "^0.12.7",
|
||||||
"pinia-plugin-persistedstate": "^3.2.1",
|
"pinia": "^2.1.7",
|
||||||
"pinyin-pro": "^3.20.4",
|
"pinia-plugin-persistedstate": "^3.2.1",
|
||||||
"plus-pro-components": "^0.1.1",
|
"pinyin-pro": "^3.20.4",
|
||||||
"qrcode": "^1.5.3",
|
"plus-pro-components": "^0.1.1",
|
||||||
"qs": "^6.12.1",
|
"qrcode": "^1.5.3",
|
||||||
"responsive-storage": "^2.2.0",
|
"qs": "^6.12.1",
|
||||||
"sortablejs": "^1.15.2",
|
"responsive-storage": "^2.2.0",
|
||||||
"swiper": "^11.1.1",
|
"sortablejs": "^1.15.2",
|
||||||
"terser": "^5.31.0",
|
"swiper": "^11.1.1",
|
||||||
"typeit": "^8.8.3",
|
"terser": "^5.31.0",
|
||||||
"v-contextmenu": "^3.2.0",
|
"typeit": "^8.8.3",
|
||||||
"v3-infinite-loading": "^1.3.1",
|
"v-contextmenu": "^3.2.0",
|
||||||
"version-rocket": "^1.7.1",
|
"v3-infinite-loading": "^1.3.1",
|
||||||
"vite-plugin-vue-inspector": "^5.1.3",
|
"version-rocket": "^1.7.1",
|
||||||
"vue": "^3.4.27",
|
"vite-plugin-vue-inspector": "^5.1.3",
|
||||||
"vue-i18n": "^9.13.1",
|
"vue": "^3.4.27",
|
||||||
"vue-json-pretty": "^2.4.0",
|
"vue-json-pretty": "^2.4.0",
|
||||||
"vue-pdf-embed": "^2.0.3",
|
"vue-pdf-embed": "^2.0.3",
|
||||||
"vue-router": "^4.3.2",
|
"vue-router": "^4.3.2",
|
||||||
"vue-tippy": "^6.4.1",
|
"vue-tippy": "^6.4.1",
|
||||||
"vue-types": "^5.1.2",
|
"vue-types": "^5.1.2",
|
||||||
"vue-virtual-scroller": "2.0.0-beta.8",
|
"vue-virtual-scroller": "2.0.0-beta.8",
|
||||||
"vue-waterfall-plugin-next": "^2.4.3",
|
"vue-waterfall-plugin-next": "^2.4.3",
|
||||||
"vue3-danmaku": "^1.6.0",
|
"vue3-danmaku": "^1.6.0",
|
||||||
"vue3-puzzle-vcode": "^1.1.7",
|
"vue3-puzzle-vcode": "^1.1.7",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0",
|
||||||
"vxe-table": "^4.6.9",
|
"vxe-table": "^4.6.18",
|
||||||
"wavesurfer.js": "^7.7.13",
|
"wavesurfer.js": "^7.7.13",
|
||||||
"xgplayer": "^3.0.17",
|
"xgplayer": "^3.0.17",
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^19.3.0",
|
"@commitlint/cli": "^19.3.0",
|
||||||
"@commitlint/config-conventional": "^19.2.2",
|
"@commitlint/config-conventional": "^19.2.2",
|
||||||
"@commitlint/types": "^19.0.3",
|
"@commitlint/types": "^19.0.3",
|
||||||
"@eslint/js": "^9.2.0",
|
"@eslint/js": "^9.2.0",
|
||||||
"@faker-js/faker": "^8.4.1",
|
"@faker-js/faker": "^8.4.1",
|
||||||
"@iconify-icons/ep": "^1.2.12",
|
"@iconify-icons/ep": "^1.2.12",
|
||||||
"@iconify-icons/ri": "^1.2.10",
|
"@iconify-icons/ri": "^1.2.10",
|
||||||
"@iconify/vue": "^4.1.2",
|
"@iconify/vue": "^4.1.2",
|
||||||
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
"@pureadmin/theme": "^3.2.0",
|
||||||
"@pureadmin/theme": "^3.2.0",
|
"@types/dagre": "^0.7.52",
|
||||||
"@types/dagre": "^0.7.52",
|
"@types/gradient-string": "^1.1.6",
|
||||||
"@types/gradient-string": "^1.1.6",
|
"@types/intro.js": "^5.1.5",
|
||||||
"@types/intro.js": "^5.1.5",
|
"@types/js-cookie": "^3.0.6",
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/node": "^20.12.11",
|
||||||
"@types/node": "^20.12.11",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/qrcode": "^1.5.5",
|
||||||
"@types/qrcode": "^1.5.5",
|
"@types/qs": "^6.9.15",
|
||||||
"@types/qs": "^6.9.15",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@types/sortablejs": "^1.15.8",
|
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
"@typescript-eslint/parser": "^7.8.0",
|
||||||
"@typescript-eslint/parser": "^7.8.0",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"autoprefixer": "^10.4.19",
|
||||||
"autoprefixer": "^10.4.19",
|
"boxen": "^7.1.1",
|
||||||
"boxen": "^7.1.1",
|
"commitizen": "^4.2.4",
|
||||||
"commitizen": "^4.2.4",
|
"cssnano": "^7.0.1",
|
||||||
"commitlint": "^17.0.1",
|
"cz-git": "^1.3.2",
|
||||||
"cssnano": "^7.0.1",
|
"dagre": "^0.8.5",
|
||||||
"cz-git": "^1.3.2",
|
"eslint": "^9.2.0",
|
||||||
"dagre": "^0.8.5",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint": "^9.2.0",
|
"eslint-define-config": "^2.1.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-define-config": "^2.1.0",
|
"eslint-plugin-vue": "^9.25.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"gradient-string": "^2.0.2",
|
||||||
"eslint-plugin-vue": "^9.25.0",
|
"husky": "^8.0.1",
|
||||||
"gradient-string": "^2.0.2",
|
"lint-staged": "^15.2.2",
|
||||||
"husky": "^8.0.1",
|
"postcss": "^8.4.38",
|
||||||
"lint-staged": "^15.2.2",
|
"postcss-html": "^1.7.0",
|
||||||
"postcss": "^8.4.38",
|
"postcss-import": "^16.1.0",
|
||||||
"postcss-html": "^1.7.0",
|
"postcss-scss": "^4.0.9",
|
||||||
"postcss-import": "^16.1.0",
|
"prettier": "^3.2.5",
|
||||||
"postcss-scss": "^4.0.9",
|
"rimraf": "^5.0.5",
|
||||||
"prettier": "^3.2.5",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"rimraf": "^5.0.5",
|
"sass": "^1.77.0",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"stylelint": "^16.5.0",
|
||||||
"sass": "^1.77.0",
|
"stylelint-config-recess-order": "^5.0.1",
|
||||||
"stylelint": "^16.5.0",
|
"stylelint-config-recommended-vue": "^1.5.0",
|
||||||
"stylelint-config-recess-order": "^5.0.1",
|
"stylelint-config-standard-scss": "^13.1.0",
|
||||||
"stylelint-config-recommended-vue": "^1.5.0",
|
"stylelint-prettier": "^5.0.0",
|
||||||
"stylelint-config-standard-scss": "^13.1.0",
|
"svgo": "^3.3.0",
|
||||||
"stylelint-prettier": "^5.0.0",
|
"tailwindcss": "^3.4.3",
|
||||||
"svgo": "^3.3.0",
|
"typescript": "^5.4.5",
|
||||||
"tailwindcss": "^3.4.3",
|
"vite": "^5.2.11",
|
||||||
"typescript": "^5.4.5",
|
"vite-plugin-cdn-import": "^0.3.5",
|
||||||
"vite": "^5.2.11",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-cdn-import": "^0.3.5",
|
"vite-plugin-fake-server": "^2.1.1",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-remove-console": "^2.2.0",
|
||||||
"vite-plugin-fake-server": "^2.1.1",
|
"vite-plugin-router-warn": "^1.0.0",
|
||||||
"vite-plugin-remove-console": "^2.2.0",
|
"vite-svg-loader": "^5.1.0",
|
||||||
"vite-plugin-router-warn": "^1.0.0",
|
"vue-eslint-parser": "^9.4.2",
|
||||||
"vite-svg-loader": "^5.1.0",
|
"vue-tsc": "^1.8.27"
|
||||||
"vue-eslint-parser": "^9.4.2",
|
},
|
||||||
"vue-tsc": "^1.8.27"
|
"engines": {
|
||||||
},
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0",
|
||||||
"engines": {
|
"pnpm": ">=9"
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0",
|
},
|
||||||
"pnpm": ">=9"
|
"pnpm": {
|
||||||
},
|
"allowedDeprecatedVersions": {
|
||||||
"pnpm": {
|
"are-we-there-yet": "*",
|
||||||
"allowedDeprecatedVersions": {
|
"sourcemap-codec": "*",
|
||||||
"are-we-there-yet": "*",
|
"domexception": "*",
|
||||||
"sourcemap-codec": "*",
|
"w3c-hr-time": "*",
|
||||||
"domexception": "*",
|
"inflight": "*",
|
||||||
"w3c-hr-time": "*",
|
"npmlog": "*",
|
||||||
"inflight": "*",
|
"rimraf": "*",
|
||||||
"npmlog": "*",
|
"stable": "*",
|
||||||
"rimraf": "*",
|
"gauge": "*",
|
||||||
"stable": "*",
|
"abab": "*",
|
||||||
"gauge": "*",
|
"glob": "*"
|
||||||
"abab": "*",
|
},
|
||||||
"glob": "*"
|
"peerDependencyRules": {
|
||||||
},
|
"allowedVersions": {
|
||||||
"peerDependencyRules": {
|
"eslint": "9"
|
||||||
"allowedVersions": {
|
}
|
||||||
"eslint": "9"
|
}
|
||||||
}
|
},
|
||||||
}
|
"config": {
|
||||||
},
|
"commitizen": {
|
||||||
"config": {
|
"path": "node_modules/cz-git"
|
||||||
"commitizen": {
|
}
|
||||||
"path": "node_modules/cz-git"
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
820
pnpm-lock.yaml
820
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
/** @type {import('postcss-load-config').Config} */
|
/** @type {import("postcss-load-config").Config} */
|
||||||
export default {
|
export default {
|
||||||
plugins: {
|
plugins: {
|
||||||
"postcss-import": {},
|
'postcss-import': {},
|
||||||
"tailwindcss/nesting": {},
|
'tailwindcss/nesting': {},
|
||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
autoprefixer: {},
|
autoprefixer: {},
|
||||||
...(process.env.NODE_ENV === "production" ? { cssnano: {} } : {})
|
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}),
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="main">
|
|
||||||
<pure-table
|
|
||||||
ref="tableRef"
|
|
||||||
:adaptiveConfig="{ offsetBottom: 108 }"
|
|
||||||
:columns="column"
|
|
||||||
:data="dataList"
|
|
||||||
:header-cell-style="cellHeaderStyle"
|
|
||||||
:loading="loading"
|
|
||||||
:size="size"
|
|
||||||
adaptive
|
|
||||||
align-whole="center"
|
|
||||||
border
|
|
||||||
row-key="id"
|
|
||||||
table-layout="auto"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { cellHeaderStyle } from "@/components/TableBar/utils/tableStyle";
|
|
||||||
import PureTable from "@pureadmin/table";
|
|
||||||
import type { PropType } from "vue";
|
|
||||||
|
|
||||||
// * 传入数据
|
|
||||||
defineProps({
|
|
||||||
// 表格数据
|
|
||||||
dataList: {
|
|
||||||
type: Array<any>,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
// 表格列字段
|
|
||||||
column: {
|
|
||||||
type: Array<any>,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
loading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: String as PropType<any>,
|
|
||||||
default: "default"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
|
@ -1,96 +1,80 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {
|
import { getCurrentInstance, nextTick, onMounted, PropType, ref, unref, watch } from 'vue';
|
||||||
getCurrentInstance,
|
import { rendTipProps } from '@/components/TableBar/utils/tableConfig';
|
||||||
nextTick,
|
import { cellHeaderStyle, getDropdownItemStyle, iconClass, topClass } from '@/components/TableBar/utils/tableStyle';
|
||||||
onMounted,
|
import PureTable from '@pureadmin/table';
|
||||||
PropType,
|
import { useRoute } from 'vue-router';
|
||||||
ref,
|
import RefreshIcon from '@/assets/table-bar/refresh.svg?component';
|
||||||
unref,
|
import CollapseIcon from '@/assets/table-bar/collapse.svg?component';
|
||||||
watch
|
import SettingIcon from '@/assets/table-bar/settings.svg?component';
|
||||||
} from "vue";
|
import { cloneDeep, getKeyList, isBoolean, isFunction } from '@pureadmin/utils';
|
||||||
import { rendTipProps } from "@/components/TableBar/utils/tableConfig";
|
import DragIcon from '@/assets/table-bar/drag.svg?component';
|
||||||
import {
|
import Sortable from 'sortablejs';
|
||||||
cellHeaderStyle,
|
import { DeleteFilled, EditPen } from '@element-plus/icons-vue';
|
||||||
getDropdownItemStyle,
|
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
|
||||||
iconClass,
|
import Refresh from '@iconify-icons/ep/refresh';
|
||||||
topClass
|
import { FormInstance } from 'element-plus';
|
||||||
} from "@/components/TableBar/utils/tableStyle";
|
|
||||||
import PureTable from "@pureadmin/table";
|
|
||||||
import { useRoute } from "vue-router";
|
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
import RefreshIcon from "@/assets/table-bar/refresh.svg?component";
|
|
||||||
import CollapseIcon from "@/assets/table-bar/collapse.svg?component";
|
|
||||||
import SettingIcon from "@/assets/table-bar/settings.svg?component";
|
|
||||||
import { cloneDeep, getKeyList, isBoolean, isFunction } from "@pureadmin/utils";
|
|
||||||
import DragIcon from "@/assets/table-bar/drag.svg?component";
|
|
||||||
import Sortable from "sortablejs";
|
|
||||||
import { $t } from "@/plugins/i18n";
|
|
||||||
import { DeleteFilled, EditPen } from "@element-plus/icons-vue";
|
|
||||||
import { useRenderIcon } from "@/components/CommonIcon/src/hooks";
|
|
||||||
import Refresh from "@iconify-icons/ep/refresh";
|
|
||||||
import { FormInstance } from "element-plus";
|
|
||||||
|
|
||||||
// * 传入数据
|
// * 传入数据
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 表格数据
|
// 表格数据
|
||||||
dataList: { type: Array<any>, default: [] },
|
dataList: { type: Array<any>, default: [] },
|
||||||
// 表格列字段
|
// 表格列字段
|
||||||
column: { type: Array as PropType<any>, default: () => [] },
|
column: { type: Array as PropType<any>, default: () => [] },
|
||||||
// 是否加载
|
// 是否加载
|
||||||
loading: { type: Boolean, default: false },
|
loading: { type: Boolean, default: false },
|
||||||
// 表格头部查询
|
// 表格头部查询
|
||||||
tableQueryFormVisible: { type: Boolean, default: true },
|
tableQueryFormVisible: { type: Boolean, default: true },
|
||||||
// 页面字体大小,small | default | large
|
// 页面字体大小,small | default | large
|
||||||
size: { type: String as PropType<any>, default: "default" },
|
size: { type: String as PropType<any>, default: 'default' },
|
||||||
// 分页器参数
|
// 分页器参数
|
||||||
pagination: { type: Object, default: Object },
|
pagination: { type: Object, default: Object },
|
||||||
// 选择行发生变化
|
// 选择行发生变化
|
||||||
handleSelectionChange: {
|
handleSelectionChange: {
|
||||||
type: Function as PropType<Function>,
|
type: Function as PropType<Function>,
|
||||||
default: () => {}
|
default: () => {},
|
||||||
},
|
},
|
||||||
// 分页大小变化
|
// 分页大小变化
|
||||||
handleSizeChange: {
|
onPageSizeChange: {
|
||||||
type: Function as PropType<Function>,
|
type: Function as PropType<Function>,
|
||||||
default: () => {}
|
default: () => {},
|
||||||
},
|
},
|
||||||
// 当前页变化
|
// 当前页变化
|
||||||
handleCurrentChange: {
|
onPageCurrentChange: {
|
||||||
type: Function as PropType<Function>,
|
type: Function as PropType<Function>,
|
||||||
default: () => {}
|
default: () => {},
|
||||||
},
|
},
|
||||||
// 表单参数
|
// 表单参数
|
||||||
form: {
|
form: {
|
||||||
type: Object as PropType<any>,
|
type: Object as PropType<any>,
|
||||||
default: Object
|
default: Object,
|
||||||
},
|
},
|
||||||
// 表格的key值
|
// 表格的key值
|
||||||
tableKey: {
|
tableKey: {
|
||||||
type: [String, Number] as PropType<string | number>,
|
type: [String, Number] as PropType<string | number>,
|
||||||
default: "0"
|
default: '0',
|
||||||
},
|
},
|
||||||
// 表格标题
|
// 表格标题
|
||||||
tableTitle: { type: String, default: "" },
|
tableTitle: { type: String, default: '' },
|
||||||
// 表格修改
|
// 表格修改
|
||||||
tableEdit: {
|
tableEdit: {
|
||||||
type: Function as PropType<Function>,
|
type: Function as PropType<Function>,
|
||||||
default: () => {}
|
default: () => {},
|
||||||
}, // 表格删除
|
}, // 表格删除
|
||||||
tableDelete: {
|
tableDelete: {
|
||||||
type: Function as PropType<Function>,
|
type: Function as PropType<Function>,
|
||||||
default: () => {}
|
default: () => {},
|
||||||
},
|
},
|
||||||
// 刷新时
|
// 刷新时
|
||||||
onReFresh: {
|
onReFresh: {
|
||||||
type: Function as PropType<Function>,
|
type: Function as PropType<Function>,
|
||||||
default: () => {}
|
default: () => {},
|
||||||
},
|
},
|
||||||
onSearch: { type: Function as PropType<any> },
|
onSearch: { type: Function as PropType<any> },
|
||||||
model: { type: Object as PropType<any> }
|
model: { type: Object as PropType<any> },
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["changeColumn"]);
|
const emit = defineEmits(['changeColumn']);
|
||||||
const { t, locale } = useI18n();
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
// 是否全选
|
// 是否全选
|
||||||
const checkAll = ref(true);
|
const checkAll = ref(true);
|
||||||
|
@ -100,16 +84,10 @@ const isIndeterminate = ref(false);
|
||||||
// 动态行
|
// 动态行
|
||||||
const dynamicColumns = ref(props.column);
|
const dynamicColumns = ref(props.column);
|
||||||
// 过滤是否选中的列
|
// 过滤是否选中的列
|
||||||
const filterColumns = cloneDeep(props.column).filter(column =>
|
const filterColumns = cloneDeep(props.column).filter(column => (isBoolean(column?.hide) ? !column.hide : !(isFunction(column?.hide) && column?.hide())));
|
||||||
isBoolean(column?.hide)
|
|
||||||
? !column.hide
|
|
||||||
: !(isFunction(column?.hide) && column?.hide())
|
|
||||||
);
|
|
||||||
// 选择当前列
|
// 选择当前列
|
||||||
const checkedColumns = ref(getKeyList(cloneDeep(filterColumns), "label"));
|
const checkedColumns = ref(getKeyList(cloneDeep(filterColumns), 'label'));
|
||||||
const checkColumnList = ref(
|
const checkColumnList = ref(getKeyList(cloneDeep(dynamicColumns.value), 'label'));
|
||||||
getKeyList(cloneDeep(dynamicColumns.value), "label")
|
|
||||||
);
|
|
||||||
const instance = getCurrentInstance()!;
|
const instance = getCurrentInstance()!;
|
||||||
const ruleFormRef = ref<FormInstance>();
|
const ruleFormRef = ref<FormInstance>();
|
||||||
|
|
||||||
|
@ -118,7 +96,7 @@ const ruleFormRef = ref<FormInstance>();
|
||||||
* @param value 修改样式大小 larger | default | small
|
* @param value 修改样式大小 larger | default | small
|
||||||
*/
|
*/
|
||||||
const handleTableSizeClick = (value: string) => {
|
const handleTableSizeClick = (value: string) => {
|
||||||
size.value = value;
|
size.value = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,11 +104,9 @@ const handleTableSizeClick = (value: string) => {
|
||||||
* @param val 是否全部显示
|
* @param val 是否全部显示
|
||||||
*/
|
*/
|
||||||
const handleCheckAllChange = (val: boolean) => {
|
const handleCheckAllChange = (val: boolean) => {
|
||||||
checkedColumns.value = val ? checkColumnList.value : [];
|
checkedColumns.value = val ? checkColumnList.value : [];
|
||||||
isIndeterminate.value = false;
|
isIndeterminate.value = false;
|
||||||
dynamicColumns.value.map(column =>
|
dynamicColumns.value.map(column => (val ? (column.hide = false) : (column.hide = true)));
|
||||||
val ? (column.hide = false) : (column.hide = true)
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,11 +114,10 @@ const handleCheckAllChange = (val: boolean) => {
|
||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
const handleCheckedColumnsChange = (value: string[]) => {
|
const handleCheckedColumnsChange = (value: string[]) => {
|
||||||
checkedColumns.value = value;
|
checkedColumns.value = value;
|
||||||
const checkedCount = value.length;
|
const checkedCount = value.length;
|
||||||
checkAll.value = checkedCount === checkColumnList.value.length;
|
checkAll.value = checkedCount === checkColumnList.value.length;
|
||||||
isIndeterminate.value =
|
isIndeterminate.value = checkedCount > 0 && checkedCount < checkColumnList.value.length;
|
||||||
checkedCount > 0 && checkedCount < checkColumnList.value.length;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,9 +125,7 @@ const handleCheckedColumnsChange = (value: string[]) => {
|
||||||
* @param label
|
* @param label
|
||||||
*/
|
*/
|
||||||
const handleCheckColumnListChange = (label: string) => {
|
const handleCheckColumnListChange = (label: string) => {
|
||||||
dynamicColumns.value.filter(item => item.label === label)[0].hide = !(
|
dynamicColumns.value.filter(item => item.label === label)[0].hide = !(event.target as any).checked;
|
||||||
event.target as any
|
|
||||||
).checked;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -160,72 +133,67 @@ const handleCheckColumnListChange = (label: string) => {
|
||||||
* @param label
|
* @param label
|
||||||
*/
|
*/
|
||||||
const isFixedColumn = (label: string) => {
|
const isFixedColumn = (label: string) => {
|
||||||
return dynamicColumns.value.filter(item => item.label === label)[0].fixed;
|
return dynamicColumns.value.filter(item => item.label === label)[0].fixed;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 重置自定义表格列字段
|
* * 重置自定义表格列字段
|
||||||
*/
|
*/
|
||||||
const onReset = async () => {
|
const onReset = async () => {
|
||||||
// 重置列表值
|
// 重置列表值
|
||||||
const list = [];
|
const list = [];
|
||||||
// 全选按钮设为true
|
// 全选按钮设为true
|
||||||
checkAll.value = true;
|
checkAll.value = true;
|
||||||
isIndeterminate.value = false;
|
isIndeterminate.value = false;
|
||||||
// 当前选中的列
|
// 当前选中的列
|
||||||
checkedColumns.value = getKeyList(cloneDeep(filterColumns), "label");
|
checkedColumns.value = getKeyList(cloneDeep(filterColumns), 'label');
|
||||||
// ? 重新赋值,拖拽排序不会改变原有值,响应式数据的特性 直接对 ref 或 reactive 创建的变量进行赋值可能不会触发视图的更新
|
// ? 重新赋值,拖拽排序不会改变原有值,响应式数据的特性 直接对 ref 或 reactive 创建的变量进行赋值可能不会触发视图的更新
|
||||||
// ? Proxy 来追踪属性的访问和修改,使用异步方式确保正确更新视图
|
// ? Proxy 来追踪属性的访问和修改,使用异步方式确保正确更新视图
|
||||||
checkColumnList.value = [];
|
checkColumnList.value = [];
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
checkColumnList.value = getKeyList(filterColumns, "label");
|
checkColumnList.value = getKeyList(filterColumns, 'label');
|
||||||
});
|
});
|
||||||
|
|
||||||
// checkedColumns 是原有顺序,根据这个顺序重新得到list
|
// checkedColumns 是原有顺序,根据这个顺序重新得到list
|
||||||
checkedColumns.value.forEach(item => {
|
checkedColumns.value.forEach(item => {
|
||||||
dynamicColumns.value.forEach(column => {
|
dynamicColumns.value.forEach(column => {
|
||||||
if (column.label == item) {
|
if (column.label == item) {
|
||||||
list.push(column);
|
list.push(column);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
emit("changeColumn", list);
|
emit('changeColumn', list);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 列展示拖拽排序 */
|
/** 列展示拖拽排序 */
|
||||||
const rowDrop = (event: any) => {
|
const rowDrop = (event: any) => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const wrapper: HTMLElement = (
|
const wrapper: HTMLElement = (instance?.proxy?.$refs[`GroupRef${unref(props.tableKey)}`] as any).$el.firstElementChild;
|
||||||
instance?.proxy?.$refs[`GroupRef${unref(props.tableKey)}`] as any
|
Sortable.create(wrapper, {
|
||||||
).$el.firstElementChild;
|
animation: 300,
|
||||||
Sortable.create(wrapper, {
|
handle: '.drag-btn',
|
||||||
animation: 300,
|
onEnd: ({ newIndex, oldIndex, item }) => {
|
||||||
handle: ".drag-btn",
|
const targetThElem = item;
|
||||||
onEnd: ({ newIndex, oldIndex, item }) => {
|
const wrapperElem = targetThElem.parentNode as HTMLElement;
|
||||||
const targetThElem = item;
|
const oldColumn = dynamicColumns.value[oldIndex];
|
||||||
const wrapperElem = targetThElem.parentNode as HTMLElement;
|
const newColumn = dynamicColumns.value[newIndex];
|
||||||
const oldColumn = dynamicColumns.value[oldIndex];
|
if (oldColumn?.fixed || newColumn?.fixed) {
|
||||||
const newColumn = dynamicColumns.value[newIndex];
|
// 当前列存在fixed属性 则不可拖拽
|
||||||
if (oldColumn?.fixed || newColumn?.fixed) {
|
const oldThElem = wrapperElem.children[oldIndex] as HTMLElement;
|
||||||
// 当前列存在fixed属性 则不可拖拽
|
if (newIndex > oldIndex) {
|
||||||
const oldThElem = wrapperElem.children[oldIndex] as HTMLElement;
|
wrapperElem.insertBefore(targetThElem, oldThElem);
|
||||||
if (newIndex > oldIndex) {
|
} else {
|
||||||
wrapperElem.insertBefore(targetThElem, oldThElem);
|
wrapperElem.insertBefore(targetThElem, oldThElem ? oldThElem.nextElementSibling : oldThElem);
|
||||||
} else {
|
}
|
||||||
wrapperElem.insertBefore(
|
return;
|
||||||
targetThElem,
|
}
|
||||||
oldThElem ? oldThElem.nextElementSibling : oldThElem
|
const currentRow = dynamicColumns.value.splice(oldIndex, 1)[0];
|
||||||
);
|
dynamicColumns.value.splice(newIndex, 0, currentRow);
|
||||||
}
|
emit('changeColumn', dynamicColumns.value);
|
||||||
return;
|
},
|
||||||
}
|
});
|
||||||
const currentRow = dynamicColumns.value.splice(oldIndex, 1)[0];
|
}).then();
|
||||||
dynamicColumns.value.splice(newIndex, 0, currentRow);
|
|
||||||
emit("changeColumn", dynamicColumns.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).then();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -233,234 +201,141 @@ const rowDrop = (event: any) => {
|
||||||
* @param formEl
|
* @param formEl
|
||||||
*/
|
*/
|
||||||
const resetForm = (formEl: FormInstance | undefined) => {
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
formEl.resetFields();
|
formEl.resetFields();
|
||||||
props.onSearch();
|
props.onSearch();
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
watch([() => props.column], () => {
|
watch([() => props.column], () => {
|
||||||
dynamicColumns.value = props.column;
|
dynamicColumns.value = props.column;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<!-- 表单设置,外加插槽 -->
|
<!-- 表单设置,外加插槽 -->
|
||||||
<el-form
|
<el-form v-show="tableQueryFormVisible" ref="ruleFormRef" :inline="true" :model="model" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto" @submit="onSearch">
|
||||||
v-show="tableQueryFormVisible"
|
<slot name="tableForm" />
|
||||||
ref="ruleFormRef"
|
<el-form-item>
|
||||||
:inline="true"
|
<el-button :icon="useRenderIcon('ri:search-line')" :loading="loading" type="primary" @click="onSearch"> 搜索 </el-button>
|
||||||
:model="model"
|
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(ruleFormRef)"> 重置</el-button>
|
||||||
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"
|
</el-form-item>
|
||||||
@submit="onSearch"
|
</el-form>
|
||||||
>
|
|
||||||
<slot name="tableForm" />
|
|
||||||
<el-form-item>
|
|
||||||
<el-button
|
|
||||||
:icon="useRenderIcon('ri:search-line')"
|
|
||||||
:loading="loading"
|
|
||||||
type="primary"
|
|
||||||
@click="onSearch"
|
|
||||||
>
|
|
||||||
{{ $t("buttons.search") }}
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
:icon="useRenderIcon(Refresh)"
|
|
||||||
@click="resetForm(ruleFormRef)"
|
|
||||||
>
|
|
||||||
{{ $t("buttons.rest") }}</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<!-- 表格头部设置 -->
|
<!-- 表格头部设置 -->
|
||||||
<div class="w-[99/100] mt-2 px-2 pb-2 bg-bg_color">
|
<div class="w-[99/100] mt-2 px-2 pb-2 bg-bg_color">
|
||||||
<div class="flex justify-between w-full h-[60px] p-4">
|
<div class="flex justify-between w-full h-[60px] p-4">
|
||||||
<!-- 自定义左边头部内容 -->
|
<!-- 自定义左边头部内容 -->
|
||||||
<slot name="tableTitle">
|
<slot name="tableTitle">
|
||||||
<p class="font-bold truncate">
|
<p class="font-bold truncate">
|
||||||
{{ tableTitle ? tableTitle : t(route.meta.title) }}
|
{{ tableTitle ? tableTitle : route.meta.title }}
|
||||||
</p>
|
</p>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
||||||
<!-- 自定义表格操作内容 -->
|
<!-- 自定义表格操作内容 -->
|
||||||
<slot name="tableOperation">
|
<slot name="tableOperation">
|
||||||
<div class="flex items-center justify-around">
|
<div class="flex items-center justify-around">
|
||||||
<!-- 插槽内容 -->
|
<!-- 插槽内容 -->
|
||||||
<div class="mr-4">
|
<div class="mr-4">
|
||||||
<slot name="tableButtons" />
|
<slot name="tableButtons" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格刷新按钮 -->
|
<!-- 表格刷新按钮 -->
|
||||||
<RefreshIcon
|
<RefreshIcon v-tippy="rendTipProps('刷新')" :class="`w-[16px] ${iconClass()}} ${loading ? 'animate-spin' : ''}`" @click="onReFresh" />
|
||||||
v-tippy="rendTipProps('刷新')"
|
<el-divider direction="vertical" />
|
||||||
:class="`w-[16px] ${iconClass()}} ${loading ? 'animate-spin' : ''}`"
|
|
||||||
@click="onReFresh"
|
|
||||||
/>
|
|
||||||
<el-divider direction="vertical" />
|
|
||||||
|
|
||||||
<!-- 选择表格大小 -->
|
<!-- 选择表格大小 -->
|
||||||
<el-dropdown trigger="click">
|
<el-dropdown trigger="click">
|
||||||
<CollapseIcon :class="`w-[16px] ${iconClass()}`" />
|
<CollapseIcon :class="`w-[16px] ${iconClass()}`" />
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu class="translation">
|
<el-dropdown-menu class="translation">
|
||||||
<el-dropdown-item
|
<el-dropdown-item :style="getDropdownItemStyle(size, 'large')" @click="handleTableSizeClick('large')"> 大 </el-dropdown-item>
|
||||||
:style="getDropdownItemStyle(size, 'large')"
|
<el-dropdown-item :style="getDropdownItemStyle(size, 'default')" @click="handleTableSizeClick('default')"> 默认 </el-dropdown-item>
|
||||||
@click="handleTableSizeClick('large')"
|
<el-dropdown-item :style="getDropdownItemStyle(size, 'small')" @click="handleTableSizeClick('small')"> 小 </el-dropdown-item>
|
||||||
>
|
</el-dropdown-menu>
|
||||||
{{ $t("style.larger") }}
|
</template>
|
||||||
</el-dropdown-item>
|
</el-dropdown>
|
||||||
<el-dropdown-item
|
<el-divider direction="vertical" />
|
||||||
:style="getDropdownItemStyle(size, 'default')"
|
|
||||||
@click="handleTableSizeClick('default')"
|
|
||||||
>
|
|
||||||
{{ t("style.default") }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
:style="getDropdownItemStyle(size, 'small')"
|
|
||||||
@click="handleTableSizeClick('small')"
|
|
||||||
>
|
|
||||||
{{ t("style.small") }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
<el-divider direction="vertical" />
|
|
||||||
|
|
||||||
<!-- 表格列设置 -->
|
<!-- 表格列设置 -->
|
||||||
<el-popover
|
<el-popover :popper-style="{ padding: 0 }" placement="bottom-start" trigger="click" width="200">
|
||||||
:popper-style="{ padding: 0 }"
|
<template #reference>
|
||||||
placement="bottom-start"
|
<SettingIcon v-tippy="rendTipProps('列设置')" :class="`w-[16px] ${iconClass()}`" />
|
||||||
trigger="click"
|
</template>
|
||||||
width="200"
|
|
||||||
>
|
|
||||||
<template #reference>
|
|
||||||
<SettingIcon
|
|
||||||
v-tippy="rendTipProps('列设置')"
|
|
||||||
:class="`w-[16px] ${iconClass()}`"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div :class="topClass()">
|
<div :class="topClass()">
|
||||||
<el-checkbox
|
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" class="!-mr-1" label="列展示" @change="handleCheckAllChange" />
|
||||||
v-model="checkAll"
|
<el-button link type="primary" @click="onReset"> 重置</el-button>
|
||||||
:indeterminate="isIndeterminate"
|
</div>
|
||||||
class="!-mr-1"
|
|
||||||
label="列展示"
|
|
||||||
@change="handleCheckAllChange"
|
|
||||||
/>
|
|
||||||
<el-button link type="primary" @click="onReset">
|
|
||||||
{{ t("buttons.rest") }}</el-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pt-[6px] pl-[11px]">
|
<div class="pt-[6px] pl-[11px]">
|
||||||
<el-scrollbar max-height="36vh">
|
<el-scrollbar max-height="36vh">
|
||||||
<el-checkbox-group
|
<el-checkbox-group :ref="`GroupRef${unref(props.tableKey)}`" :modelValue="checkedColumns" @change="handleCheckedColumnsChange">
|
||||||
:ref="`GroupRef${unref(props.tableKey)}`"
|
<el-space :alignment="'flex-start'" :size="0" direction="vertical">
|
||||||
:modelValue="checkedColumns"
|
<div v-for="(item, index) in checkColumnList" :key="index" class="flex items-center">
|
||||||
@change="handleCheckedColumnsChange"
|
<DragIcon :class="`drag-btn w-[16px] mr-2 ${isFixedColumn(item) ? '!cursor-no-drop' : '!cursor-grab'}`" @mouseenter.prevent="rowDrop" />
|
||||||
>
|
<el-checkbox :key="index" :label="item" :value="item" @change="handleCheckColumnListChange(item)">
|
||||||
<el-space
|
<span :title="item" class="inline-block w-[120px] truncate hover:text-text_color_primary">
|
||||||
:alignment="'flex-start'"
|
{{ item }}
|
||||||
:size="0"
|
</span>
|
||||||
direction="vertical"
|
</el-checkbox>
|
||||||
>
|
</div>
|
||||||
<div
|
</el-space>
|
||||||
v-for="(item, index) in checkColumnList"
|
</el-checkbox-group>
|
||||||
:key="index"
|
</el-scrollbar>
|
||||||
class="flex items-center"
|
</div>
|
||||||
>
|
</el-popover>
|
||||||
<DragIcon
|
</div>
|
||||||
:class="`drag-btn w-[16px] mr-2 ${isFixedColumn(item) ? '!cursor-no-drop' : '!cursor-grab'}`"
|
</slot>
|
||||||
@mouseenter.prevent="rowDrop"
|
</div>
|
||||||
/>
|
<slot name="tableSelect" />
|
||||||
<el-checkbox
|
<pure-table
|
||||||
:key="index"
|
ref="tableRef"
|
||||||
:label="item"
|
:adaptiveConfig="{ offsetBottom: 108 }"
|
||||||
:value="item"
|
:columns="column"
|
||||||
@change="handleCheckColumnListChange(item)"
|
:data="dataList"
|
||||||
>
|
:header-cell-style="cellHeaderStyle"
|
||||||
<span
|
:loading="loading"
|
||||||
:title="item"
|
:on-page-current-change="onPageCurrentChange"
|
||||||
class="inline-block w-[120px] truncate hover:text-text_color_primary"
|
:on-page-size-change="onPageSizeChange"
|
||||||
>
|
:pagination="pagination"
|
||||||
{{ item }}
|
:paginationSmall="size === 'small'"
|
||||||
</span>
|
:size="size"
|
||||||
</el-checkbox>
|
adaptive
|
||||||
</div>
|
align-whole="center"
|
||||||
</el-space>
|
border
|
||||||
</el-checkbox-group>
|
row-key="id"
|
||||||
</el-scrollbar>
|
stripe
|
||||||
</div>
|
table-layout="fixed"
|
||||||
</el-popover>
|
v-bind="$attrs"
|
||||||
</div>
|
@selection-change="handleSelectionChange"
|
||||||
</slot>
|
>
|
||||||
</div>
|
<template v-for="item in column" :key="item.prop" v-slot:[item.slot]="scope" v-bind="item">
|
||||||
<slot name="tableSelect" />
|
<slot :name="item.slot" v-bind="scope" />
|
||||||
<pure-table
|
<slot v-if="item.slot === 'operation'" name="operation">
|
||||||
ref="tableRef"
|
<el-button :icon="EditPen" link type="warning" @click="tableEdit(scope)">修改</el-button>
|
||||||
:adaptiveConfig="{ offsetBottom: 108 }"
|
<el-popconfirm title="是否确认删除" @confirm="tableDelete(scope)">
|
||||||
:columns="column"
|
<template #reference>
|
||||||
:data="dataList"
|
<el-button :icon="DeleteFilled" link type="danger">删除</el-button>
|
||||||
:header-cell-style="cellHeaderStyle"
|
</template>
|
||||||
:loading="loading"
|
</el-popconfirm>
|
||||||
:pagination="pagination"
|
</slot>
|
||||||
:paginationSmall="size === 'small'"
|
</template>
|
||||||
:size="size"
|
</pure-table>
|
||||||
adaptive
|
</div>
|
||||||
align-whole="center"
|
</div>
|
||||||
border
|
|
||||||
row-key="id"
|
|
||||||
stripe
|
|
||||||
table-layout="fixed"
|
|
||||||
v-bind="$attrs"
|
|
||||||
@page-size-change="handleSizeChange"
|
|
||||||
@page-current-change="handleCurrentChange"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
>
|
|
||||||
<template
|
|
||||||
v-for="item in column"
|
|
||||||
:key="item.prop"
|
|
||||||
v-slot:[item.slot]="scope"
|
|
||||||
v-bind="item"
|
|
||||||
>
|
|
||||||
<slot :name="item.slot" v-bind="scope" />
|
|
||||||
<slot v-if="item.slot === 'operation'" name="operation">
|
|
||||||
<el-button
|
|
||||||
:icon="EditPen"
|
|
||||||
link
|
|
||||||
type="warning"
|
|
||||||
@click="tableEdit(scope)"
|
|
||||||
>修改</el-button
|
|
||||||
>
|
|
||||||
<el-popconfirm
|
|
||||||
:title="t('table.popConfirmTitle')"
|
|
||||||
@confirm="tableDelete(scope)"
|
|
||||||
>
|
|
||||||
<template #reference>
|
|
||||||
<el-button :icon="DeleteFilled" link type="danger"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</el-popconfirm>
|
|
||||||
</slot>
|
|
||||||
</template>
|
|
||||||
</pure-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.el-dropdown-menu__item i) {
|
:deep(.el-dropdown-menu__item i) {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-form {
|
.search-form {
|
||||||
:deep(.el-form-item) {
|
:deep(.el-form-item) {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="main mt-2 p-2 bg-bg_color">
|
|
||||||
<pure-table
|
|
||||||
ref="tableRef"
|
|
||||||
:adaptiveConfig="{ offsetBottom: 108 }"
|
|
||||||
:columns="column"
|
|
||||||
:data="dataList"
|
|
||||||
:header-cell-style="cellHeaderStyle"
|
|
||||||
:loading="loading"
|
|
||||||
:pagination="pagination"
|
|
||||||
:paginationSmall="size === 'small'"
|
|
||||||
:size="size"
|
|
||||||
adaptive
|
|
||||||
align-whole="center"
|
|
||||||
border
|
|
||||||
row-key="id"
|
|
||||||
table-layout="auto"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
@page-size-change="handleSizeChange"
|
|
||||||
@page-current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { cellHeaderStyle } from "@/components/TableBar/utils/tableStyle";
|
|
||||||
import PureTable from "@pureadmin/table";
|
|
||||||
import type { PropType } from "vue";
|
|
||||||
|
|
||||||
// * 传入数据
|
|
||||||
defineProps({
|
|
||||||
// 表格数据
|
|
||||||
dataList: {
|
|
||||||
type: Array<any>,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
// 表格列字段
|
|
||||||
column: {
|
|
||||||
type: Array<any>,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
// 是否加载
|
|
||||||
loading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 页面字体大小,small | default | large
|
|
||||||
size: {
|
|
||||||
type: String as PropType<any>,
|
|
||||||
default: "default"
|
|
||||||
},
|
|
||||||
// 分页器参数
|
|
||||||
pagination: {
|
|
||||||
type: Object,
|
|
||||||
default: Object
|
|
||||||
},
|
|
||||||
// 一页大小变化
|
|
||||||
handleSelectionChange: {
|
|
||||||
type: Function as PropType<Function>,
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
// 分页大小变化
|
|
||||||
handleSizeChange: {
|
|
||||||
type: Function as PropType<Function>,
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
// 当前页变化
|
|
||||||
handleCurrentChange: {
|
|
||||||
type: Function as PropType<Function>,
|
|
||||||
default: () => {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
|
@ -1,105 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="main">
|
|
||||||
<el-form
|
|
||||||
ref="formRef"
|
|
||||||
:inline="true"
|
|
||||||
:model="form"
|
|
||||||
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"
|
|
||||||
>
|
|
||||||
<slot name="tableForm" />
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<div class="mt-2 p-2 bg-bg_color">
|
|
||||||
<pure-table
|
|
||||||
ref="tableRef"
|
|
||||||
:adaptiveConfig="{ offsetBottom: 108 }"
|
|
||||||
:columns="column"
|
|
||||||
:data="dataList"
|
|
||||||
:header-cell-style="cellHeaderStyle"
|
|
||||||
:loading="loading"
|
|
||||||
:pagination="pagination"
|
|
||||||
:paginationSmall="size === 'small'"
|
|
||||||
:size="size"
|
|
||||||
adaptive
|
|
||||||
align-whole="center"
|
|
||||||
border
|
|
||||||
row-key="id"
|
|
||||||
table-layout="auto"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
@page-size-change="handleSizeChange"
|
|
||||||
@page-current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from "vue";
|
|
||||||
import { cellHeaderStyle } from "@/components/TableBar/utils/tableStyle";
|
|
||||||
import PureTable from "@pureadmin/table";
|
|
||||||
|
|
||||||
// * 传入数据
|
|
||||||
defineProps({
|
|
||||||
// 表格数据
|
|
||||||
dataList: {
|
|
||||||
type: Array<any>,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
// 表格列字段
|
|
||||||
column: {
|
|
||||||
type: Array<any>,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
// 是否加载
|
|
||||||
loading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 页面字体大小,small | default | large
|
|
||||||
size: {
|
|
||||||
type: String as PropType<any>,
|
|
||||||
default: "default"
|
|
||||||
},
|
|
||||||
// 分页器参数
|
|
||||||
pagination: {
|
|
||||||
type: Object,
|
|
||||||
default: Object
|
|
||||||
},
|
|
||||||
// 一页大小变化
|
|
||||||
handleSelectionChange: {
|
|
||||||
type: Function as PropType<Function>,
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
// 分页大小变化
|
|
||||||
handleSizeChange: {
|
|
||||||
type: Function as PropType<Function>,
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
// 当前页变化
|
|
||||||
handleCurrentChange: {
|
|
||||||
type: Function as PropType<Function>,
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
// 表单参数
|
|
||||||
form: {
|
|
||||||
type: Object as PropType<any>,
|
|
||||||
default: Object
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
:deep(.el-dropdown-menu__item i) {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-content {
|
|
||||||
margin: 24px 24px 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-form {
|
|
||||||
:deep(.el-form-item) {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, PropType, ref } from 'vue';
|
||||||
|
import { rendTipProps } from '@/components/TableBar/utils/tableConfig';
|
||||||
|
import { getDropdownItemStyle, iconClass } from '@/components/TableBar/utils/tableStyle';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import RefreshIcon from '@/assets/table-bar/refresh.svg?component';
|
||||||
|
import CollapseIcon from '@/assets/table-bar/collapse.svg?component';
|
||||||
|
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
|
||||||
|
import Refresh from '@iconify-icons/ep/refresh';
|
||||||
|
import { FormInstance } from 'element-plus';
|
||||||
|
import { Pagination } from '../../../../types/pagination/pagination';
|
||||||
|
import { VxeTableInstance, VxeToolbarInstance } from 'vxe-table';
|
||||||
|
import { pageSizes } from '@/enum/baseConstant';
|
||||||
|
|
||||||
|
// * 传入数据
|
||||||
|
const props = defineProps({
|
||||||
|
// 表格数据
|
||||||
|
dataList: { type: Array<any>, default: [] },
|
||||||
|
// 表格列字段
|
||||||
|
column: { type: Array as PropType<any>, default: () => [] },
|
||||||
|
// 是否加载
|
||||||
|
loading: { type: Boolean, default: false },
|
||||||
|
// 表格头部查询
|
||||||
|
tableQueryFormVisible: { type: Boolean, default: true },
|
||||||
|
// 页面字体大小,medium | small | mini
|
||||||
|
size: { type: String as PropType<any>, default: 'medium' },
|
||||||
|
// 分页器参数
|
||||||
|
pagination: { type: Object as PropType<Pagination>, default: Object },
|
||||||
|
// 当前页变化
|
||||||
|
onPageChange: {
|
||||||
|
type: Function as PropType<any>,
|
||||||
|
},
|
||||||
|
// 表单参数
|
||||||
|
form: {
|
||||||
|
type: Object as PropType<any>,
|
||||||
|
default: Object,
|
||||||
|
},
|
||||||
|
// 表格标题
|
||||||
|
tableTitle: { type: String, default: '' },
|
||||||
|
// 表格修改
|
||||||
|
onTableEdit: {
|
||||||
|
type: Function as PropType<Function>,
|
||||||
|
default: () => {},
|
||||||
|
}, // 表格删除
|
||||||
|
onTableDelete: {
|
||||||
|
type: Function as PropType<Function>,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
// 刷新时
|
||||||
|
onReFresh: {
|
||||||
|
type: Function as PropType<any>,
|
||||||
|
},
|
||||||
|
onSearch: { type: Function as PropType<any> },
|
||||||
|
});
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
// 表格样式大小
|
||||||
|
const size = ref(props.size);
|
||||||
|
const toolbarRef = ref<VxeToolbarInstance>();
|
||||||
|
const tableRef = ref<VxeTableInstance>();
|
||||||
|
const ruleFormRef = ref<FormInstance>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 修改表格样式大小
|
||||||
|
* @param value 修改样式大小 medium | small | mini
|
||||||
|
*/
|
||||||
|
const handleTableSizeClick = (value: string) => {
|
||||||
|
size.value = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置表单
|
||||||
|
* @param formEl
|
||||||
|
*/
|
||||||
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
props.onSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const $table = tableRef.value;
|
||||||
|
const $toolbarRef = toolbarRef.value;
|
||||||
|
if ($table && $toolbarRef) {
|
||||||
|
$table.connect($toolbarRef);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="main">
|
||||||
|
<!-- 表单设置,外加插槽 -->
|
||||||
|
<el-form v-show="tableQueryFormVisible" ref="ruleFormRef" :inline="true" :model="form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto" @submit="onSearch">
|
||||||
|
<slot name="tableForm" />
|
||||||
|
<el-form-item>
|
||||||
|
<el-button :icon="useRenderIcon('ri:search-line')" :loading="loading" type="primary" @click="onSearch"> 搜索 </el-button>
|
||||||
|
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(ruleFormRef)"> 重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 表格头部设置 -->
|
||||||
|
<div class="w-[99/100] mt-2 px-2 pb-2 bg-bg_color">
|
||||||
|
<div class="flex justify-between w-full h-[60px] p-4">
|
||||||
|
<!-- 自定义左边头部内容 -->
|
||||||
|
<slot name="tableTitle">
|
||||||
|
<p class="font-bold truncate">
|
||||||
|
{{ tableTitle ? tableTitle : route.meta.title }}
|
||||||
|
</p>
|
||||||
|
</slot>
|
||||||
|
|
||||||
|
<!-- 自定义表格操作内容 -->
|
||||||
|
<slot name="tableOperation">
|
||||||
|
<div class="flex items-center justify-around">
|
||||||
|
<!-- 插槽内容 -->
|
||||||
|
<div class="mr-4">
|
||||||
|
<slot name="tableButtons" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 表格刷新按钮 -->
|
||||||
|
<RefreshIcon v-tippy="rendTipProps('刷新')" :class="`w-[16px] ${iconClass()}} ${loading ? 'animate-spin' : ''}`" @click="onReFresh" />
|
||||||
|
<el-divider direction="vertical" />
|
||||||
|
|
||||||
|
<!-- 选择表格大小 -->
|
||||||
|
<el-dropdown trigger="click">
|
||||||
|
<CollapseIcon :class="`w-[16px] ${iconClass()}`" />
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu class="translation">
|
||||||
|
<el-dropdown-item :style="getDropdownItemStyle(size, 'medium')" @click="handleTableSizeClick('medium')"> 大 </el-dropdown-item>
|
||||||
|
<el-dropdown-item :style="getDropdownItemStyle(size, 'small')" @click="handleTableSizeClick('small')"> 默认 </el-dropdown-item>
|
||||||
|
<el-dropdown-item :style="getDropdownItemStyle(size, 'mini')" @click="handleTableSizeClick('mini')"> 小 </el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
<el-divider direction="vertical" />
|
||||||
|
<vxe-toolbar ref="toolbarRef" custom export print />
|
||||||
|
<el-divider direction="vertical" />
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
<slot name="tableSelect" />
|
||||||
|
<!-- 表格 -->
|
||||||
|
<vxe-table
|
||||||
|
ref="tableRef"
|
||||||
|
:column-config="{ resizable: true }"
|
||||||
|
:custom-config="{}"
|
||||||
|
:data="dataList"
|
||||||
|
:export-config="{}"
|
||||||
|
:loading="loading"
|
||||||
|
:print-config="{}"
|
||||||
|
:row-config="{ isHover: true }"
|
||||||
|
:size="size"
|
||||||
|
:tooltip-config="{ enterable: true, showAll: true }"
|
||||||
|
:tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }"
|
||||||
|
align="center"
|
||||||
|
border
|
||||||
|
header-align="center"
|
||||||
|
round
|
||||||
|
show-overflow
|
||||||
|
stripe
|
||||||
|
>
|
||||||
|
<slot name="tableType">
|
||||||
|
<vxe-column title="序号" type="seq" width="70" />
|
||||||
|
</slot>
|
||||||
|
<vxe-column v-for="item in column" :key="item.prop" :field="item.prop" :title="item.label">
|
||||||
|
<template v-if="$slots[item.prop]" #default="scope">
|
||||||
|
<slot :name="item.prop" v-bind="scope" />
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
<template #empty>
|
||||||
|
<div>
|
||||||
|
<img alt="" src="https://pic2.zhimg.com/50/v2-f7031359103859e1ed38559715ef5f3f_hd.gif" />
|
||||||
|
<p>不用再看了,没有更多数据了!</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</vxe-table>
|
||||||
|
<vxe-pager
|
||||||
|
v-show="onPageChange !== undefined"
|
||||||
|
:background="true"
|
||||||
|
:current-page="pagination.currentPage"
|
||||||
|
:layouts="['Home', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'End', 'Sizes', 'FullJump', 'Total']"
|
||||||
|
:loading="loading"
|
||||||
|
:on-page-change="onPageChange"
|
||||||
|
:page-size="pagination.pageSize"
|
||||||
|
:page-sizes="pageSizes"
|
||||||
|
:pager-count="5"
|
||||||
|
:size="size"
|
||||||
|
:total="pagination.total"
|
||||||
|
border
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-dropdown-menu__item i) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-form {
|
||||||
|
:deep(.el-form-item) {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,30 +1,28 @@
|
||||||
import { computed } from "vue";
|
import { computed } from 'vue';
|
||||||
import { useEpThemeStoreHook } from "@/store/epTheme";
|
import { useEpThemeStoreHook } from '@/store/modules/epTheme';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 表格头部样式
|
* * 表格头部样式
|
||||||
*/
|
*/
|
||||||
export const cellHeaderStyle = () => ({
|
export const cellHeaderStyle = () => ({
|
||||||
background: "var(--el-fill-color-light)",
|
background: 'var(--el-fill-color-light)',
|
||||||
color: "var(--el-text-color-primary)"
|
color: 'var(--el-text-color-primary)',
|
||||||
});
|
});
|
||||||
|
|
||||||
// * icon 样式
|
// * icon 样式
|
||||||
export const iconClass = () =>
|
export const iconClass = () => 'text-black dark:text-white duration-100 hover:!text-primary cursor-pointer outline-none ';
|
||||||
"text-black dark:text-white duration-100 hover:!text-primary cursor-pointer outline-none ";
|
|
||||||
|
|
||||||
// * 顶部样式
|
// * 顶部样式
|
||||||
export const topClass = () =>
|
export const topClass = () => 'flex justify-between pt-[3px] px-[11px] border-b-[1px] border-solid border-[#dcdfe6] dark:border-[#303030]';
|
||||||
"flex justify-between pt-[3px] px-[11px] border-b-[1px] border-solid border-[#dcdfe6] dark:border-[#303030]";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 拖拽列样式
|
* * 拖拽列样式
|
||||||
*/
|
*/
|
||||||
export const getDropdownItemStyle = computed(() => {
|
export const getDropdownItemStyle = computed(() => {
|
||||||
return (size: string, s: string) => {
|
return (size: string, s: string) => {
|
||||||
return {
|
return {
|
||||||
background: s === size ? useEpThemeStoreHook().epThemeColor : "",
|
background: s === size ? useEpThemeStoreHook().epThemeColor : '',
|
||||||
color: s === size ? "#fff" : "var(--el-text-color-primary)"
|
color: s === size ? '#fff' : 'var(--el-text-color-primary)',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,52 +1,52 @@
|
||||||
import axios from "axios";
|
import axios from 'axios';
|
||||||
import type { App } from "vue";
|
import type { App } from 'vue';
|
||||||
|
|
||||||
let config: object = {};
|
let config: object = {};
|
||||||
const { VITE_PUBLIC_PATH } = import.meta.env;
|
const { VITE_PUBLIC_PATH } = import.meta.env;
|
||||||
|
|
||||||
const setConfig = (cfg?: unknown) => {
|
const setConfig = (cfg?: unknown) => {
|
||||||
config = Object.assign(config, cfg);
|
config = Object.assign(config, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getConfig = (key?: string): PlatformConfigs => {
|
const getConfig = (key?: string): PlatformConfigs => {
|
||||||
if (typeof key === "string") {
|
if (typeof key === 'string') {
|
||||||
const arr = key.split(".");
|
const arr = key.split('.');
|
||||||
if (arr && arr.length) {
|
if (arr && arr.length) {
|
||||||
let data = config;
|
let data = config;
|
||||||
arr.forEach(v => {
|
arr.forEach(v => {
|
||||||
if (data && typeof data[v] !== "undefined") {
|
if (data && typeof data[v] !== 'undefined') {
|
||||||
data = data[v];
|
data = data[v];
|
||||||
} else {
|
} else {
|
||||||
data = null;
|
data = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 获取项目动态全局配置 */
|
/** 获取项目动态全局配置 */
|
||||||
export const getPlatformConfig = async (app: App): Promise<undefined> => {
|
export const getPlatformConfig = async (app: App): Promise<undefined> => {
|
||||||
app.config.globalProperties.$config = getConfig();
|
app.config.globalProperties.$config = getConfig();
|
||||||
return axios({
|
return axios({
|
||||||
method: "get",
|
method: 'get',
|
||||||
url: `${VITE_PUBLIC_PATH}platform-config.json`
|
url: `${VITE_PUBLIC_PATH}platform-config.json`,
|
||||||
})
|
})
|
||||||
.then(({ data: config }) => {
|
.then(({ data: config }) => {
|
||||||
let $config = app.config.globalProperties.$config;
|
let $config = app.config.globalProperties.$config;
|
||||||
// 自动注入系统配置
|
// 自动注入系统配置
|
||||||
if (app && $config && typeof config === "object") {
|
if (app && $config && typeof config === 'object') {
|
||||||
$config = Object.assign($config, config);
|
$config = Object.assign($config, config);
|
||||||
app.config.globalProperties.$config = $config;
|
app.config.globalProperties.$config = $config;
|
||||||
// 设置全局配置
|
// 设置全局配置
|
||||||
setConfig($config);
|
setConfig($config);
|
||||||
}
|
}
|
||||||
return $config;
|
return $config;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
throw "请在public文件夹下添加platform-config.json配置文件";
|
throw '请在public文件夹下添加platform-config.json配置文件';
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 本地响应式存储的命名空间 */
|
/** 本地响应式存储的命名空间 */
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import type { Option } from '../../types/enum/options';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 是否默认
|
||||||
|
*/
|
||||||
|
export const isDefaultOptions: Option[] = [
|
||||||
|
{ value: true, label: '是' },
|
||||||
|
{ value: false, label: '否' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 是否显示
|
||||||
|
*/
|
||||||
|
export const isDefaultVisibleOptions: Option[] = [
|
||||||
|
{ value: true, label: '显示' },
|
||||||
|
{ value: false, label: '不显示' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 性别
|
||||||
|
*/
|
||||||
|
export const sexConstant: Option[] = [
|
||||||
|
{ value: 1, label: '男' },
|
||||||
|
{ value: 0, label: '女' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 分页默认数组个数
|
||||||
|
*/
|
||||||
|
export const pageSizes: number[] = [10, 30, 50, 100, 150, 200, 300];
|
|
@ -0,0 +1,29 @@
|
||||||
|
// ? 表单选项
|
||||||
|
import type { Option } from '../../types/enum/options';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 默认状态
|
||||||
|
*/
|
||||||
|
export const defaultStatus: Option[] = [
|
||||||
|
{ value: '', label: '' },
|
||||||
|
{ value: 1, label: '启用' },
|
||||||
|
{ value: 0, label: '禁用' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 是否错误
|
||||||
|
*/
|
||||||
|
export const isErrorStatus: Option[] = [
|
||||||
|
{ value: '', label: '' },
|
||||||
|
{ value: false, label: '未出错' },
|
||||||
|
{ value: true, label: '错误' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 默认状态
|
||||||
|
*/
|
||||||
|
export const statusConstant: Option[] = [
|
||||||
|
{ value: '', label: '' },
|
||||||
|
{ value: 1, label: '是' },
|
||||||
|
{ value: 0, label: '否' },
|
||||||
|
];
|
|
@ -0,0 +1,10 @@
|
||||||
|
import type { Option } from '../../../types/enum/options';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标选项
|
||||||
|
*/
|
||||||
|
export const faviconCategory: Option[] = [
|
||||||
|
{ value: '', label: '' },
|
||||||
|
{ value: 'web', label: 'web 前台' },
|
||||||
|
{ value: 'admin', label: 'admin 后台' },
|
||||||
|
];
|
|
@ -0,0 +1,21 @@
|
||||||
|
import type { Option } from '../../../types/enum/options';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 用户反馈
|
||||||
|
*/
|
||||||
|
export const feedback: Option[] = [
|
||||||
|
{ value: '', label: '' },
|
||||||
|
{ value: 1, label: '已处理' },
|
||||||
|
{ value: 0, label: '未处理' },
|
||||||
|
{ value: -1, label: '其它问题' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 反馈类型选择
|
||||||
|
*/
|
||||||
|
export const feedbackTypeOptions: Option[] = [
|
||||||
|
{ label: '优化建议', value: '优化建议' },
|
||||||
|
{ label: 'bug反馈', value: 'bug反馈' },
|
||||||
|
{ label: '新增功能建议', value: '新增功能建议' },
|
||||||
|
{ label: '其它', value: '其它' },
|
||||||
|
];
|
|
@ -0,0 +1,25 @@
|
||||||
|
import type { Option } from '../../../types/enum/options';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 布局方式
|
||||||
|
*/
|
||||||
|
export const layoutConstant: Option[] = [
|
||||||
|
{ value: 'ltr', label: '从左到右' },
|
||||||
|
{ value: 'rtl', label: '从右到左' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 文章显示模式
|
||||||
|
*/
|
||||||
|
export const articleModeConstant: Option[] = [
|
||||||
|
{ value: 'album', label: '相册模式' },
|
||||||
|
{ value: 'list', label: '列表模式' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 默认状态
|
||||||
|
*/
|
||||||
|
export const userStatus: Option[] = [
|
||||||
|
{ value: 0, label: '启用' },
|
||||||
|
{ value: 1, label: '禁用' },
|
||||||
|
];
|
88
src/main.ts
88
src/main.ts
|
@ -1,67 +1,67 @@
|
||||||
import App from "./App.vue";
|
import App from './App.vue';
|
||||||
import router from "./router";
|
import router from './router';
|
||||||
import { setupStore } from "@/store";
|
import { setupStore } from '@/store';
|
||||||
import { getPlatformConfig } from "./config";
|
import { getPlatformConfig } from './config';
|
||||||
import { MotionPlugin } from "@vueuse/motion";
|
import { MotionPlugin } from '@vueuse/motion';
|
||||||
// import { useEcharts } from "@/plugins/echarts";
|
// import { useEcharts } from "@/plugins/echarts";
|
||||||
import { createApp, type Directive } from "vue";
|
import { createApp, type Directive } from 'vue';
|
||||||
import { useElementPlus } from "@/plugins/elementPlus";
|
import { useElementPlus } from '@/plugins/elementPlus';
|
||||||
import { injectResponsiveStorage } from "@/utils/responsive";
|
import { injectResponsiveStorage } from '@/utils/responsive';
|
||||||
|
|
||||||
import Table from "@pureadmin/table";
|
import Table from '@pureadmin/table';
|
||||||
// import PureDescriptions from "@pureadmin/descriptions";
|
// import PureDescriptions from "@pureadmin/descriptions";
|
||||||
// 引入重置样式
|
// 引入重置样式
|
||||||
import "./style/reset.scss";
|
import './style/reset.scss';
|
||||||
// 导入公共样式
|
// 导入公共样式
|
||||||
import "./style/index.scss";
|
import './style/index.scss';
|
||||||
// 一定要在main.ts中导入tailwind.css,防止vite每次hmr都会请求src/style/index.scss整体css文件导致热更新慢的问题
|
// 一定要在main.ts中导入tailwind.css,防止vite每次hmr都会请求src/style/index.scss整体css文件导致热更新慢的问题
|
||||||
import "./style/tailwind.css";
|
import './style/tailwind.css';
|
||||||
import "element-plus/dist/index.css";
|
import 'element-plus/dist/index.css';
|
||||||
// 导入字体图标
|
// 导入字体图标
|
||||||
import "./assets/iconfont/iconfont.js";
|
import './assets/iconfont/iconfont.js';
|
||||||
import "./assets/iconfont/iconfont.css";
|
import './assets/iconfont/iconfont.css';
|
||||||
// 自定义指令
|
// 自定义指令
|
||||||
import * as directives from "@/directives";
|
import * as directives from '@/directives';
|
||||||
// 全局注册@iconify/vue图标库
|
// 全局注册@iconify/vue图标库
|
||||||
import {
|
import { FontIcon, IconifyIconOffline, IconifyIconOnline } from './components/CommonIcon';
|
||||||
FontIcon,
|
|
||||||
IconifyIconOffline,
|
|
||||||
IconifyIconOnline
|
|
||||||
} from "./components/CommonIcon";
|
|
||||||
// 全局注册按钮级别权限组件
|
// 全局注册按钮级别权限组件
|
||||||
import { Auth } from "@/components/Auth";
|
import { Auth } from '@/components/Auth';
|
||||||
import { Perms } from "@/components/Perms";
|
import { Perms } from '@/components/Perms';
|
||||||
// 全局注册vue-tippy
|
// 全局注册vue-tippy
|
||||||
import "tippy.js/dist/tippy.css";
|
import 'tippy.js/dist/tippy.css';
|
||||||
import "tippy.js/themes/light.css";
|
import 'tippy.js/themes/light.css';
|
||||||
import VueTippy from "vue-tippy";
|
import VueTippy from 'vue-tippy';
|
||||||
import { useEcharts } from "@/plugins/echarts";
|
import { useEcharts } from '@/plugins/echarts';
|
||||||
|
// 完整导入 表格库
|
||||||
|
import VxeUITable from 'vxe-table';
|
||||||
|
import 'vxe-table/lib/style.css';
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
Object.keys(directives).forEach(key => {
|
Object.keys(directives).forEach(key => {
|
||||||
app.directive(key, (directives as { [key: string]: Directive })[key]);
|
app.directive(key, (directives as { [key: string]: Directive })[key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.component("IconifyIconOffline", IconifyIconOffline);
|
app.component('IconifyIconOffline', IconifyIconOffline);
|
||||||
app.component("IconifyIconOnline", IconifyIconOnline);
|
app.component('IconifyIconOnline', IconifyIconOnline);
|
||||||
app.component("FontIcon", FontIcon);
|
app.component('FontIcon', FontIcon);
|
||||||
|
|
||||||
app.component("Auth", Auth);
|
app.component('Auth', Auth);
|
||||||
app.component("Perms", Perms);
|
app.component('Perms', Perms);
|
||||||
|
|
||||||
app.use(VueTippy);
|
app.use(VueTippy);
|
||||||
|
|
||||||
getPlatformConfig(app).then(async config => {
|
getPlatformConfig(app).then(async config => {
|
||||||
setupStore(app);
|
setupStore(app);
|
||||||
app.use(router);
|
app.use(router);
|
||||||
await router.isReady();
|
await router.isReady();
|
||||||
injectResponsiveStorage(app, config);
|
injectResponsiveStorage(app, config);
|
||||||
app
|
app
|
||||||
.use(MotionPlugin)
|
.use(MotionPlugin)
|
||||||
.use(useElementPlus)
|
.use(useElementPlus)
|
||||||
.use(Table)
|
.use(Table)
|
||||||
// .use(PureDescriptions)
|
.use(VxeUITable)
|
||||||
.use(useEcharts);
|
// .use(PureDescriptions)
|
||||||
app.mount("#app");
|
.use(useEcharts);
|
||||||
|
app.mount('#app');
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
export const columns = [
|
||||||
|
{ prop: 'id', label: 'id' },
|
||||||
|
{ prop: 'name', label: 'name' },
|
||||||
|
{ prop: 'nickname', label: 'nickname' },
|
||||||
|
{ prop: 'role', label: 'role' },
|
||||||
|
{ prop: 'sex', label: 'sex' },
|
||||||
|
{ prop: 'age', label: 'age' },
|
||||||
|
{ prop: 'address', label: 'address' },
|
||||||
|
];
|
|
@ -1,66 +1,264 @@
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import { initRouter } from "@/router/utils";
|
import { initRouter } from '@/router/utils';
|
||||||
import { storageLocal } from "@pureadmin/utils";
|
import { storageLocal } from '@pureadmin/utils';
|
||||||
import { type CSSProperties, ref, computed } from "vue";
|
import { computed, type CSSProperties, ref } from 'vue';
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
import { useUserStoreHook } from '@/store/modules/user';
|
||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
import { usePermissionStoreHook } from '@/store/modules/permission';
|
||||||
|
import TablePlusVxeBar from '@/components/TableBar/src/TablePlusVxeBar.vue';
|
||||||
|
import { columns } from '@/views/permission/page/columns';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "PermissionPage"
|
name: 'PermissionPage',
|
||||||
});
|
});
|
||||||
|
|
||||||
const elStyle = computed((): CSSProperties => {
|
const elStyle = computed((): CSSProperties => {
|
||||||
return {
|
return {
|
||||||
width: "85vw",
|
width: '85vw',
|
||||||
justifyContent: "start"
|
justifyContent: 'start',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const username = ref(useUserStoreHook()?.username);
|
const username = ref(useUserStoreHook()?.username);
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
value: "admin",
|
value: 'admin',
|
||||||
label: "管理员角色"
|
label: '管理员角色',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "common",
|
value: 'common',
|
||||||
label: "普通角色"
|
label: '普通角色',
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function onChange() {
|
function onChange() {
|
||||||
useUserStoreHook()
|
useUserStoreHook()
|
||||||
.loginByUsername({ username: username.value, password: "admin123" })
|
.loginByUsername({ username: username.value, password: 'admin123' })
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
storageLocal().removeItem("async-routes");
|
storageLocal().removeItem('async-routes');
|
||||||
usePermissionStoreHook().clearAllCachePage();
|
usePermissionStoreHook().clearAllCachePage();
|
||||||
initRouter();
|
initRouter();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dataList = [
|
||||||
|
{
|
||||||
|
id: 10001,
|
||||||
|
name: 'Test1',
|
||||||
|
nickname: 'T1',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 28,
|
||||||
|
address: 'Shenzhen',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10002,
|
||||||
|
name: 'Test2',
|
||||||
|
nickname: 'T2',
|
||||||
|
role: 'Test',
|
||||||
|
sex: 'Women',
|
||||||
|
age: 22,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10003,
|
||||||
|
name: 'Test3',
|
||||||
|
nickname: 'T3',
|
||||||
|
role: 'PM',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 32,
|
||||||
|
address: 'Shanghai',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10004,
|
||||||
|
name: 'Test4',
|
||||||
|
nickname: 'T4',
|
||||||
|
role: 'Designer',
|
||||||
|
sex: 'Women',
|
||||||
|
age: 23,
|
||||||
|
address: 'test abc',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10005,
|
||||||
|
name: 'Test5',
|
||||||
|
nickname: 'T5',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Women',
|
||||||
|
age: 30,
|
||||||
|
address: 'Shanghai',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10006,
|
||||||
|
name: 'Test6',
|
||||||
|
nickname: 'T6',
|
||||||
|
role: 'Designer',
|
||||||
|
sex: 'Women',
|
||||||
|
age: 21,
|
||||||
|
address: 'Shenzhen',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10007,
|
||||||
|
name: 'Test7',
|
||||||
|
nickname: 'T7',
|
||||||
|
role: 'Test',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 29,
|
||||||
|
address: 'Shenzhen',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10008,
|
||||||
|
name: 'Test8',
|
||||||
|
nickname: 'T8',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 35,
|
||||||
|
address: 'test abc',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10009,
|
||||||
|
name: 'Test9',
|
||||||
|
nickname: 'T9',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 35,
|
||||||
|
address: 'Shenzhen',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100010,
|
||||||
|
name: 'Test10',
|
||||||
|
nickname: 'T10',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 35,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100011,
|
||||||
|
name: 'Test11',
|
||||||
|
nickname: 'T11',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 49,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100012,
|
||||||
|
name: 'Test12',
|
||||||
|
nickname: 'T12',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Women',
|
||||||
|
age: 45,
|
||||||
|
address: 'Shanghai',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100013,
|
||||||
|
name: 'Test13',
|
||||||
|
nickname: 'T13',
|
||||||
|
role: 'Test',
|
||||||
|
sex: 'Women',
|
||||||
|
age: 35,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100014,
|
||||||
|
name: 'Test14',
|
||||||
|
nickname: 'T14',
|
||||||
|
role: 'Test',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 29,
|
||||||
|
address: 'Shanghai',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100015,
|
||||||
|
name: 'Test15',
|
||||||
|
nickname: 'T15',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 39,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100016,
|
||||||
|
name: 'Test16',
|
||||||
|
nickname: 'T16',
|
||||||
|
role: 'Test',
|
||||||
|
sex: 'Women',
|
||||||
|
age: 35,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100017,
|
||||||
|
name: 'Test17',
|
||||||
|
nickname: 'T17',
|
||||||
|
role: 'Test',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 39,
|
||||||
|
address: 'Shanghai',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100018,
|
||||||
|
name: 'Test18',
|
||||||
|
nickname: 'T18',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 44,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100019,
|
||||||
|
name: 'Test19',
|
||||||
|
nickname: 'T19',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 39,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100020,
|
||||||
|
name: 'Test20',
|
||||||
|
nickname: 'T20',
|
||||||
|
role: 'Test',
|
||||||
|
sex: 'Women',
|
||||||
|
age: 35,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100021,
|
||||||
|
name: 'Test21',
|
||||||
|
nickname: 'T21',
|
||||||
|
role: 'Test',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 39,
|
||||||
|
address: 'Shanghai',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 100022,
|
||||||
|
name: 'Test22',
|
||||||
|
nickname: 'T22',
|
||||||
|
role: 'Develop',
|
||||||
|
sex: 'Man',
|
||||||
|
age: 44,
|
||||||
|
address: 'Guangzhou',
|
||||||
|
},
|
||||||
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<p class="mb-2">
|
<p class="mb-2">模拟后台根据不同角色返回对应路由,观察左侧菜单变化(管理员角色可查看系统管理菜单、普通角色不可查看系统管理菜单)</p>
|
||||||
模拟后台根据不同角色返回对应路由,观察左侧菜单变化(管理员角色可查看系统管理菜单、普通角色不可查看系统管理菜单)
|
<el-card :style="elStyle" shadow="never">
|
||||||
</p>
|
<template #header>
|
||||||
<el-card shadow="never" :style="elStyle">
|
<div class="card-header">
|
||||||
<template #header>
|
<span>当前角色:{{ username }}</span>
|
||||||
<div class="card-header">
|
</div>
|
||||||
<span>当前角色:{{ username }}</span>
|
</template>
|
||||||
</div>
|
<el-select v-model="username" class="!w-[160px]" @change="onChange">
|
||||||
</template>
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
<el-select v-model="username" class="!w-[160px]" @change="onChange">
|
</el-select>
|
||||||
<el-option
|
</el-card>
|
||||||
v-for="item in options"
|
|
||||||
:key="item.value"
|
<TablePlusVxeBar :column="columns" :data-list="dataList" :loading="false" />
|
||||||
:label="item.label"
|
</div>
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
import type { Directive } from "vue";
|
import type { Directive } from 'vue';
|
||||||
import type { CopyEl, OptimizeOptions, RippleOptions } from "@/directives";
|
import type { CopyEl, OptimizeOptions, RippleOptions } from '@/directives';
|
||||||
|
|
||||||
declare module "vue" {
|
declare module 'vue' {
|
||||||
export interface ComponentCustomProperties {
|
export interface ComponentCustomProperties {
|
||||||
/** `Loading` 动画加载指令,具体看:https://element-plus.org/zh-CN/component/loading.html#%E6%8C%87%E4%BB%A4 */
|
/** `Loading` 动画加载指令,具体看:https://element-plus.org/zh-CN/component/loading.html#%E6%8C%87%E4%BB%A4 */
|
||||||
vLoading: Directive<Element, boolean>;
|
vLoading: Directive<Element, boolean>;
|
||||||
/** 按钮权限指令(根据路由`meta`中的`auths`字段进行判断)*/
|
/** 按钮权限指令(根据路由`meta`中的`auths`字段进行判断)*/
|
||||||
vAuth: Directive<HTMLElement, string | Array<string>>;
|
vAuth: Directive<HTMLElement, string | Array<string>>;
|
||||||
/** 文本复制指令(默认双击复制) */
|
/** 文本复制指令(默认双击复制) */
|
||||||
vCopy: Directive<CopyEl, string>;
|
vCopy: Directive<CopyEl, string>;
|
||||||
/** 长按指令 */
|
/** 长按指令 */
|
||||||
vLongpress: Directive<HTMLElement, Function>;
|
vLongpress: Directive<HTMLElement, Function>;
|
||||||
/** 防抖、节流指令 */
|
/** 防抖、节流指令 */
|
||||||
vOptimize: Directive<HTMLElement, OptimizeOptions>;
|
vOptimize: Directive<HTMLElement, OptimizeOptions>;
|
||||||
/** 按钮权限指令(根据登录接口返回的`permissions`字段进行判断)*/
|
/** 按钮权限指令(根据登录接口返回的`permissions`字段进行判断)*/
|
||||||
vPerms: Directive<HTMLElement, string | Array<string>>;
|
vPerms: Directive<HTMLElement, string | Array<string>>;
|
||||||
/**
|
/**
|
||||||
* `v-ripple`指令,用法如下:
|
* `v-ripple`指令,用法如下:
|
||||||
* 1. `v-ripple`代表启用基本的`ripple`功能
|
* 1. `v-ripple`代表启用基本的`ripple`功能
|
||||||
* 2. `v-ripple="{ class: 'text-red' }"`代表自定义`ripple`颜色,支持`tailwindcss`,生效样式是`color`
|
* 2. `v-ripple="{ class: 'text-red' }"`代表自定义`ripple`颜色,支持`tailwindcss`,生效样式是`color`
|
||||||
* 3. `v-ripple.center`代表从中心扩散
|
* 3. `v-ripple.center`代表从中心扩散
|
||||||
*/
|
*/
|
||||||
vRipple: Directive<HTMLElement, RippleOptions>;
|
vRipple: Directive<HTMLElement, RippleOptions>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// 默认option选项
|
||||||
|
export interface Option {
|
||||||
|
value: string | number | boolean | undefined;
|
||||||
|
label: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 属性结构
|
||||||
|
export interface TreeData {
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
children?: TreeData[];
|
||||||
|
}
|
|
@ -1,193 +1,186 @@
|
||||||
import type { ECharts } from "echarts";
|
import type { ECharts } from 'echarts';
|
||||||
import type { TableColumns } from "@pureadmin/table";
|
import type { TableColumns } from '@pureadmin/table';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局类型声明,无需引入直接在 `.vue` 、`.ts` 、`.tsx` 文件使用即可获得类型提示
|
* 全局类型声明,无需引入直接在 `.vue` 、`.ts` 、`.tsx` 文件使用即可获得类型提示
|
||||||
*/
|
*/
|
||||||
declare global {
|
declare global {
|
||||||
/**
|
/**
|
||||||
* 平台的名称、版本、运行所需的`node`和`pnpm`版本、依赖、最后构建时间的类型提示
|
* 平台的名称、版本、运行所需的`node`和`pnpm`版本、依赖、最后构建时间的类型提示
|
||||||
*/
|
*/
|
||||||
const __APP_INFO__: {
|
const __APP_INFO__: {
|
||||||
pkg: {
|
pkg: {
|
||||||
name: string;
|
name: string;
|
||||||
version: string;
|
version: string;
|
||||||
engines: {
|
engines: {
|
||||||
node: string;
|
node: string;
|
||||||
pnpm: string;
|
pnpm: string;
|
||||||
};
|
};
|
||||||
dependencies: Recordable<string>;
|
dependencies: Recordable<string>;
|
||||||
devDependencies: Recordable<string>;
|
devDependencies: Recordable<string>;
|
||||||
};
|
};
|
||||||
lastBuildTime: string;
|
lastBuildTime: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Window 的类型提示
|
* Window 的类型提示
|
||||||
*/
|
*/
|
||||||
interface Window {
|
interface Window {
|
||||||
// Global vue app instance
|
// Global vue app instance
|
||||||
__APP__: App<Element>;
|
__APP__: App<Element>;
|
||||||
webkitCancelAnimationFrame: (handle: number) => void;
|
webkitCancelAnimationFrame: (handle: number) => void;
|
||||||
mozCancelAnimationFrame: (handle: number) => void;
|
mozCancelAnimationFrame: (handle: number) => void;
|
||||||
oCancelAnimationFrame: (handle: number) => void;
|
oCancelAnimationFrame: (handle: number) => void;
|
||||||
msCancelAnimationFrame: (handle: number) => void;
|
msCancelAnimationFrame: (handle: number) => void;
|
||||||
webkitRequestAnimationFrame: (callback: FrameRequestCallback) => number;
|
webkitRequestAnimationFrame: (callback: FrameRequestCallback) => number;
|
||||||
mozRequestAnimationFrame: (callback: FrameRequestCallback) => number;
|
mozRequestAnimationFrame: (callback: FrameRequestCallback) => number;
|
||||||
oRequestAnimationFrame: (callback: FrameRequestCallback) => number;
|
oRequestAnimationFrame: (callback: FrameRequestCallback) => number;
|
||||||
msRequestAnimationFrame: (callback: FrameRequestCallback) => number;
|
msRequestAnimationFrame: (callback: FrameRequestCallback) => number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Document 的类型提示
|
* Document 的类型提示
|
||||||
*/
|
*/
|
||||||
interface Document {
|
interface Document {
|
||||||
webkitFullscreenElement?: Element;
|
webkitFullscreenElement?: Element;
|
||||||
mozFullScreenElement?: Element;
|
mozFullScreenElement?: Element;
|
||||||
msFullscreenElement?: Element;
|
msFullscreenElement?: Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打包压缩格式的类型声明
|
* 打包压缩格式的类型声明
|
||||||
*/
|
*/
|
||||||
type ViteCompression =
|
type ViteCompression = 'none' | 'gzip' | 'brotli' | 'both' | 'gzip-clear' | 'brotli-clear' | 'both-clear';
|
||||||
| "none"
|
|
||||||
| "gzip"
|
|
||||||
| "brotli"
|
|
||||||
| "both"
|
|
||||||
| "gzip-clear"
|
|
||||||
| "brotli-clear"
|
|
||||||
| "both-clear";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局自定义环境变量的类型声明
|
* 全局自定义环境变量的类型声明
|
||||||
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#%E5%85%B7%E4%BD%93%E9%85%8D%E7%BD%AE}
|
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#%E5%85%B7%E4%BD%93%E9%85%8D%E7%BD%AE}
|
||||||
*/
|
*/
|
||||||
interface ViteEnv {
|
interface ViteEnv {
|
||||||
VITE_PORT: number;
|
VITE_PORT: number;
|
||||||
VITE_PUBLIC_PATH: string;
|
VITE_PUBLIC_PATH: string;
|
||||||
VITE_ROUTER_HISTORY: string;
|
VITE_ROUTER_HISTORY: string;
|
||||||
VITE_CDN: boolean;
|
VITE_CDN: boolean;
|
||||||
VITE_HIDE_HOME: string;
|
VITE_HIDE_HOME: string;
|
||||||
VITE_COMPRESSION: ViteCompression;
|
VITE_COMPRESSION: ViteCompression;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 继承 `@pureadmin/table` 的 `TableColumns` ,方便全局直接调用
|
* 继承 `@pureadmin/table` 的 `TableColumns` ,方便全局直接调用
|
||||||
*/
|
*/
|
||||||
interface TableColumnList extends Array<TableColumns> {}
|
interface TableColumnList extends Array<TableColumns> {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对应 `public/platform-config.json` 文件的类型声明
|
* 对应 `public/platform-config.json` 文件的类型声明
|
||||||
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#platform-config-json}
|
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#platform-config-json}
|
||||||
*/
|
*/
|
||||||
interface PlatformConfigs {
|
interface PlatformConfigs {
|
||||||
Version?: string;
|
Version?: string;
|
||||||
Title?: string;
|
Title?: string;
|
||||||
FixedHeader?: boolean;
|
FixedHeader?: boolean;
|
||||||
HiddenSideBar?: boolean;
|
HiddenSideBar?: boolean;
|
||||||
MultiTagsCache?: boolean;
|
MultiTagsCache?: boolean;
|
||||||
MaxTagsLevel?: number;
|
MaxTagsLevel?: number;
|
||||||
KeepAlive?: boolean;
|
KeepAlive?: boolean;
|
||||||
Locale?: string;
|
Locale?: string;
|
||||||
Layout?: string;
|
Layout?: string;
|
||||||
Theme?: string;
|
Theme?: string;
|
||||||
DarkMode?: boolean;
|
DarkMode?: boolean;
|
||||||
OverallStyle?: string;
|
OverallStyle?: string;
|
||||||
Grey?: boolean;
|
Grey?: boolean;
|
||||||
Weak?: boolean;
|
Weak?: boolean;
|
||||||
HideTabs?: boolean;
|
HideTabs?: boolean;
|
||||||
HideFooter?: boolean;
|
HideFooter?: boolean;
|
||||||
Stretch?: boolean | number;
|
Stretch?: boolean | number;
|
||||||
SidebarStatus?: boolean;
|
SidebarStatus?: boolean;
|
||||||
EpThemeColor?: string;
|
EpThemeColor?: string;
|
||||||
ShowLogo?: boolean;
|
ShowLogo?: boolean;
|
||||||
ShowModel?: string;
|
ShowModel?: string;
|
||||||
MenuArrowIconNoTransition?: boolean;
|
MenuArrowIconNoTransition?: boolean;
|
||||||
CachingAsyncRoutes?: boolean;
|
CachingAsyncRoutes?: boolean;
|
||||||
TooltipEffect?: Effect;
|
TooltipEffect?: Effect;
|
||||||
ResponsiveStorageNameSpace?: string;
|
ResponsiveStorageNameSpace?: string;
|
||||||
MenuSearchHistory?: number;
|
MenuSearchHistory?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 与 `PlatformConfigs` 类型不同,这里是缓存到浏览器本地存储的类型声明
|
* 与 `PlatformConfigs` 类型不同,这里是缓存到浏览器本地存储的类型声明
|
||||||
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#platform-config-json}
|
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#platform-config-json}
|
||||||
*/
|
*/
|
||||||
interface StorageConfigs {
|
interface StorageConfigs {
|
||||||
version?: string;
|
version?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
fixedHeader?: boolean;
|
fixedHeader?: boolean;
|
||||||
hiddenSideBar?: boolean;
|
hiddenSideBar?: boolean;
|
||||||
multiTagsCache?: boolean;
|
multiTagsCache?: boolean;
|
||||||
keepAlive?: boolean;
|
keepAlive?: boolean;
|
||||||
locale?: string;
|
locale?: string;
|
||||||
layout?: string;
|
layout?: string;
|
||||||
theme?: string;
|
theme?: string;
|
||||||
darkMode?: boolean;
|
darkMode?: boolean;
|
||||||
grey?: boolean;
|
grey?: boolean;
|
||||||
weak?: boolean;
|
weak?: boolean;
|
||||||
hideTabs?: boolean;
|
hideTabs?: boolean;
|
||||||
hideFooter?: boolean;
|
hideFooter?: boolean;
|
||||||
sidebarStatus?: boolean;
|
sidebarStatus?: boolean;
|
||||||
epThemeColor?: string;
|
epThemeColor?: string;
|
||||||
themeColor?: string;
|
themeColor?: string;
|
||||||
overallStyle?: string;
|
overallStyle?: string;
|
||||||
showLogo?: boolean;
|
showLogo?: boolean;
|
||||||
showModel?: string;
|
showModel?: string;
|
||||||
menuSearchHistory?: number;
|
menuSearchHistory?: number;
|
||||||
username?: string;
|
username?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `responsive-storage` 本地响应式 `storage` 的类型声明
|
* `responsive-storage` 本地响应式 `storage` 的类型声明
|
||||||
*/
|
*/
|
||||||
interface ResponsiveStorage {
|
interface ResponsiveStorage {
|
||||||
locale: {
|
locale: {
|
||||||
locale?: string;
|
locale?: string;
|
||||||
};
|
};
|
||||||
layout: {
|
layout: {
|
||||||
layout?: string;
|
layout?: string;
|
||||||
theme?: string;
|
theme?: string;
|
||||||
darkMode?: boolean;
|
darkMode?: boolean;
|
||||||
sidebarStatus?: boolean;
|
sidebarStatus?: boolean;
|
||||||
epThemeColor?: string;
|
epThemeColor?: string;
|
||||||
themeColor?: string;
|
themeColor?: string;
|
||||||
overallStyle?: string;
|
overallStyle?: string;
|
||||||
};
|
};
|
||||||
configure: {
|
configure: {
|
||||||
grey?: boolean;
|
grey?: boolean;
|
||||||
weak?: boolean;
|
weak?: boolean;
|
||||||
hideTabs?: boolean;
|
hideTabs?: boolean;
|
||||||
hideFooter?: boolean;
|
hideFooter?: boolean;
|
||||||
showLogo?: boolean;
|
showLogo?: boolean;
|
||||||
showModel?: string;
|
showModel?: string;
|
||||||
multiTagsCache?: boolean;
|
multiTagsCache?: boolean;
|
||||||
stretch?: boolean | number;
|
stretch?: boolean | number;
|
||||||
};
|
};
|
||||||
tags?: Array<any>;
|
tags?: Array<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 平台里所有组件实例都能访问到的全局属性对象的类型声明
|
* 平台里所有组件实例都能访问到的全局属性对象的类型声明
|
||||||
*/
|
*/
|
||||||
interface GlobalPropertiesApi {
|
interface GlobalPropertiesApi {
|
||||||
$echarts: ECharts;
|
$echarts: ECharts;
|
||||||
$storage: ResponsiveStorage;
|
$storage: ResponsiveStorage;
|
||||||
$config: PlatformConfigs;
|
$config: PlatformConfigs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扩展 `Element`
|
* 扩展 `Element`
|
||||||
*/
|
*/
|
||||||
interface Element {
|
interface Element {
|
||||||
// v-ripple 作用于 src/directives/ripple/index.ts 文件
|
// v-ripple 作用于 src/directives/ripple/index.ts 文件
|
||||||
_ripple?: {
|
_ripple?: {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
centered?: boolean;
|
centered?: boolean;
|
||||||
class?: string;
|
class?: string;
|
||||||
circle?: boolean;
|
circle?: boolean;
|
||||||
touched?: boolean;
|
touched?: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,14 @@ type RefType<T> = T | null;
|
||||||
|
|
||||||
type EmitType = (event: string, ...args: any[]) => void;
|
type EmitType = (event: string, ...args: any[]) => void;
|
||||||
|
|
||||||
type TargetContext = "_self" | "_blank";
|
type TargetContext = '_self' | '_blank';
|
||||||
|
|
||||||
type ComponentRef<T extends HTMLElement = HTMLDivElement> =
|
type ComponentRef<T extends HTMLElement = HTMLDivElement> = ComponentElRef<T> | null;
|
||||||
ComponentElRef<T> | null;
|
|
||||||
|
|
||||||
type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>;
|
type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>;
|
||||||
|
|
||||||
type ForDataType<T> = {
|
type ForDataType<T> = {
|
||||||
[P in T]?: ForDataType<T[P]>;
|
[P in T]?: ForDataType<T[P]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type AnyFunction<T> = (...args: any[]) => T;
|
type AnyFunction<T> = (...args: any[]) => T;
|
||||||
|
@ -20,7 +19,7 @@ type AnyFunction<T> = (...args: any[]) => T;
|
||||||
type PropType<T> = VuePropType<T>;
|
type PropType<T> = VuePropType<T>;
|
||||||
|
|
||||||
type Writable<T> = {
|
type Writable<T> = {
|
||||||
-readonly [P in keyof T]: T[P];
|
-readonly [P in keyof T]: T[P];
|
||||||
};
|
};
|
||||||
|
|
||||||
type Nullable<T> = T | null;
|
type Nullable<T> = T | null;
|
||||||
|
@ -30,15 +29,15 @@ type NonNullable<T> = T extends null | undefined ? never : T;
|
||||||
type Recordable<T = any> = Record<string, T>;
|
type Recordable<T = any> = Record<string, T>;
|
||||||
|
|
||||||
type ReadonlyRecordable<T = any> = {
|
type ReadonlyRecordable<T = any> = {
|
||||||
readonly [key: string]: T;
|
readonly [key: string]: T;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Indexable<T = any> = {
|
type Indexable<T = any> = {
|
||||||
[key: string]: T;
|
[key: string]: T;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DeepPartial<T> = {
|
type DeepPartial<T> = {
|
||||||
[P in keyof T]?: DeepPartial<T[P]>;
|
[P in keyof T]?: DeepPartial<T[P]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
|
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
|
||||||
|
@ -49,30 +48,30 @@ type TimeoutHandle = ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
type IntervalHandle = ReturnType<typeof setInterval>;
|
type IntervalHandle = ReturnType<typeof setInterval>;
|
||||||
|
|
||||||
type Effect = "light" | "dark";
|
type Effect = 'light' | 'dark';
|
||||||
|
|
||||||
interface ChangeEvent extends Event {
|
interface ChangeEvent extends Event {
|
||||||
target: HTMLInputElement;
|
target: HTMLInputElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WheelEvent {
|
interface WheelEvent {
|
||||||
path?: EventTarget[];
|
path?: EventTarget[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImportMetaEnv extends ViteEnv {
|
interface ImportMetaEnv extends ViteEnv {
|
||||||
__: unknown;
|
__: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Fn<T = any, R = T> {
|
interface Fn<T = any, R = T> {
|
||||||
(...arg: T[]): R;
|
(...arg: T[]): R;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PromiseFn<T = any, R = T> {
|
interface PromiseFn<T = any, R = T> {
|
||||||
(...arg: T[]): Promise<R>;
|
(...arg: T[]): Promise<R>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ComponentElRef<T extends HTMLElement = HTMLDivElement> {
|
interface ComponentElRef<T extends HTMLElement = HTMLDivElement> {
|
||||||
$el: T;
|
$el: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// 分页参数接口
|
||||||
|
export interface Pagination {
|
||||||
|
currentPage: number;
|
||||||
|
pageSize: number;
|
||||||
|
total: number;
|
||||||
|
pageSizes: number[];
|
||||||
|
}
|
|
@ -1,108 +1,108 @@
|
||||||
// 全局路由类型声明
|
// 全局路由类型声明
|
||||||
|
|
||||||
import type { RouteComponent, RouteLocationNormalized } from "vue-router";
|
import type { RouteComponent, RouteLocationNormalized } from 'vue-router';
|
||||||
import type { FunctionalComponent } from "vue";
|
import type { FunctionalComponent } from 'vue';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface ToRouteType extends RouteLocationNormalized {
|
interface ToRouteType extends RouteLocationNormalized {
|
||||||
meta: CustomizeRouteMeta;
|
meta: CustomizeRouteMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 完整子路由的`meta`配置表
|
* @description 完整子路由的`meta`配置表
|
||||||
*/
|
*/
|
||||||
interface CustomizeRouteMeta {
|
interface CustomizeRouteMeta {
|
||||||
/** 菜单名称(兼容国际化、非国际化,如何用国际化的写法就必须在根目录的`locales`文件夹下对应添加) `必填` */
|
/** 菜单名称(兼容国际化、非国际化,如何用国际化的写法就必须在根目录的`locales`文件夹下对应添加) `必填` */
|
||||||
title: string;
|
title: string;
|
||||||
/** 菜单图标 `可选` */
|
/** 菜单图标 `可选` */
|
||||||
icon?: string | FunctionalComponent | IconifyIcon;
|
icon?: string | FunctionalComponent | IconifyIcon;
|
||||||
/** 菜单名称右侧的额外图标 */
|
/** 菜单名称右侧的额外图标 */
|
||||||
extraIcon?: string | FunctionalComponent | IconifyIcon;
|
extraIcon?: string | FunctionalComponent | IconifyIcon;
|
||||||
/** 是否在菜单中显示(默认`true`)`可选` */
|
/** 是否在菜单中显示(默认`true`)`可选` */
|
||||||
showLink?: boolean;
|
showLink?: boolean;
|
||||||
/** 是否显示父级菜单 `可选` */
|
/** 是否显示父级菜单 `可选` */
|
||||||
showParent?: boolean;
|
showParent?: boolean;
|
||||||
/** 页面级别权限设置 `可选` */
|
/** 页面级别权限设置 `可选` */
|
||||||
roles?: Array<string>;
|
roles?: Array<string>;
|
||||||
/** 按钮级别权限设置 `可选` */
|
/** 按钮级别权限设置 `可选` */
|
||||||
auths?: Array<string>;
|
auths?: Array<string>;
|
||||||
/** 路由组件缓存(开启 `true`、关闭 `false`)`可选` */
|
/** 路由组件缓存(开启 `true`、关闭 `false`)`可选` */
|
||||||
keepAlive?: boolean;
|
keepAlive?: boolean;
|
||||||
/** 内嵌的`iframe`链接 `可选` */
|
/** 内嵌的`iframe`链接 `可选` */
|
||||||
frameSrc?: string;
|
frameSrc?: string;
|
||||||
/** `iframe`页是否开启首次加载动画(默认`true`)`可选` */
|
/** `iframe`页是否开启首次加载动画(默认`true`)`可选` */
|
||||||
frameLoading?: boolean;
|
frameLoading?: boolean;
|
||||||
/** 页面加载动画(两种模式,第二种权重更高,第一种直接采用`vue`内置的`transitions`动画,第二种是使用`animate.css`编写进、离场动画,平台更推荐使用第二种模式,已经内置了`animate.css`,直接写对应的动画名即可)`可选` */
|
/** 页面加载动画(两种模式,第二种权重更高,第一种直接采用`vue`内置的`transitions`动画,第二种是使用`animate.css`编写进、离场动画,平台更推荐使用第二种模式,已经内置了`animate.css`,直接写对应的动画名即可)`可选` */
|
||||||
transition?: {
|
transition?: {
|
||||||
/**
|
/**
|
||||||
* @description 当前路由动画效果
|
* @description 当前路由动画效果
|
||||||
* @see {@link https://next.router.vuejs.org/guide/advanced/transitions.html#transitions}
|
* @see {@link https://next.router.vuejs.org/guide/advanced/transitions.html#transitions}
|
||||||
* @see animate.css {@link https://animate.style}
|
* @see animate.css {@link https://animate.style}
|
||||||
*/
|
*/
|
||||||
name?: string;
|
name?: string;
|
||||||
/** 进场动画 */
|
/** 进场动画 */
|
||||||
enterTransition?: string;
|
enterTransition?: string;
|
||||||
/** 离场动画 */
|
/** 离场动画 */
|
||||||
leaveTransition?: string;
|
leaveTransition?: string;
|
||||||
};
|
};
|
||||||
/** 当前菜单名称或自定义信息禁止添加到标签页(默认`false`) */
|
/** 当前菜单名称或自定义信息禁止添加到标签页(默认`false`) */
|
||||||
hiddenTag?: boolean;
|
hiddenTag?: boolean;
|
||||||
/** 当前菜单名称是否固定显示在标签页且不可关闭(默认`false`) */
|
/** 当前菜单名称是否固定显示在标签页且不可关闭(默认`false`) */
|
||||||
fixedTag?: boolean;
|
fixedTag?: boolean;
|
||||||
/** 动态路由可打开的最大数量 `可选` */
|
/** 动态路由可打开的最大数量 `可选` */
|
||||||
dynamicLevel?: number;
|
dynamicLevel?: number;
|
||||||
/** 将某个菜单激活
|
/** 将某个菜单激活
|
||||||
* (主要用于通过`query`或`params`传参的路由,当它们通过配置`showLink: false`后不在菜单中显示,就不会有任何菜单高亮,
|
* (主要用于通过`query`或`params`传参的路由,当它们通过配置`showLink: false`后不在菜单中显示,就不会有任何菜单高亮,
|
||||||
* 而通过设置`activePath`指定激活菜单即可获得高亮,`activePath`为指定激活菜单的`path`)
|
* 而通过设置`activePath`指定激活菜单即可获得高亮,`activePath`为指定激活菜单的`path`)
|
||||||
*/
|
*/
|
||||||
activePath?: string;
|
activePath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 完整子路由配置表
|
* @description 完整子路由配置表
|
||||||
*/
|
*/
|
||||||
interface RouteChildrenConfigsTable {
|
interface RouteChildrenConfigsTable {
|
||||||
/** 子路由地址 `必填` */
|
/** 子路由地址 `必填` */
|
||||||
path: string;
|
path: string;
|
||||||
/** 路由名字(对应不要重复,和当前组件的`name`保持一致)`必填` */
|
/** 路由名字(对应不要重复,和当前组件的`name`保持一致)`必填` */
|
||||||
name?: string;
|
name?: string;
|
||||||
/** 路由重定向 `可选` */
|
/** 路由重定向 `可选` */
|
||||||
redirect?: string;
|
redirect?: string;
|
||||||
/** 按需加载组件 `可选` */
|
/** 按需加载组件 `可选` */
|
||||||
component?: RouteComponent;
|
component?: RouteComponent;
|
||||||
meta?: CustomizeRouteMeta;
|
meta?: CustomizeRouteMeta;
|
||||||
/** 子路由配置项 */
|
/** 子路由配置项 */
|
||||||
children?: Array<RouteChildrenConfigsTable>;
|
children?: Array<RouteChildrenConfigsTable>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 整体路由配置表(包括完整子路由)
|
* @description 整体路由配置表(包括完整子路由)
|
||||||
*/
|
*/
|
||||||
interface RouteConfigsTable {
|
interface RouteConfigsTable {
|
||||||
/** 路由地址 `必填` */
|
/** 路由地址 `必填` */
|
||||||
path: string;
|
path: string;
|
||||||
/** 路由名字(保持唯一)`可选` */
|
/** 路由名字(保持唯一)`可选` */
|
||||||
name?: string;
|
name?: string;
|
||||||
/** `Layout`组件 `可选` */
|
/** `Layout`组件 `可选` */
|
||||||
component?: RouteComponent;
|
component?: RouteComponent;
|
||||||
/** 路由重定向 `可选` */
|
/** 路由重定向 `可选` */
|
||||||
redirect?: string;
|
redirect?: string;
|
||||||
meta?: {
|
meta?: {
|
||||||
/** 菜单名称(兼容国际化、非国际化,如何用国际化的写法就必须在根目录的`locales`文件夹下对应添加)`必填` */
|
/** 菜单名称(兼容国际化、非国际化,如何用国际化的写法就必须在根目录的`locales`文件夹下对应添加)`必填` */
|
||||||
title: string;
|
title: string;
|
||||||
/** 菜单图标 `可选` */
|
/** 菜单图标 `可选` */
|
||||||
icon?: string | FunctionalComponent | IconifyIcon;
|
icon?: string | FunctionalComponent | IconifyIcon;
|
||||||
/** 是否在菜单中显示(默认`true`)`可选` */
|
/** 是否在菜单中显示(默认`true`)`可选` */
|
||||||
showLink?: boolean;
|
showLink?: boolean;
|
||||||
/** 菜单升序排序,值越高排的越后(只针对顶级路由)`可选` */
|
/** 菜单升序排序,值越高排的越后(只针对顶级路由)`可选` */
|
||||||
rank?: number;
|
rank?: number;
|
||||||
};
|
};
|
||||||
/** 子路由配置项 */
|
/** 子路由配置项 */
|
||||||
children?: Array<RouteChildrenConfigsTable>;
|
children?: Array<RouteChildrenConfigsTable>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://router.vuejs.org/zh/guide/advanced/meta.html#typescript
|
// https://router.vuejs.org/zh/guide/advanced/meta.html#typescript
|
||||||
declare module "vue-router" {
|
declare module 'vue-router' {
|
||||||
interface RouteMeta extends CustomizeRouteMeta {}
|
interface RouteMeta extends CustomizeRouteMeta {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
import type { VNode } from "vue";
|
import type Vue, { VNode } from 'vue';
|
||||||
import type Vue from "vue";
|
|
||||||
|
|
||||||
declare module "*.tsx" {
|
declare module '*.tsx' {
|
||||||
import Vue from "compatible-vue";
|
import Vue from 'compatible-vue';
|
||||||
export default Vue;
|
export default Vue;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace JSX {
|
namespace JSX {
|
||||||
interface Element extends VNode {}
|
interface Element extends VNode {}
|
||||||
interface ElementClass extends Vue {}
|
|
||||||
interface ElementAttributesProperty {
|
interface ElementClass extends Vue {}
|
||||||
$props: any;
|
|
||||||
}
|
interface ElementAttributesProperty {
|
||||||
interface IntrinsicElements {
|
$props: any;
|
||||||
[elem: string]: any;
|
}
|
||||||
}
|
|
||||||
interface IntrinsicAttributes {
|
interface IntrinsicElements {
|
||||||
[elem: string]: any;
|
[elem: string]: any;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
interface IntrinsicAttributes {
|
||||||
|
[elem: string]: any;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
declare module "*.vue" {
|
declare module '*.vue' {
|
||||||
import type { DefineComponent } from "vue";
|
import type { DefineComponent } from 'vue';
|
||||||
const component: DefineComponent<{}, {}, any>;
|
const component: DefineComponent<{}, {}, any>;
|
||||||
export default component;
|
export default component;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "*.scss" {
|
declare module '*.scss' {
|
||||||
const scss: Record<string, string>;
|
const scss: Record<string, string>;
|
||||||
export default scss;
|
export default scss;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// 返回响应内容
|
||||||
|
export interface Result<T> {
|
||||||
|
code: number;
|
||||||
|
data: T;
|
||||||
|
message: string;
|
||||||
|
}
|
|
@ -1,32 +1,31 @@
|
||||||
import { getPluginsList } from "./build/plugins";
|
import { getPluginsList } from './build/plugins';
|
||||||
import { exclude, include } from "./build/optimize";
|
import { exclude, include } from './build/optimize';
|
||||||
import { type ConfigEnv, loadEnv, type UserConfigExport } from "vite";
|
import { type ConfigEnv, loadEnv, type UserConfigExport } from 'vite';
|
||||||
import { __APP_INFO__, alias, root, wrapperEnv } from "./build/utils";
|
import { __APP_INFO__, alias, root, wrapperEnv } from './build/utils';
|
||||||
import { serverOptions } from "./build/server";
|
import { serverOptions } from './build/server';
|
||||||
import { buildEnvironment } from "./build/buildEnv";
|
import { buildEnvironment } from './build/buildEnv';
|
||||||
|
|
||||||
export default ({ mode }: ConfigEnv): UserConfigExport => {
|
export default ({ mode }: ConfigEnv): UserConfigExport => {
|
||||||
const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH } =
|
const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH } = wrapperEnv(loadEnv(mode, root));
|
||||||
wrapperEnv(loadEnv(mode, root));
|
return {
|
||||||
return {
|
base: VITE_PUBLIC_PATH,
|
||||||
base: VITE_PUBLIC_PATH,
|
root,
|
||||||
root,
|
resolve: { alias },
|
||||||
resolve: { alias },
|
// 服务端渲染
|
||||||
// 服务端渲染
|
server: serverOptions(mode),
|
||||||
server: serverOptions(mode),
|
plugins: getPluginsList(VITE_CDN, VITE_COMPRESSION, VITE_PORT),
|
||||||
plugins: getPluginsList(VITE_CDN, VITE_COMPRESSION, VITE_PORT),
|
// https://cn.vitejs.dev/config/dep-optimization-options.html#dep-optimization-options
|
||||||
// https://cn.vitejs.dev/config/dep-optimization-options.html#dep-optimization-options
|
optimizeDeps: { include, exclude },
|
||||||
optimizeDeps: { include, exclude },
|
esbuild: {
|
||||||
esbuild: {
|
pure: ['console.log', 'debugger'],
|
||||||
pure: ["console.log", "debugger"],
|
jsxFactory: 'h',
|
||||||
jsxFactory: "h",
|
jsxFragment: 'Fragment',
|
||||||
jsxFragment: "Fragment",
|
jsxInject: "import { h } from 'vue';",
|
||||||
jsxInject: "import { h } from 'vue';"
|
},
|
||||||
},
|
build: buildEnvironment(),
|
||||||
build: buildEnvironment(),
|
define: {
|
||||||
define: {
|
__INTLIFY_PROD_DEVTOOLS__: false,
|
||||||
__INTLIFY_PROD_DEVTOOLS__: false,
|
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
||||||
__APP_INFO__: JSON.stringify(__APP_INFO__)
|
},
|
||||||
}
|
};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue