Merge remote-tracking branch 'yudao/master' into dev-to-dev

This commit is contained in:
puhui999 2023-08-02 21:14:06 +08:00
commit 0b06f36aa2
53 changed files with 479 additions and 395 deletions

View File

@ -1,15 +1,19 @@
{ {
"recommendations": [ "recommendations": [
"voorjaar.windicss-intellisense", "christian-kohler.path-intellisense",
"vscode-icons-team.vscode-icons", "vscode-icons-team.vscode-icons",
"davidanson.vscode-markdownlint", "davidanson.vscode-markdownlint",
"stylelint.vscode-stylelint", "stylelint.vscode-stylelint",
"dbaeumer.vscode-eslint", "dbaeumer.vscode-eslint",
"esbenp.prettier-vscode", "esbenp.prettier-vscode",
"vue.volar", "mrmlnc.vscode-less",
"lokalise.i18n-ally", "lokalise.i18n-ally",
"redhat.vscode-yaml",
"csstools.postcss",
"mikestead.dotenv", "mikestead.dotenv",
"eamodio.gitlens", "eamodio.gitlens",
"antfu.iconify" "antfu.iconify",
"antfu.unocss",
"Vue.volar"
] ]
} }

16
.vscode/settings.json vendored
View File

@ -102,14 +102,12 @@
"i18n-ally.displayLanguage": "zh-CN", "i18n-ally.displayLanguage": "zh-CN",
"i18n-ally.enabledFrameworks": ["vue", "react"], "i18n-ally.enabledFrameworks": ["vue", "react"],
"cSpell.words": [ "cSpell.words": [
"vben", "xingyu",
"windicss", "yudao",
"tailwind", "unocss",
"browserslist", "browserslist",
"tailwindcss",
"esnext", "esnext",
"antv", "unplugin",
"tinymce",
"qrcode", "qrcode",
"sider", "sider",
"pinia", "pinia",
@ -123,8 +121,9 @@
"codemirror", "codemirror",
"iconify", "iconify",
"commitlint", "commitlint",
"vditor", "videojs",
"echarts", "echarts",
"wangeditor",
"cropperjs", "cropperjs",
"logicflow", "logicflow",
"vueuse", "vueuse",
@ -132,8 +131,7 @@
"lintstagedrc", "lintstagedrc",
"brotli", "brotli",
"sider", "sider",
"pnpm", "pnpm"
"antd"
], ],
"vetur.format.scriptInitialIndent": true, "vetur.format.scriptInitialIndent": true,
"vetur.format.styleInitialIndent": true, "vetur.format.styleInitialIndent": true,

View File

@ -24,7 +24,7 @@
* 改换 saas自动引入等功能 * 改换 saas自动引入等功能
* 使用 Element Plus 免费开源的中后台模版,具备如下特性: * 使用 Element Plus 免费开源的中后台模版,具备如下特性:
![首页](preview/home.png) ![首页](public/home.png)
* **最新技术栈**:使用 Vue3、Vite4 等前端前沿技术开发 * **最新技术栈**:使用 Vue3、Vite4 等前端前沿技术开发
* **TypeScript**: 应用程序级 JavaScript 的语言 * **TypeScript**: 应用程序级 JavaScript 的语言
@ -39,15 +39,15 @@
| 框架 | 说明 | 版本 | | 框架 | 说明 | 版本 |
|----------------------------------------------------------------------|------------------|--------| |----------------------------------------------------------------------|------------------|--------|
| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.3.4 | | [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.3.4 |
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.3.9 | | [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.4.7 |
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.7 | | [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.8 |
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.0.4 | | [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.1.6 |
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.4 | | [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.6 |
| [vueuse](https://vueuse.org/) | 常用工具集 | 10.2.0 | | [vueuse](https://vueuse.org/) | 常用工具集 | 10.2.1 |
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 |
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.2.1 | | [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.2.4 |
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 | | [unocss](https://uno.antfu.me/) | 原子 css | 0.54.0 |
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.1.0 | | [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.1.1 |
| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.23 | | [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.23 |
## 开发工具 ## 开发工具
@ -58,7 +58,7 @@
|-------------------------------|--------------------------| |-------------------------------|--------------------------|
| TypeScript Vue Plugin (Volar) | 用于 TypeScript 的 Vue 插件 | | TypeScript Vue Plugin (Volar) | 用于 TypeScript 的 Vue 插件 |
| Vue Language Features (Volar) | Vue3.0 语法支持 | | Vue Language Features (Volar) | Vue3.0 语法支持 |
| WindiCSS IntelliSense | 自动完成、语法突出显示、代码折叠和构建等高级功能 | | unocss | unocss for vscode |
| Iconify IntelliSense | Iconify 预览和搜索 | | Iconify IntelliSense | Iconify 预览和搜索 |
| i18n Ally | 国际化智能提示 | | i18n Ally | 国际化智能提示 |
| Stylelint | Css 格式化 | | Stylelint | Css 格式化 |

View File

@ -1,7 +1,6 @@
import { resolve } from 'path' import { resolve } from 'path'
import Vue from '@vitejs/plugin-vue' import Vue from '@vitejs/plugin-vue'
import VueJsx from '@vitejs/plugin-vue-jsx' import VueJsx from '@vitejs/plugin-vue-jsx'
import WindiCSS from 'vite-plugin-windicss'
import progress from 'vite-plugin-progress' import progress from 'vite-plugin-progress'
import EslintPlugin from 'vite-plugin-eslint' import EslintPlugin from 'vite-plugin-eslint'
import PurgeIcons from 'vite-plugin-purge-icons' import PurgeIcons from 'vite-plugin-purge-icons'
@ -15,6 +14,7 @@ import viteCompression from 'vite-plugin-compression'
import topLevelAwait from 'vite-plugin-top-level-await' import topLevelAwait from 'vite-plugin-top-level-await'
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import UnoCSS from 'unocss/vite'
export function createVitePlugins() { export function createVitePlugins() {
const root = process.cwd() const root = process.cwd()
@ -27,7 +27,7 @@ export function createVitePlugins() {
return [ return [
Vue(), Vue(),
VueJsx(), VueJsx(),
WindiCSS(), UnoCSS(),
progress(), progress(),
PurgeIcons(), PurgeIcons(),
ElementPlus({}), ElementPlus({}),

View File

@ -8,7 +8,7 @@ const include = [
'pinia', 'pinia',
'dayjs', 'dayjs',
'qrcode', 'qrcode',
'windicss', 'unocss',
'vue-router', 'vue-router',
'vue-types', 'vue-types',
'vue-i18n', 'vue-i18n',

View File

@ -1,6 +1,6 @@
{ {
"name": "yudao-ui-admin-vue3", "name": "yudao-ui-admin-vue3",
"version": "1.7.3-snapshot", "version": "1.8.0-snapshot",
"description": "基于vue3、vite4、element-plus、typesScript", "description": "基于vue3、vite4、element-plus、typesScript",
"author": "xingyu", "author": "xingyu",
"private": false, "private": false,
@ -32,12 +32,12 @@
"@element-plus/icons-vue": "^2.1.0", "@element-plus/icons-vue": "^2.1.0",
"@form-create/designer": "^3.1.0", "@form-create/designer": "^3.1.0",
"@form-create/element-ui": "^3.1.17", "@form-create/element-ui": "^3.1.17",
"@iconify/iconify": "^3.1.0", "@iconify/iconify": "^3.1.1",
"@videojs-player/vue": "^1.0.0", "@videojs-player/vue": "^1.0.0",
"@vueuse/core": "^10.2.0", "@vueuse/core": "^10.2.1",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.10", "@wangeditor/editor-for-vue": "^5.1.10",
"@zxcvbn-ts/core": "^3.0.2", "@zxcvbn-ts/core": "^3.0.3",
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"axios": "^1.4.0", "axios": "^1.4.0",
"benz-amr-recorder": "^1.1.5", "benz-amr-recorder": "^1.1.5",
@ -45,79 +45,82 @@
"camunda-bpmn-moddle": "^7.0.1", "camunda-bpmn-moddle": "^7.0.1",
"cropperjs": "^1.5.13", "cropperjs": "^1.5.13",
"crypto-js": "^4.1.1", "crypto-js": "^4.1.1",
"dayjs": "^1.11.8", "dayjs": "^1.11.9",
"diagram-js": "^11.6.0", "diagram-js": "^11.6.0",
"echarts": "^5.4.2", "echarts": "^5.4.3",
"echarts-wordcloud": "^2.1.0", "echarts-wordcloud": "^2.1.0",
"element-plus": "2.3.7", "element-plus": "2.3.8",
"fast-xml-parser": "^4.2.4", "fast-xml-parser": "^4.2.6",
"highlight.js": "^11.8.0", "highlight.js": "^11.8.0",
"intro.js": "^7.0.1", "intro.js": "^7.0.1",
"jsencrypt": "^3.3.2", "jsencrypt": "^3.3.2",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"min-dash": "^4.1.1", "min-dash": "^4.1.1",
"mitt": "^3.0.0", "mitt": "^3.0.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"pinia": "^2.1.4", "pinia": "^2.1.6",
"qrcode": "^1.5.3", "qrcode": "^1.5.3",
"qs": "^6.11.2", "qs": "^6.11.2",
"steady-xml": "^0.1.0", "steady-xml": "^0.1.0",
"url": "^0.11.1", "url": "^0.11.1",
"video.js": "^8.3.0", "video.js": "^7.21.5",
"vue": "3.3.4", "vue": "3.3.4",
"vue-dompurify-html": "^4.1.4", "vue-dompurify-html": "^4.1.4",
"vue-i18n": "9.2.2", "vue-i18n": "9.2.2",
"vue-router": "^4.2.2", "vue-router": "^4.2.4",
"vue-types": "^5.0.4", "vue-types": "^5.1.1",
"vuedraggable": "^4.1.0", "vuedraggable": "^4.1.0",
"web-storage-cache": "^1.1.1", "web-storage-cache": "^1.1.1",
"xml-js": "^1.6.11" "xml-js": "^1.6.11"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^17.6.5", "@commitlint/cli": "^17.6.7",
"@commitlint/config-conventional": "^17.6.5", "@commitlint/config-conventional": "^17.6.7",
"@iconify/json": "^2.2.80", "@iconify/json": "^2.2.95",
"@intlify/unplugin-vue-i18n": "^0.11.0", "@intlify/unplugin-vue-i18n": "^0.12.2",
"@purge-icons/generated": "^0.9.0", "@purge-icons/generated": "^0.9.0",
"@types/intro.js": "^5.1.1", "@types/intro.js": "^5.1.1",
"@types/lodash-es": "^4.17.7", "@types/lodash-es": "^4.17.8",
"@types/node": "^20.3.1", "@types/node": "^20.4.0",
"@types/nprogress": "^0.2.0", "@types/nprogress": "^0.2.0",
"@types/qrcode": "^1.5.0", "@types/qrcode": "^1.5.1",
"@types/qs": "^6.9.7", "@types/qs": "^6.9.7",
"@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/eslint-plugin": "^6.2.0",
"@typescript-eslint/parser": "^5.59.11", "@typescript-eslint/parser": "^6.2.0",
"@vitejs/plugin-legacy": "^4.0.4", "@unocss/transformer-variant-group": "^0.51.4",
"@vitejs/plugin-legacy": "^4.1.1",
"@vitejs/plugin-vue": "^4.2.3", "@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.0.1", "@vitejs/plugin-vue-jsx": "^3.0.1",
"@vue-macros/volar": "^0.12.3",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"bpmn-js": "^8.9.0", "bpmn-js": "^8.9.0",
"bpmn-js-properties-panel": "^0.46.0", "bpmn-js-properties-panel": "^0.46.0",
"consola": "^3.1.0", "consola": "^3.2.3",
"eslint": "^8.43.0", "eslint": "^8.46.0",
"eslint-config-prettier": "^8.8.0", "eslint-config-prettier": "^8.9.0",
"eslint-define-config": "^1.21.0", "eslint-define-config": "^1.21.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-vue": "^9.15.0", "eslint-plugin-vue": "^9.15.1",
"lint-staged": "^13.2.2", "lint-staged": "^13.2.3",
"postcss": "^8.4.24", "postcss": "^8.4.27",
"postcss-html": "^1.5.0", "postcss-html": "^1.5.0",
"postcss-scss": "^4.0.6", "postcss-scss": "^4.0.6",
"prettier": "^2.8.8", "prettier": "^3.0.0",
"rimraf": "^5.0.1", "rimraf": "^5.0.1",
"rollup": "^3.25.1", "rollup": "^3.27.0",
"sass": "^1.63.5", "sass": "^1.64.1",
"stylelint": "^15.8.0", "stylelint": "^15.10.2",
"stylelint-config-recommended": "^12.0.0", "stylelint-config-recommended": "^13.0.0",
"stylelint-config-recommended-vue": "^1.4.0", "stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard": "^33.0.0", "stylelint-config-standard": "^34.0.0",
"stylelint-order": "^6.0.3", "stylelint-order": "^6.0.3",
"terser": "^5.18.1", "terser": "^5.19.2",
"typescript": "5.0.4", "typescript": "5.1.6",
"unplugin-auto-import": "^0.16.4", "unocss": "^0.54.0",
"unplugin-element-plus": "^0.7.1", "unplugin-auto-import": "^0.16.6",
"unplugin-element-plus": "^0.7.2",
"unplugin-vue-components": "^0.25.1", "unplugin-vue-components": "^0.25.1",
"vite": "4.3.9", "vite": "4.4.7",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vite-plugin-ejs": "^1.6.4", "vite-plugin-ejs": "^1.6.4",
"vite-plugin-eslint": "^1.8.1", "vite-plugin-eslint": "^1.8.1",
@ -125,9 +128,7 @@
"vite-plugin-purge-icons": "^0.9.2", "vite-plugin-purge-icons": "^0.9.2",
"vite-plugin-svg-icons": "^2.0.1", "vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-top-level-await": "^1.3.1", "vite-plugin-top-level-await": "^1.3.1",
"vite-plugin-windicss": "^1.9.0", "vue-tsc": "^1.8.8"
"vue-tsc": "^1.8.1",
"windicss": "^3.5.6"
}, },
"license": "MIT", "license": "MIT",
"repository": { "repository": {

0
preview/home.png → public/home.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -37,11 +37,6 @@ export const getInfo = () => {
return request.get({ url: '/system/auth/get-permission-info' }) 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) => { export const sendSmsCode = (data: SmsCodeVO) => {
return request.post({ url: '/system/auth/send-sms-code', data }) return request.post({ url: '/system/auth/send-sms-code', data })

View File

@ -1,6 +1,8 @@
import request from '@/config/axios' import request from '@/config/axios'
import { Sku, Spu } from '@/api/mall/product/spu' import { Sku, Spu } from '@/api/mall/product/spu'
// TODO @puhui999: combinationActivity.ts
export interface CombinationActivityVO { export interface CombinationActivityVO {
id?: number id?: number
name?: string name?: string

View File

@ -28,7 +28,7 @@ onMounted(() => {
<div <div
:class="[ :class="[
`${prefixCls}-header`, `${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 ']"> <div :class="[`${prefixCls}-header__back`, 'flex pl-10px pr-10px ']">

View File

@ -222,7 +222,9 @@ $prefix-cls: #{$namespace}-cropper-am;
transparent 75%, transparent 75%,
rgb(0 0 0 / 25%) 0 rgb(0 0 0 / 25%) 0
); );
background-position: 0 0, 12px 12px; background-position:
0 0,
12px 12px;
background-size: 24px 24px; background-size: 24px 24px;
} }

View File

@ -71,14 +71,14 @@ const toggleClick = () => {
<div <div
:class="[ :class="[
prefixCls, 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 <div
v-if="title" v-if="title"
:class="[ :class="[
`${prefixCls}-header`, `${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" @click="toggleClick"
> >

View File

@ -99,13 +99,19 @@ const dialogStyle = computed(() => {
</template> </template>
<style lang="scss"> <style lang="scss">
.#{$elNamespace}-dialog__header { .#{$elNamespace}-dialog {
&__header {
margin-right: 0 !important; margin-right: 0 !important;
border-bottom: 1px solid var(--tags-view-border-color); border-bottom: 1px solid var(--el-border-color);
} }
.#{$elNamespace}-dialog__footer { &__body {
border-top: 1px solid var(--tags-view-border-color); padding: 0 !important;
}
&__footer {
border-top: 1px solid var(--el-border-color);
}
} }
.is-hover { .is-hover {
@ -113,14 +119,4 @@ const dialogStyle = computed(() => {
color: var(--el-color-primary) !important; 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> </style>

View File

@ -164,7 +164,6 @@ const handleChange = (editor: IDomEditor) => {
// //
onBeforeUnmount(() => { onBeforeUnmount(() => {
const editor = unref(editorRef.value) const editor = unref(editorRef.value)
if (editor === null) return
// editor // editor
editor?.destroy() editor?.destroy()
@ -181,12 +180,12 @@ defineExpose({
</script> </script>
<template> <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 <Toolbar
:editor="editorRef" :editor="editorRef"
:editorId="editorId" :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 <Editor

View File

@ -114,7 +114,9 @@ $prefix-cls: #{$namespace}-input-password;
height: inherit; height: inherit;
background-color: transparent; background-color: transparent;
border-radius: inherit; 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'] { &[data-score='0'] {
width: 20%; width: 20%;

View File

@ -109,22 +109,22 @@ const elementBusinessObject = ref<any>({}) // 元素 businessObject 镜像,提
const conditionFormVisible = ref(false) // const conditionFormVisible = ref(false) //
const formVisible = ref(false) // const formVisible = ref(false) //
const bpmnElement = ref() const bpmnElement = ref()
const timer = ref()
provide('prefix', props.prefix) provide('prefix', props.prefix)
provide('width', props.width) provide('width', props.width)
const bpmnInstances = () => (window as any)?.bpmnInstances const bpmnInstances = () => (window as any)?.bpmnInstances
const initModels = () => {
// console.log(props, 'props') // props.bpmnModeler initModels
// console.log(props.bpmnModeler, 'sakdjjaskdsajdkasdjkadsjk') const unwatchBpmn = watch(
// modeler moddle () => props.bpmnModeler,
// nextTick(() => { () => {
if (!props.bpmnModeler) {
// //
timer.value = setTimeout(() => initModels(), 10) if (!props.bpmnModeler) {
console.log('缺少props.bpmnModeler')
return return
} }
if (timer.value) {
clearTimeout(timer.value) console.log('props.bpmnModeler 有值了!!!')
const w = window as any const w = window as any
w.bpmnInstances = { w.bpmnInstances = {
modeler: props.bpmnModeler, modeler: props.bpmnModeler,
@ -137,12 +137,16 @@ const initModels = () => {
replace: props.bpmnModeler.get('replace'), replace: props.bpmnModeler.get('replace'),
selection: props.bpmnModeler.get('selection') selection: props.bpmnModeler.get('selection')
} }
}
console.log(bpmnInstances(), 'window.bpmnInstances') console.log(bpmnInstances(), 'window.bpmnInstances')
getActiveElement() getActiveElement()
// }) unwatchBpmn()
},
{
immediate: true
} }
)
const getActiveElement = () => { const getActiveElement = () => {
// bpmn:Process // bpmn:Process
initFormOnChanged(null) initFormOnChanged(null)
@ -190,11 +194,7 @@ const initFormOnChanged = (element) => {
) )
formVisible.value = elementType.value === 'UserTask' || elementType.value === 'StartEvent' formVisible.value = elementType.value === 'UserTask' || elementType.value === 'StartEvent'
} }
onMounted(() => {
setTimeout(() => {
initModels()
}, 100)
})
onBeforeUnmount(() => { onBeforeUnmount(() => {
const w = window as any const w = window as any
w.bpmnInstances = null w.bpmnInstances = null

View File

@ -136,9 +136,7 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
}) })
if (res) { if (res) {
tableObject.tableList = (res as unknown as ResponseType).list tableObject.tableList = (res as unknown as ResponseType).list
if ((res as unknown as ResponseType).total) { tableObject.total = (res as unknown as ResponseType).total ?? 0
tableObject.total = (res as unknown as ResponseType).total as unknown as number
}
} }
}, },
setProps: async (props: TableProps = {}) => { setProps: async (props: TableProps = {}) => {

View File

@ -18,26 +18,33 @@ const tagsViewStore = useTagsViewStore()
const getCaches = computed((): string[] => { const getCaches = computed((): string[] => {
return tagsViewStore.getCachedViews return tagsViewStore.getCachedViews
}) })
const tagsView = computed(() => appStore.getTagsView)
</script> </script>
<template> <template>
<section <section
:class="[ :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))]': '!min-h-[calc(100%-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height))]':
((fixedHeader && (layout === 'classic' || layout === 'topLeft')) || layout === 'top') && (fixedHeader &&
footer, (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, !fixedHeader && layout === 'classic' && footer,
'!min-h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]': '!min-h-[calc(100%-var(--tags-view-height)-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height))]':
!fixedHeader && (layout === 'topLeft' || layout === 'top') && footer, !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 !fixedHeader && layout === 'cutMenu' && footer
} }
]" ]"

View File

@ -38,7 +38,7 @@ const setLang = (lang: LocaleType) => {
:class="$attrs.class" :class="$attrs.class"
:color="color" :color="color"
:size="18" :size="18"
class="cursor-pointer" class="cursor-pointer !p-0"
icon="ion:language-sharp" icon="ion:language-sharp"
/> />
<template #dropdown> <template #dropdown>

View File

@ -62,8 +62,7 @@ watch(
:class="[ :class="[
prefixCls, prefixCls,
layout !== 'classic' ? `${prefixCls}__Top` : '', layout !== 'classic' ? `${prefixCls}__Top` : '',
'flex !h-[var(--logo-height)] items-center cursor-pointer justify-center relative', 'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative decoration-none overflow-hidden'
'dark:bg-[var(--el-bg-color)]'
]" ]"
to="/" to="/"
> >

View File

@ -138,15 +138,6 @@ $prefix-cls: #{$namespace}-menu;
position: relative; position: relative;
transition: width var(--transition-time-02); 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) { :deep(.#{$elNamespace}-menu) {
width: 100% !important; width: 100% !important;
border-right: none; border-right: none;

View File

@ -35,9 +35,12 @@ onMounted(() => {
// //
getUnreadCount() getUnreadCount()
// //
setInterval(() => { setInterval(
() => {
getUnreadCount() getUnreadCount()
}, 1000 * 60 * 2) },
1000 * 60 * 2
)
}) })
</script> </script>
<template> <template>

View File

@ -44,7 +44,6 @@ const setHeaderTheme = (color: string) => {
setCssVar('--top-header-bg-color', color) setCssVar('--top-header-bg-color', color)
setCssVar('--top-header-text-color', textColor) setCssVar('--top-header-text-color', textColor)
setCssVar('--top-header-hover-color', textHoverColor) setCssVar('--top-header-hover-color', textHoverColor)
setCssVar('--top-tool-border-color', topToolBorderColor)
appStore.setTheme({ appStore.setTheme({
topHeaderBgColor: color, topHeaderBgColor: color,
topHeaderTextColor: textColor, topHeaderTextColor: textColor,

View File

@ -139,7 +139,7 @@ export default defineComponent({
id={`${variables.namespace}-menu`} id={`${variables.namespace}-menu`}
class={[ class={[
prefixCls, prefixCls,
'relative bg-[var(--left-menu-bg-color)] top-1px z-3000', 'relative bg-[var(--left-menu-bg-color)] top-1px z-3000 layout-border__right',
{ {
'w-[var(--tab-menu-max-width)]': !unref(collapse), 'w-[var(--tab-menu-max-width)]': !unref(collapse),
'w-[var(--tab-menu-min-width)]': unref(collapse) 'w-[var(--tab-menu-min-width)]': unref(collapse)
@ -195,7 +195,7 @@ export default defineComponent({
</div> </div>
<Menu <Menu
class={[ class={[
'!absolute top-0 border-left-1 border-solid border-[var(--left-menu-bg-light-color)]', '!absolute top-0',
{ {
'!left-[var(--tab-menu-min-width)]': unref(collapse), '!left-[var(--tab-menu-min-width)]': unref(collapse),
'!left-[var(--tab-menu-max-width)]': !unref(collapse), '!left-[var(--tab-menu-max-width)]': !unref(collapse),
@ -217,16 +217,6 @@ $prefix-cls: #{$namespace}-tab-menu;
.#{$prefix-cls} { .#{$prefix-cls} {
transition: all var(--transition-time-02); transition: all var(--transition-time-02);
&::after {
position: absolute;
top: 0;
right: 0;
width: 1px;
height: 100%;
border-left: 1px solid var(--left-menu-border-color);
content: '';
}
&__item { &__item {
color: var(--left-menu-text-color); color: var(--left-menu-text-color);
transition: all var(--transition-time-02); transition: all var(--transition-time-02);
@ -240,7 +230,6 @@ $prefix-cls: #{$namespace}-tab-menu;
&--collapse { &--collapse {
color: var(--left-menu-text-color); color: var(--left-menu-text-color);
background-color: var(--left-menu-bg-light-color); background-color: var(--left-menu-bg-light-color);
border-top: 1px solid var(--left-menu-border-color);
} }
.is-active { .is-active {

View File

@ -1,17 +1,17 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, watch, computed, unref, ref, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router' import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router'
import { usePermissionStore } from '@/store/modules/permission' import { usePermissionStore } from '@/store/modules/permission'
import { useTagsViewStore } from '@/store/modules/tagsView' import { useTagsViewStore } from '@/store/modules/tagsView'
import { useAppStore } from '@/store/modules/app' import { useAppStore } from '@/store/modules/app'
import { useI18n } from '@/hooks/web/useI18n'
import { filterAffixTags } from './helper' import { filterAffixTags } from './helper'
import { ContextMenu, ContextMenuExpose } from '@/layout/components/ContextMenu' import { ContextMenu, ContextMenuExpose } from '@/layout/components/ContextMenu'
import { useDesign } from '@/hooks/web/useDesign' import { useDesign } from '@/hooks/web/useDesign'
import { useTemplateRefsList } from '@vueuse/core'
import { ElScrollbar } from 'element-plus' import { ElScrollbar } from 'element-plus'
import { useScrollTo } from '@/hooks/event/useScrollTo' import { useScrollTo } from '@/hooks/event/useScrollTo'
import { useTemplateRefsList } from '@vueuse/core'
defineOptions({ name: 'TagsView' })
const { getPrefixCls } = useDesign() const { getPrefixCls } = useDesign()
@ -35,6 +35,8 @@ const appStore = useAppStore()
const tagsViewIcon = computed(() => appStore.getTagsViewIcon) const tagsViewIcon = computed(() => appStore.getTagsViewIcon)
const isDark = computed(() => appStore.getIsDark)
// tag // tag
const initTags = () => { const initTags = () => {
affixTagArr.value = filterAffixTags(unref(routers)) affixTagArr.value = filterAffixTags(unref(routers))
@ -73,7 +75,7 @@ const closeAllTags = () => {
toLastView() toLastView()
} }
// //
const closeOthersTags = () => { const closeOthersTags = () => {
tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded) tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
} }
@ -128,6 +130,7 @@ const moveToCurrentTag = async () => {
if (v.fullPath !== unref(currentRoute).fullPath) { if (v.fullPath !== unref(currentRoute).fullPath) {
tagsViewStore.updateVisitedView(unref(currentRoute)) tagsViewStore.updateVisitedView(unref(currentRoute))
} }
break break
} }
} }
@ -263,29 +266,21 @@ watch(
class="flex w-full relative bg-[#fff] dark:bg-[var(--el-bg-color)]" class="flex w-full relative bg-[#fff] dark:bg-[var(--el-bg-color)]"
> >
<span <span
:class="`${prefixCls}__tool`" :class="`${prefixCls}__tool ${prefixCls}__tool--first`"
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] cursor-pointer" class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer"
@click="move(-200)" @click="move(-200)"
> >
<Icon <Icon
:color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
icon="ep:d-arrow-left" icon="ep:d-arrow-left"
color="var(--el-text-color-placeholder)"
:hover-color="isDark ? '#fff' : 'var(--el-color-black)'"
/> />
</span> </span>
<div class="overflow-hidden flex-1"> <div class="overflow-hidden flex-1">
<ElScrollbar ref="scrollbarRef" class="h-full" @scroll="scroll"> <ElScrollbar ref="scrollbarRef" class="h-full" @scroll="scroll">
<div class="flex h-full"> <div class="flex h-full">
<ContextMenu <ContextMenu
v-for="item in visitedViews"
:key="item.fullPath"
:ref="itemRefs.set" :ref="itemRefs.set"
:class="[
`${prefixCls}__item`,
item?.meta?.affix ? `${prefixCls}__item--affix` : '',
{
'is-active': isActive(item)
}
]"
:schema="[ :schema="[
{ {
icon: 'ep:refresh', icon: 'ep:refresh',
@ -343,14 +338,23 @@ watch(
} }
} }
]" ]"
v-for="item in visitedViews"
:key="item.fullPath"
:tag-item="item" :tag-item="item"
:class="[
`${prefixCls}__item`,
item?.meta?.affix ? `${prefixCls}__item--affix` : '',
{
'is-active': isActive(item)
}
]"
@visible-change="visibleChange" @visible-change="visibleChange"
> >
<div> <div>
<router-link :ref="tagLinksRefs.set" v-slot="{ navigate }" :to="{ ...item }" custom> <router-link :ref="tagLinksRefs.set" :to="{ ...item }" custom v-slot="{ navigate }">
<div <div
class="h-full flex justify-center items-center whitespace-nowrap pl-15px"
@click="navigate" @click="navigate"
class="h-full flex justify-center items-center whitespace-nowrap pl-15px"
> >
<Icon <Icon
v-if=" v-if="
@ -366,9 +370,9 @@ watch(
{{ t(item?.meta?.title as string) }} {{ t(item?.meta?.title as string) }}
<Icon <Icon
:class="`${prefixCls}__item--close`" :class="`${prefixCls}__item--close`"
:size="12"
color="#333" color="#333"
icon="ep:close" icon="ep:close"
:size="12"
@click.prevent.stop="closeSelectedTag(item)" @click.prevent.stop="closeSelectedTag(item)"
/> />
</div> </div>
@ -380,25 +384,28 @@ watch(
</div> </div>
<span <span
:class="`${prefixCls}__tool`" :class="`${prefixCls}__tool`"
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer" class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer"
@click="move(200)" @click="move(200)"
> >
<Icon <Icon
:color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
icon="ep:d-arrow-right" icon="ep:d-arrow-right"
color="var(--el-text-color-placeholder)"
:hover-color="isDark ? '#fff' : 'var(--el-color-black)'"
/> />
</span> </span>
<span <span
:class="`${prefixCls}__tool`" :class="`${prefixCls}__tool`"
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer" class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer"
@click="refreshSelectedTag(selectedTag)" @click="refreshSelectedTag(selectedTag)"
> >
<Icon <Icon
:color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
icon="ep:refresh-right" icon="ep:refresh-right"
color="var(--el-text-color-placeholder)"
:hover-color="isDark ? '#fff' : 'var(--el-color-black)'"
/> />
</span> </span>
<ContextMenu <ContextMenu
trigger="click"
:schema="[ :schema="[
{ {
icon: 'ep:refresh', icon: 'ep:refresh',
@ -450,15 +457,15 @@ watch(
} }
} }
]" ]"
trigger="click"
> >
<span <span
:class="`${prefixCls}__tool`" :class="`${prefixCls}__tool`"
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer block" class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer block"
> >
<Icon <Icon
:color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
icon="ep:menu" icon="ep:menu"
color="var(--el-text-color-placeholder)"
:hover-color="isDark ? '#fff' : 'var(--el-color-black)'"
/> />
</span> </span>
</ContextMenu> </ContextMenu>
@ -475,47 +482,49 @@ $prefix-cls: #{$namespace}-tags-view;
&__tool { &__tool {
position: relative; position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
&:hover { &::before {
:deep(span) {
color: var(--el-color-black) !important;
}
}
&::after {
position: absolute; position: absolute;
top: 1px; top: 1px;
left: 0; left: 0;
width: 100%; width: 100%;
height: calc(100% - 1px); height: calc(100% - 1px);
border-right: 1px solid var(--tags-view-border-color); border-left: 1px solid var(--el-border-color);
border-left: 1px solid var(--tags-view-border-color);
content: ''; content: '';
} }
&--first {
&::before {
position: absolute;
top: 1px;
left: 0;
width: 100%;
height: calc(100% - 1px);
border-right: 1px solid var(--el-border-color);
border-left: none;
content: '';
}
}
} }
&__item { &__item {
position: relative; position: relative;
top: 2px; top: 2px;
height: calc(100% - 4px); height: calc(100% - 6px);
padding-right: 16px; padding-right: 25px;
margin-left: 4px; margin-left: 4px;
font-size: 12px; font-size: 12px;
border-radius: 3px;
cursor: pointer; cursor: pointer;
border: 1px solid #d9d9d9; border: 1px solid #d9d9d9;
border-radius: 2px;
&--close { &--close {
position: absolute; position: absolute;
top: 50%; top: 50%;
right: 3px; right: 5px;
display: none; display: none;
transform: translate(0, -50%); transform: translate(0, -50%);
} }
&:not(.#{$prefix-cls}__item--affix):hover { &:not(.#{$prefix-cls}__item--affix):hover {
.#{$prefix-cls}__item--close { .#{$prefix-cls}__item--close {
display: block; display: block;
@ -533,7 +542,6 @@ $prefix-cls: #{$namespace}-tags-view;
color: var(--el-color-white); color: var(--el-color-white);
background-color: var(--el-color-primary); background-color: var(--el-color-primary);
border: 1px solid var(--el-color-primary); border: 1px solid var(--el-color-primary);
.#{$prefix-cls}__item--close { .#{$prefix-cls}__item--close {
:deep(span) { :deep(span) {
color: var(--el-color-white) !important; color: var(--el-color-white) !important;
@ -545,26 +553,14 @@ $prefix-cls: #{$namespace}-tags-view;
.dark { .dark {
.#{$prefix-cls} { .#{$prefix-cls} {
&__tool { &__tool {
&:hover { &--first {
:deep(span) {
color: #fff !important;
}
}
&::after { &::after {
border-right: 1px solid var(--el-border-color); display: none;
border-left: 1px solid var(--el-border-color); }
} }
} }
&__item { &__item {
position: relative;
top: 2px;
height: calc(100% - 4px);
padding-right: 16px;
font-size: 12px;
border-radius: 3px;
cursor: pointer;
border: 1px solid var(--el-border-color); border: 1px solid var(--el-border-color);
} }
@ -577,7 +573,7 @@ $prefix-cls: #{$namespace}-tags-view;
&__item.is-active { &__item.is-active {
color: var(--el-color-white); color: var(--el-color-white);
background-color: var(--el-color-primary); background-color: var(--el-color-primary);
border: 1px solid var(--el-color-primary);
.#{$prefix-cls}__item--close { .#{$prefix-cls}__item--close {
:deep(span) { :deep(span) {
color: var(--el-color-white) !important; color: var(--el-color-white) !important;

View File

@ -52,28 +52,28 @@ export default defineComponent({
{layout.value !== 'top' ? ( {layout.value !== 'top' ? (
<div class="h-full flex items-center"> <div class="h-full flex items-center">
{hamburger.value && layout.value !== 'cutMenu' ? ( {hamburger.value && layout.value !== 'cutMenu' ? (
<Collapse class="hover-trigger" color="var(--top-header-text-color)"></Collapse> <Collapse class="custom-hover" color="var(--top-header-text-color)"></Collapse>
) : undefined} ) : undefined}
{breadcrumb.value ? <Breadcrumb class="<md:hidden"></Breadcrumb> : undefined} {breadcrumb.value ? <Breadcrumb class="lt-md:hidden"></Breadcrumb> : undefined}
</div> </div>
) : undefined} ) : undefined}
<div class="h-full flex items-center"> <div class="h-full flex items-center">
{screenfull.value ? ( {screenfull.value ? (
<Screenfull class="hover-trigger" color="var(--top-header-text-color)"></Screenfull> <Screenfull class="custom-hover" color="var(--top-header-text-color)"></Screenfull>
) : undefined} ) : undefined}
{size.value ? ( {size.value ? (
<SizeDropdown class="hover-trigger" color="var(--top-header-text-color)"></SizeDropdown> <SizeDropdown class="custom-hover" color="var(--top-header-text-color)"></SizeDropdown>
) : undefined} ) : undefined}
{locale.value ? ( {locale.value ? (
<LocaleDropdown <LocaleDropdown
class="hover-trigger" class="custom-hover"
color="var(--top-header-text-color)" color="var(--top-header-text-color)"
></LocaleDropdown> ></LocaleDropdown>
) : undefined} ) : undefined}
{message.value ? ( {message.value ? (
<Message class="hover-trigger" color="var(--top-header-text-color)"></Message> <Message class="custom-hover" color="var(--top-header-text-color)"></Message>
) : undefined} ) : undefined}
<UserInfo class="hover-trigger"></UserInfo> <UserInfo></UserInfo>
</div> </div>
</div> </div>
) )

View File

@ -51,7 +51,7 @@ const toDocument = () => {
</script> </script>
<template> <template>
<ElDropdown :class="prefixCls" trigger="click"> <ElDropdown class="custom-hover" :class="prefixCls" trigger="click">
<div class="flex items-center"> <div class="flex items-center">
<img :src="avatar" alt="" class="w-[calc(var(--logo-height)-25px)] rounded-[50%]" /> <img :src="avatar" alt="" class="w-[calc(var(--logo-height)-25px)] rounded-[50%]" />
<span class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]"> <span class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]">

View File

@ -39,11 +39,16 @@ export const useRenderLayout = () => {
const renderClassic = () => { const renderClassic = () => {
return ( return (
<> <>
<div class={['absolute top-0 left-0 h-full', { '!fixed z-3000': mobile.value }]}> <div
class={[
'absolute top-0 left-0 h-full layout-border__right',
{ '!fixed z-3000': mobile.value }
]}
>
{logo.value ? ( {logo.value ? (
<Logo <Logo
class={[ class={[
'bg-[var(--left-menu-bg-color)] border-bottom-1 border-solid border-[var(--logo-border-color)] dark:border-[var(--el-border-color)]', 'bg-[var(--left-menu-bg-color)] relative',
{ {
'!pl-0': mobile.value && collapse.value, '!pl-0': mobile.value && collapse.value,
'w-[var(--left-menu-min-width)]': appStore.getCollapse, 'w-[var(--left-menu-min-width)]': appStore.getCollapse,
@ -83,19 +88,26 @@ export const useRenderLayout = () => {
class={[ class={[
{ {
'fixed top-0 left-0 z-10': fixedHeader.value, 'fixed top-0 left-0 z-10': fixedHeader.value,
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]': 'w-[calc(100%-var(--left-menu-min-width))] !left-[var(--left-menu-min-width)]':
collapse.value && fixedHeader.value && !mobile.value, collapse.value && fixedHeader.value && !mobile.value,
'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)]': 'w-[calc(100%-var(--left-menu-max-width))] !left-[var(--left-menu-max-width)]':
!collapse.value && fixedHeader.value && !mobile.value, !collapse.value && fixedHeader.value && !mobile.value,
'!w-full !left-0': mobile.value '!w-full !left-0': mobile.value
} }
]} ]}
style="transition: all var(--transition-time-02);" style="transition: all var(--transition-time-02);"
> >
<ToolHeader class="border-bottom-1 border-solid border-[var(--top-tool-border-color)] bg-[var(--top-header-bg-color)] dark:border-[var(--el-border-color)]"></ToolHeader> <ToolHeader
class={[
'bg-[var(--top-header-bg-color)]',
{
'layout-border__bottom': !tagsView.value
}
]}
></ToolHeader>
{tagsView.value ? ( {tagsView.value ? (
<TagsView class="border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]"></TagsView> <TagsView class="layout-border__bottom layout-border__top"></TagsView>
) : undefined} ) : undefined}
</div> </div>
@ -109,13 +121,13 @@ export const useRenderLayout = () => {
const renderTopLeft = () => { const renderTopLeft = () => {
return ( return (
<> <>
<div class="flex items-center bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]"> <div class="flex items-center bg-[var(--top-header-bg-color)] relative layout-border__bottom dark:bg-[var(--el-bg-color)]">
{logo.value ? <Logo class="hover-trigger !pr-15px"></Logo> : undefined} {logo.value ? <Logo class="custom-hover"></Logo> : undefined}
<ToolHeader class="flex-1"></ToolHeader> <ToolHeader class="flex-1"></ToolHeader>
</div> </div>
<div class="absolute top-[var(--logo-height)+1px] left-0 w-full h-[calc(100%-1px-var(--logo-height))] flex"> <div class="absolute top-[var(--logo-height)+1px] left-0 w-full h-[calc(100%-1px-var(--logo-height))] flex">
<Menu class="!h-full"></Menu> <Menu class="!h-full relative layout-border__right"></Menu>
<div <div
class={[ class={[
`${prefixCls}-content`, `${prefixCls}-content`,
@ -142,12 +154,12 @@ export const useRenderLayout = () => {
{tagsView.value ? ( {tagsView.value ? (
<TagsView <TagsView
class={[ class={[
'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]', 'layout-border__bottom absolute',
{ {
'!fixed top-0 left-0 z-10': fixedHeader.value, '!fixed top-0 left-0 z-10': fixedHeader.value,
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)] mt-[var(--logo-height)]': 'w-[calc(100%-var(--left-menu-min-width))] !left-[var(--left-menu-min-width)] mt-[calc(var(--logo-height)+1px)]':
collapse.value && fixedHeader.value, collapse.value && fixedHeader.value,
'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)] mt-[var(--logo-height)]': 'w-[calc(100%-var(--left-menu-max-width))] !left-[var(--left-menu-max-width)] mt-[calc(var(--logo-height)+1px)]':
!collapse.value && fixedHeader.value !collapse.value && fixedHeader.value
} }
]} ]}
@ -166,12 +178,28 @@ export const useRenderLayout = () => {
const renderTop = () => { const renderTop = () => {
return ( return (
<> <>
<div class="flex items-center justify-between bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]"> <div
{logo.value ? <Logo class="hover-trigger"></Logo> : undefined} class={[
'flex items-center justify-between bg-[var(--top-header-bg-color)] relative',
{
'layout-border__bottom': !tagsView.value
}
]}
>
{logo.value ? <Logo class="custom-hover"></Logo> : undefined}
<Menu class="flex-1 px-10px h-[var(--top-tool-height)]"></Menu> <Menu class="flex-1 px-10px h-[var(--top-tool-height)]"></Menu>
<ToolHeader></ToolHeader> <ToolHeader></ToolHeader>
</div> </div>
<div class={[`${prefixCls}-content`, 'h-full w-full']}> <div
class={[
`${prefixCls}-content`,
'w-full',
{
'h-[calc(100%-var(--app-footer-height))]': !fixedHeader.value,
'h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]': fixedHeader.value
}
]}
>
<ElScrollbar <ElScrollbar
v-loading={pageLoading.value} v-loading={pageLoading.value}
class={[ class={[
@ -186,9 +214,9 @@ export const useRenderLayout = () => {
{tagsView.value ? ( {tagsView.value ? (
<TagsView <TagsView
class={[ class={[
'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]', 'layout-border__bottom layout-border__top relative',
{ {
'!fixed w-full top-[var(--top-tool-height)] left-0': fixedHeader.value '!fixed w-full top-[calc(var(--top-tool-height)+1px)] left-0': fixedHeader.value
} }
]} ]}
style="transition: width var(--transition-time-02), left var(--transition-time-02);" style="transition: width var(--transition-time-02), left var(--transition-time-02);"
@ -205,12 +233,12 @@ export const useRenderLayout = () => {
const renderCutMenu = () => { const renderCutMenu = () => {
return ( return (
<> <>
<div class="flex items-center bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]"> <div class="flex items-center bg-[var(--top-header-bg-color)] relative layout-border__bottom">
{logo.value ? <Logo class="hover-trigger !pr-15px"></Logo> : undefined} {logo.value ? <Logo class="custom-hover !pr-15px"></Logo> : undefined}
<ToolHeader class="flex-1"></ToolHeader> <ToolHeader class="flex-1"></ToolHeader>
</div> </div>
<div class="absolute top-[var(--logo-height)] left-0 w-full h-[calc(100%-var(--logo-height))] flex"> <div class="absolute top-[var(--logo-height)] left-0 w-[calc(100%-2px)] h-[calc(100%-var(--logo-height))] flex">
<TabMenu></TabMenu> <TabMenu></TabMenu>
<div <div
class={[ class={[
@ -242,18 +270,18 @@ export const useRenderLayout = () => {
{tagsView.value ? ( {tagsView.value ? (
<TagsView <TagsView
class={[ class={[
'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]', 'relative layout-border__bottom layout-border__top',
{ {
'!fixed top-0 left-0 z-10': fixedHeader.value, '!fixed top-0 left-0 z-10': fixedHeader.value,
'w-[calc(100%-var(--tab-menu-min-width))] left-[var(--tab-menu-min-width)] mt-[var(--logo-height)]': 'w-[calc(100%-var(--tab-menu-min-width))] !left-[var(--tab-menu-min-width)] mt-[var(--logo-height)]':
collapse.value && fixedHeader.value, collapse.value && fixedHeader.value,
'w-[calc(100%-var(--tab-menu-max-width))] left-[var(--tab-menu-max-width)] mt-[var(--logo-height)]': 'w-[calc(100%-var(--tab-menu-max-width))] !left-[var(--tab-menu-max-width)] mt-[var(--logo-height)]':
!collapse.value && fixedHeader.value, !collapse.value && fixedHeader.value,
'!fixed top-0 left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] z-10': '!fixed top-0 !left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] z-10':
fixedHeader.value && fixedMenu.value, fixedHeader.value && fixedMenu.value,
'w-[calc(100%-var(--tab-menu-min-width)-var(--left-menu-max-width))] left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]': 'w-[calc(100%-var(--tab-menu-min-width)-var(--left-menu-max-width))] !left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]':
collapse.value && fixedHeader.value && fixedMenu.value, collapse.value && fixedHeader.value && fixedMenu.value,
'w-[calc(100%-var(--tab-menu-max-width)-var(--left-menu-max-width))] left-[var(--tab-menu-max-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]': 'w-[calc(100%-var(--tab-menu-max-width)-var(--left-menu-max-width))] !left-[var(--tab-menu-max-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]':
!collapse.value && fixedHeader.value && fixedMenu.value !collapse.value && fixedHeader.value && fixedMenu.value
} }
]} ]}

View File

@ -1,5 +1,5 @@
// 引入windi css // 引入unocss css
import '@/plugins/windi.css' import '@/plugins/unocss'
// 导入全局的svg图标 // 导入全局的svg图标
import '@/plugins/svgIcon' import '@/plugins/svgIcon'

View File

@ -0,0 +1 @@
import 'virtual:uno.css'

View File

@ -1,3 +0,0 @@
import 'virtual:windi.css'
import 'virtual:windi-devtools'

View File

@ -3,7 +3,6 @@ import { store } from '../index'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import remainingRouter from '@/router/modules/remaining' import remainingRouter from '@/router/modules/remaining'
import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper' import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper'
import { getAsyncRoutes } from '@/api/login'
import { CACHE_KEY, useCache } from '@/hooks/web/useCache' import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache() const { wsCache } = useCache()
@ -34,12 +33,10 @@ export const usePermissionStore = defineStore('permission', {
actions: { actions: {
async generateRoutes(): Promise<unknown> { async generateRoutes(): Promise<unknown> {
return new Promise<void>(async (resolve) => { return new Promise<void>(async (resolve) => {
// 获得菜单列表它在登录的时候setUserInfoAction 方法中已经进行获取
let res: AppCustomRouteRecordRaw[] let res: AppCustomRouteRecordRaw[]
if (wsCache.get(CACHE_KEY.ROLE_ROUTERS)) { if (wsCache.get(CACHE_KEY.ROLE_ROUTERS)) {
res = wsCache.get(CACHE_KEY.ROLE_ROUTERS) as AppCustomRouteRecordRaw[] res = wsCache.get(CACHE_KEY.ROLE_ROUTERS) as AppCustomRouteRecordRaw[]
} else {
res = await getAsyncRoutes()
wsCache.set(CACHE_KEY.ROLE_ROUTERS, res)
} }
const routerMap: AppRouteRecordRaw[] = generateRoute(res as AppCustomRouteRecordRaw[]) const routerMap: AppRouteRecordRaw[] = generateRoute(res as AppCustomRouteRecordRaw[])
// 动态路由404一定要放到最后面 // 动态路由404一定要放到最后面

View File

@ -58,6 +58,7 @@ export const useUserStore = defineStore('admin-user', {
this.user = userInfo.user this.user = userInfo.user
this.isSetUser = true this.isSetUser = true
wsCache.set(CACHE_KEY.USER, userInfo) wsCache.set(CACHE_KEY.USER, userInfo)
wsCache.set(CACHE_KEY.ROLE_ROUTERS, userInfo.menus)
}, },
async loginOut() { async loginOut() {
await loginOut() await loginOut()

View File

@ -23,7 +23,9 @@
} }
& .peg { & .peg {
box-shadow: 0 0 10px var(--el-color-primary), 0 0 5px var(--el-color-primary) !important; box-shadow:
0 0 10px var(--el-color-primary),
0 0 5px var(--el-color-primary) !important;
} }
& .spinner-icon { & .spinner-icon {

View File

@ -1,8 +1,5 @@
:root { :root {
--dark-bg-color: #293146; --login-bg-color: #293146;
/* left menu start */
--left-menu-border-color: '#eee';
--left-menu-max-width: 200px; --left-menu-max-width: 200px;
@ -25,8 +22,6 @@
--logo-height: 50px; --logo-height: 50px;
--logo-title-text-color: #fff; --logo-title-text-color: #fff;
--logo-border-color: 'inherit';
/* logo end */ /* logo end */
/* header start */ /* header start */
@ -40,11 +35,7 @@
--top-tool-p-x: 0; --top-tool-p-x: 0;
--top-tool-border-color: #eee;
--tags-view-height: 35px; --tags-view-height: 35px;
--tags-view-border-color: #eee;
/* header start */ /* header start */
/* tab menu start */ /* tab menu start */
@ -53,8 +44,6 @@
--tab-menu-min-width: 30px; --tab-menu-min-width: 30px;
--tab-menu-collapse-height: 36px; --tab-menu-collapse-height: 36px;
--tab-menu-border-color: #eee;
/* tab menu end */ /* tab menu end */
--app-content-padding: 20px; --app-content-padding: 20px;
@ -66,6 +55,10 @@
--transition-time-02: 0.2s; --transition-time-02: 0.2s;
} }
.dark {
--app-content-bg-color: var(--el-bg-color);
}
html, html,
body { body {
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;

View File

@ -7,7 +7,7 @@
<div class="flex items-center"> <div class="flex items-center">
<img :src="avatar" alt="" class="w-70px h-70px rounded-[50%] mr-20px" /> <img :src="avatar" alt="" class="w-70px h-70px rounded-[50%] mr-20px" />
<div> <div>
<div class="text-20px text-700"> <div class="text-20px">
{{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }} {{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}
</div> </div>
<div class="mt-10px text-14px text-gray-500"> <div class="mt-10px text-14px text-gray-500">
@ -17,7 +17,7 @@
</div> </div>
</el-col> </el-col>
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24"> <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
<div class="flex h-70px items-center justify-end <sm:mt-10px"> <div class="flex h-70px items-center justify-end lt-sm:mt-10px">
<div class="px-8px text-right"> <div class="px-8px text-right">
<div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div> <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div>
<CountTo <CountTo

View File

@ -1,11 +1,11 @@
<template> <template>
<div <div
:class="prefixCls" :class="prefixCls"
class="h-[100%] relative <xl:bg-v-dark <sm:px-10px <xl:px-10px <md:px-10px" class="h-[100%] relative lt-xl:bg-[var(--login-bg-color)] lt-sm:px-10px lt-xl:px-10px lt-md:px-10px"
> >
<div class="relative h-full flex mx-auto"> <div class="relative h-full flex mx-auto">
<div <div
:class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px <xl:hidden`" :class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px lt-xl:hidden`"
> >
<!-- 左上角的 logo + 系统标题 --> <!-- 左上角的 logo + 系统标题 -->
<div class="flex items-center relative text-white"> <div class="flex items-center relative text-white">
@ -27,33 +27,35 @@
</TransitionGroup> </TransitionGroup>
</div> </div>
</div> </div>
<div class="flex-1 p-30px <sm:p-10px dark:bg-v-dark relative"> <div class="flex-1 p-30px lt-sm:p-10px dark:bg-[var(--login-bg-color)] relative">
<!-- 右上角的主题语言选择 --> <!-- 右上角的主题语言选择 -->
<div class="flex justify-between items-center text-white @2xl:justify-end @xl:justify-end"> <div
<div class="flex items-center @2xl:hidden @xl:hidden"> class="flex justify-between items-center text-white at-2xl:justify-end at-xl:justify-end"
>
<div class="flex items-center at-2xl:hidden at-xl:hidden">
<img alt="" class="w-48px h-48px mr-10px" src="@/assets/imgs/logo.png" /> <img alt="" class="w-48px h-48px mr-10px" src="@/assets/imgs/logo.png" />
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span> <span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
</div> </div>
<div class="flex justify-end items-center space-x-10px"> <div class="flex justify-end items-center space-x-10px">
<ThemeSwitch /> <ThemeSwitch />
<LocaleDropdown class="<xl:text-white dark:text-white" /> <LocaleDropdown class="lt-xl:text-white dark:text-white" />
</div> </div>
</div> </div>
<!-- 右边的登录界面 --> <!-- 右边的登录界面 -->
<Transition appear enter-active-class="animate__animated animate__bounceInRight"> <Transition appear enter-active-class="animate__animated animate__bounceInRight">
<div <div
class="h-full flex items-center m-auto w-[100%] @2xl:max-w-500px @xl:max-w-500px @md:max-w-500px @lg:max-w-500px" class="h-full flex items-center m-auto w-[100%] at-2xl:max-w-500px at-xl:max-w-500px at-md:max-w-500px at-lg:max-w-500px"
> >
<!-- 账号登录 --> <!-- 账号登录 -->
<LoginForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> <LoginForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
<!-- 手机登录 --> <!-- 手机登录 -->
<MobileForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> <MobileForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
<!-- 二维码登录 --> <!-- 二维码登录 -->
<QrCodeForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> <QrCodeForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
<!-- 注册 --> <!-- 注册 -->
<RegisterForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> <RegisterForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
<!-- 三方登录 --> <!-- 三方登录 -->
<SSOLoginVue class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> <SSOLoginVue class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" />
</div> </div>
</Transition> </Transition>
</div> </div>
@ -82,6 +84,8 @@ const prefixCls = getPrefixCls('login')
$prefix-cls: #{$namespace}-login; $prefix-cls: #{$namespace}-login;
.#{$prefix-cls} { .#{$prefix-cls} {
overflow: auto;
&__left { &__left {
&::before { &::before {
position: absolute; position: absolute;

View File

@ -9,7 +9,7 @@
label-width="120px" label-width="120px"
size="large" size="large"
> >
<el-row style="maring-left: -10px; maring-right: -10px"> <el-row style="margin-left: -10px; margin-right: -10px">
<el-col :span="24" style="padding-left: 10px; padding-right: 10px"> <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
<el-form-item> <el-form-item>
<LoginFormTitle style="width: 100%" /> <LoginFormTitle style="width: 100%" />

View File

@ -185,12 +185,17 @@ const signIn = async () => {
await getTenantId() await getTenantId()
const data = await validForm() const data = await validForm()
if (!data) return if (!data) return
ElLoading.service({
lock: true,
text: '正在加载系统中...',
background: 'rgba(0, 0, 0, 0.7)'
})
loginLoading.value = true loginLoading.value = true
smsVO.loginSms.mobile = loginData.loginForm.mobileNumber smsVO.loginSms.mobile = loginData.loginForm.mobileNumber
smsVO.loginSms.code = loginData.loginForm.code smsVO.loginSms.code = loginData.loginForm.code
await smsLogin(smsVO.loginSms) await smsLogin(smsVO.loginSms)
.then(async (res) => { .then(async (res) => {
setToken(res?.token) setToken(res)
if (!redirect.value) { if (!redirect.value) {
redirect.value = '/' redirect.value = '/'
} }
@ -199,6 +204,10 @@ const signIn = async () => {
.catch(() => {}) .catch(() => {})
.finally(() => { .finally(() => {
loginLoading.value = false loginLoading.value = false
setTimeout(() => {
const loadingInstance = ElLoading.service()
loadingInstance.close()
}, 400)
}) })
} }
</script> </script>

View File

@ -1,5 +1,5 @@
<template> <template>
<el-row v-show="getShow" style="maring-left: -10px; maring-right: -10px"> <el-row v-show="getShow" style="margin-left: -10px; margin-right: -10px">
<el-col :span="24" style="padding-left: 10px; padding-right: 10px"> <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
<LoginFormTitle style="width: 100%" /> <LoginFormTitle style="width: 100%" />
</el-col> </el-col>

View File

@ -55,7 +55,14 @@ const client = ref({
name: '', name: '',
logo: '' logo: ''
}) })
const queryParams = reactive({ interface queryType {
responseType: string
clientId: string
redirectUri: string
state: string
scopes: string[]
}
const queryParams = reactive<queryType>({
// URL client_idscope // URL client_idscope
responseType: '', responseType: '',
clientId: '', clientId: '',
@ -64,7 +71,10 @@ const queryParams = reactive({
scopes: [] // query scopes: [] // query
}) })
const ssoVisible = computed(() => unref(getLoginState) === LoginStateEnum.SSO) // SSO const ssoVisible = computed(() => unref(getLoginState) === LoginStateEnum.SSO) // SSO
const formData = reactive({ interface formType {
scopes: string[]
}
const formData = reactive<formType>({
scopes: [] // scope scopes: [] // scope
}) })
const formLoading = ref(false) // const formLoading = ref(false) //

View File

@ -23,7 +23,7 @@
</el-button> </el-button>
<el-scrollbar height="580"> <el-scrollbar height="580">
<div> <div>
<pre><code class="hljs" v-html="highlightedCode(formData)"></code></pre> <pre><code class="hljs" v-dompurify-html="highlightedCode(formData)"></code></pre>
</div> </div>
</el-scrollbar> </el-scrollbar>
</div> </div>
@ -39,6 +39,7 @@ import hljs from 'highlight.js' // 导入代码高亮文件
import 'highlight.js/styles/github.css' // import 'highlight.js/styles/github.css' //
import xml from 'highlight.js/lib/languages/java' import xml from 'highlight.js/lib/languages/java'
import json from 'highlight.js/lib/languages/json' import json from 'highlight.js/lib/languages/json'
import formCreate from '@form-create/element-ui'
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //

View File

@ -106,7 +106,7 @@
<el-button <el-button
type="danger" type="danger"
link link
@click="handleDelete(scope.row)" @click="handleDelete(scope.row.id)"
v-hasPermi="['infra:job:delete']" v-hasPermi="['infra:job:delete']"
> >
删除 删除

View File

@ -443,7 +443,8 @@ const generateTableData = (propertyList: any[]) => {
*/ */
const validateData = (propertyList: any[]) => { const validateData = (propertyList: any[]) => {
const skuPropertyIds: number[] = [] const skuPropertyIds: number[] = []
formData.value!.skus!.forEach((sku) => formData.value!.skus!.forEach(
(sku) =>
sku.properties sku.properties
?.map((property) => property.propertyId) ?.map((property) => property.propertyId)
?.forEach((propertyId) => { ?.forEach((propertyId) => {

View File

@ -134,11 +134,7 @@ const open = async (type: string, id?: number) => {
const data = (await CombinationActivityApi.getCombinationActivity( const data = (await CombinationActivityApi.getCombinationActivity(
id id
)) as CombinationActivityApi.CombinationActivityVO )) as CombinationActivityApi.CombinationActivityVO
await getSpuDetails( await getSpuDetails(data.spuId!, data.products?.map((sku) => sku.skuId), data.products)
data.spuId!,
data.products?.map((sku) => sku.skuId),
data.products
)
formRef.value.setValues(data) formRef.value.setValues(data)
} finally { } finally {
formLoading.value = false formLoading.value = false

View File

@ -98,9 +98,10 @@ const handleDelete = (id: number) => {
tableMethods.delList(id, false) tableMethods.delList(id, false)
} }
// TODO @puhui999使 element plus crud schema
/** 初始化 **/ /** 初始化 **/
onMounted(() => { onMounted(() => {
/* /**
TODO TODO
后面准备封装成一个函数来操作 tableColumns 重新排列比如说需求是表单上商品选择是在后面的而列表展示的时候需要调到位置 后面准备封装成一个函数来操作 tableColumns 重新排列比如说需求是表单上商品选择是在后面的而列表展示的时候需要调到位置
封装效果支持批量操作给出 field 和需要插入的位置[{field:'spuId',index: 1}] 效果为把 field spuId column 移动到第一个位置 封装效果支持批量操作给出 field 和需要插入的位置[{field:'spuId',index: 1}] 效果为把 field spuId column 移动到第一个位置

View File

@ -50,8 +50,10 @@ const spuData = ref<Spu[]>([]) // spu 详情数据列表
const skuListRef = ref() // Ref const skuListRef = ref() // Ref
const spuPropertyList = ref<SpuProperty<T>[]>([]) // spuId sku const spuPropertyList = ref<SpuProperty<T>[]>([]) // spuId sku
const expandRowKeys = ref<number[]>() // row-key 使 keys const expandRowKeys = ref<number[]>() // row-key 使 keys
/** /**
* 获取所有 sku 活动配置 * 获取所有 sku 活动配置
*
* @param extendedAttribute sku 上扩展的属性秒杀活动 sku 扩展属性 productConfig 请参考 seckillActivity.ts * @param extendedAttribute sku 上扩展的属性秒杀活动 sku 扩展属性 productConfig 请参考 seckillActivity.ts
*/ */
const getSkuConfigs = (extendedAttribute: string) => { const getSkuConfigs = (extendedAttribute: string) => {

View File

@ -144,11 +144,7 @@ const open = async (type: string, id?: number) => {
const data = (await SeckillActivityApi.getSeckillActivity( const data = (await SeckillActivityApi.getSeckillActivity(
id id
)) as SeckillActivityApi.SeckillActivityVO )) as SeckillActivityApi.SeckillActivityVO
await getSpuDetails( await getSpuDetails(data.spuId!, data.products?.map((sku) => sku.skuId), data.products)
data.spuId!,
data.products?.map((sku) => sku.skuId),
data.products
)
formRef.value.setValues(data) formRef.value.setValues(data)
} finally { } finally {
formLoading.value = false formLoading.value = false

View File

@ -12,7 +12,7 @@
<el-select class="!w-280px" v-model="queryParams.status" clearable placeholder="全部"> <el-select class="!w-280px" v-model="queryParams.status" clearable placeholder="全部">
<el-option <el-option
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)" v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)"
:key="(dict.value as string)" :key="dict.value as string"
:label="dict.label" :label="dict.label"
:value="dict.value" :value="dict.value"
/> />
@ -27,7 +27,7 @@
> >
<el-option <el-option
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE_TYPE)" v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE_TYPE)"
:key="(dict.value as string)" :key="dict.value as string"
:label="dict.label" :label="dict.label"
:value="dict.value" :value="dict.value"
/> />
@ -48,7 +48,7 @@
<el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部"> <el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部">
<el-option <el-option
v-for="dict in getStrDictOptions(DICT_TYPE.TERMINAL)" v-for="dict in getStrDictOptions(DICT_TYPE.TERMINAL)"
:key="(dict.value as string)" :key="dict.value as string"
:label="dict.label" :label="dict.label"
:value="dict.value" :value="dict.value"
/> />
@ -58,7 +58,7 @@
<el-select class="!w-280px" v-model="queryParams.type" clearable placeholder="全部"> <el-select class="!w-280px" v-model="queryParams.type" clearable placeholder="全部">
<el-option <el-option
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)" v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)"
:key="(dict.value as string)" :key="dict.value as string"
:label="dict.label" :label="dict.label"
:value="dict.value" :value="dict.value"
/> />

View File

@ -90,8 +90,19 @@
padding: 15px; padding: 15px;
overflow: hidden; overflow: hidden;
background: #fff; background: #fff;
font-family: Segoe UI, Lucida Grande, Helvetica, Arial, Microsoft YaHei, FreeSans, Arimo, font-family:
Droid Sans, wenquanyi micro hei, Hiragino Sans GB, Hiragino Sans GB W3, FontAwesome, Segoe UI,
Lucida Grande,
Helvetica,
Arial,
Microsoft YaHei,
FreeSans,
Arimo,
Droid Sans,
wenquanyi micro hei,
Hiragino Sans GB,
Hiragino Sans GB W3,
FontAwesome,
sans-serif; sans-serif;
color: #333; color: #333;
font-size: 14px; font-size: 14px;
@ -99,7 +110,16 @@
blockquote { blockquote {
margin: 0; margin: 0;
font-family: Georgia, Times New Roman, Times, Kai, Kaiti SC, KaiTi, BiauKai, FontAwesome, serif; font-family:
Georgia,
Times New Roman,
Times,
Kai,
Kaiti SC,
KaiTi,
BiauKai,
FontAwesome,
serif;
padding: 1px 0 1px 15px; padding: 1px 0 1px 15px;
border-left: 4px solid #ddd; border-left: 4px solid #ddd;
} }

View File

@ -10,7 +10,7 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"esModuleInterop": true, "esModuleInterop": true,
"lib": ["esnext", "dom"], "lib": ["esnext", "dom"],
"baseUrl": ".", "baseUrl": "./",
"allowJs": true, "allowJs": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
@ -36,7 +36,7 @@
"typeRoots": ["./node_modules/@types/", "./types"] "typeRoots": ["./node_modules/@types/", "./types"]
}, },
"include": [ "include": [
"src/**/*", "src",
"types/**/*.d.ts", "types/**/*.d.ts",
"src/types/auto-imports.d.ts", "src/types/auto-imports.d.ts",
"src/types/auto-components.d.ts" "src/types/auto-components.d.ts"

105
uno.config.ts Normal file
View File

@ -0,0 +1,105 @@
import { defineConfig, toEscapedSelector as e, presetUno } from 'unocss'
import transformerVariantGroup from '@unocss/transformer-variant-group'
export default defineConfig({
// ...UnoCSS options
rules: [
[
/^custom-hover$/,
([], { rawSelector }) => {
const selector = e(rawSelector)
return `
${selector} {
display: flex;
height: 100%;
padding: 1px 10px 0;
cursor: pointer;
align-items: center;
transition: background var(--transition-time-02);
}
/* you can have multiple rules */
${selector}:hover {
background-color: var(--top-header-hover-color);
}
.dark ${selector}:hover {
background-color: var(--el-bg-color-overlay);
}
`
}
],
[
/^layout-border__left$/,
([], { rawSelector }) => {
const selector = e(rawSelector)
return `
${selector}:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 1px;
height: 100%;
background-color: var(--el-border-color);
z-index: 3;
}
`
}
],
[
/^layout-border__right$/,
([], { rawSelector }) => {
const selector = e(rawSelector)
return `
${selector}:after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 1px;
height: 100%;
background-color: var(--el-border-color);
z-index: 3;
}
`
}
],
[
/^layout-border__top$/,
([], { rawSelector }) => {
const selector = e(rawSelector)
return `
${selector}:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 1px;
background-color: var(--el-border-color);
z-index: 3;
}
`
}
],
[
/^layout-border__bottom$/,
([], { rawSelector }) => {
const selector = e(rawSelector)
return `
${selector}:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 1px;
background-color: var(--el-border-color);
z-index: 3;
}
`
}
]
],
presets: [presetUno({ dark: 'class', attributify: false })],
transformers: [transformerVariantGroup()]
})

View File

@ -1,61 +0,0 @@
import { defineConfig } from 'vite-plugin-windicss'
import plugin from 'windicss/plugin'
function range(size, startAt = 1) {
return Array.from(Array(size).keys()).map((i) => i + startAt)
}
export default defineConfig({
extract: {
include: ['src/**/*.{vue,html,jsx,tsx}'],
exclude: ['node_modules', '.git']
},
darkMode: 'class',
attributify: false,
theme: {
extend: {
backgroundColor: {
// 暗黑背景色
'v-dark': 'var(--dark-bg-color)'
}
}
},
plugins: [
plugin(({ addComponents }) => {
const obj = {}
range(50).map((i) => {
obj[`.border-top-${i}`] = {
borderTopWidth: `${i}px`
}
obj[`.border-left-${i}`] = {
borderLeftWidth: `${i}px`
}
obj[`.border-right-${i}`] = {
borderRightWidth: `${i}px`
}
obj[`.border-bottom-${i}`] = {
borderBottomWidth: `${i}px`
}
})
addComponents({
'.hover-trigger': {
display: 'flex',
height: '100%',
padding: '1px 10px 0',
cursor: 'pointer',
alignItems: 'center',
transition: 'background var(--transition-time-02)',
'&:hover': {
backgroundColor: 'var(--top-header-hover-color)'
}
},
'.dark .hover-trigger': {
'&:hover': {
backgroundColor: 'var(--el-bg-color-overlay)'
}
},
...obj
})
})
]
})