Merge branch 'master' into feature/fake_data
commit
7e45c2e798
6
.env.dev
6
.env.dev
|
|
@ -1,5 +1,5 @@
|
|||
# 开发环境
|
||||
NODE_ENV=production
|
||||
NODE_ENV=development
|
||||
|
||||
VITE_DEV=false
|
||||
|
||||
|
|
@ -19,13 +19,13 @@ VITE_API_URL=/admin-api
|
|||
VITE_BASE_PATH=/
|
||||
|
||||
# 是否删除debugger
|
||||
VITE_DROP_DEBUGGER=false
|
||||
VITE_DROP_DEBUGGER=true
|
||||
|
||||
# 是否删除console.log
|
||||
VITE_DROP_CONSOLE=false
|
||||
|
||||
# 是否sourcemap
|
||||
VITE_SOURCEMAP=true
|
||||
VITE_SOURCEMAP=false
|
||||
|
||||
# 输出路径
|
||||
VITE_OUT_DIR=dist-dev
|
||||
|
|
|
|||
32
.eslintrc.js
32
.eslintrc.js
|
|
@ -1,6 +1,4 @@
|
|||
// @ts-check
|
||||
const { defineConfig } = require('eslint-define-config')
|
||||
module.exports = defineConfig({
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
|
|
@ -8,6 +6,7 @@ module.exports = defineConfig({
|
|||
es6: true
|
||||
},
|
||||
parser: 'vue-eslint-parser',
|
||||
plugins: ['vue'],
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser',
|
||||
ecmaVersion: 2020,
|
||||
|
|
@ -17,16 +16,9 @@ module.exports = defineConfig({
|
|||
jsx: true
|
||||
}
|
||||
},
|
||||
extends: [
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'prettier',
|
||||
'plugin:prettier/recommended',
|
||||
'./.eslintrc-auto-import.json'
|
||||
],
|
||||
extends: ['plugin:vue/vue3-recommended', 'prettier', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
|
||||
rules: {
|
||||
'vue/script-setup-uses-vars': 'error',
|
||||
'vue/no-reserved-component-names': 'off',
|
||||
'@typescript-eslint/ban-ts-ignore': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
|
|
@ -39,8 +31,20 @@ module.exports = defineConfig({
|
|||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'no-unused-vars': 'error',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_'
|
||||
}
|
||||
],
|
||||
'no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_'
|
||||
}
|
||||
],
|
||||
'space-before-function-paren': 'off',
|
||||
|
||||
'vue/attributes-order': 'off',
|
||||
|
|
@ -66,4 +70,4 @@ module.exports = defineConfig({
|
|||
],
|
||||
'vue/multi-word-component-names': 'off'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"voorjaar.windicss-intellisense",
|
||||
"christian-kohler.path-intellisense",
|
||||
"vscode-icons-team.vscode-icons",
|
||||
"davidanson.vscode-markdownlint",
|
||||
"stylelint.vscode-stylelint",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"vue.volar",
|
||||
"mrmlnc.vscode-less",
|
||||
"lokalise.i18n-ally",
|
||||
"redhat.vscode-yaml",
|
||||
"csstools.postcss",
|
||||
"mikestead.dotenv",
|
||||
"eamodio.gitlens",
|
||||
"antfu.iconify"
|
||||
"antfu.iconify",
|
||||
"antfu.unocss",
|
||||
"Vue.volar"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +1,98 @@
|
|||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"prettier.enable": true,
|
||||
"editor.formatOnType": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
"volar.tsPlugin": true,
|
||||
"volar.tsPluginStatus": false,
|
||||
"npm.packageManager": "pnpm",
|
||||
"editor.tabSize": 2,
|
||||
"prettier.printWidth": 100, // 超过最大值换行
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"files.eol": "\n",
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/*.log": true,
|
||||
"**/*.log*": true,
|
||||
"**/bower_components": true,
|
||||
"**/dist": true,
|
||||
"**/elehukouben": true,
|
||||
"**/.git": true,
|
||||
"**/.gitignore": true,
|
||||
"**/.svn": true,
|
||||
"**/.DS_Store": true,
|
||||
"**/.idea": true,
|
||||
"**/.vscode": false,
|
||||
"**/yarn.lock": true,
|
||||
"**/tmp": true,
|
||||
"out": true,
|
||||
"dist": true,
|
||||
"node_modules": true,
|
||||
"CHANGELOG.md": true,
|
||||
"examples": true,
|
||||
"res": true,
|
||||
"screenshots": true,
|
||||
"yarn-error.log": true,
|
||||
"**/.yarn": true
|
||||
},
|
||||
"[vue]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
"files.exclude": {
|
||||
"**/.cache": true,
|
||||
"**/.editorconfig": true,
|
||||
"**/.eslintcache": true,
|
||||
"**/bower_components": true,
|
||||
"**/.idea": true,
|
||||
"**/tmp": true,
|
||||
"**/.git": true,
|
||||
"**/.svn": true,
|
||||
"**/.hg": true,
|
||||
"**/CVS": true,
|
||||
"**/.DS_Store": true
|
||||
},
|
||||
"[javascript]": {
|
||||
"files.watcherExclude": {
|
||||
"**/.git/objects/**": true,
|
||||
"**/.git/subtree-cache/**": true,
|
||||
"**/.vscode/**": true,
|
||||
"**/node_modules/**": true,
|
||||
"**/tmp/**": true,
|
||||
"**/bower_components/**": true,
|
||||
"**/dist/**": true,
|
||||
"**/yarn.lock": true
|
||||
},
|
||||
"stylelint.enable": true,
|
||||
"stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"],
|
||||
"path-intellisense.mappings": {
|
||||
"@/": "${workspaceRoot}/src"
|
||||
},
|
||||
"[javascriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
||||
},
|
||||
"[html]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[css]": {
|
||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
||||
},
|
||||
"[less]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[scss]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[markdown]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"[vue]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true,
|
||||
"source.fixAll.stylelint": true
|
||||
}
|
||||
},
|
||||
"i18n-ally.localesPaths": ["src/locales"],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.sortKeys": true,
|
||||
|
|
@ -39,16 +101,67 @@
|
|||
"i18n-ally.sourceLanguage": "en",
|
||||
"i18n-ally.displayLanguage": "zh-CN",
|
||||
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
||||
"god.tsconfig": "./tsconfig.json",
|
||||
"vue-i18n.i18nPaths": "src/locales",
|
||||
"cSpell.words": [
|
||||
"xingyu",
|
||||
"yudao",
|
||||
"unocss",
|
||||
"browserslist",
|
||||
"esnext",
|
||||
"unplugin",
|
||||
"qrcode",
|
||||
"sider",
|
||||
"pinia",
|
||||
"sider",
|
||||
"nprogress",
|
||||
"INTLIFY",
|
||||
"stylelint",
|
||||
"esno",
|
||||
"vitejs",
|
||||
"sortablejs",
|
||||
"codemirror",
|
||||
"iconify",
|
||||
"commitlint",
|
||||
"videojs",
|
||||
"echarts",
|
||||
"wangeditor",
|
||||
"cropperjs",
|
||||
"logicflow",
|
||||
"vueuse",
|
||||
"zxcvbn",
|
||||
"lintstagedrc",
|
||||
"brotli",
|
||||
"sider",
|
||||
"pnpm"
|
||||
],
|
||||
"vetur.format.scriptInitialIndent": true,
|
||||
"vetur.format.styleInitialIndent": true,
|
||||
"vetur.validation.script": false,
|
||||
"MicroPython.executeButton": [
|
||||
{
|
||||
"text": "▶",
|
||||
"tooltip": "运行",
|
||||
"alignment": "left",
|
||||
"command": "extension.executeFile",
|
||||
"priority": 3.5
|
||||
}
|
||||
],
|
||||
"MicroPython.syncButton": [
|
||||
{
|
||||
"text": "$(sync)",
|
||||
"tooltip": "同步",
|
||||
"alignment": "left",
|
||||
"command": "extension.execute",
|
||||
"priority": 4
|
||||
}
|
||||
],
|
||||
// 控制相关文件嵌套展示
|
||||
"explorer.fileNesting.enabled": true,
|
||||
"explorer.fileNesting.expand": false,
|
||||
"explorer.fileNesting.patterns": {
|
||||
"*.ts": "$(capture).test.ts, $(capture).test.tsx",
|
||||
"*.tsx": "$(capture).test.ts, $(capture).test.tsx",
|
||||
"*.env": "$(capture).env.*",
|
||||
"CHANGELOG.md": "CHANGELOG*",
|
||||
"package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,README*,.npmrc,.browserslistrc,vite.config.*,windi.*,tailwind.*,tsconfig.*,postcss*",
|
||||
".eslintrc.js": ".eslintignore,.eslintrc-*,.prettierignore,.stylelintignore,.commitlintrc.js,.prettierrc.js,.stylelint*,stylelint*,prettier.*,.editorconfig"
|
||||
}
|
||||
"package.json": "pnpm-lock.yaml,yarn.lock,LICENSE,README*,CHANGELOG*,CNAME,.gitattributes,.gitignore,prettier.config.js,stylelint.config.js,commitlint.config.js,.stylelintignore,.prettierignore,.gitpod.yml,.eslintrc.js,.eslintignore"
|
||||
},
|
||||
"terminal.integrated.scrollback": 10000
|
||||
}
|
||||
|
|
|
|||
36
README.md
36
README.md
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
## 🐶 新手必读
|
||||
|
||||
* nodejs > 16.0.0 && pnpm > 7.30.0
|
||||
* nodejs > 16.0.0 && pnpm > 8.6.0 (强制使用pnpm)
|
||||
* 演示地址【Vue3 + element-plus】:<http://dashboard-vue3.yudao.iocoder.cn>
|
||||
* 演示地址【Vue3 + vben(ant-design-vue)】:<http://dashboard-vben.yudao.iocoder.cn>
|
||||
* 演示地址【Vue2 + element-ui】:<http://dashboard.yudao.iocoder.cn>
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
* 改换 saas,自动引入等功能
|
||||
* 使用 Element Plus 免费开源的中后台模版,具备如下特性:
|
||||
|
||||

|
||||

|
||||
|
||||
* **最新技术栈**:使用 Vue3、Vite4 等前端前沿技术开发
|
||||
* **TypeScript**: 应用程序级 JavaScript 的语言
|
||||
|
|
@ -38,16 +38,16 @@
|
|||
|
||||
| 框架 | 说明 | 版本 |
|
||||
|----------------------------------------------------------------------|------------------|--------|
|
||||
| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.47 |
|
||||
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.3.1 |
|
||||
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.3 |
|
||||
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.0.4 |
|
||||
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.35 |
|
||||
| [vueuse](https://vueuse.org/) | 常用工具集 | 10.1.0 |
|
||||
| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.3.4 |
|
||||
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.4.7 |
|
||||
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.8 |
|
||||
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.1.6 |
|
||||
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.6 |
|
||||
| [vueuse](https://vueuse.org/) | 常用工具集 | 10.2.1 |
|
||||
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 |
|
||||
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.1.6 |
|
||||
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 |
|
||||
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.1.0 |
|
||||
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.2.4 |
|
||||
| [unocss](https://uno.antfu.me/) | 原子 css | 0.54.0 |
|
||||
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.1.1 |
|
||||
| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.23 |
|
||||
|
||||
## 开发工具
|
||||
|
|
@ -56,14 +56,14 @@
|
|||
|
||||
| 插件名 | 功能 |
|
||||
|-------------------------------|--------------------------|
|
||||
| TypeScript Vue Plugin (Volar) | 用于 TypeScript 的 Vue 插件 |
|
||||
| TypeScript Vue Plugin (Volar) | 用于 TypeScript 的 Vue 插件 |
|
||||
| Vue Language Features (Volar) | Vue3.0 语法支持 |
|
||||
| WindiCSS IntelliSense | 自动完成、语法突出显示、代码折叠和构建等高级功能 |
|
||||
| Iconify IntelliSense | Iconify 预览和搜索 |
|
||||
| i18n Ally | 国际化智能提示 |
|
||||
| unocss | unocss for vscode |
|
||||
| Iconify IntelliSense | Iconify 预览和搜索 |
|
||||
| i18n Ally | 国际化智能提示 |
|
||||
| Stylelint | Css 格式化 |
|
||||
| Prettier | 代码格式化 |
|
||||
| ESLint | 脚本代码检查 |
|
||||
| Prettier | 代码格式化 |
|
||||
| ESLint | 脚本代码检查 |
|
||||
| DotENV | env 文件高亮 |
|
||||
|
||||
## 内置功能
|
||||
|
|
@ -136,7 +136,7 @@ ps:核心功能已经实现,正在对接微信小程序中...
|
|||
| | 表单构建 | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件 |
|
||||
| 🚀 | 配置管理 | 对系统动态配置常用参数,支持 SpringBoot 加载 |
|
||||
| ⭐️ | 定时任务 | 在线(添加、修改、删除)任务调度包含执行结果日志 |
|
||||
| 🚀 | 文件服务 | 支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等 |
|
||||
| 🚀 | 文件服务 | 支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等 |
|
||||
| 🚀 | API 日志 | 包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题 |
|
||||
| | MySQL 监控 | 监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈 |
|
||||
| | Redis 监控 | 监控 Redis 数据库的使用情况,使用的 Redis Key 管理 |
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { resolve } from 'path'
|
||||
import Vue from '@vitejs/plugin-vue'
|
||||
import VueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import WindiCSS from 'vite-plugin-windicss'
|
||||
import progress from 'vite-plugin-progress'
|
||||
import EslintPlugin from 'vite-plugin-eslint'
|
||||
import PurgeIcons from 'vite-plugin-purge-icons'
|
||||
|
|
@ -13,9 +12,9 @@ import Components from 'unplugin-vue-components/vite'
|
|||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
import viteCompression from 'vite-plugin-compression'
|
||||
import topLevelAwait from 'vite-plugin-top-level-await'
|
||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus'
|
||||
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
|
||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
||||
import UnoCSS from 'unocss/vite'
|
||||
|
||||
export function createVitePlugins() {
|
||||
const root = process.cwd()
|
||||
|
|
@ -28,10 +27,9 @@ export function createVitePlugins() {
|
|||
return [
|
||||
Vue(),
|
||||
VueJsx(),
|
||||
WindiCSS(),
|
||||
UnoCSS(),
|
||||
progress(),
|
||||
PurgeIcons(),
|
||||
vueSetupExtend(),
|
||||
ElementPlus({}),
|
||||
AutoImport({
|
||||
include: [
|
||||
|
|
|
|||
|
|
@ -8,11 +8,10 @@ const include = [
|
|||
'pinia',
|
||||
'dayjs',
|
||||
'qrcode',
|
||||
'windicss',
|
||||
'unocss',
|
||||
'vue-router',
|
||||
'vue-types',
|
||||
'vue-i18n',
|
||||
'xe-utils',
|
||||
'crypto-js',
|
||||
'cropperjs',
|
||||
'lodash-es',
|
||||
|
|
@ -102,7 +101,8 @@ const include = [
|
|||
'element-plus/es/components/timeline-item/style/css',
|
||||
'element-plus/es/components/collapse/style/css',
|
||||
'element-plus/es/components/collapse-item/style/css',
|
||||
'element-plus/es/components/button-group/style/css'
|
||||
'element-plus/es/components/button-group/style/css',
|
||||
'element-plus/es/components/text/style/css'
|
||||
]
|
||||
|
||||
const exclude = ['@iconify/json']
|
||||
|
|
|
|||
139
package.json
139
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "yudao-ui-admin-vue3",
|
||||
"version": "1.7.2-snapshot",
|
||||
"version": "1.8.0-snapshot",
|
||||
"description": "基于vue3、vite4、element-plus、typesScript",
|
||||
"author": "xingyu",
|
||||
"private": false,
|
||||
|
|
@ -9,15 +9,16 @@
|
|||
"dev": "vite --mode base",
|
||||
"front": "vite --mode front",
|
||||
"ts:check": "vue-tsc --noEmit",
|
||||
"build:pro": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode pro",
|
||||
"build:dev": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode dev",
|
||||
"build:stage": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode stage",
|
||||
"build:test": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode test",
|
||||
"build:static": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode static",
|
||||
"build:front": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode front",
|
||||
"build:pro": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode pro",
|
||||
"build:dev": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode dev",
|
||||
"build:stage": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode stage",
|
||||
"build:test": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode test",
|
||||
"build:static": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode static",
|
||||
"build:front": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode front",
|
||||
"serve:pro": "vite preview --mode pro",
|
||||
"serve:dev": "vite preview --mode dev",
|
||||
"serve:test": "vite preview --mode test",
|
||||
"preview": "pnpm build && vite preview",
|
||||
"npm:check": "npx npm-check-updates",
|
||||
"clean": "npx rimraf node_modules",
|
||||
"clean:cache": "npx rimraf node_modules/.cache",
|
||||
|
|
@ -31,106 +32,103 @@
|
|||
"@element-plus/icons-vue": "^2.1.0",
|
||||
"@form-create/designer": "^3.1.0",
|
||||
"@form-create/element-ui": "^3.1.17",
|
||||
"@iconify/iconify": "^3.1.0",
|
||||
"@iconify/iconify": "^3.1.1",
|
||||
"@videojs-player/vue": "^1.0.0",
|
||||
"@vueuse/core": "^10.1.0",
|
||||
"@vueuse/core": "^10.2.1",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.10",
|
||||
"@zxcvbn-ts/core": "^2.2.1",
|
||||
"@zxcvbn-ts/core": "^3.0.3",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.3.6",
|
||||
"axios": "^1.4.0",
|
||||
"benz-amr-recorder": "^1.1.5",
|
||||
"bpmn-js-token-simulation": "^0.10.0",
|
||||
"camunda-bpmn-moddle": "^7.0.1",
|
||||
"cropperjs": "^1.5.13",
|
||||
"crypto-js": "^4.1.1",
|
||||
"dayjs": "^1.11.7",
|
||||
"dayjs": "^1.11.9",
|
||||
"diagram-js": "^11.6.0",
|
||||
"echarts": "^5.4.2",
|
||||
"echarts": "^5.4.3",
|
||||
"echarts-wordcloud": "^2.1.0",
|
||||
"element-plus": "2.3.3",
|
||||
"fast-xml-parser": "^4.2.2",
|
||||
"highlight.js": "^11.7.0",
|
||||
"element-plus": "2.3.8",
|
||||
"fast-xml-parser": "^4.2.6",
|
||||
"highlight.js": "^11.8.0",
|
||||
"intro.js": "^7.0.1",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"min-dash": "^4.1.0",
|
||||
"mitt": "^3.0.0",
|
||||
"min-dash": "^4.1.1",
|
||||
"mitt": "^3.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.35",
|
||||
"pinia": "^2.1.6",
|
||||
"qrcode": "^1.5.3",
|
||||
"qs": "^6.11.1",
|
||||
"qs": "^6.11.2",
|
||||
"steady-xml": "^0.1.0",
|
||||
"url": "^0.11.0",
|
||||
"video.js": "^8.0.4",
|
||||
"vue": "3.2.47",
|
||||
"url": "^0.11.1",
|
||||
"video.js": "^7.21.5",
|
||||
"vue": "3.3.4",
|
||||
"vue-dompurify-html": "^4.1.4",
|
||||
"vue-i18n": "9.2.2",
|
||||
"vue-router": "^4.1.6",
|
||||
"vue-types": "^5.0.2",
|
||||
"vue-router": "^4.2.4",
|
||||
"vue-types": "^5.1.1",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"web-storage-cache": "^1.1.1",
|
||||
"xe-utils": "^3.5.7",
|
||||
"xml-js": "^1.6.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.6.1",
|
||||
"@commitlint/config-conventional": "^17.6.1",
|
||||
"@iconify/json": "^2.2.54",
|
||||
"@intlify/unplugin-vue-i18n": "^0.10.0",
|
||||
"@commitlint/cli": "^17.6.7",
|
||||
"@commitlint/config-conventional": "^17.6.7",
|
||||
"@iconify/json": "^2.2.95",
|
||||
"@intlify/unplugin-vue-i18n": "^0.12.2",
|
||||
"@purge-icons/generated": "^0.9.0",
|
||||
"@types/intro.js": "^5.1.1",
|
||||
"@types/lodash-es": "^4.17.7",
|
||||
"@types/node": "^18.16.0",
|
||||
"@types/lodash-es": "^4.17.8",
|
||||
"@types/node": "^20.4.0",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/qrcode": "^1.5.0",
|
||||
"@types/qrcode": "^1.5.1",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.0",
|
||||
"@typescript-eslint/parser": "^5.59.0",
|
||||
"@vitejs/plugin-legacy": "^4.0.2",
|
||||
"@vitejs/plugin-vue": "^4.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
||||
"@typescript-eslint/parser": "^6.2.0",
|
||||
"@unocss/transformer-variant-group": "^0.51.4",
|
||||
"@vitejs/plugin-legacy": "^4.1.1",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
||||
"@vue-macros/volar": "^0.12.3",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"bpmn-js": "^8.9.0",
|
||||
"bpmn-js-properties-panel": "^0.46.0",
|
||||
"consola": "^3.1.0",
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-define-config": "^1.18.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-vue": "^9.11.0",
|
||||
"lint-staged": "^13.2.1",
|
||||
"postcss": "^8.4.23",
|
||||
"consola": "^3.2.3",
|
||||
"eslint": "^8.46.0",
|
||||
"eslint-config-prettier": "^8.9.0",
|
||||
"eslint-define-config": "^1.21.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"eslint-plugin-vue": "^9.15.1",
|
||||
"lint-staged": "^13.2.3",
|
||||
"postcss": "^8.4.27",
|
||||
"postcss-html": "^1.5.0",
|
||||
"postcss-scss": "^4.0.6",
|
||||
"prettier": "^2.8.8",
|
||||
"rimraf": "^5.0.0",
|
||||
"rollup": "^3.20.7",
|
||||
"sass": "^1.62.0",
|
||||
"stylelint": "^15.6.0",
|
||||
"stylelint-config-html": "^1.1.0",
|
||||
"stylelint-config-recommended": "^12.0.0",
|
||||
"stylelint-config-standard": "^33.0.0",
|
||||
"prettier": "^3.0.0",
|
||||
"rimraf": "^5.0.1",
|
||||
"rollup": "^3.27.0",
|
||||
"sass": "^1.64.1",
|
||||
"stylelint": "^15.10.2",
|
||||
"stylelint-config-recommended": "^13.0.0",
|
||||
"stylelint-config-recommended-vue": "^1.5.0",
|
||||
"stylelint-config-standard": "^34.0.0",
|
||||
"stylelint-order": "^6.0.3",
|
||||
"terser": "^5.17.1",
|
||||
"typescript": "5.0.4",
|
||||
"unplugin-auto-import": "^0.15.3",
|
||||
"unplugin-element-plus": "^0.7.1",
|
||||
"unplugin-vue-components": "^0.24.1",
|
||||
"vite": "4.3.1",
|
||||
"terser": "^5.19.2",
|
||||
"typescript": "5.1.6",
|
||||
"unocss": "^0.54.0",
|
||||
"unplugin-auto-import": "^0.16.6",
|
||||
"unplugin-element-plus": "^0.7.2",
|
||||
"unplugin-vue-components": "^0.25.1",
|
||||
"vite": "4.4.7",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-ejs": "^1.6.4",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-plugin-progress": "^0.0.7",
|
||||
"vite-plugin-purge-icons": "^0.9.2",
|
||||
"vite-plugin-svg-icons": "^2.0.1",
|
||||
"vite-plugin-top-level-await": "^1.3.0",
|
||||
"vite-plugin-vue-setup-extend-plus": "^0.1.0",
|
||||
"vite-plugin-windicss": "^1.8.10",
|
||||
"vue-tsc": "^1.4.4",
|
||||
"windicss": "^3.5.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
"vite-plugin-top-level-await": "^1.3.1",
|
||||
"vue-tsc": "^1.8.8"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
|
@ -140,5 +138,10 @@
|
|||
"bugs": {
|
||||
"url": "https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues"
|
||||
},
|
||||
"homepage": "https://gitee.com/yudaocode/yudao-ui-admin-vue3"
|
||||
"homepage": "https://gitee.com/yudaocode/yudao-ui-admin-vue3",
|
||||
"packageManager": "pnpm@8.6.0",
|
||||
"engines": {
|
||||
"node": ">= 16.0.0",
|
||||
"pnpm": ">=8.6.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
10
src/App.vue
10
src/App.vue
|
|
@ -1,8 +1,11 @@
|
|||
<script lang="ts" name="APP" setup>
|
||||
<script lang="ts" setup>
|
||||
import { isDark } from '@/utils/is'
|
||||
import { useAppStore } from '@/store/modules/app'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
||||
import routerSearch from '@/components/RouterSearch/index.vue'
|
||||
|
||||
defineOptions({ name: 'APP' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
const prefixCls = getPrefixCls('app')
|
||||
|
|
@ -24,10 +27,12 @@ setDefaultTheme()
|
|||
<template>
|
||||
<ConfigGlobal :size="currentSize">
|
||||
<RouterView :class="greyMode ? `${prefixCls}-grey-mode` : ''" />
|
||||
<routerSearch />
|
||||
</ConfigGlobal>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
$prefix-cls: #{$namespace}-app;
|
||||
|
||||
.size {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -35,10 +40,11 @@ $prefix-cls: #{$namespace}-app;
|
|||
|
||||
html,
|
||||
body {
|
||||
@extend .size;
|
||||
|
||||
padding: 0 !important;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
@extend .size;
|
||||
|
||||
#app {
|
||||
@extend .size;
|
||||
|
|
|
|||
|
|
@ -37,11 +37,6 @@ export const getInfo = () => {
|
|||
return request.get({ url: '/system/auth/get-permission-info' })
|
||||
}
|
||||
|
||||
// 路由
|
||||
export const getAsyncRoutes = () => {
|
||||
return request.get({ url: '/system/auth/list-menus' })
|
||||
}
|
||||
|
||||
//获取登录验证码
|
||||
export const sendSmsCode = (data: SmsCodeVO) => {
|
||||
return request.post({ url: '/system/auth/send-sms-code', data })
|
||||
|
|
|
|||
|
|
@ -54,3 +54,8 @@ export const getBrand = (id: number) => {
|
|||
export const getBrandParam = (params: PageParam) => {
|
||||
return request.get({ url: '/product/brand/page', params })
|
||||
}
|
||||
|
||||
// 获得商品品牌精简信息列表
|
||||
export const getSimpleBrandList = () => {
|
||||
return request.get({ url: '/product/brand/list-all-simple' })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,17 +17,17 @@ export interface CategoryVO {
|
|||
*/
|
||||
name: string
|
||||
/**
|
||||
* 分类图片
|
||||
* 移动端分类图
|
||||
*/
|
||||
picUrl: string
|
||||
/**
|
||||
* PC 端分类图
|
||||
*/
|
||||
bigPicUrl?: string
|
||||
/**
|
||||
* 分类排序
|
||||
*/
|
||||
sort?: number
|
||||
/**
|
||||
* 分类描述
|
||||
*/
|
||||
description?: string
|
||||
sort: number
|
||||
/**
|
||||
* 开启状态
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@ export const getPropertyList = (params: any) => {
|
|||
}
|
||||
|
||||
// 获得属性项列表
|
||||
export const getPropertyListAndValue = (params: any) => {
|
||||
return request.get({ url: '/product/property/get-value-list', params })
|
||||
export const getPropertyListAndValue = (data: any) => {
|
||||
return request.post({ url: '/product/property/get-value-list', data })
|
||||
}
|
||||
|
||||
// ------------------------ 属性值 -------------------
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface Property {
|
||||
propertyId?: number // 属性编号
|
||||
propertyName?: string // 属性名称
|
||||
valueId?: number // 属性值编号
|
||||
valueName?: string // 属性值名称
|
||||
}
|
||||
|
||||
export interface Sku {
|
||||
id?: number // 商品 SKU 编号
|
||||
spuId?: number // SPU 编号
|
||||
properties?: Property[] // 属性数组
|
||||
price?: number // 商品价格
|
||||
marketPrice?: number // 市场价
|
||||
costPrice?: number // 成本价
|
||||
barCode?: string // 商品条码
|
||||
picUrl?: string // 图片地址
|
||||
stock?: number // 库存
|
||||
weight?: number // 商品重量,单位:kg 千克
|
||||
volume?: number // 商品体积,单位:m^3 平米
|
||||
subCommissionFirstPrice?: number // 一级分销的佣金
|
||||
subCommissionSecondPrice?: number // 二级分销的佣金
|
||||
salesCount?: number // 商品销量
|
||||
}
|
||||
|
||||
export interface Spu {
|
||||
id?: number
|
||||
name?: string // 商品名称
|
||||
categoryId?: number | null // 商品分类
|
||||
keyword?: string // 关键字
|
||||
unit?: number | null // 单位
|
||||
picUrl?: string // 商品封面图
|
||||
sliderPicUrls?: string[] // 商品轮播图
|
||||
introduction?: string // 商品简介
|
||||
deliveryTemplateId?: number | null // 运费模版
|
||||
brandId?: number | null // 商品品牌编号
|
||||
specType?: boolean // 商品规格
|
||||
subCommissionType?: boolean // 分销类型
|
||||
skus?: Sku[] // sku数组
|
||||
description?: string // 商品详情
|
||||
sort?: number // 商品排序
|
||||
giveIntegral?: number // 赠送积分
|
||||
virtualSalesCount?: number // 虚拟销量
|
||||
recommendHot?: boolean // 是否热卖
|
||||
recommendBenefit?: boolean // 是否优惠
|
||||
recommendBest?: boolean // 是否精品
|
||||
recommendNew?: boolean // 是否新品
|
||||
recommendGood?: boolean // 是否优品
|
||||
price?: number // 商品价格
|
||||
salesCount?: number // 商品销量
|
||||
marketPrice?: number // 市场价
|
||||
costPrice?: number // 成本价
|
||||
stock?: number // 商品库存
|
||||
createTime?: Date // 商品创建时间
|
||||
status?: number // 商品状态
|
||||
}
|
||||
|
||||
// 获得 Spu 列表
|
||||
export const getSpuPage = (params: PageParam) => {
|
||||
return request.get({ url: '/product/spu/page', params })
|
||||
}
|
||||
|
||||
// 获得 Spu 列表 tabsCount
|
||||
export const getTabsCount = () => {
|
||||
return request.get({ url: '/product/spu/get-count' })
|
||||
}
|
||||
|
||||
// 创建商品 Spu
|
||||
export const createSpu = (data: Spu) => {
|
||||
return request.post({ url: '/product/spu/create', data })
|
||||
}
|
||||
|
||||
// 更新商品 Spu
|
||||
export const updateSpu = (data: Spu) => {
|
||||
return request.put({ url: '/product/spu/update', data })
|
||||
}
|
||||
|
||||
// 更新商品 Spu status
|
||||
export const updateStatus = (data: { id: number; status: number }) => {
|
||||
return request.put({ url: '/product/spu/update-status', data })
|
||||
}
|
||||
|
||||
// 获得商品 Spu
|
||||
export const getSpu = (id: number) => {
|
||||
return request.get({ url: `/product/spu/get-detail?id=${id}` })
|
||||
}
|
||||
|
||||
// 获得商品 Spu 详情列表
|
||||
export const getSpuDetailList = (ids: number[]) => {
|
||||
return request.get({ url: `/product/spu/list?spuIds=${ids}` })
|
||||
}
|
||||
|
||||
// 删除商品 Spu
|
||||
export const deleteSpu = (id: number) => {
|
||||
return request.delete({ url: `/product/spu/delete?id=${id}` })
|
||||
}
|
||||
|
||||
// 导出商品 Spu Excel
|
||||
export const exportSpu = async (params) => {
|
||||
return await request.download({ url: '/product/spu/export', params })
|
||||
}
|
||||
|
||||
// 获得商品 SPU 精简列表
|
||||
export const getSpuSimpleList = async () => {
|
||||
return request.get({ url: '/product/spu/get-simple-list' })
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import request from '@/config/axios'
|
||||
import { Sku, Spu } from '@/api/mall/product/spu'
|
||||
|
||||
// TODO @puhui999: combinationActivity.ts
|
||||
|
||||
export interface CombinationActivityVO {
|
||||
id?: number
|
||||
name?: string
|
||||
spuId?: number
|
||||
totalLimitCount?: number
|
||||
singleLimitCount?: number
|
||||
startTime?: Date
|
||||
endTime?: Date
|
||||
userSize?: number
|
||||
totalNum?: number
|
||||
successNum?: number
|
||||
orderUserCount?: number
|
||||
virtualGroup?: number
|
||||
status?: number
|
||||
limitDuration?: number
|
||||
products: CombinationProductVO[]
|
||||
}
|
||||
|
||||
// 拼团活动所需属性
|
||||
export interface CombinationProductVO {
|
||||
spuId: number
|
||||
skuId: number
|
||||
activePrice: number // 拼团价格
|
||||
}
|
||||
|
||||
// 扩展 Sku 配置
|
||||
export type SkuExtension = Sku & {
|
||||
productConfig: CombinationProductVO
|
||||
}
|
||||
|
||||
export interface SpuExtension extends Spu {
|
||||
skus: SkuExtension[] // 重写类型
|
||||
}
|
||||
|
||||
// 查询拼团活动列表
|
||||
export const getCombinationActivityPage = async (params) => {
|
||||
return await request.get({ url: '/promotion/combination-activity/page', params })
|
||||
}
|
||||
|
||||
// 查询拼团活动详情
|
||||
export const getCombinationActivity = async (id: number) => {
|
||||
return await request.get({ url: '/promotion/combination-activity/get?id=' + id })
|
||||
}
|
||||
|
||||
// 新增拼团活动
|
||||
export const createCombinationActivity = async (data: CombinationActivityVO) => {
|
||||
return await request.post({ url: '/promotion/combination-activity/create', data })
|
||||
}
|
||||
|
||||
// 修改拼团活动
|
||||
export const updateCombinationActivity = async (data: CombinationActivityVO) => {
|
||||
return await request.put({ url: '/promotion/combination-activity/update', data })
|
||||
}
|
||||
|
||||
// 删除拼团活动
|
||||
export const deleteCombinationActivity = async (id: number) => {
|
||||
return await request.delete({ url: '/promotion/combination-activity/delete?id=' + id })
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// TODO @dhb52:vo 缺少
|
||||
|
||||
// 删除优惠劵
|
||||
export const deleteCoupon = async (id: number) => {
|
||||
return request.delete({
|
||||
url: `/promotion/coupon/delete?id=${id}`
|
||||
})
|
||||
}
|
||||
|
||||
// 获得优惠劵分页
|
||||
export const getCouponPage = async (params: PageParam) => {
|
||||
return request.get({
|
||||
url: '/promotion/coupon/page',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface CouponTemplateVO {
|
||||
id: number
|
||||
name: string
|
||||
status: number
|
||||
totalCount: number
|
||||
takeLimitCount: number
|
||||
takeType: number
|
||||
usePrice: number
|
||||
productScope: number
|
||||
productSpuIds: string
|
||||
validityType: number
|
||||
validStartTime: Date
|
||||
validEndTime: Date
|
||||
fixedStartTerm: number
|
||||
fixedEndTerm: number
|
||||
discountType: number
|
||||
discountPercent: number
|
||||
discountPrice: number
|
||||
discountLimitPrice: number
|
||||
takeCount: number
|
||||
useCount: number
|
||||
}
|
||||
|
||||
// 创建优惠劵模板
|
||||
export function createCouponTemplate(data: CouponTemplateVO) {
|
||||
return request.post({
|
||||
url: '/promotion/coupon-template/create',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新优惠劵模板
|
||||
export function updateCouponTemplate(data: CouponTemplateVO) {
|
||||
return request.put({
|
||||
url: '/promotion/coupon-template/update',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新优惠劵模板的状态
|
||||
export function updateCouponTemplateStatus(id: number, status: [0, 1]) {
|
||||
const data = {
|
||||
id,
|
||||
status
|
||||
}
|
||||
return request.put({
|
||||
url: '/promotion/coupon-template/update-status',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除优惠劵模板
|
||||
export function deleteCouponTemplate(id: number) {
|
||||
return request.delete({
|
||||
url: '/promotion/coupon-template/delete?id=' + id
|
||||
})
|
||||
}
|
||||
|
||||
// 获得优惠劵模板
|
||||
export function getCouponTemplate(id: number) {
|
||||
return request.get({
|
||||
url: '/promotion/coupon-template/get?id=' + id
|
||||
})
|
||||
}
|
||||
|
||||
// 获得优惠劵模板分页
|
||||
export function getCouponTemplatePage(params: PageParam) {
|
||||
return request.get({
|
||||
url: '/promotion/coupon-template/page',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
|
||||
// 导出优惠劵模板 Excel
|
||||
export function exportCouponTemplateExcel(params: PageParam) {
|
||||
return request.get({
|
||||
url: '/promotion/coupon-template/export-excel',
|
||||
params: params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import request from '@/config/axios'
|
||||
import { Sku, Spu } from '@/api/mall/product/spu'
|
||||
|
||||
export interface SeckillActivityVO {
|
||||
id?: number
|
||||
spuId?: number
|
||||
name?: string
|
||||
status?: number
|
||||
remark?: string
|
||||
startTime?: Date
|
||||
endTime?: Date
|
||||
sort?: number
|
||||
configIds?: string
|
||||
orderCount?: number
|
||||
userCount?: number
|
||||
totalPrice?: number
|
||||
totalLimitCount?: number
|
||||
singleLimitCount?: number
|
||||
stock?: number
|
||||
totalStock?: number
|
||||
products?: SeckillProductVO[]
|
||||
}
|
||||
|
||||
// 秒杀活动所需属性
|
||||
export interface SeckillProductVO {
|
||||
skuId: number
|
||||
seckillPrice: number
|
||||
stock: number
|
||||
}
|
||||
|
||||
// 扩展 Sku 配置
|
||||
export type SkuExtension = Sku & {
|
||||
productConfig: SeckillProductVO
|
||||
}
|
||||
|
||||
export interface SpuExtension extends Spu {
|
||||
skus: SkuExtension[] // 重写类型
|
||||
}
|
||||
|
||||
// 查询秒杀活动列表
|
||||
export const getSeckillActivityPage = async (params) => {
|
||||
return await request.get({ url: '/promotion/seckill-activity/page', params })
|
||||
}
|
||||
|
||||
// 查询秒杀活动详情
|
||||
export const getSeckillActivity = async (id: number) => {
|
||||
return await request.get({ url: '/promotion/seckill-activity/get?id=' + id })
|
||||
}
|
||||
|
||||
// 新增秒杀活动
|
||||
export const createSeckillActivity = async (data: SeckillActivityVO) => {
|
||||
return await request.post({ url: '/promotion/seckill-activity/create', data })
|
||||
}
|
||||
|
||||
// 修改秒杀活动
|
||||
export const updateSeckillActivity = async (data: SeckillActivityVO) => {
|
||||
return await request.put({ url: '/promotion/seckill-activity/update', data })
|
||||
}
|
||||
|
||||
// 删除秒杀活动
|
||||
export const deleteSeckillActivity = async (id: number) => {
|
||||
return await request.delete({ url: '/promotion/seckill-activity/delete?id=' + id })
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface SeckillConfigVO {
|
||||
id: number
|
||||
name: string
|
||||
startTime: string
|
||||
endTime: string
|
||||
sliderPicUrls: string[]
|
||||
status: number
|
||||
}
|
||||
|
||||
// 查询秒杀时段配置列表
|
||||
export const getSeckillConfigPage = async (params) => {
|
||||
return await request.get({ url: '/promotion/seckill-config/page', params })
|
||||
}
|
||||
|
||||
// 查询秒杀时段配置详情
|
||||
export const getSeckillConfig = async (id: number) => {
|
||||
return await request.get({ url: '/promotion/seckill-config/get?id=' + id })
|
||||
}
|
||||
|
||||
// 获得所有开启状态的秒杀时段精简列表
|
||||
export const getListAllSimple = async () => {
|
||||
return await request.get({ url: '/promotion/seckill-config/list-all-simple' })
|
||||
}
|
||||
|
||||
// 新增秒杀时段配置
|
||||
export const createSeckillConfig = async (data: SeckillConfigVO) => {
|
||||
return await request.post({ url: '/promotion/seckill-config/create', data })
|
||||
}
|
||||
|
||||
// 修改秒杀时段配置
|
||||
export const updateSeckillConfig = async (data: SeckillConfigVO) => {
|
||||
return await request.put({ url: '/promotion/seckill-config/update', data })
|
||||
}
|
||||
|
||||
// 修改时段配置状态
|
||||
export const updateSeckillConfigStatus = (id: number, status: number) => {
|
||||
const data = {
|
||||
id,
|
||||
status
|
||||
}
|
||||
return request.put({ url: '/promotion/seckill-config/update-status', data: data })
|
||||
}
|
||||
|
||||
// 删除秒杀时段配置
|
||||
export const deleteSeckillConfig = async (id: number) => {
|
||||
return await request.delete({ url: '/promotion/seckill-config/delete?id=' + id })
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface DeliveryExpressVO {
|
||||
id: number
|
||||
code: string
|
||||
name: string
|
||||
logo: string
|
||||
sort: number
|
||||
status: number
|
||||
}
|
||||
|
||||
// 查询快递公司列表
|
||||
export const getDeliveryExpressPage = async (params: PageParam) => {
|
||||
return await request.get({ url: '/trade/delivery/express/page', params })
|
||||
}
|
||||
|
||||
// 查询快递公司详情
|
||||
export const getDeliveryExpress = async (id: number) => {
|
||||
return await request.get({ url: '/trade/delivery/express/get?id=' + id })
|
||||
}
|
||||
|
||||
// 新增快递公司
|
||||
export const createDeliveryExpress = async (data: DeliveryExpressVO) => {
|
||||
return await request.post({ url: '/trade/delivery/express/create', data })
|
||||
}
|
||||
|
||||
// 修改快递公司
|
||||
export const updateDeliveryExpress = async (data: DeliveryExpressVO) => {
|
||||
return await request.put({ url: '/trade/delivery/express/update', data })
|
||||
}
|
||||
|
||||
// 删除快递公司
|
||||
export const deleteDeliveryExpress = async (id: number) => {
|
||||
return await request.delete({ url: '/trade/delivery/express/delete?id=' + id })
|
||||
}
|
||||
|
||||
// 导出快递公司 Excel
|
||||
export const exportDeliveryExpressApi = async (params) => {
|
||||
return await request.download({ url: '/trade/delivery/express/export-excel', params })
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface DeliveryExpressTemplateVO {
|
||||
id: number
|
||||
name: string
|
||||
chargeMode: number
|
||||
sort: number
|
||||
templateCharge: ExpressTemplateChargeVO[]
|
||||
templateFree: ExpressTemplateFreeVO[]
|
||||
}
|
||||
|
||||
export declare type ExpressTemplateChargeVO = {
|
||||
areaIds: number[]
|
||||
startCount: number
|
||||
startPrice: number
|
||||
extraCount: number
|
||||
extraPrice: number
|
||||
}
|
||||
|
||||
export declare type ExpressTemplateFreeVO = {
|
||||
areaIds: number[]
|
||||
freeCount: number
|
||||
freePrice: number
|
||||
}
|
||||
|
||||
// 查询快递运费模板列表
|
||||
export const getDeliveryExpressTemplatePage = async (params: PageParam) => {
|
||||
return await request.get({ url: '/trade/delivery/express-template/page', params })
|
||||
}
|
||||
|
||||
// 查询快递运费模板详情
|
||||
export const getDeliveryExpressTemplate = async (id: number) => {
|
||||
return await request.get({ url: '/trade/delivery/express-template/get?id=' + id })
|
||||
}
|
||||
|
||||
// 查询快递运费模板详情
|
||||
export const getSimpleTemplateList = async () => {
|
||||
return await request.get({ url: '/trade/delivery/express-template/list-all-simple' })
|
||||
}
|
||||
|
||||
// 新增快递运费模板
|
||||
export const createDeliveryExpressTemplate = async (data: DeliveryExpressTemplateVO) => {
|
||||
return await request.post({ url: '/trade/delivery/express-template/create', data })
|
||||
}
|
||||
|
||||
// 修改快递运费模板
|
||||
export const updateDeliveryExpressTemplate = async (data: DeliveryExpressTemplateVO) => {
|
||||
return await request.put({ url: '/trade/delivery/express-template/update', data })
|
||||
}
|
||||
|
||||
// 删除快递运费模板
|
||||
export const deleteDeliveryExpressTemplate = async (id: number) => {
|
||||
return await request.delete({ url: '/trade/delivery/express-template/delete?id=' + id })
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface DeliveryPickUpStoreVO {
|
||||
id: number
|
||||
name: string
|
||||
introduction: string
|
||||
phone: string
|
||||
areaId: number
|
||||
detailAddress: string
|
||||
logo: string
|
||||
openingTime: string
|
||||
closingTime: string
|
||||
latitude: number
|
||||
longitude: number
|
||||
status: number
|
||||
}
|
||||
|
||||
// 查询自提门店列表
|
||||
export const getDeliveryPickUpStorePage = async (params: DeliveryPickUpStorePageReqVO) => {
|
||||
return await request.get({ url: '/trade/delivery/pick-up-store/page', params })
|
||||
}
|
||||
|
||||
// 查询自提门店详情
|
||||
export const getDeliveryPickUpStore = async (id: number) => {
|
||||
return await request.get({ url: '/trade/delivery/pick-up-store/get?id=' + id })
|
||||
}
|
||||
|
||||
// 新增自提门店
|
||||
export const createDeliveryPickUpStore = async (data: DeliveryPickUpStoreVO) => {
|
||||
return await request.post({ url: '/trade/delivery/pick-up-store/create', data })
|
||||
}
|
||||
|
||||
// 修改自提门店
|
||||
export const updateDeliveryPickUpStore = async (data: DeliveryPickUpStoreVO) => {
|
||||
return await request.put({ url: '/trade/delivery/pick-up-store/update', data })
|
||||
}
|
||||
|
||||
// 删除自提门店
|
||||
export const deleteDeliveryPickUpStore = async (id: number) => {
|
||||
return await request.delete({ url: '/trade/delivery/pick-up-store/delete?id=' + id })
|
||||
}
|
||||
|
||||
// 导出自提门店 Excel
|
||||
export const exportDeliveryPickUpStoreApi = async (params) => {
|
||||
return await request.download({ url: '/trade/delivery/pick-up-store/export-excel', params })
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 获得交易订单分页
|
||||
// TODO @xiaobai:改成 getOrderPage
|
||||
export const getOrderList = (params: PageParam) => {
|
||||
return request.get({ url: '/trade/order/page', params })
|
||||
}
|
||||
|
||||
// 获得交易订单详情
|
||||
export const getOrderDetail = (id: number) => {
|
||||
return request.get({ url: '/trade/order/get-detail?id=' + id })
|
||||
}
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
// TODO @xiaobai:这个放到 order/index.ts 里哈
|
||||
// TODO @xiaobai:注释放到变量后面,这样简洁一点
|
||||
// TODO @xiaobai:这个改成 TradeOrderRespVO
|
||||
export interface TradeOrderPageItemRespVO {
|
||||
// 订单编号
|
||||
id?: number
|
||||
// 订单流水号
|
||||
no?: string
|
||||
// 下单时间
|
||||
createTime?: Date
|
||||
// 订单类型
|
||||
type?: number
|
||||
// 订单来源
|
||||
terminal?: number
|
||||
// 用户编号
|
||||
userId?: number
|
||||
// 用户 IP
|
||||
userIp?: string
|
||||
// 用户备注
|
||||
userRemark?: string
|
||||
// 订单状态
|
||||
status?: number
|
||||
// 购买的商品数量
|
||||
productCount?: number
|
||||
// 订单完成时间
|
||||
finishTime?: Date
|
||||
// 订单取消时间
|
||||
cancelTime?: Date
|
||||
// 取消类型
|
||||
cancelType?: number
|
||||
// 商家备注
|
||||
remark?: string
|
||||
// 支付订单编号
|
||||
payOrderId: number
|
||||
// 是否已支付
|
||||
payed?: boolean
|
||||
// 付款时间
|
||||
payTime?: Date
|
||||
// 支付渠道
|
||||
payChannelCode?: string
|
||||
// 商品原价(总)
|
||||
originalPrice?: number
|
||||
// 订单原价(总)
|
||||
orderPrice?: number
|
||||
// 订单优惠(总)
|
||||
discountPrice?: number
|
||||
// 运费金额
|
||||
deliveryPrice?: number
|
||||
// 订单调价(总)
|
||||
adjustPrice?: number
|
||||
// 应付金额(总)
|
||||
payPrice?: number
|
||||
// 配送模板编号
|
||||
deliveryTemplateId?: number
|
||||
// 发货物流公司编号
|
||||
logisticsId?: number
|
||||
// 发货物流单号
|
||||
logisticsNo?: string
|
||||
// 发货状态
|
||||
deliveryStatus?: number
|
||||
// 发货时间
|
||||
deliveryTime?: Date
|
||||
// 收货时间
|
||||
receiveTime?: Date
|
||||
// 收件人名称
|
||||
receiverName?: string
|
||||
// 收件人手机
|
||||
receiverMobile?: string
|
||||
// 收件人地区编号
|
||||
receiverAreaId?: number
|
||||
// 收件人邮编
|
||||
receiverPostCode?: number
|
||||
// 收件人详细地址
|
||||
receiverDetailAddress?: string
|
||||
// 售后状态
|
||||
afterSaleStatus?: number
|
||||
// 退款金额
|
||||
refundPrice?: number
|
||||
// 优惠劵编号
|
||||
couponId?: number
|
||||
// 优惠劵减免金额
|
||||
couponPrice?: number
|
||||
// 积分抵扣的金额
|
||||
pointPrice?: number
|
||||
//收件人地区名字
|
||||
receiverAreaName?: string
|
||||
// 订单项列表
|
||||
items?: TradeOrderItemBaseVO[]
|
||||
//用户信息
|
||||
user?: MemberUserRespDTO
|
||||
}
|
||||
|
||||
// TODO @xiaobai:这个改成 TradeOrderItemRespVO
|
||||
/**
|
||||
* 交易订单项 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
export interface TradeOrderItemBaseVO {
|
||||
// ========== 订单项基本信息 ==========
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
id?: number
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
userId?: number
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
orderId?: number
|
||||
// ========== 商品基本信息 ==========
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
spuId?: number
|
||||
/**
|
||||
* 商品 SPU 名称
|
||||
*/
|
||||
spuName?: string
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
skuId?: number
|
||||
/**
|
||||
* 商品图片
|
||||
*/
|
||||
picUrl?: string
|
||||
/**
|
||||
* 购买数量
|
||||
*/
|
||||
count?: number
|
||||
// ========== 价格 + 支付基本信息 ==========
|
||||
/**
|
||||
* 商品原价(总)
|
||||
*/
|
||||
originalPrice?: number
|
||||
/**
|
||||
* 商品原价(单)
|
||||
*/
|
||||
originalUnitPrice?: number
|
||||
/**
|
||||
* 商品优惠(总)
|
||||
*/
|
||||
discountPrice?: number
|
||||
/**
|
||||
* 商品实付金额(总)
|
||||
*/
|
||||
payPrice?: number
|
||||
/**
|
||||
* 子订单分摊金额(总)
|
||||
*/
|
||||
orderPartPrice?: number
|
||||
/**
|
||||
* 分摊后子订单实付金额(总)
|
||||
*/
|
||||
orderDividePrice?: number
|
||||
// ========== 营销基本信息 ==========
|
||||
// TODO 芋艿:在捉摸一下
|
||||
// ========== 售后基本信息 ==========
|
||||
/**
|
||||
* 售后状态
|
||||
*/
|
||||
afterSaleStatus?: number
|
||||
//属性数组
|
||||
properties?: ProductPropertyValueDetailRespVO[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理后台 - 商品属性值的明细 Response VO
|
||||
*/
|
||||
export interface ProductPropertyValueDetailRespVO {
|
||||
/**
|
||||
* 属性的编号
|
||||
*/
|
||||
propertyId?: number
|
||||
/**
|
||||
* 属性的名称
|
||||
*/
|
||||
propertyName?: string
|
||||
/**
|
||||
* 属性值的编号
|
||||
*/
|
||||
valueId?: number
|
||||
/**
|
||||
* 属性值的名称
|
||||
*/
|
||||
valueName?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单详情查询 请求
|
||||
*/
|
||||
export interface TradeOrderPageReqVO {
|
||||
pageNo: number
|
||||
pageSize: number
|
||||
no?: string
|
||||
userId?: string
|
||||
userNickname?: string
|
||||
userMobile?: string
|
||||
receiverName?: string
|
||||
receiverMobile?: string
|
||||
terminal?: string
|
||||
type?: number
|
||||
status?: number
|
||||
payChannelCode?: string
|
||||
createTime?: [Date, Date]
|
||||
spuName?: string
|
||||
itemCount?: string
|
||||
all?: string
|
||||
}
|
||||
|
||||
//用户信息
|
||||
export interface MemberUserRespDTO {
|
||||
id?: number
|
||||
nickname?: string
|
||||
status?: number
|
||||
avatar?: string
|
||||
mobile?: string
|
||||
}
|
||||
//订单详情选中type
|
||||
export interface SelectType {
|
||||
queryParams: TradeOrderPageReqVO
|
||||
selectTotal: number //选中的数量
|
||||
selectAllFlag: boolean //全选标识
|
||||
selectData: Map<number, Set<string>> //存放涉及选中得页面以及每页选中得数据订单号 全选时根据条件查询 排除取消的list订单
|
||||
unSelectList: Set<string> //登记取消的list 全选标识为true 时登记单独取消的list,再次选中时排除, 全选标识为false 时清空list
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface AccountVO {
|
||||
id?: number
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface ConfigVO {
|
||||
id: number
|
||||
tradeDeductEnable: number
|
||||
tradeDeductUnitPrice: number
|
||||
tradeDeductMaxPrice: number
|
||||
tradeGivePoint: number
|
||||
}
|
||||
|
||||
// 查询积分设置详情
|
||||
export const getConfig = async () => {
|
||||
return await request.get({ url: `/point/config/get` })
|
||||
}
|
||||
|
||||
// 新增修改积分设置
|
||||
export const saveConfig = async (data: ConfigVO) => {
|
||||
return await request.put({ url: `/point/config/save`, data })
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface RecordVO {
|
||||
id: number
|
||||
bizId: string
|
||||
bizType: string
|
||||
type: string
|
||||
title: string
|
||||
description: string
|
||||
point: number
|
||||
totalPoint: number
|
||||
status: number
|
||||
userId: number
|
||||
freezingTime: Date
|
||||
thawingTime: Date
|
||||
createDate: Date
|
||||
}
|
||||
|
||||
// 查询用户积分记录列表
|
||||
export const getRecordPage = async (params) => {
|
||||
return await request.get({ url: `/point/record/page`, params })
|
||||
}
|
||||
|
||||
// 查询用户积分记录详情
|
||||
export const getRecord = async (id: number) => {
|
||||
return await request.get({ url: `/point/record/get?id=` + id })
|
||||
}
|
||||
|
||||
// 新增用户积分记录
|
||||
export const createRecord = async (data: RecordVO) => {
|
||||
return await request.post({ url: `/point/record/create`, data })
|
||||
}
|
||||
|
||||
// 修改用户积分记录
|
||||
export const updateRecord = async (data: RecordVO) => {
|
||||
return await request.put({ url: `/point/record/update`, data })
|
||||
}
|
||||
|
||||
// 删除用户积分记录
|
||||
export const deleteRecord = async (id: number) => {
|
||||
return await request.delete({ url: `/point/record/delete?id=` + id })
|
||||
}
|
||||
|
||||
// 导出用户积分记录 Excel
|
||||
export const exportRecord = async (params) => {
|
||||
return await request.download({ url: `/point/record/export-excel`, params })
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface SignInConfigVO {
|
||||
id: number
|
||||
day: number
|
||||
point: number
|
||||
}
|
||||
|
||||
// 查询积分签到规则列表
|
||||
export const getSignInConfigPage = async (params) => {
|
||||
return await request.get({ url: `/point/sign-in-config/page`, params })
|
||||
}
|
||||
|
||||
// 查询积分签到规则详情
|
||||
export const getSignInConfig = async (id: number) => {
|
||||
return await request.get({ url: `/point/sign-in-config/get?id=` + id })
|
||||
}
|
||||
|
||||
// 新增积分签到规则
|
||||
export const createSignInConfig = async (data: SignInConfigVO) => {
|
||||
return await request.post({ url: `/point/sign-in-config/create`, data })
|
||||
}
|
||||
|
||||
// 修改积分签到规则
|
||||
export const updateSignInConfig = async (data: SignInConfigVO) => {
|
||||
return await request.put({ url: `/point/sign-in-config/update`, data })
|
||||
}
|
||||
|
||||
// 删除积分签到规则
|
||||
export const deleteSignInConfig = async (id: number) => {
|
||||
return await request.delete({ url: `/point/sign-in-config/delete?id=` + id })
|
||||
}
|
||||
|
||||
// 导出积分签到规则 Excel
|
||||
export const exportSignInConfig = async (params) => {
|
||||
return await request.download({ url: `/point/sign-in-config/export-excel`, params })
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
export interface SignInRecordVO {
|
||||
id: number
|
||||
userId: number
|
||||
day: number
|
||||
point: number
|
||||
}
|
||||
|
||||
// 查询用户签到积分列表
|
||||
export const getSignInRecordPage = async (params) => {
|
||||
return await request.get({ url: `/point/sign-in-record/page`, params })
|
||||
}
|
||||
|
||||
// 查询用户签到积分详情
|
||||
export const getSignInRecord = async (id: number) => {
|
||||
return await request.get({ url: `/point/sign-in-record/get?id=` + id })
|
||||
}
|
||||
|
||||
// 新增用户签到积分
|
||||
export const createSignInRecord = async (data: SignInRecordVO) => {
|
||||
return await request.post({ url: `/point/sign-in-record/create`, data })
|
||||
}
|
||||
|
||||
// 修改用户签到积分
|
||||
export const updateSignInRecord = async (data: SignInRecordVO) => {
|
||||
return await request.put({ url: `/point/sign-in-record/update`, data })
|
||||
}
|
||||
|
||||
// 删除用户签到积分
|
||||
export const deleteSignInRecord = async (id: number) => {
|
||||
return await request.delete({ url: `/point/sign-in-record/delete?id=` + id })
|
||||
}
|
||||
|
||||
// 导出用户签到积分 Excel
|
||||
export const exportSignInRecord = async (params) => {
|
||||
return await request.download({ url: `/point/sign-in-record/export-excel`, params })
|
||||
}
|
||||
|
|
@ -5,6 +5,14 @@ export const getAreaTree = async () => {
|
|||
return await request.get({ url: '/system/area/tree' })
|
||||
}
|
||||
|
||||
export const getChildrenArea = async (id: number) => {
|
||||
return await request.get({ url: '/system/area/get-children?id=' + id })
|
||||
}
|
||||
|
||||
export const getAreaListByIds = async (ids) => {
|
||||
return await request.get({ url: '/system/area/get-by-ids?ids=' + ids })
|
||||
}
|
||||
|
||||
// 获得 IP 对应的地区名
|
||||
export const getAreaByIp = async (ip: string) => {
|
||||
return await request.get({ url: '/system/area/get-by-ip?ip=' + ip })
|
||||
|
|
|
|||
|
|
@ -17,6 +17,6 @@ export const getAccessTokenPage = (params: PageParam) => {
|
|||
}
|
||||
|
||||
// 删除 token
|
||||
export const deleteAccessToken = (accessToken: number) => {
|
||||
export const deleteAccessToken = (accessToken: string) => {
|
||||
return request.delete({ url: '/system/oauth2-token/delete?accessToken=' + accessToken })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script lang="ts" name="BackTop" setup>
|
||||
<script lang="ts" setup>
|
||||
import { ElBacktop } from 'element-plus'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'BackTop' })
|
||||
|
||||
const { getPrefixCls, variables } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('backtop')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" name="ConfigGlobal" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useLocaleStore } from '@/store/modules/locale'
|
||||
import { useAppStore } from '@/store/modules/app'
|
||||
|
|
@ -7,6 +7,8 @@ import { useDesign } from '@/hooks/web/useDesign'
|
|||
import { ElementPlusSize } from '@/types/elementPlus'
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
|
||||
defineOptions({ name: 'ConfigGlobal' })
|
||||
|
||||
const { variables } = useDesign()
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script lang="ts" name="ContentDetailWrap" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'ContentDetailWrap' })
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
|
@ -26,7 +28,7 @@ onMounted(() => {
|
|||
<div
|
||||
:class="[
|
||||
`${prefixCls}-header`,
|
||||
'flex border-bottom-1 h-50px items-center text-center pr-10px'
|
||||
'flex b-b-1 h-50px items-center text-center bg-white pr-10px'
|
||||
]"
|
||||
>
|
||||
<div :class="[`${prefixCls}-header__back`, 'flex pl-10px pr-10px ']">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script lang="ts" name="ContentWrap" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'ContentWrap' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('content-wrap')
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts" name="CountTo" setup>
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
import { isNumber } from '@/utils/is'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'CountTo' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('count-to')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script lang="ts" name="Crontab" setup>
|
||||
<script lang="ts" setup>
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { PropType } from 'vue'
|
||||
|
||||
defineOptions({ name: 'Crontab' })
|
||||
|
||||
interface shortcutsType {
|
||||
text: string
|
||||
value: string
|
||||
|
|
@ -966,37 +968,37 @@ const submit = () => {
|
|||
<style scoped>
|
||||
.sc-cron:deep(.el-tabs__item) {
|
||||
height: auto;
|
||||
line-height: 1;
|
||||
padding: 0 7px;
|
||||
line-height: 1;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.sc-cron-num {
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sc-cron-num h2 {
|
||||
font-size: 12px;
|
||||
margin-bottom: 15px;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.sc-cron-num h4 {
|
||||
display: block;
|
||||
height: 32px;
|
||||
line-height: 30px;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
height: 32px;
|
||||
padding: 0 15px;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
background: var(--el-color-primary-light-9);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.sc-cron:deep(.el-tabs__item.is-active) .sc-cron-num h4 {
|
||||
background: var(--el-color-primary);
|
||||
color: #fff;
|
||||
background: var(--el-color-primary);
|
||||
}
|
||||
|
||||
[data-theme='dark'] .sc-cron-num h4 {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@
|
|||
</Dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" name="CopperModal" setup>
|
||||
<script lang="ts" setup>
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
import { dataURLtoBlob } from '@/utils/filt'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
|
@ -121,6 +121,8 @@ import type { CropendResult, Cropper } from './types'
|
|||
import { propTypes } from '@/utils/propTypes'
|
||||
import { CropperImage } from '@/components/Cropper'
|
||||
|
||||
defineOptions({ name: 'CopperModal' })
|
||||
|
||||
const props = defineProps({
|
||||
srcValue: propTypes.string.def(''),
|
||||
circled: propTypes.bool.def(true)
|
||||
|
|
@ -220,7 +222,9 @@ $prefix-cls: #{$namespace}-cropper-am;
|
|||
transparent 75%,
|
||||
rgb(0 0 0 / 25%) 0
|
||||
);
|
||||
background-position: 0 0, 12px 12px;
|
||||
background-position:
|
||||
0 0,
|
||||
12px 12px;
|
||||
background-size: 24px 24px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" name="Cropper" setup>
|
||||
<script lang="ts" setup>
|
||||
import { CSSProperties, PropType } from 'vue'
|
||||
import Cropper from 'cropperjs'
|
||||
import 'cropperjs/dist/cropper.css'
|
||||
|
|
@ -18,6 +18,8 @@ import { useDesign } from '@/hooks/web/useDesign'
|
|||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
|
||||
defineOptions({ name: 'Cropper' })
|
||||
|
||||
type Options = Cropper.Options
|
||||
|
||||
const defaultOptions: Options = {
|
||||
|
|
|
|||
|
|
@ -11,13 +11,15 @@
|
|||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" name="CropperAvatar" setup>
|
||||
<script lang="ts" setup>
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import CopperModal from './CopperModal.vue'
|
||||
|
||||
defineOptions({ name: 'CropperAvatar' })
|
||||
|
||||
const props = defineProps({
|
||||
width: propTypes.string.def('200px'),
|
||||
value: propTypes.string.def(''),
|
||||
|
|
@ -83,14 +85,14 @@ $prefix-cls: #{$namespace}--cropper-avatar;
|
|||
}
|
||||
|
||||
&-image-mask {
|
||||
opacity: 0%;
|
||||
position: absolute;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
border-radius: inherit;
|
||||
border: inherit;
|
||||
background: rgb(0 0 0 / 40%);
|
||||
cursor: pointer;
|
||||
background: rgb(0 0 0 / 40%);
|
||||
border: inherit;
|
||||
border-radius: inherit;
|
||||
opacity: 0;
|
||||
transition: opacity 0.4s;
|
||||
|
||||
::v-deep(svg) {
|
||||
|
|
@ -99,7 +101,7 @@ $prefix-cls: #{$namespace}--cropper-avatar;
|
|||
}
|
||||
|
||||
&-image-mask:hover {
|
||||
opacity: 4000%;
|
||||
opacity: 40;
|
||||
}
|
||||
|
||||
&-upload-btn {
|
||||
|
|
@ -121,21 +123,18 @@ $prefix-cls: #{$namespace}--cropper-avatar;
|
|||
height: 120px;
|
||||
}
|
||||
|
||||
.user-info-head:hover:after {
|
||||
content: '+';
|
||||
.user-info-head:hover::after {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
color: #eee;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
inset: 0;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
cursor: pointer;
|
||||
font-style: normal;
|
||||
line-height: 110px;
|
||||
color: #eee;
|
||||
cursor: pointer;
|
||||
background: rgb(0 0 0 / 50%);
|
||||
border-radius: 50%;
|
||||
content: '+';
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" name="Descriptions" setup>
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
|
@ -6,6 +6,8 @@ import { propTypes } from '@/utils/propTypes'
|
|||
import { useAppStore } from '@/store/modules/app'
|
||||
import { DescriptionsSchema } from '@/types/descriptions'
|
||||
|
||||
defineOptions({ name: 'Descriptions' })
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
const mobile = computed(() => appStore.getMobile)
|
||||
|
|
@ -69,14 +71,14 @@ const toggleClick = () => {
|
|||
<div
|
||||
:class="[
|
||||
prefixCls,
|
||||
'bg-[var(--el-color-white)] dark:(bg-[var(--el-bg-color)] border-[var(--el-border-color)] border-1px)'
|
||||
'bg-[var(--el-color-white)] dark:bg-[var(--el-bg-color)] dark:border-[var(--el-border-color)] dark:border-1px'
|
||||
]"
|
||||
>
|
||||
<div
|
||||
v-if="title"
|
||||
:class="[
|
||||
`${prefixCls}-header`,
|
||||
'h-50px flex justify-between items-center border-bottom-1 border-solid border-[var(--tags-view-border-color)] px-10px cursor-pointer dark:border-[var(--el-border-color)]'
|
||||
'h-50px flex justify-between items-center b-b-1 border-solid border-[var(--el-border-color)] px-10px cursor-pointer dark:border-[var(--el-border-color)]'
|
||||
]"
|
||||
@click="toggleClick"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<script lang="ts" name="Dialog" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { isNumber } from '@/utils/is'
|
||||
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
defineOptions({ name: 'Dialog' })
|
||||
|
||||
const slots = useSlots()
|
||||
|
||||
const props = defineProps({
|
||||
|
|
@ -14,7 +17,7 @@ const props = defineProps({
|
|||
})
|
||||
|
||||
const getBindValue = computed(() => {
|
||||
const delArr: string[] = ['fullscreen', 'title', 'maxHeight']
|
||||
const delArr: string[] = ['fullscreen', 'title', 'maxHeight', 'appendToBody']
|
||||
const attrs = useAttrs()
|
||||
const obj = { ...attrs, ...props }
|
||||
for (const key in obj) {
|
||||
|
|
@ -96,13 +99,19 @@ const dialogStyle = computed(() => {
|
|||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.#{$elNamespace}-dialog__header {
|
||||
margin-right: 0 !important;
|
||||
border-bottom: 1px solid var(--tags-view-border-color);
|
||||
}
|
||||
.#{$elNamespace}-dialog {
|
||||
&__header {
|
||||
margin-right: 0 !important;
|
||||
border-bottom: 1px solid var(--el-border-color);
|
||||
}
|
||||
|
||||
.#{$elNamespace}-dialog__footer {
|
||||
border-top: 1px solid var(--tags-view-border-color);
|
||||
&__body {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
border-top: 1px solid var(--el-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
.is-hover {
|
||||
|
|
@ -110,14 +119,4 @@ const dialogStyle = computed(() => {
|
|||
color: var(--el-color-primary) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dark {
|
||||
.#{$elNamespace}-dialog__header {
|
||||
border-bottom: 1px solid var(--el-border-color);
|
||||
}
|
||||
|
||||
.#{$elNamespace}-dialog__footer {
|
||||
border-top: 1px solid var(--el-border-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
</template>
|
||||
</el-alert>
|
||||
</template>
|
||||
<script setup lang="tsx" name="DocAlert">
|
||||
<script setup lang="tsx">
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
|
||||
defineOptions({ name: 'DocAlert' })
|
||||
|
||||
const props = defineProps({
|
||||
title: propTypes.string,
|
||||
url: propTypes.string
|
||||
|
|
@ -25,8 +27,8 @@ const getEnable = () => {
|
|||
</script>
|
||||
<style scoped>
|
||||
.el-alert--success.is-light {
|
||||
border: 1px solid green;
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
border: 1px solid green;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" name="EChart" setup>
|
||||
<script lang="ts" setup>
|
||||
import type { EChartsOption } from 'echarts'
|
||||
import echarts from '@/plugins/echarts'
|
||||
import { debounce } from 'lodash-es'
|
||||
|
|
@ -9,6 +9,8 @@ import { useAppStore } from '@/store/modules/app'
|
|||
import { isString } from '@/utils/is'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'EChart' })
|
||||
|
||||
const { getPrefixCls, variables } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('echart')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" name="Editor" setup>
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||
import { i18nChangeLanguage, IDomEditor, IEditorConfig } from '@wangeditor/editor'
|
||||
|
|
@ -8,6 +8,8 @@ import { ElMessage } from 'element-plus'
|
|||
import { useLocaleStore } from '@/store/modules/locale'
|
||||
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||
|
||||
defineOptions({ name: 'Editor' })
|
||||
|
||||
type InsertFnType = (url: string, alt: string, href: string) => void
|
||||
|
||||
const localeStore = useLocaleStore()
|
||||
|
|
@ -162,7 +164,6 @@ const handleChange = (editor: IDomEditor) => {
|
|||
// 组件销毁时,及时销毁编辑器
|
||||
onBeforeUnmount(() => {
|
||||
const editor = unref(editorRef.value)
|
||||
if (editor === null) return
|
||||
|
||||
// 销毁,并移除 editor
|
||||
editor?.destroy()
|
||||
|
|
@ -179,12 +180,12 @@ defineExpose({
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="border-1 border-solid border-[var(--tags-view-border-color)] z-99">
|
||||
<div class="border-1 border-solid border-[var(--el-border-color)] z-99">
|
||||
<!-- 工具栏 -->
|
||||
<Toolbar
|
||||
:editor="editorRef"
|
||||
:editorId="editorId"
|
||||
class="border-bottom-1 border-solid border-[var(--tags-view-border-color)]"
|
||||
class="border-0 b-b-1 border-solid border-[var(--el-border-color)]"
|
||||
/>
|
||||
<!-- 编辑器 -->
|
||||
<Editor
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts" name="Error" setup>
|
||||
<script lang="ts" setup>
|
||||
import pageError from '@/assets/svgs/404.svg'
|
||||
import networkError from '@/assets/svgs/500.svg'
|
||||
import noPermission from '@/assets/svgs/403.svg'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
|
||||
defineOptions({ name: 'Error' })
|
||||
|
||||
interface ErrorMap {
|
||||
url: string
|
||||
message: string
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
<script lang="tsx">
|
||||
import { PropType, defineComponent, ref, computed, unref, watch, onMounted } from 'vue'
|
||||
import { ElForm, ElFormItem, ElRow, ElCol, ElTooltip } from 'element-plus'
|
||||
import { computed, defineComponent, onMounted, PropType, ref, unref, watch } from 'vue'
|
||||
import { ElCol, ElForm, ElFormItem, ElRow, ElTooltip } from 'element-plus'
|
||||
import { componentMap } from './componentMap'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { getSlot } from '@/utils/tsxHelper'
|
||||
import {
|
||||
setTextPlaceholder,
|
||||
setGridProp,
|
||||
setComponentProps,
|
||||
setItemComponentSlots,
|
||||
initModel,
|
||||
setFormItemSlots
|
||||
setComponentProps,
|
||||
setFormItemSlots,
|
||||
setGridProp,
|
||||
setItemComponentSlots,
|
||||
setTextPlaceholder
|
||||
} from './helper'
|
||||
import { useRenderSelect } from './components/useRenderSelect'
|
||||
import { useRenderRadio } from './components/useRenderRadio'
|
||||
|
|
@ -27,6 +27,7 @@ const { getPrefixCls } = useDesign()
|
|||
const prefixCls = getPrefixCls('form')
|
||||
|
||||
export default defineComponent({
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
name: 'Form',
|
||||
props: {
|
||||
// 生成Form的布局结构数组
|
||||
|
|
@ -196,7 +197,7 @@ export default defineComponent({
|
|||
<span>{item.label}</span>
|
||||
<ElTooltip placement="right" raw-content>
|
||||
{{
|
||||
content: () => <span v-html={item.labelMessage}></span>,
|
||||
content: () => <span v-dompurify-html={item.labelMessage}></span>,
|
||||
default: () => (
|
||||
<Icon
|
||||
icon="ep:warning"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { Slots } from 'vue'
|
||||
import { getSlot } from '@/utils/tsxHelper'
|
||||
import { PlaceholderMoel } from './types'
|
||||
import { PlaceholderModel } from './types'
|
||||
import { FormSchema } from '@/types/form'
|
||||
import { ColProps } from '@/types/components'
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ import { ColProps } from '@/types/components'
|
|||
* @returns 返回提示信息对象
|
||||
* @description 用于自动设置placeholder
|
||||
*/
|
||||
export const setTextPlaceholder = (schema: FormSchema): PlaceholderMoel => {
|
||||
export const setTextPlaceholder = (schema: FormSchema): PlaceholderModel => {
|
||||
const { t } = useI18n()
|
||||
const textMap = ['Input', 'Autocomplete', 'InputNumber', 'InputPassword']
|
||||
const selectMap = ['Select', 'SelectV2', 'TimePicker', 'DatePicker', 'TimeSelect', 'TimeSelect']
|
||||
|
|
@ -108,8 +108,8 @@ export const setItemComponentSlots = (
|
|||
/**
|
||||
*
|
||||
* @param schema Form表单结构化数组
|
||||
* @param formModel FormMoel
|
||||
* @returns FormMoel
|
||||
* @param formModel FormModel
|
||||
* @returns FormModel
|
||||
* @description 生成对应的formModel
|
||||
*/
|
||||
export const initModel = (schema: FormSchema[], formModel: Recordable) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { FormSchema } from '@/types/form'
|
||||
|
||||
export interface PlaceholderMoel {
|
||||
export interface PlaceholderModel {
|
||||
placeholder?: string
|
||||
startPlaceholder?: string
|
||||
endPlaceholder?: string
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<script lang="ts" name="IFrame" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
|
||||
defineOptions({ name: 'IFrame' })
|
||||
|
||||
const props = defineProps({
|
||||
src: propTypes.string.def('')
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<script lang="ts" name="Icon" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import Iconify from '@purge-icons/generated'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'Icon' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('icon')
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<script lang="ts" name="IconSelect" setup>
|
||||
<script lang="ts" setup>
|
||||
import { CSSProperties } from 'vue'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { IconJson } from '@/components/Icon/src/data'
|
||||
|
||||
defineOptions({ name: 'IconSelect' })
|
||||
|
||||
type ParameterCSSProperties = (item?: string) => CSSProperties | undefined
|
||||
|
||||
const props = defineProps({
|
||||
|
|
@ -189,10 +191,10 @@ watch(
|
|||
|
||||
.icon-item {
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
color: var(--el-color-primary);
|
||||
transition: all 0.4s;
|
||||
border-color: var(--el-color-primary);
|
||||
transform: scaleX(1.05);
|
||||
transition: all 0.4s;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,15 +215,15 @@ watch(
|
|||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
height: 30px;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__header),
|
||||
:deep(.el-tabs__nav-wrap) {
|
||||
margin: 0;
|
||||
position: static;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script lang="ts" name="ImageViewer" setup>
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
|
||||
defineOptions({ name: 'ImageViewer' })
|
||||
|
||||
const props = defineProps({
|
||||
urlList: {
|
||||
type: Array as PropType<string[]>,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts" name="InfoTip" setup>
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { TipSchema } from '@/types/infoTip'
|
||||
|
||||
defineOptions({ name: 'InfoTip' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('infotip')
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
<script lang="ts" name="InputPassword" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useConfigGlobal } from '@/hooks/web/useConfigGlobal'
|
||||
import type { ZxcvbnResult } from '@zxcvbn-ts/core'
|
||||
import { zxcvbn } from '@zxcvbn-ts/core'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'InputPassword' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('input-password')
|
||||
|
|
@ -94,7 +96,7 @@ $prefix-cls: #{$namespace}-input-password;
|
|||
background-color: transparent;
|
||||
border-color: var(--el-color-white);
|
||||
border-style: solid;
|
||||
border-width: 0 5px 0 5px;
|
||||
border-width: 0 5px;
|
||||
content: '';
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +114,9 @@ $prefix-cls: #{$namespace}-input-password;
|
|||
height: inherit;
|
||||
background-color: transparent;
|
||||
border-radius: inherit;
|
||||
transition: width 0.5s ease-in-out, background 0.25s;
|
||||
transition:
|
||||
width 0.5s ease-in-out,
|
||||
background 0.25s;
|
||||
|
||||
&[data-score='0'] {
|
||||
width: 20%;
|
||||
|
|
|
|||
|
|
@ -14,9 +14,11 @@
|
|||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</template>
|
||||
<script name="Pagination" setup>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
defineOptions({ name: 'Pagination' })
|
||||
|
||||
const props = defineProps({
|
||||
// 总条目数
|
||||
total: {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" name="Qrcode" setup>
|
||||
<script lang="ts" setup>
|
||||
import { computed, nextTick, PropType, ref, unref, watch } from 'vue'
|
||||
import QRCode, { QRCodeRenderersOptions } from 'qrcode'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
|
|
@ -7,6 +7,8 @@ import { useDesign } from '@/hooks/web/useDesign'
|
|||
import { isString } from '@/utils/is'
|
||||
import { QrcodeLogo } from '@/types/qrcode'
|
||||
|
||||
defineOptions({ name: 'Qrcode' })
|
||||
|
||||
const props = defineProps({
|
||||
// img 或者 canvas,img不支持logo嵌套
|
||||
tag: propTypes.string.validate((v: string) => ['canvas', 'img'].includes(v)).def('canvas'),
|
||||
|
|
@ -241,7 +243,7 @@ $prefix-cls: #{$namespace}-qrcode;
|
|||
|
||||
.#{$prefix-cls} {
|
||||
&--disabled {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
background: rgb(255 255 255 / 95%);
|
||||
|
||||
& > div {
|
||||
transform: translate(-50%, -50%);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<ElDialog v-model="showSearch" :show-close="false" title="菜单搜索">
|
||||
<el-select
|
||||
filterable
|
||||
:reserve-keyword="false"
|
||||
remote
|
||||
placeholder="请输入菜单内容"
|
||||
:remote-method="remoteMethod"
|
||||
style="width: 100%"
|
||||
@change="handleChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</ElDialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const router = useRouter() // 路由对象
|
||||
const showSearch = ref(false) // 是否显示弹框
|
||||
const value: Ref = ref('') // 用户输入的值
|
||||
|
||||
const routers = router.getRoutes() // 路由对象
|
||||
const options = computed(() => {
|
||||
// 提示选项
|
||||
if (!value.value) {
|
||||
return []
|
||||
}
|
||||
const list = routers.filter((item: any) => {
|
||||
if (item.meta.title?.indexOf(value.value) > -1 || item.path.indexOf(value.value) > -1) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
return list.map((item) => {
|
||||
return {
|
||||
label: `${item.meta.title}${item.path}`,
|
||||
value: item.path
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
function remoteMethod(data) {
|
||||
// 这里可以执行相应的操作(例如打开搜索框等)
|
||||
value.value = data
|
||||
}
|
||||
|
||||
function handleChange(path) {
|
||||
router.push({ path })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('keydown', listenKey)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('keydown', listenKey)
|
||||
})
|
||||
|
||||
// 监听 ctrl + k
|
||||
function listenKey(event) {
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
|
||||
showSearch.value = !showSearch.value
|
||||
// 这里可以执行相应的操作(例如打开搜索框等)
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openSearch: () => {
|
||||
showSearch.value = true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" name="Search" setup>
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
|
||||
|
|
@ -7,6 +7,8 @@ import { findIndex } from '@/utils'
|
|||
import { cloneDeep } from 'lodash-es'
|
||||
import { FormSchema } from '@/types/form'
|
||||
|
||||
defineOptions({ name: 'Search' })
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<script lang="ts" name="Sticky" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { isClient, useEventListener, useWindowSize } from '@vueuse/core'
|
||||
import type { CSSProperties } from 'vue'
|
||||
|
||||
defineOptions({ name: 'Sticky' })
|
||||
|
||||
const props = defineProps({
|
||||
// 距离顶部或者底部的距离(单位px)
|
||||
offset: propTypes.number.def(0),
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { set } from 'lodash-es'
|
|||
import { Pagination, TableColumn, TableSetPropsType, TableSlotDefault } from '@/types/table'
|
||||
|
||||
export default defineComponent({
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
name: 'Table',
|
||||
props: {
|
||||
pageSize: propTypes.number.def(10),
|
||||
|
|
@ -302,6 +303,7 @@ export default defineComponent({
|
|||
margin-left: 0;
|
||||
padding: 8px 4px;
|
||||
}
|
||||
|
||||
:deep(.el-button.is-link) {
|
||||
margin-left: 0;
|
||||
padding: 8px 4px;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<script lang="ts" name="Tooltip" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
|
||||
defineOptions({ name: 'Tooltip' })
|
||||
|
||||
defineProps({
|
||||
titel: propTypes.string.def(''),
|
||||
message: propTypes.string.def(''),
|
||||
|
|
|
|||
|
|
@ -32,13 +32,15 @@
|
|||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts" name="UploadFile">
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||
import type { UploadInstance, UploadUserFile, UploadProps, UploadRawFile } from 'element-plus'
|
||||
|
||||
defineOptions({ name: 'UploadFile' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
|
|
@ -143,21 +145,25 @@ const listToString = (list: UploadUserFile[], separator?: string) => {
|
|||
.upload-file-uploader {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
:deep(.upload-file-list .el-upload-list__item) {
|
||||
border: 1px solid #e4e7ed;
|
||||
line-height: 2;
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:deep(.el-upload-list__item-file-name) {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
:deep(.upload-file-list .ele-upload-list__item-content) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
:deep(.ele-upload-list__item-content-action .el-link) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,13 +50,15 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="UploadImg">
|
||||
<script lang="ts" setup>
|
||||
import type { UploadProps } from 'element-plus'
|
||||
|
||||
import { generateUUID } from '@/utils'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||
|
||||
defineOptions({ name: 'UploadImg' })
|
||||
|
||||
type FileTypes =
|
||||
| 'image/apng'
|
||||
| 'image/bmp'
|
||||
|
|
@ -79,7 +81,7 @@ const props = defineProps({
|
|||
fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // 图片类型限制 ==> 非必传(默认为 ["image/jpeg", "image/png", "image/gif"])
|
||||
height: propTypes.string.def('150px'), // 组件高度 ==> 非必传(默认为 150px)
|
||||
width: propTypes.string.def('150px'), // 组件宽度 ==> 非必传(默认为 150px)
|
||||
borderRadius: propTypes.string.def('8px') // 组件边框圆角 ==> 非必传(默认为 8px)
|
||||
borderradius: propTypes.string.def('8px') // 组件边框圆角 ==> 非必传(默认为 8px)
|
||||
})
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
|
@ -130,29 +132,34 @@ const uploadError = () => {
|
|||
:deep(.el-upload),
|
||||
:deep(.el-upload-dragger) {
|
||||
border: 1px dashed var(--el-color-danger) !important;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.disabled) {
|
||||
.el-upload,
|
||||
.el-upload-dragger {
|
||||
cursor: not-allowed !important;
|
||||
background: var(--el-disabled-bg-color);
|
||||
border: 1px dashed var(--el-border-color-darker) !important;
|
||||
|
||||
&:hover {
|
||||
border: 1px dashed var(--el-border-color-darker) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload-box {
|
||||
.no-border {
|
||||
:deep(.el-upload) {
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.upload) {
|
||||
.el-upload {
|
||||
position: relative;
|
||||
|
|
@ -163,14 +170,17 @@ const uploadError = () => {
|
|||
height: v-bind(height);
|
||||
overflow: hidden;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
border-radius: v-bind(borderRadius);
|
||||
border-radius: v-bind(borderradius);
|
||||
transition: var(--el-transition-duration-fast);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
|
||||
.upload-handle {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload-dragger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -181,20 +191,24 @@ const uploadError = () => {
|
|||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
border-radius: v-bind(borderRadius);
|
||||
border-radius: v-bind(borderradius);
|
||||
|
||||
&:hover {
|
||||
border: 1px dashed var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload-dragger.is-dragover {
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
border: 2px dashed var(--el-color-primary) !important;
|
||||
}
|
||||
|
||||
.upload-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.upload-empty {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
|
@ -204,11 +218,13 @@ const uploadError = () => {
|
|||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
color: var(--el-color-info);
|
||||
|
||||
.el-icon {
|
||||
font-size: 28px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.upload-handle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
@ -223,6 +239,7 @@ const uploadError = () => {
|
|||
background: rgb(0 0 0 / 60%);
|
||||
opacity: 0;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
|
||||
.handle-icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -230,11 +247,13 @@ const uploadError = () => {
|
|||
justify-content: center;
|
||||
padding: 0 6%;
|
||||
color: aliceblue;
|
||||
|
||||
.el-icon {
|
||||
margin-bottom: 40%;
|
||||
font-size: 130%;
|
||||
line-height: 130%;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 85%;
|
||||
line-height: 85%;
|
||||
|
|
@ -243,6 +262,7 @@ const uploadError = () => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload__tip {
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
<template>
|
||||
<div class="upload-box">
|
||||
<el-upload
|
||||
:action="updateUrl"
|
||||
list-type="picture-card"
|
||||
:class="['upload', drag ? 'no-border' : '']"
|
||||
v-model:file-list="fileList"
|
||||
:multiple="true"
|
||||
:limit="limit"
|
||||
:headers="uploadHeaders"
|
||||
:accept="fileType.join(',')"
|
||||
:action="updateUrl"
|
||||
:before-upload="beforeUpload"
|
||||
:class="['upload', drag ? 'no-border' : '']"
|
||||
:drag="drag"
|
||||
:headers="uploadHeaders"
|
||||
:limit="limit"
|
||||
:multiple="true"
|
||||
:on-error="uploadError"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="uploadSuccess"
|
||||
:on-error="uploadError"
|
||||
:drag="drag"
|
||||
:accept="fileType.join(',')"
|
||||
list-type="picture-card"
|
||||
>
|
||||
<div class="upload-empty">
|
||||
<slot name="empty">
|
||||
|
|
@ -40,19 +40,21 @@
|
|||
</div>
|
||||
<el-image-viewer
|
||||
v-if="imgViewVisible"
|
||||
@close="imgViewVisible = false"
|
||||
:url-list="[viewImageUrl]"
|
||||
@close="imgViewVisible = false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts" name="UploadImgs">
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
import type { UploadFile, UploadProps, UploadUserFile } from 'element-plus'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import type { UploadProps, UploadFile, UploadUserFile } from 'element-plus'
|
||||
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||
|
||||
defineOptions({ name: 'UploadImgs' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
type FileTypes =
|
||||
|
|
@ -80,7 +82,7 @@ const props = defineProps({
|
|||
fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // 图片类型限制 ==> 非必传(默认为 ["image/jpeg", "image/png", "image/gif"])
|
||||
height: propTypes.string.def('150px'), // 组件高度 ==> 非必传(默认为 150px)
|
||||
width: propTypes.string.def('150px'), // 组件宽度 ==> 非必传(默认为 150px)
|
||||
borderRadius: propTypes.string.def('8px') // 组件边框圆角 ==> 非必传(默认为 8px)
|
||||
borderradius: propTypes.string.def('8px') // 组件边框圆角 ==> 非必传(默认为 8px)
|
||||
})
|
||||
|
||||
const uploadHeaders = ref({
|
||||
|
|
@ -88,8 +90,19 @@ const uploadHeaders = ref({
|
|||
'tenant-id': getTenantId()
|
||||
})
|
||||
|
||||
const fileList = ref<UploadUserFile[]>(props.modelValue)
|
||||
|
||||
const fileList = ref<UploadUserFile[]>([])
|
||||
// fix: 改为动态监听赋值解决图片回显问题
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(data) => {
|
||||
if (!data) return
|
||||
fileList.value = data
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
/**
|
||||
* @description 文件上传之前判断
|
||||
* @param rawFile 上传的文件
|
||||
|
|
@ -116,9 +129,11 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
|||
interface UploadEmits {
|
||||
(e: 'update:modelValue', value: UploadUserFile[]): void
|
||||
}
|
||||
|
||||
const emit = defineEmits<UploadEmits>()
|
||||
const uploadSuccess = (response, uploadFile: UploadFile) => {
|
||||
if (!response) return
|
||||
// TODO 多图上传组件成功后只是把保存成功后的url替换掉组件选图时的文件路径,所以返回的fileList包含的是一个包含文件信息的对象列表
|
||||
uploadFile.url = response.data
|
||||
emit('update:modelValue', fileList.value)
|
||||
message.success('上传成功')
|
||||
|
|
@ -159,35 +174,40 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.is-error {
|
||||
.upload {
|
||||
:deep(.el-upload--picture-card),
|
||||
:deep(.el-upload-dragger) {
|
||||
border: 1px dashed var(--el-color-danger) !important;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.disabled) {
|
||||
.el-upload--picture-card,
|
||||
.el-upload-dragger {
|
||||
cursor: not-allowed;
|
||||
background: var(--el-disabled-bg-color) !important;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--el-border-color-darker) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload-box {
|
||||
.no-border {
|
||||
:deep(.el-upload--picture-card) {
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.upload) {
|
||||
.el-upload-dragger {
|
||||
display: flex;
|
||||
|
|
@ -198,27 +218,32 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
|||
padding: 0;
|
||||
overflow: hidden;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
border-radius: v-bind(borderRadius);
|
||||
border-radius: v-bind(borderradius);
|
||||
|
||||
&:hover {
|
||||
border: 1px dashed var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload-dragger.is-dragover {
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
border: 2px dashed var(--el-color-primary) !important;
|
||||
}
|
||||
|
||||
.el-upload-list__item,
|
||||
.el-upload--picture-card {
|
||||
width: v-bind(width);
|
||||
height: v-bind(height);
|
||||
background-color: transparent;
|
||||
border-radius: v-bind(borderRadius);
|
||||
border-radius: v-bind(borderradius);
|
||||
}
|
||||
|
||||
.upload-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.upload-handle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
@ -233,6 +258,7 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
|||
background: rgb(0 0 0 / 60%);
|
||||
opacity: 0;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
|
||||
.handle-icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -240,15 +266,18 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
|||
justify-content: center;
|
||||
padding: 0 6%;
|
||||
color: aliceblue;
|
||||
|
||||
.el-icon {
|
||||
margin-bottom: 15%;
|
||||
font-size: 140%;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload-list__item {
|
||||
&:hover {
|
||||
.upload-handle {
|
||||
|
|
@ -256,6 +285,7 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -263,12 +293,14 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
|||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
color: var(--el-color-info);
|
||||
|
||||
.el-icon {
|
||||
font-size: 28px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload__tip {
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -57,7 +57,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script name="VerifyPoints" setup type="text/babel">
|
||||
<script setup type="text/babel">
|
||||
/**
|
||||
* VerifyPoints
|
||||
* @description 点选
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script name="VerifySlide" setup type="text/babel">
|
||||
<script setup type="text/babel">
|
||||
/**
|
||||
* VerifySlide
|
||||
* @description 滑块
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script lang="ts" name="XButton" setup>
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
|
||||
defineOptions({ name: 'XButton' })
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: propTypes.bool.def(false),
|
||||
loading: propTypes.bool.def(false),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script lang="ts" name="XTextButton" setup>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { PropType } from 'vue'
|
||||
|
||||
defineOptions({ name: 'XTextButton' })
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: propTypes.bool.def(false),
|
||||
loading: propTypes.bool.def(false),
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="MyProcessDesigner">
|
||||
<script lang="ts" setup>
|
||||
// import 'bpmn-js/dist/assets/diagram-js.css' // 左边工具栏以及编辑节点的样式
|
||||
// import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
|
||||
// import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
|
||||
|
|
@ -244,6 +244,9 @@ import { XmlNode, XmlNodeType, parseXmlString } from 'steady-xml'
|
|||
// const eventName = reactive({
|
||||
// name: ''
|
||||
// })
|
||||
|
||||
defineOptions({ name: 'MyProcessDesigner' })
|
||||
|
||||
const bpmnCanvas = ref()
|
||||
const refFile = ref()
|
||||
const emit = defineEmits([
|
||||
|
|
|
|||
|
|
@ -6,10 +6,14 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="MyProcessViewer">
|
||||
<script lang="ts" setup>
|
||||
import BpmnViewer from 'bpmn-js/lib/Viewer'
|
||||
import DefaultEmptyXML from './plugins/defaultEmpty'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
|
||||
defineOptions({ name: 'MyProcessViewer' })
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
// BPMN XML 字符串
|
||||
|
|
@ -403,6 +407,7 @@ watch(
|
|||
stroke-dasharray: 4px !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
}
|
||||
|
||||
.highlight-todo.djs-shape .djs-visual > :nth-child(1) {
|
||||
fill: #1890ff !important;
|
||||
stroke: #1890ff !important;
|
||||
|
|
@ -414,8 +419,9 @@ watch(
|
|||
stroke: #1890ff !important;
|
||||
stroke-dasharray: 4px !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
marker-end: url(#sequenceflow-end-_E7DFDF-_E7DFDF-803g1kf6zwzmcig1y2ulm5egr);
|
||||
marker-end: url('#sequenceflow-end-_E7DFDF-_E7DFDF-803g1kf6zwzmcig1y2ulm5egr');
|
||||
}
|
||||
|
||||
:deep(.highlight-todo.djs-shape .djs-visual > :nth-child(1)) {
|
||||
fill: #1890ff !important;
|
||||
stroke: #1890ff !important;
|
||||
|
|
@ -429,14 +435,17 @@ watch(
|
|||
stroke: green !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
}
|
||||
|
||||
.highlight.djs-shape .djs-visual > :nth-child(2) {
|
||||
fill: green !important;
|
||||
}
|
||||
|
||||
.highlight.djs-shape .djs-visual > path {
|
||||
fill: green !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
stroke: green !important;
|
||||
}
|
||||
|
||||
.highlight.djs-connection > .djs-visual > path {
|
||||
stroke: green !important;
|
||||
}
|
||||
|
|
@ -450,14 +459,17 @@ watch(
|
|||
stroke: green !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
}
|
||||
|
||||
:deep(.highlight.djs-shape .djs-visual > :nth-child(2)) {
|
||||
fill: green !important;
|
||||
}
|
||||
|
||||
:deep(.highlight.djs-shape .djs-visual > path) {
|
||||
fill: green !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
stroke: green !important;
|
||||
}
|
||||
|
||||
:deep(.highlight.djs-connection > .djs-visual > path) {
|
||||
stroke: green !important;
|
||||
}
|
||||
|
|
@ -468,14 +480,17 @@ watch(
|
|||
stroke: red !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
}
|
||||
|
||||
.highlight-reject.djs-shape .djs-visual > :nth-child(2) {
|
||||
fill: red !important;
|
||||
}
|
||||
|
||||
.highlight-reject.djs-shape .djs-visual > path {
|
||||
fill: red !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
stroke: red !important;
|
||||
}
|
||||
|
||||
.highlight-reject.djs-connection > .djs-visual > path {
|
||||
stroke: red !important;
|
||||
}
|
||||
|
|
@ -489,14 +504,17 @@ watch(
|
|||
stroke: red !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
}
|
||||
|
||||
:deep(.highlight-reject.djs-shape .djs-visual > :nth-child(2)) {
|
||||
fill: red !important;
|
||||
}
|
||||
|
||||
:deep(.highlight-reject.djs-shape .djs-visual > path) {
|
||||
fill: red !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
stroke: red !important;
|
||||
}
|
||||
|
||||
:deep(.highlight-reject.djs-connection > .djs-visual > path) {
|
||||
stroke: red !important;
|
||||
}
|
||||
|
|
@ -507,14 +525,17 @@ watch(
|
|||
stroke: grey !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
}
|
||||
|
||||
.highlight-cancel.djs-shape .djs-visual > :nth-child(2) {
|
||||
fill: grey !important;
|
||||
}
|
||||
|
||||
.highlight-cancel.djs-shape .djs-visual > path {
|
||||
fill: grey !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
stroke: grey !important;
|
||||
}
|
||||
|
||||
.highlight-cancel.djs-connection > .djs-visual > path {
|
||||
stroke: grey !important;
|
||||
}
|
||||
|
|
@ -528,14 +549,17 @@ watch(
|
|||
stroke: grey !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
}
|
||||
|
||||
:deep(.highlight-cancel.djs-shape .djs-visual > :nth-child(2)) {
|
||||
fill: grey !important;
|
||||
}
|
||||
|
||||
:deep(.highlight-cancel.djs-shape .djs-visual > path) {
|
||||
fill: grey !important;
|
||||
fill-opacity: 0.2 !important;
|
||||
stroke: grey !important;
|
||||
}
|
||||
|
||||
:deep(.highlight-cancel.djs-connection > .djs-visual > path) {
|
||||
stroke: grey !important;
|
||||
}
|
||||
|
|
@ -543,7 +567,7 @@ watch(
|
|||
.element-overlays {
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
background: rgb(0 0 0 / 60%);
|
||||
border-radius: 4px;
|
||||
color: #fafafa;
|
||||
width: 200px;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="MyProcessPalette">
|
||||
<script lang="ts" setup>
|
||||
import { assign } from 'min-dash'
|
||||
|
||||
defineOptions({ name: 'MyProcessPalette' })
|
||||
|
||||
const bpmnInstances = () => (window as any).bpmnInstances
|
||||
const addTask = (event, options: any = {}) => {
|
||||
const ElementFactory = bpmnInstances().elementFactory
|
||||
|
|
@ -30,12 +32,13 @@ const addTask = (event, options: any = {}) => {
|
|||
<style scoped lang="scss">
|
||||
.my-process-palette {
|
||||
box-sizing: border-box;
|
||||
padding: 80px 20px 20px 20px;
|
||||
padding: 80px 20px 20px;
|
||||
|
||||
.test-button {
|
||||
box-sizing: border-box;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(24, 144, 255, 0.8);
|
||||
border: 1px solid rgb(24 144 255 / 80%);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
</el-collapse>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts" name="MyPropertiesPanel">
|
||||
<script lang="ts" setup>
|
||||
import ElementBaseInfo from './base/ElementBaseInfo.vue'
|
||||
import ElementOtherConfig from './other/ElementOtherConfig.vue'
|
||||
import ElementTask from './task/ElementTask.vue'
|
||||
|
|
@ -73,6 +73,9 @@ import ElementListeners from './listeners/ElementListeners.vue'
|
|||
import ElementProperties from './properties/ElementProperties.vue'
|
||||
// import ElementForm from './form/ElementForm.vue'
|
||||
import UserTaskListeners from './listeners/UserTaskListeners.vue'
|
||||
|
||||
defineOptions({ name: 'MyPropertiesPanel' })
|
||||
|
||||
/**
|
||||
* 侧边栏
|
||||
* @Author MiyueFE
|
||||
|
|
@ -106,22 +109,22 @@ const elementBusinessObject = ref<any>({}) // 元素 businessObject 镜像,提
|
|||
const conditionFormVisible = ref(false) // 流转条件设置
|
||||
const formVisible = ref(false) // 表单配置
|
||||
const bpmnElement = ref()
|
||||
const timer = ref()
|
||||
|
||||
provide('prefix', props.prefix)
|
||||
provide('width', props.width)
|
||||
const bpmnInstances = () => (window as any)?.bpmnInstances
|
||||
const initModels = () => {
|
||||
// console.log(props, 'props')
|
||||
// console.log(props.bpmnModeler, 'sakdjjaskdsajdkasdjkadsjk')
|
||||
// 初始化 modeler 以及其他 moddle
|
||||
// nextTick(() => {
|
||||
if (!props.bpmnModeler) {
|
||||
|
||||
// 监听 props.bpmnModeler 然后 initModels
|
||||
const unwatchBpmn = watch(
|
||||
() => props.bpmnModeler,
|
||||
() => {
|
||||
// 避免加载时 流程图 并未加载完成
|
||||
timer.value = setTimeout(() => initModels(), 10)
|
||||
return
|
||||
}
|
||||
if (timer.value) {
|
||||
clearTimeout(timer.value)
|
||||
if (!props.bpmnModeler) {
|
||||
console.log('缺少props.bpmnModeler')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('props.bpmnModeler 有值了!!!')
|
||||
const w = window as any
|
||||
w.bpmnInstances = {
|
||||
modeler: props.bpmnModeler,
|
||||
|
|
@ -134,12 +137,16 @@ const initModels = () => {
|
|||
replace: props.bpmnModeler.get('replace'),
|
||||
selection: props.bpmnModeler.get('selection')
|
||||
}
|
||||
}
|
||||
|
||||
console.log(bpmnInstances(), 'window.bpmnInstances')
|
||||
getActiveElement()
|
||||
// })
|
||||
}
|
||||
console.log(bpmnInstances(), 'window.bpmnInstances')
|
||||
getActiveElement()
|
||||
unwatchBpmn()
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
|
||||
const getActiveElement = () => {
|
||||
// 初始第一个选中元素 bpmn:Process
|
||||
initFormOnChanged(null)
|
||||
|
|
@ -187,11 +194,7 @@ const initFormOnChanged = (element) => {
|
|||
)
|
||||
formVisible.value = elementType.value === 'UserTask' || elementType.value === 'StartEvent'
|
||||
}
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
initModels()
|
||||
}, 100)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
const w = window as any
|
||||
w.bpmnInstances = null
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@
|
|||
href="https://doc.iocoder.cn/bpm/#_3-%E6%B5%81%E7%A8%8B%E5%9B%BE%E7%A4%BA%E4%BE%8B"
|
||||
type="danger"
|
||||
target="_blank"
|
||||
>如何实现实现会签、或签?</el-link
|
||||
>
|
||||
如何实现实现会签、或签?
|
||||
</el-link>
|
||||
<el-form-item label="流程标识" prop="id">
|
||||
<el-input
|
||||
v-model="needProps.id"
|
||||
|
|
@ -37,7 +38,9 @@
|
|||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts" name="ElementBaseInfo">
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'ElementBaseInfo' })
|
||||
|
||||
const props = defineProps({
|
||||
businessObject: {
|
||||
type: Object,
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="FlowCondition">
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'FlowCondition' })
|
||||
|
||||
const props = defineProps({
|
||||
businessObject: Object,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -222,7 +222,9 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ElementForm">
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'ElementForm' })
|
||||
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -241,10 +241,13 @@
|
|||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts" name="ElementListeners">
|
||||
<script lang="ts" setup>
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { createListenerObject, updateElementExtensions } from '../../utils'
|
||||
import { initListenerType, initListenerForm, listenerType, fieldType } from './utilSelf'
|
||||
|
||||
defineOptions({ name: 'ElementListeners' })
|
||||
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -287,10 +287,13 @@
|
|||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts" name="UserTaskListeners">
|
||||
<script lang="ts" setup>
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { createListenerObject, updateElementExtensions } from '../../utils'
|
||||
import { initListenerForm, initListenerType, eventType, listenerType, fieldType } from './utilSelf'
|
||||
|
||||
defineOptions({ name: 'UserTaskListeners' })
|
||||
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -66,7 +66,9 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ElementMultiInstance">
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'ElementMultiInstance' })
|
||||
|
||||
const props = defineProps({
|
||||
businessObject: Object,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ElementOtherConfig">
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'ElementOtherConfig' })
|
||||
const props = defineProps({
|
||||
id: String
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,17 +6,18 @@
|
|||
<el-table-column label="属性值" prop="value" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="110px">
|
||||
<template #default="scope">
|
||||
<el-button link @click="openAttributesForm(scope.row, scope.$index)" size="small"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button link @click="openAttributesForm(scope.row, scope.$index)" size="small">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
link
|
||||
size="small"
|
||||
style="color: #ff4d4f"
|
||||
@click="removeAttributes(scope.row, scope.$index)"
|
||||
>移除</el-button
|
||||
>
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -52,8 +53,9 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ElementProperties">
|
||||
<script lang="ts" setup>
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
defineOptions({ name: 'ElementProperties' })
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="panel-tab__content">
|
||||
<div class="panel-tab__content--title">
|
||||
<span><Icon icon="ep:menu" style="margin-right: 8px; color: #555555" />消息列表</span>
|
||||
<span><Icon icon="ep:menu" style="margin-right: 8px; color: #555" />消息列表</span>
|
||||
<XButton type="primary" title="创建新消息" preIcon="ep:plus" @click="openModel('message')" />
|
||||
</div>
|
||||
<el-table :data="messageList" border>
|
||||
|
|
@ -11,9 +11,9 @@
|
|||
</el-table>
|
||||
<div
|
||||
class="panel-tab__content--title"
|
||||
style="padding-top: 8px; margin-top: 8px; border-top: 1px solid #eeeeee"
|
||||
style="padding-top: 8px; margin-top: 8px; border-top: 1px solid #eee"
|
||||
>
|
||||
<span><Icon icon="ep:menu" style="margin-right: 8px; color: #555555" />信号列表</span>
|
||||
<span><Icon icon="ep:menu" style="margin-right: 8px; color: #555" />信号列表</span>
|
||||
<XButton type="primary" title="创建新信号" preIcon="ep:plus" @click="openModel('signal')" />
|
||||
</div>
|
||||
<el-table :data="signalList" border>
|
||||
|
|
@ -45,7 +45,9 @@
|
|||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts" name="SignalAndMassage">
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'SignalAndMassage' })
|
||||
|
||||
const message = useMessage()
|
||||
const signalList = ref<any[]>([])
|
||||
const messageList = ref<any[]>([])
|
||||
|
|
|
|||
|
|
@ -20,11 +20,13 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ElementTaskConfig">
|
||||
<script lang="ts" setup>
|
||||
import UserTask from './task-components/UserTask.vue'
|
||||
import ScriptTask from './task-components/ScriptTask.vue'
|
||||
import ReceiveTask from './task-components/ReceiveTask.vue'
|
||||
|
||||
defineOptions({ name: 'ElementTaskConfig' })
|
||||
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ReceiveTask">
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'ReceiveTask' })
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ScriptTask">
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'ScriptTask' })
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="UserTask">
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'UserTask' })
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { reactive } from 'vue'
|
||||
import { AxiosPromise } from 'axios'
|
||||
import { findIndex } from '@/utils'
|
||||
import { eachTree, treeMap, filter } from '@/utils/tree'
|
||||
import { eachTree, filter, treeMap } from '@/utils/tree'
|
||||
import { getBoolDictOptions, getDictOptions, getIntDictOptions } from '@/utils/dict'
|
||||
|
||||
import { FormSchema } from '@/types/form'
|
||||
|
|
@ -36,8 +36,11 @@ type CrudSearchParams = {
|
|||
type CrudTableParams = {
|
||||
// 是否显示表头
|
||||
show?: boolean
|
||||
// 列宽配置
|
||||
width?: number | string
|
||||
// 列是否固定在左侧或者右侧
|
||||
fixed?: 'left' | 'right'
|
||||
} & Omit<FormSchema, 'field'>
|
||||
|
||||
type CrudFormParams = {
|
||||
// 是否显示表单项
|
||||
show?: boolean
|
||||
|
|
|
|||
|
|
@ -136,9 +136,7 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
|
|||
})
|
||||
if (res) {
|
||||
tableObject.tableList = (res as unknown as ResponseType).list
|
||||
if ((res as unknown as ResponseType).total) {
|
||||
tableObject.total = (res as unknown as ResponseType).total as unknown as number
|
||||
}
|
||||
tableObject.total = (res as unknown as ResponseType).total ?? 0
|
||||
}
|
||||
},
|
||||
setProps: async (props: TableProps = {}) => {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<script lang="ts" name="AppView" setup>
|
||||
<script lang="ts" setup>
|
||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
||||
import { useAppStore } from '@/store/modules/app'
|
||||
import { Footer } from '@/layout/components/Footer'
|
||||
|
||||
defineOptions({ name: 'AppView' })
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
const layout = computed(() => appStore.getLayout)
|
||||
|
|
@ -16,26 +18,33 @@ const tagsViewStore = useTagsViewStore()
|
|||
const getCaches = computed((): string[] => {
|
||||
return tagsViewStore.getCachedViews
|
||||
})
|
||||
|
||||
const tagsView = computed(() => appStore.getTagsView)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section
|
||||
:class="[
|
||||
'p-[var(--app-content-padding)] w-[100%] bg-[var(--app-content-bg-color)] dark:bg-[var(--el-bg-color)]',
|
||||
'p-[var(--app-content-padding)] w-[calc(100%-var(--app-content-padding)-var(--app-content-padding))] bg-[var(--app-content-bg-color)] dark:bg-[var(--el-bg-color)]',
|
||||
{
|
||||
'!min-h-[calc(100%-var(--app-footer-height))]':
|
||||
((fixedHeader && (layout === 'classic' || layout === 'topLeft')) || layout === 'top') &&
|
||||
footer,
|
||||
'!min-h-[calc(100%-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height))]':
|
||||
(fixedHeader &&
|
||||
(layout === 'classic' || layout === 'topLeft' || layout === 'top') &&
|
||||
footer) ||
|
||||
(!tagsView && layout === 'top' && footer),
|
||||
'!min-h-[calc(100%-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height)-var(--tags-view-height))]':
|
||||
tagsView && layout === 'top' && footer,
|
||||
|
||||
'!min-h-[calc(100%-var(--tags-view-height)-var(--top-tool-height)-var(--app-footer-height))]':
|
||||
'!min-h-[calc(100%-var(--tags-view-height)-var(--app-content-padding)-var(--app-content-padding)-var(--top-tool-height)-var(--app-footer-height))]':
|
||||
!fixedHeader && layout === 'classic' && footer,
|
||||
|
||||
'!min-h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]':
|
||||
!fixedHeader && (layout === 'topLeft' || layout === 'top') && footer,
|
||||
'!min-h-[calc(100%-var(--tags-view-height)-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height))]':
|
||||
!fixedHeader && layout === 'topLeft' && footer,
|
||||
|
||||
'!min-h-[calc(100%-var(--top-tool-height))]': fixedHeader && layout === 'cutMenu' && footer,
|
||||
'!min-h-[calc(100%-var(--top-tool-height)-var(--app-content-padding)-var(--app-content-padding))]':
|
||||
fixedHeader && layout === 'cutMenu' && footer,
|
||||
|
||||
'!min-h-[calc(100%-var(--top-tool-height)-var(--tags-view-height))]':
|
||||
'!min-h-[calc(100%-var(--top-tool-height)-var(--app-content-padding)-var(--app-content-padding)-var(--tags-view-height))]':
|
||||
!fixedHeader && layout === 'cutMenu' && footer
|
||||
}
|
||||
]"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<script lang="ts" name="Collapse" setup>
|
||||
<script lang="ts" setup>
|
||||
import { useAppStore } from '@/store/modules/app'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'Collapse' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('collapse')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" name="ContextMenu" setup>
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue'
|
||||
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
|
@ -6,6 +6,8 @@ import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
|||
import { contextMenuSchema } from '@/types/contextMenu'
|
||||
import type { ElDropdown } from 'element-plus'
|
||||
|
||||
defineOptions({ name: 'ContextMenu' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('context-menu')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<script lang="ts" name="Footer" setup>
|
||||
<script lang="ts" setup>
|
||||
import { useAppStore } from '@/store/modules/app'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
defineOptions({ name: 'Footer' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('footer')
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts" name="LocaleDropdown" setup>
|
||||
<script lang="ts" setup>
|
||||
import { useLocaleStore } from '@/store/modules/locale'
|
||||
import { useLocale } from '@/hooks/web/useLocale'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'LocaleDropdown' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('locale-dropdown')
|
||||
|
|
@ -36,7 +38,7 @@ const setLang = (lang: LocaleType) => {
|
|||
:class="$attrs.class"
|
||||
:color="color"
|
||||
:size="18"
|
||||
class="cursor-pointer"
|
||||
class="cursor-pointer !p-0"
|
||||
icon="ion:language-sharp"
|
||||
/>
|
||||
<template #dropdown>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<script lang="ts" name="Logo" setup>
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, unref, watch } from 'vue'
|
||||
import { useAppStore } from '@/store/modules/app'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'Logo' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('logo')
|
||||
|
|
@ -60,8 +62,7 @@ watch(
|
|||
:class="[
|
||||
prefixCls,
|
||||
layout !== 'classic' ? `${prefixCls}__Top` : '',
|
||||
'flex !h-[var(--logo-height)] items-center cursor-pointer justify-center relative',
|
||||
'dark:bg-[var(--el-bg-color)]'
|
||||
'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative decoration-none overflow-hidden'
|
||||
]"
|
||||
to="/"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const { getPrefixCls } = useDesign()
|
|||
const prefixCls = getPrefixCls('menu')
|
||||
|
||||
export default defineComponent({
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
name: 'Menu',
|
||||
props: {
|
||||
menuSelect: {
|
||||
|
|
@ -137,15 +138,6 @@ $prefix-cls: #{$namespace}-menu;
|
|||
position: relative;
|
||||
transition: width var(--transition-time-02);
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
border-left: 1px solid var(--left-menu-border-color);
|
||||
content: '';
|
||||
}
|
||||
|
||||
:deep(.#{$elNamespace}-menu) {
|
||||
width: 100% !important;
|
||||
border-right: none;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script lang="ts" name="Message" setup>
|
||||
<script lang="ts" setup>
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import * as NotifyMessageApi from '@/api/system/notify/message'
|
||||
|
||||
defineOptions({ name: 'Message' })
|
||||
|
||||
const { push } = useRouter()
|
||||
const activeName = ref('notice')
|
||||
const unreadCount = ref(0) // 未读消息数量
|
||||
|
|
@ -33,9 +35,12 @@ onMounted(() => {
|
|||
// 首次加载小红点
|
||||
getUnreadCount()
|
||||
// 轮询刷新小红点
|
||||
setInterval(() => {
|
||||
getUnreadCount()
|
||||
}, 1000 * 60 * 2)
|
||||
setInterval(
|
||||
() => {
|
||||
getUnreadCount()
|
||||
},
|
||||
1000 * 60 * 2
|
||||
)
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts" name="ScreenFull" setup>
|
||||
<script lang="ts" setup>
|
||||
import { Icon } from '@/components/Icon'
|
||||
import { useFullscreen } from '@vueuse/core'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
defineOptions({ name: 'ScreenFull' })
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls('screenfull')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<script lang="ts" name="Setting" setup>
|
||||
<script lang="ts" setup>
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useClipboard, useCssVar } from '@vueuse/core'
|
||||
|
||||
|
|
@ -13,6 +13,8 @@ import ColorRadioPicker from './components/ColorRadioPicker.vue'
|
|||
import InterfaceDisplay from './components/InterfaceDisplay.vue'
|
||||
import LayoutRadioPicker from './components/LayoutRadioPicker.vue'
|
||||
|
||||
defineOptions({ name: 'Setting' })
|
||||
|
||||
const { t } = useI18n()
|
||||
const appStore = useAppStore()
|
||||
|
||||
|
|
@ -42,7 +44,6 @@ const setHeaderTheme = (color: string) => {
|
|||
setCssVar('--top-header-bg-color', color)
|
||||
setCssVar('--top-header-text-color', textColor)
|
||||
setCssVar('--top-header-hover-color', textHoverColor)
|
||||
setCssVar('--top-tool-border-color', topToolBorderColor)
|
||||
appStore.setTheme({
|
||||
topHeaderBgColor: color,
|
||||
topHeaderTextColor: textColor,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue