updates
4
.env
|
|
@ -2,10 +2,10 @@
|
||||||
VITE_PORT = 3100
|
VITE_PORT = 3100
|
||||||
|
|
||||||
# 网站标题
|
# 网站标题
|
||||||
VITE_GLOB_APP_TITLE = 后台管理系统
|
VITE_GLOB_APP_TITLE = 艺体志愿宝 管理平台
|
||||||
|
|
||||||
# 简称,用于配置文件名字 不要出现空格、数字开头等特殊字符
|
# 简称,用于配置文件名字 不要出现空格、数字开头等特殊字符
|
||||||
VITE_GLOB_APP_SHORT_NAME = JeecgBootAdmin
|
VITE_GLOB_APP_SHORT_NAME = YitishengAdmin
|
||||||
|
|
||||||
# 单点登录服务端地址
|
# 单点登录服务端地址
|
||||||
VITE_GLOB_APP_CAS_BASE_URL=http://cas.test.com:8443/cas
|
VITE_GLOB_APP_CAS_BASE_URL=http://cas.test.com:8443/cas
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,14 @@ VITE_USE_MOCK = true
|
||||||
# 发布路径
|
# 发布路径
|
||||||
VITE_PUBLIC_PATH = /
|
VITE_PUBLIC_PATH = /
|
||||||
|
|
||||||
|
|
||||||
# 跨域代理,您可以配置多个 ,请注意,没有换行符
|
# 跨域代理,您可以配置多个 ,请注意,没有换行符
|
||||||
VITE_PROXY = [["/jeecgboot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]]
|
VITE_PROXY = [["/jeecgboot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]]
|
||||||
|
|
||||||
# 控制台不输出
|
|
||||||
VITE_DROP_CONSOLE = false
|
|
||||||
|
|
||||||
#后台接口父地址(必填)
|
|
||||||
VITE_GLOB_API_URL=/jeecgboot
|
|
||||||
|
|
||||||
#后台接口全路径地址(必填)
|
#后台接口全路径地址(必填)
|
||||||
VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot
|
VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot/
|
||||||
|
#后台接口父地址(必填)
|
||||||
|
VITE_GLOB_API_URL=http://localhost:8080/jeecg-boot/
|
||||||
|
|
||||||
# 接口前缀
|
# 接口前缀
|
||||||
VITE_GLOB_API_URL_PREFIX=
|
VITE_GLOB_API_URL_PREFIX=
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,6 @@ VITE_USE_MOCK = true
|
||||||
# 发布路径
|
# 发布路径
|
||||||
VITE_PUBLIC_PATH = /
|
VITE_PUBLIC_PATH = /
|
||||||
|
|
||||||
# 控制台不输出
|
|
||||||
VITE_DROP_CONSOLE = true
|
|
||||||
|
|
||||||
# 是否启用gzip或brotli压缩
|
# 是否启用gzip或brotli压缩
|
||||||
# 选项值: gzip | brotli | none
|
# 选项值: gzip | brotli | none
|
||||||
# 如果需要多个可以使用“,”分隔
|
# 如果需要多个可以使用“,”分隔
|
||||||
|
|
@ -16,19 +13,10 @@ VITE_BUILD_COMPRESS = 'gzip'
|
||||||
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
|
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
|
||||||
|
|
||||||
#后台接口父地址(必填)
|
#后台接口父地址(必填)
|
||||||
VITE_GLOB_API_URL=/jeecgboot
|
VITE_GLOB_API_URL=https://yitisheng.vip/jbttest
|
||||||
|
|
||||||
#后台接口全路径地址(必填)
|
#后台接口全路径地址(必填)
|
||||||
VITE_GLOB_DOMAIN_URL=http://jeecg-boot-system:8080/jeecg-boot
|
VITE_GLOB_DOMAIN_URL=https://yitisheng.vip/jbttest
|
||||||
|
|
||||||
|
|
||||||
# 接口父路径前缀
|
# 接口父路径前缀
|
||||||
VITE_GLOB_API_URL_PREFIX=
|
VITE_GLOB_API_URL_PREFIX=
|
||||||
|
|
||||||
# 是否启用图像压缩
|
|
||||||
VITE_USE_IMAGEMIN= true
|
|
||||||
|
|
||||||
# 使用pwa
|
|
||||||
VITE_USE_PWA = false
|
|
||||||
|
|
||||||
# 是否兼容旧浏览器
|
|
||||||
VITE_LEGACY = false
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ pnpm-debug.log*
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.idea
|
.idea
|
||||||
|
.svn
|
||||||
# .vscode
|
# .vscode
|
||||||
*.suo
|
*.suo
|
||||||
*.ntvs*
|
*.ntvs*
|
||||||
|
|
@ -29,6 +30,7 @@ pnpm-debug.log*
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
/os_del.cmd
|
/os_del.cmd
|
||||||
|
os_del.cmd
|
||||||
/.vscode/
|
/.vscode/
|
||||||
/.history/
|
/.history/
|
||||||
/svn clear.bat
|
/svn clear.bat
|
||||||
|
|
|
||||||
6
LICENSE
|
|
@ -23,7 +23,7 @@ SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
开源协议补充
|
开源协议补充
|
||||||
JeecgBoot 是由 北京敲敲云科技有限公司 发行的软件。 总部位于北京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com
|
JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com
|
||||||
本软件受适用的国家软件著作权法(包括国际条约)和双重保护许可。
|
本软件受适用的国家软件著作权法(包括国际条约)和双重保护许可。
|
||||||
|
|
||||||
1.允许基于本平台软件开展业务系统开发。
|
1.允许基于本平台软件开展业务系统开发。
|
||||||
|
|
@ -32,4 +32,6 @@ SOFTWARE.
|
||||||
违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。
|
违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。
|
||||||
|
|
||||||
总结:在遵循Apache开源协议和开源协议补充条款下,允许商用使用,不会造成侵权行为!
|
总结:在遵循Apache开源协议和开源协议补充条款下,允许商用使用,不会造成侵权行为!
|
||||||
解释权归:http://www.jeecg.com
|
解释权归:
|
||||||
|
http://www.jeecg.com
|
||||||
|
http://guojusoft.com
|
||||||
|
|
|
||||||
24
README.md
|
|
@ -1,18 +1,18 @@
|
||||||
JEECG BOOT 低代码开发平台(Vue3前端)
|
JEECG BOOT 低代码开发平台(Vue3前端)
|
||||||
===============
|
===============
|
||||||
当前最新版本: 3.5.3(发布时间:2023-07-24)
|
当前最新版本: 3.6.3(发布时间:2024-03-11)
|
||||||
|
|
||||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||||
[](http://www.jeecg.com)
|
[](http://jeecg.com/aboutusIndex)
|
||||||
[](https://jeecg.blog.csdn.net)
|
[](https://jeecg.blog.csdn.net)
|
||||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
JeecgBoot-Vue3采用 Vue3.0、Vite、 Ant-Design-Vue3、TypeScript 等新技术方案,包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能。
|
JeecgBoot-Vue3采用 Vue3.0、Vite、 Ant-Design-Vue4、TypeScript 等新技术方案,包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能。
|
||||||
是采用Vben实现的 JeecgBoot低代码平台的全新vue3版本。
|
是采用Vben实现的 JeecgBoot低代码平台的全新vue3版本。
|
||||||
|
|
||||||
> 强大的代码生成器让前后端代码一键生成! JeecgBoot引领低代码开发模式(OnlineCoding-> 代码生成-> 手工MERGE), 帮助解决Java项目70%的重复工作,让开发更多关注业务。既能快速提高效率,节省成本,同时又不失灵活性
|
> 强大的代码生成器让前后端代码一键生成! JeecgBoot引领低代码开发模式(OnlineCoding-> 代码生成-> 手工MERGE), 帮助解决Java项目70%的重复工作,让开发更多关注业务。既能快速提高效率,节省成本,同时又不失灵活性
|
||||||
|
|
@ -31,10 +31,10 @@ JeecgBoot-Vue3采用 Vue3.0、Vite、 Ant-Design-Vue3、TypeScript 等新技术
|
||||||
|
|
||||||
##### 项目说明
|
##### 项目说明
|
||||||
|
|
||||||
| 项目名 | 说明 |
|
| 项目名 | 说明 |
|
||||||
|--------------------|------------------------|
|
|--------------------|-----------------------------------------|
|
||||||
| `jeecgboot-vue3` | Vue3版前端代码 |
|
| `jeecgboot-vue3` | 前端源码Vue3版下载 |
|
||||||
| `jeecg-boot` | SpringBoot后台项目(支持微服务) |
|
| `jeecg-boot` | 后端JAVA源码下载(SpringBoot+SpringCloud) |
|
||||||
|
|
||||||
## 开发环境搭建
|
## 开发环境搭建
|
||||||
|
|
||||||
|
|
@ -44,11 +44,11 @@ JeecgBoot-Vue3采用 Vue3.0、Vite、 Ant-Design-Vue3、TypeScript 等新技术
|
||||||
|
|
||||||
## 技术文档
|
## 技术文档
|
||||||
|
|
||||||
- 官方文档:[http://help.jeecg.com](http://help.jeecg.com)
|
- 官方文档:[https://help.jeecg.com](https://help.jeecg.com)
|
||||||
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
|
- 官方网站: [https://www.jeecg.com](https://www.jeecg.com)
|
||||||
- 快速入门:[快速入门](http://jeecg.com/doc/quickstart) | [常见问题](http://help.jeecg.com/qa.html) | [视频教程](https://www.bilibili.com/video/BV1V34y187Y9 "入门视频") | [ 代码生成](http://help.jeecg.com/vue3/codegen/online.html)
|
- 快速入门:[快速入门](http://jeecg.com/doc/quickstart) | [常见问题](http://help.jeecg.com/qa.html) | [视频教程](https://www.bilibili.com/video/BV1V34y187Y9 "入门视频") | [ 代码生成](http://help.jeecg.com/vue3/codegen/online.html)
|
||||||
- QQ交流群:⑦791696430、683903138
|
- QQ交流群:⑧825232878、⑦791696430(满)、683903138(满)
|
||||||
- 在线演示 : [Vue3演示](http://boot3.jeecg.com) | [Vue2演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex)
|
- 在线演示 : [Vue3演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex)| [敲敲云零代码](https://www.qiaoqiaoyun.com)
|
||||||
> 演示系统的登录账号密码,请点击 [获取账号密码](http://jeecg.com/doc/demo) 获取
|
> 演示系统的登录账号密码,请点击 [获取账号密码](http://jeecg.com/doc/demo) 获取
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,21 @@
|
||||||
import { generateAntColors, primaryColor } from '../config/themeConfig';
|
import { primaryColor } from '../config/themeConfig';
|
||||||
import { getThemeVariables } from 'ant-design-vue/dist/theme';
|
// import { getThemeVariables } from 'ant-design-vue/dist/theme';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
|
import { generate } from '@ant-design/colors';
|
||||||
|
import { theme } from 'ant-design-vue/lib';
|
||||||
|
import convertLegacyToken from 'ant-design-vue/lib/theme/convertLegacyToken';
|
||||||
|
const { defaultAlgorithm, defaultSeed } = theme;
|
||||||
|
|
||||||
|
function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') {
|
||||||
|
return generate(color, {
|
||||||
|
theme,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* less global variable
|
* less global variable
|
||||||
*/
|
*/
|
||||||
export function generateModifyVars(dark = false) {
|
export function generateModifyVars() {
|
||||||
const palettes = generateAntColors(primaryColor);
|
const palettes = generateAntColors(primaryColor);
|
||||||
const primary = palettes[5];
|
const primary = palettes[5];
|
||||||
|
|
||||||
|
|
@ -15,12 +25,14 @@ export function generateModifyVars(dark = false) {
|
||||||
primaryColorObj[`primary-${index + 1}`] = palettes[index];
|
primaryColorObj[`primary-${index + 1}`] = palettes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
const modifyVars = getThemeVariables({ dark });
|
const mapToken = defaultAlgorithm(defaultSeed);
|
||||||
|
const v3Token = convertLegacyToken(mapToken);
|
||||||
return {
|
return {
|
||||||
...modifyVars,
|
...v3Token,
|
||||||
|
// ...modifyVars,
|
||||||
// Used for global import to avoid the need to import each style file separately
|
// Used for global import to avoid the need to import each style file separately
|
||||||
// reference: Avoid repeated references
|
// reference: Avoid repeated references
|
||||||
hack: `${modifyVars.hack} @import (reference) "${resolve('src/design/config.less')}";`,
|
hack: `true; @import (reference) "${resolve('src/design/config.less')}";`,
|
||||||
'primary-color': primary,
|
'primary-color': primary,
|
||||||
...primaryColorObj,
|
...primaryColorObj,
|
||||||
'info-color': primary,
|
'info-color': primary,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* Generate additional configuration files when used for packaging. The file can be configured with some global variables, so that it can be changed directly externally without repackaging
|
* 生成外部配置文件,用于生产发布后配置,无需重新打包
|
||||||
*/
|
*/
|
||||||
import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant';
|
import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant';
|
||||||
import fs, { writeFileSync } from 'fs-extra';
|
import fs, { writeFileSync } from 'fs-extra';
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ export function configCompressPlugin(compress: 'gzip' | 'brotli' | 'none', delet
|
||||||
if (compressList.includes('gzip')) {
|
if (compressList.includes('gzip')) {
|
||||||
plugins.push(
|
plugins.push(
|
||||||
compressPlugin({
|
compressPlugin({
|
||||||
|
verbose: true,
|
||||||
|
disable: false,
|
||||||
|
threshold: 10240,
|
||||||
|
algorithm: 'gzip',
|
||||||
ext: '.gz',
|
ext: '.gz',
|
||||||
deleteOriginFile,
|
deleteOriginFile,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) {
|
||||||
const htmlPlugin: PluginOption[] = createHtmlPlugin({
|
const htmlPlugin: PluginOption[] = createHtmlPlugin({
|
||||||
minify: isBuild,
|
minify: isBuild,
|
||||||
inject: {
|
inject: {
|
||||||
// Inject data into ejs template
|
// 修改模板html的标题
|
||||||
data: {
|
data: {
|
||||||
title: VITE_GLOB_APP_TITLE,
|
title: VITE_GLOB_APP_TITLE,
|
||||||
},
|
},
|
||||||
// Embed the generated app.config.js file
|
// 将app.config.js文件注入到模板html中
|
||||||
tags: isBuild
|
tags: isBuild
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// 【图片压缩插件】
|
||||||
// Image resource files used to compress the output of the production environment
|
// Image resource files used to compress the output of the production environment
|
||||||
// https://github.com/anncwb/vite-plugin-imagemin
|
// https://github.com/anncwb/vite-plugin-imagemin
|
||||||
import viteImagemin from 'vite-plugin-imagemin';
|
import viteImagemin from 'vite-plugin-imagemin';
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,26 @@
|
||||||
import { PluginOption } from 'vite';
|
import { PluginOption } from 'vite';
|
||||||
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 legacy from '@vitejs/plugin-legacy';
|
|
||||||
import purgeIcons from 'vite-plugin-purge-icons';
|
import purgeIcons from 'vite-plugin-purge-icons';
|
||||||
import windiCSS from 'vite-plugin-windicss';
|
import UnoCSS from 'unocss/vite';
|
||||||
|
import { presetTypography, presetUno } from 'unocss';
|
||||||
|
|
||||||
|
// 本地调试https配置方法
|
||||||
import VitePluginCertificate from 'vite-plugin-mkcert';
|
import VitePluginCertificate from 'vite-plugin-mkcert';
|
||||||
//update-begin-author:liusq date:2023-06-06 for: [issues/555]开发环境,vscode断点调试,文件或行数对不上
|
//[issues/555]开发环境,vscode断点调试,文件或行数对不上
|
||||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus';
|
import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus';
|
||||||
//update-end-author:liusq date:2023-06-06 for: [issues/555]开发环境,vscode断点调试,文件或行数对不上
|
|
||||||
import { configHtmlPlugin } from './html';
|
import { configHtmlPlugin } from './html';
|
||||||
import { configPwaConfig } from './pwa';
|
|
||||||
import { configMockPlugin } from './mock';
|
import { configMockPlugin } from './mock';
|
||||||
import { configCompressPlugin } from './compress';
|
import { configCompressPlugin } from './compress';
|
||||||
import { configStyleImportPlugin } from './styleImport';
|
|
||||||
import { configVisualizerConfig } from './visualizer';
|
import { configVisualizerConfig } from './visualizer';
|
||||||
import { configThemePlugin } from './theme';
|
import { configThemePlugin } from './theme';
|
||||||
import { configImageminPlugin } from './imagemin';
|
|
||||||
import { configSvgIconsPlugin } from './svgSprite';
|
import { configSvgIconsPlugin } from './svgSprite';
|
||||||
import OptimizationPersist from 'vite-plugin-optimize-persist'
|
// //预编译加载插件(不支持vite3作废)
|
||||||
import PkgConfig from 'vite-plugin-package-config'
|
// import OptimizationPersist from 'vite-plugin-optimize-persist';
|
||||||
|
// import PkgConfig from 'vite-plugin-package-config';
|
||||||
|
|
||||||
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||||
const { VITE_USE_IMAGEMIN, VITE_USE_MOCK, VITE_LEGACY, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv;
|
const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv;
|
||||||
|
|
||||||
const vitePlugins: (PluginOption | PluginOption[])[] = [
|
const vitePlugins: (PluginOption | PluginOption[])[] = [
|
||||||
// have to
|
// have to
|
||||||
|
|
@ -36,11 +35,7 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
// vite-plugin-windicss
|
vitePlugins.push(UnoCSS({ presets: [presetUno(), presetTypography()] }));
|
||||||
vitePlugins.push(windiCSS());
|
|
||||||
|
|
||||||
// @vitejs/plugin-legacy
|
|
||||||
VITE_LEGACY && isBuild && vitePlugins.push(legacy());
|
|
||||||
|
|
||||||
// vite-plugin-html
|
// vite-plugin-html
|
||||||
vitePlugins.push(configHtmlPlugin(viteEnv, isBuild));
|
vitePlugins.push(configHtmlPlugin(viteEnv, isBuild));
|
||||||
|
|
@ -54,9 +49,6 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||||
// vite-plugin-purge-icons
|
// vite-plugin-purge-icons
|
||||||
vitePlugins.push(purgeIcons());
|
vitePlugins.push(purgeIcons());
|
||||||
|
|
||||||
// vite-plugin-style-import
|
|
||||||
vitePlugins.push(configStyleImportPlugin(isBuild));
|
|
||||||
|
|
||||||
// rollup-plugin-visualizer
|
// rollup-plugin-visualizer
|
||||||
vitePlugins.push(configVisualizerConfig());
|
vitePlugins.push(configVisualizerConfig());
|
||||||
|
|
||||||
|
|
@ -65,18 +57,14 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||||
|
|
||||||
// The following plugins only work in the production environment
|
// The following plugins only work in the production environment
|
||||||
if (isBuild) {
|
if (isBuild) {
|
||||||
// vite-plugin-imagemin
|
|
||||||
VITE_USE_IMAGEMIN && vitePlugins.push(configImageminPlugin());
|
|
||||||
|
|
||||||
// rollup-plugin-gzip
|
// rollup-plugin-gzip
|
||||||
vitePlugins.push(configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE));
|
vitePlugins.push(configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE));
|
||||||
|
|
||||||
// vite-plugin-pwa
|
|
||||||
vitePlugins.push(configPwaConfig(viteEnv));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//vite-plugin-theme【解决vite首次打开界面加载慢问题】
|
// //vite-plugin-theme【预编译加载插件,解决vite首次打开界面加载慢问题】
|
||||||
vitePlugins.push(PkgConfig());
|
// vitePlugins.push(PkgConfig());
|
||||||
vitePlugins.push(OptimizationPersist());
|
// vitePlugins.push(OptimizationPersist());
|
||||||
return vitePlugins;
|
return vitePlugins;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
/**
|
|
||||||
* Zero-config PWA for Vite
|
|
||||||
* https://github.com/antfu/vite-plugin-pwa
|
|
||||||
* vite-plugin-pwa是vite的一个官方插件,它的功能就是通过简单的配置将你的vite项目变成pwa应用
|
|
||||||
*/
|
|
||||||
import { VitePWA } from 'vite-plugin-pwa';
|
|
||||||
|
|
||||||
export function configPwaConfig(env: ViteEnv) {
|
|
||||||
const { VITE_USE_PWA, VITE_GLOB_APP_TITLE, VITE_GLOB_APP_SHORT_NAME } = env;
|
|
||||||
|
|
||||||
if (VITE_USE_PWA) {
|
|
||||||
// vite-plugin-pwa
|
|
||||||
const pwaPlugin = VitePWA({
|
|
||||||
manifest: {
|
|
||||||
name: VITE_GLOB_APP_TITLE,
|
|
||||||
short_name: VITE_GLOB_APP_SHORT_NAME,
|
|
||||||
icons: [
|
|
||||||
{
|
|
||||||
src: './resource/img/pwa-192x192.png',
|
|
||||||
sizes: '192x192',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: './resource/img/pwa-512x512.png',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return pwaPlugin;
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/**
|
/**
|
||||||
|
* 【样式按需加载插件 ——主要处理antd的样式】
|
||||||
* Introduces component library styles on demand.
|
* Introduces component library styles on demand.
|
||||||
* https://github.com/anncwb/vite-plugin-style-import
|
* https://github.com/anncwb/vite-plugin-style-import
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ export function configThemePlugin(isBuild: boolean): PluginOption[] {
|
||||||
vite_theme_plugin,
|
vite_theme_plugin,
|
||||||
antdDarkThemePlugin({
|
antdDarkThemePlugin({
|
||||||
preloadFiles: [
|
preloadFiles: [
|
||||||
path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.less'),
|
// path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/reset.css'),
|
||||||
//path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.dark.less'),
|
//path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.dark.less'),
|
||||||
path.resolve(process.cwd(), 'src/design/index.less'),
|
path.resolve(process.cwd(), 'src/design/index.less'),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
11
index.html
|
|
@ -166,5 +166,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
<!-- 百度统计 -->
|
||||||
|
<script>
|
||||||
|
var _hmt = _hmt || [];
|
||||||
|
(function() {
|
||||||
|
var hm = document.createElement("script");
|
||||||
|
hm.src = "https://hm.baidu.com/hm.js?0febd9e3cacb3f627ddac64d52caac39";
|
||||||
|
var s = document.getElementsByTagName("script")[0];
|
||||||
|
s.parentNode.insertBefore(hm, s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,19 @@ const demoList = (keyword, count = 20) => {
|
||||||
list: [] as any[],
|
list: [] as any[],
|
||||||
};
|
};
|
||||||
for (let index = 0; index < count; index++) {
|
for (let index = 0; index < count; index++) {
|
||||||
result.list.push({
|
//根据搜索关键词做一下匹配
|
||||||
name: `${keyword ?? ''}选项${index}`,
|
let name = `选项${index}`;
|
||||||
id: `${index}`,
|
if(keyword && name.indexOf(keyword)!=-1){
|
||||||
});
|
result.list.push({
|
||||||
|
name: `选项${index}`,
|
||||||
|
id: `${index}`,
|
||||||
|
});
|
||||||
|
}else if(!keyword){
|
||||||
|
result.list.push({
|
||||||
|
name: `选项${index}`,
|
||||||
|
id: `${index}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
@ -21,7 +30,7 @@ export default [
|
||||||
method: 'get',
|
method: 'get',
|
||||||
response: ({ query }) => {
|
response: ({ query }) => {
|
||||||
const { keyword,count} = query;
|
const { keyword,count} = query;
|
||||||
console.log(keyword);
|
console.log("查询条件:", keyword);
|
||||||
return resultSuccess(demoList(keyword,count));
|
return resultSuccess(demoList(keyword,count));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ export default [
|
||||||
method: 'get',
|
method: 'get',
|
||||||
response: ({ query }) => {
|
response: ({ query }) => {
|
||||||
const { keyword } = query;
|
const { keyword } = query;
|
||||||
console.log(keyword);
|
console.log("查询条件:", keyword);
|
||||||
return resultSuccess(demoTreeList(keyword));
|
return resultSuccess(demoTreeList(keyword));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
318
package.json
|
|
@ -1,185 +1,159 @@
|
||||||
{
|
{
|
||||||
"name": "jeecgboot-vue3",
|
"name": "jeecgboot-vue3",
|
||||||
"version": "3.5.3",
|
"version": "3.6.3",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "jeecg",
|
"name": "北京国炬信息技术有限公司",
|
||||||
"email": "jeecgos@163.com",
|
"email": "jeecgos@163.com",
|
||||||
"url": "https://github.com/jeecgboot/jeecgboot-vue3"
|
"url": "https://github.com/jeecgboot/jeecgboot-vue3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"bootstrap": "pnpm install",
|
"pinstall": "pnpm install",
|
||||||
"serve": "npm run dev",
|
|
||||||
"dev": "vite",
|
|
||||||
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
|
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
|
||||||
"clean:lib": "rimraf node_modules",
|
"dev": "vite",
|
||||||
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && esno ./build/script/postBuild.ts",
|
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && esno ./build/script/postBuild.ts",
|
||||||
"build:no-cache": "pnpm clean:cache && npm run build",
|
"build:report": "pnpm clean:cache && cross-env REPORT=true npm run build",
|
||||||
"report": "cross-env REPORT=true npm run build",
|
|
||||||
"type:check": "vue-tsc --noEmit --skipLibCheck",
|
|
||||||
"preview": "npm run build && vite preview",
|
"preview": "npm run build && vite preview",
|
||||||
"preview:dist": "vite preview",
|
"reinstall": "rimraf pnpm-lock.yaml && rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run install",
|
||||||
"log": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
"clean:lib": "rimraf node_modules",
|
||||||
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
|
"gen:icon": "esno ./build/generate/icon/index.ts",
|
||||||
"lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
|
"batch:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
|
||||||
"lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
|
"upgrade:log": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
||||||
"lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
|
"husky:install": "husky install"
|
||||||
"lint:pretty": "pretty-quick --staged",
|
|
||||||
"test:unit": "jest",
|
|
||||||
"test:unit-coverage": "jest --coverage",
|
|
||||||
"test:gzip": "http-server dist --cors --gzip -c-1",
|
|
||||||
"test:br": "http-server dist --cors --brotli -c-1",
|
|
||||||
"reinstall": "rimraf pnpm-lock.yaml && yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
|
|
||||||
"prepare": "husky install",
|
|
||||||
"gen:icon": "esno ./build/generate/icon/index.ts"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jeecg/online": "3.5.3-beta3",
|
"@jeecg/online": "3.6.2-beta",
|
||||||
"@qiaoqiaoyun/drag-free": "^1.0.52",
|
"@iconify/iconify": "^3.1.1",
|
||||||
"@iconify/iconify": "^2.2.1",
|
"@ant-design/colors": "^7.0.2",
|
||||||
"@ant-design/colors": "^6.0.0",
|
"@ant-design/icons-vue": "^7.0.1",
|
||||||
"@ant-design/icons-vue": "^6.1.0",
|
"@vue/shared": "^3.3.4",
|
||||||
"@logicflow/core": "^1.1.13",
|
"@vueuse/core": "^10.7.1",
|
||||||
"@logicflow/extension": "^1.1.13",
|
"@zxcvbn-ts/core": "^3.0.4",
|
||||||
"@vue/shared": "^3.2.33",
|
"ant-design-vue": "^4.1.2",
|
||||||
"@vue/runtime-core": "^3.2.33",
|
"axios": "^1.6.4",
|
||||||
"@vueuse/shared": "^8.3.0",
|
|
||||||
"@vueuse/core": "^8.3.0",
|
|
||||||
"@zxcvbn-ts/core": "^2.0.1",
|
|
||||||
"ant-design-vue": "^3.2.20",
|
|
||||||
"axios": "^0.26.1",
|
|
||||||
"china-area-data": "^5.0.1",
|
"china-area-data": "^5.0.1",
|
||||||
"clipboard": "^2.0.8",
|
"clipboard": "^2.0.11",
|
||||||
"codemirror": "^5.65.3",
|
"codemirror": "^5.65.3",
|
||||||
"cron-parser": "^3.5.0",
|
"cron-parser": "^4.9.0",
|
||||||
"cropperjs": "^1.5.12",
|
"cropperjs": "^1.6.1",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.1",
|
"dayjs": "^1.11.10",
|
||||||
"dom-align": "^1.12.2",
|
"dom-align": "^1.12.4",
|
||||||
"echarts": "^5.3.2",
|
"echarts": "^5.4.3",
|
||||||
"emoji-mart-vue-fast": "^11.1.1",
|
"emoji-mart-vue-fast": "^15.0.0",
|
||||||
"enquire.js": "^2.1.6",
|
"enquire.js": "^2.1.6",
|
||||||
"intro.js": "^5.1.0",
|
"intro.js": "^7.2.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"lodash.get": "^4.4.2",
|
"lodash.get": "^4.4.2",
|
||||||
|
"markdown-it": "^14.0.0",
|
||||||
|
"markdown-it-link-attributes": "^4.0.1",
|
||||||
|
"@traptitech/markdown-it-katex": "^3.6.0",
|
||||||
|
"event-source-polyfill": "^1.0.31",
|
||||||
|
"highlight.js": "^11.9.0",
|
||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"path-to-regexp": "^6.2.0",
|
"path-to-regexp": "^6.2.1",
|
||||||
"pinia": "2.0.12",
|
"pinia": "2.1.7",
|
||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"pinyin-pro": "^3.11.0",
|
"qs": "^6.11.2",
|
||||||
"qs": "^6.10.3",
|
"qrcode": "^1.5.3",
|
||||||
"qrcode": "^1.5.0",
|
|
||||||
"qrcodejs2": "0.0.2",
|
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
"showdown": "^2.1.0",
|
"showdown": "^2.1.0",
|
||||||
"sortablejs": "^1.15.0",
|
"sortablejs": "^1.15.1",
|
||||||
"tinymce": "^5.10.3",
|
"tinymce": "^5.10.3",
|
||||||
"vditor": "^3.8.13",
|
"vditor": "^3.9.8",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.4.15",
|
||||||
"vue-cropper": "^0.5.6",
|
"vue-cropper": "^0.6.4",
|
||||||
"vue-cropperjs": "^5.0.0",
|
"vue-cropperjs": "^5.0.0",
|
||||||
"vue-i18n": "^9.1.9",
|
"vue-i18n": "^9.8.0",
|
||||||
"vue-infinite-scroll": "^2.0.2",
|
"vue-infinite-scroll": "^2.0.2",
|
||||||
"vue-print-nb-jeecg": "^1.0.12",
|
"vue-print-nb-jeecg": "^1.0.12",
|
||||||
"vue-router": "^4.0.14",
|
"vue-router": "^4.2.5",
|
||||||
"vue-types": "^4.1.1",
|
"vue-types": "^5.1.1",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0",
|
||||||
"vxe-table": "4.1.0",
|
"vxe-table": "4.5.17",
|
||||||
"vxe-table-plugin-antd": "3.0.5",
|
"vxe-table-plugin-antd": "3.1.0",
|
||||||
"xe-utils": "^3.3.1",
|
"xe-utils": "3.5.14",
|
||||||
"vue-json-pretty": "^2.0.6",
|
"xss": "^1.0.14"
|
||||||
"xss": "^1.0.13"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^16.2.3",
|
"@commitlint/cli": "^18.4.3",
|
||||||
"@commitlint/config-conventional": "^16.2.1",
|
"@commitlint/config-conventional": "^18.4.3",
|
||||||
"@iconify/json": "^2.1.30",
|
"@iconify/json": "^2.2.164",
|
||||||
"@purge-icons/generated": "^0.8.1",
|
"@purge-icons/generated": "^0.10.0",
|
||||||
"@types/codemirror": "^5.60.5",
|
"@types/codemirror": "^5.60.15",
|
||||||
"@types/crypto-js": "^4.1.1",
|
"@types/crypto-js": "^4.2.1",
|
||||||
"@types/fs-extra": "^9.0.13",
|
"@types/fs-extra": "^11.0.4",
|
||||||
"@types/inquirer": "^8.2.1",
|
"@types/inquirer": "^9.0.7",
|
||||||
"@types/intro.js": "^3.0.2",
|
"@types/intro.js": "^5.1.5",
|
||||||
"@types/jest": "^27.0.2",
|
"@types/jest": "^29.5.11",
|
||||||
"@types/lodash-es": "^4.17.6",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/mockjs": "^1.0.6",
|
"@types/mockjs": "^1.0.10",
|
||||||
"@types/node": "^17.0.25",
|
"@types/node": "^20.10.6",
|
||||||
"@types/nprogress": "^0.2.0",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/qrcode": "^1.4.2",
|
"@types/qrcode": "^1.5.5",
|
||||||
"@types/qs": "^6.9.7",
|
"@types/qs": "^6.9.11",
|
||||||
"@types/pinyin": "^2.10.0",
|
"@types/showdown": "^2.0.6",
|
||||||
"@types/showdown": "^1.9.4",
|
"@types/sortablejs": "^1.15.7",
|
||||||
"@types/sortablejs": "^1.10.7",
|
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.20.0",
|
"@typescript-eslint/parser": "^6.17.0",
|
||||||
"@typescript-eslint/parser": "^5.20.0",
|
"@vitejs/plugin-vue": "^4.3.3",
|
||||||
"@vitejs/plugin-legacy": "^2.0.0",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"@vitejs/plugin-vue": "^3.0.1",
|
"@vue/compiler-sfc": "^3.4.4",
|
||||||
"@vitejs/plugin-vue-jsx": "^1.3.10",
|
"@vue/test-utils": "^2.4.3",
|
||||||
"@vue/compiler-sfc": "^3.2.33",
|
"autoprefixer": "^10.4.16",
|
||||||
"@vue/test-utils": "^2.0.0-rc.21",
|
"commitizen": "^4.3.0",
|
||||||
"autoprefixer": "^10.4.4",
|
"conventional-changelog-cli": "^4.1.0",
|
||||||
"commitizen": "^4.2.4",
|
|
||||||
"conventional-changelog-cli": "^2.2.2",
|
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"cz-git": "^1.3.9",
|
"cz-git": "^1.8.0",
|
||||||
"czg": "^1.3.9",
|
"czg": "^1.8.0",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.3.1",
|
||||||
"eslint": "^8.22.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-config-prettier": "^8.6.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-define-config": "^1.14.0",
|
"eslint-define-config": "^2.1.0",
|
||||||
"eslint-plugin-jest": "^27.2.1",
|
"eslint-plugin-jest": "^27.6.1",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^5.1.2",
|
||||||
"eslint-plugin-vue": "^9.9.0",
|
"eslint-plugin-vue": "^9.19.2",
|
||||||
"esno": "^0.14.1",
|
"esno": "^4.0.0",
|
||||||
"fs-extra": "^10.1.0",
|
"fs-extra": "^11.2.0",
|
||||||
"http-server": "^14.0.0",
|
"http-server": "^14.1.1",
|
||||||
"husky": "^7.0.4",
|
"husky": "^8.0.3",
|
||||||
"inquirer": "^8.2.2",
|
"inquirer": "^9.2.12",
|
||||||
"is-ci": "^3.0.0",
|
"is-ci": "^3.0.1",
|
||||||
"jest": "^27.3.1",
|
"jest": "^29.7.0",
|
||||||
"less": "^4.1.2",
|
"less": "^4.2.0",
|
||||||
"lint-staged": "12.3.7",
|
"lint-staged": "15.2.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.0.0",
|
||||||
"postcss": "^8.4.12",
|
"postcss": "^8.4.32",
|
||||||
"postcss-html": "^1.4.1",
|
"postcss-html": "^1.5.0",
|
||||||
"postcss-less": "^6.0.0",
|
"postcss-less": "^6.0.0",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^3.1.1",
|
||||||
"pretty-quick": "^3.1.1",
|
"pretty-quick": "^3.1.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^5.0.5",
|
||||||
"rollup": "^2.70.2",
|
"rollup": "^4.9.2",
|
||||||
"rollup-plugin-visualizer": "^5.6.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"stylelint": "^14.7.1",
|
"stylelint": "^16.1.0",
|
||||||
"stylelint-config-prettier": "^9.0.3",
|
"stylelint-config-prettier": "^9.0.5",
|
||||||
"stylelint-config-recommended": "^7.0.0",
|
"stylelint-config-recommended": "^14.0.0",
|
||||||
"stylelint-config-recommended-vue": "^1.4.0",
|
"stylelint-config-recommended-vue": "^1.5.0",
|
||||||
"stylelint-config-standard": "^25.0.0",
|
"stylelint-config-standard": "^36.0.0",
|
||||||
"stylelint-order": "^5.0.0",
|
"stylelint-order": "^6.0.4",
|
||||||
"ts-jest": "^27.0.7",
|
"ts-jest": "^29.1.1",
|
||||||
"ts-node": "^10.7.0",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^4.6.3",
|
"typescript": "^4.9.5",
|
||||||
"vite": "^3.2.3",
|
"vite": "^4.4.9",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-html": "^3.2.0",
|
"vite-plugin-html": "^3.2.1",
|
||||||
"vite-plugin-imagemin": "^0.6.1",
|
"vite-plugin-mkcert": "^1.17.1",
|
||||||
"vite-plugin-mkcert": "^1.10.1",
|
|
||||||
"vite-plugin-mock": "^2.9.6",
|
"vite-plugin-mock": "^2.9.6",
|
||||||
"vite-plugin-optimize-persist": "^0.1.2",
|
"vite-plugin-purge-icons": "^0.10.0",
|
||||||
"vite-plugin-package-config": "^0.1.1",
|
|
||||||
"vite-plugin-purge-icons": "^0.8.2",
|
|
||||||
"vite-plugin-pwa": "^0.12.3",
|
|
||||||
"vite-plugin-style-import": "^2.0.0",
|
|
||||||
"vite-plugin-svg-icons": "^2.0.1",
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
"@rys-fe/vite-plugin-theme": "^0.8.6",
|
"@rys-fe/vite-plugin-theme": "^0.8.6",
|
||||||
"vite-plugin-vue-setup-extend-plus": "^0.1.0",
|
"vite-plugin-vue-setup-extend-plus": "^0.1.0",
|
||||||
"vite-plugin-windicss": "^1.8.7",
|
"unocss": "^0.58.3",
|
||||||
"vue-eslint-parser": "^8.3.0",
|
"vue-eslint-parser": "^9.3.2",
|
||||||
"vue-tsc": "^0.33.9"
|
"vue-tsc": "^1.8.27"
|
||||||
},
|
|
||||||
"resolutions": {
|
|
||||||
"bin-wrapper": "npm:bin-wrapper-china",
|
|
||||||
"rollup": "^2.72.0"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
@ -189,69 +163,13 @@
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/jeecgboot/jeecgboot-vue3/issues"
|
"url": "https://github.com/jeecgboot/jeecgboot-vue3/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/jeecgboot/jeecgboot-vue3",
|
"homepage": "https://www.jeecg.com",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12 || >=14"
|
"node": "^12 || >=14"
|
||||||
},
|
},
|
||||||
"vite": {
|
"vite": {
|
||||||
"optimizeDeps": {
|
"optimizeDeps": {
|
||||||
"include": [
|
"include": [
|
||||||
"@ant-design/colors",
|
|
||||||
"@ant-design/icons-vue",
|
|
||||||
"@vueuse/core",
|
|
||||||
"@vueuse/shared",
|
|
||||||
"@zxcvbn-ts/core",
|
|
||||||
"ant-design-vue",
|
|
||||||
"axios",
|
|
||||||
"china-area-data",
|
|
||||||
"clipboard",
|
|
||||||
"codemirror",
|
|
||||||
"codemirror/addon/fold/brace-fold.js",
|
|
||||||
"codemirror/addon/fold/comment-fold.js",
|
|
||||||
"codemirror/addon/fold/foldcode.js",
|
|
||||||
"codemirror/addon/fold/foldgutter.js",
|
|
||||||
"codemirror/addon/fold/indent-fold.js",
|
|
||||||
"codemirror/addon/hint/anyword-hint.js",
|
|
||||||
"codemirror/addon/hint/show-hint.js",
|
|
||||||
"codemirror/addon/selection/active-line.js",
|
|
||||||
"codemirror/mode/clike/clike.js",
|
|
||||||
"codemirror/mode/css/css.js",
|
|
||||||
"codemirror/mode/javascript/javascript.js",
|
|
||||||
"codemirror/mode/markdown/markdown.js",
|
|
||||||
"codemirror/mode/python/python.js",
|
|
||||||
"codemirror/mode/r/r.js",
|
|
||||||
"codemirror/mode/shell/shell.js",
|
|
||||||
"codemirror/mode/sql/sql.js",
|
|
||||||
"codemirror/mode/swift/swift.js",
|
|
||||||
"codemirror/mode/vue/vue.js",
|
|
||||||
"codemirror/mode/xml/xml.js",
|
|
||||||
"cron-parser",
|
|
||||||
"cropperjs",
|
|
||||||
"crypto-js/aes",
|
|
||||||
"crypto-js/enc-base64",
|
|
||||||
"crypto-js/enc-utf8",
|
|
||||||
"crypto-js/md5",
|
|
||||||
"crypto-js/mode-ecb",
|
|
||||||
"crypto-js/pad-pkcs7",
|
|
||||||
"dom-align",
|
|
||||||
"echarts",
|
|
||||||
"echarts/charts",
|
|
||||||
"echarts/components",
|
|
||||||
"echarts/core",
|
|
||||||
"echarts/renderers",
|
|
||||||
"emoji-mart-vue-fast/src",
|
|
||||||
"intro.js",
|
|
||||||
"lodash-es",
|
|
||||||
"md5",
|
|
||||||
"nprogress",
|
|
||||||
"path-to-regexp",
|
|
||||||
"pinia",
|
|
||||||
"print-js",
|
|
||||||
"qrcode",
|
|
||||||
"qs",
|
|
||||||
"resize-observer-polyfill",
|
|
||||||
"showdown",
|
|
||||||
"sortablejs",
|
|
||||||
"tinymce/icons/default/icons",
|
"tinymce/icons/default/icons",
|
||||||
"tinymce/plugins/advlist",
|
"tinymce/plugins/advlist",
|
||||||
"tinymce/plugins/anchor",
|
"tinymce/plugins/anchor",
|
||||||
|
|
|
||||||
10778
pnpm-lock.yaml
BIN
public/logo.png
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 51 KiB |
60
src/App.vue
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<ConfigProvider :locale="getAntdLocale">
|
<ConfigProvider :theme="appTheme" :locale="getAntdLocale">
|
||||||
<AppProvider>
|
<AppProvider>
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</AppProvider>
|
</AppProvider>
|
||||||
|
|
@ -7,15 +7,73 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { watch, ref } from 'vue';
|
||||||
|
import { theme } from 'ant-design-vue';
|
||||||
import { ConfigProvider } from 'ant-design-vue';
|
import { ConfigProvider } from 'ant-design-vue';
|
||||||
import { AppProvider } from '/@/components/Application';
|
import { AppProvider } from '/@/components/Application';
|
||||||
import { useTitle } from '/@/hooks/web/useTitle';
|
import { useTitle } from '/@/hooks/web/useTitle';
|
||||||
import { useLocale } from '/@/locales/useLocale';
|
import { useLocale } from '/@/locales/useLocale';
|
||||||
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||||
|
import { ThemeEnum } from '/@/enums/appEnum';
|
||||||
|
import { changeTheme } from '/@/logics/theme/index';
|
||||||
|
|
||||||
|
const appStore = useAppStore();
|
||||||
// 解决日期时间国际化问题
|
// 解决日期时间国际化问题
|
||||||
import 'dayjs/locale/zh-cn';
|
import 'dayjs/locale/zh-cn';
|
||||||
// support Multi-language
|
// support Multi-language
|
||||||
const { getAntdLocale } = useLocale();
|
const { getAntdLocale } = useLocale();
|
||||||
|
|
||||||
useTitle();
|
useTitle();
|
||||||
|
// update-begin--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||||
|
const appTheme: any = ref({});
|
||||||
|
const { getDarkMode } = useRootSetting();
|
||||||
|
watch(
|
||||||
|
() => getDarkMode.value,
|
||||||
|
(newValue) => {
|
||||||
|
delete appTheme.value.algorithm;
|
||||||
|
if (newValue === ThemeEnum.DARK) {
|
||||||
|
appTheme.value.algorithm = theme.darkAlgorithm;
|
||||||
|
}
|
||||||
|
appTheme.value = {
|
||||||
|
...appTheme.value,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
appStore.getProjectConfig,
|
||||||
|
(newValue) => {
|
||||||
|
const primary = newValue.themeColor;
|
||||||
|
appTheme.value = {
|
||||||
|
...appTheme.value,
|
||||||
|
...{
|
||||||
|
token: {
|
||||||
|
colorPrimary: primary,
|
||||||
|
wireframe: true,
|
||||||
|
fontSize: 14,
|
||||||
|
colorSuccess: '#55D187',
|
||||||
|
colorInfo: primary,
|
||||||
|
borderRadius: 2,
|
||||||
|
sizeStep: 4,
|
||||||
|
sizeUnit: 4,
|
||||||
|
colorWarning: '#EFBD47',
|
||||||
|
colorError: '#ED6F6F',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
setTimeout(() => {
|
||||||
|
appStore.getProjectConfig?.themeColor && changeTheme(appStore.getProjectConfig.themeColor);
|
||||||
|
}, 300);
|
||||||
|
// update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="less">
|
||||||
|
// update-begin--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
|
||||||
|
img {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,13 @@ export const getMenuList = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 获取后台菜单权限和按钮权限
|
||||||
|
*/
|
||||||
|
export function getBackMenuAndPerms() {
|
||||||
|
return defHttp.get({ url: Api.GetMenuList });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换成vue3菜单
|
* 切换成vue3菜单
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,17 @@ export function getUserInfo() {
|
||||||
const userStore = useUserStoreWithOut();
|
const userStore = useUserStoreWithOut();
|
||||||
userStore.setToken('');
|
userStore.setToken('');
|
||||||
setAuthCache(TOKEN_KEY, null);
|
setAuthCache(TOKEN_KEY, null);
|
||||||
router.push(PageEnum.BASE_LOGIN);
|
|
||||||
|
// update-begin-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
|
||||||
|
router.push({
|
||||||
|
path: PageEnum.BASE_LOGIN,
|
||||||
|
query: {
|
||||||
|
// 传入当前的路由,登录成功后跳转到当前路由
|
||||||
|
redirect: router.currentRoute.value.fullPath,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// update-end-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
|
||||||
|
|
||||||
}
|
}
|
||||||
// update-end--author:zyf---date:20220425---for:【VUEN-76】捕获接口超时异常,跳转到登录界面
|
// update-end--author:zyf---date:20220425---for:【VUEN-76】捕获接口超时异常,跳转到登录界面
|
||||||
});
|
});
|
||||||
|
|
@ -116,6 +126,9 @@ export function getCaptcha(params) {
|
||||||
createErrorModal({ title: '错误提示', content: res.message || '未知问题' });
|
createErrorModal({ title: '错误提示', content: res.message || '未知问题' });
|
||||||
reject();
|
reject();
|
||||||
}
|
}
|
||||||
|
}).catch((res)=>{
|
||||||
|
createErrorModal({ title: '错误提示', content: res.message || '未知问题' });
|
||||||
|
reject();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -146,9 +159,15 @@ export const passwordChange = (params) => defHttp.get({ url: Api.passwordChange,
|
||||||
* @description: 第三方登录
|
* @description: 第三方登录
|
||||||
*/
|
*/
|
||||||
export function thirdLogin(params, mode: ErrorMessageMode = 'modal') {
|
export function thirdLogin(params, mode: ErrorMessageMode = 'modal') {
|
||||||
|
//==========begin 第三方登录/auth2登录需要传递租户id===========
|
||||||
|
let tenantId = "0";
|
||||||
|
if(!params.tenantId){
|
||||||
|
tenantId = params.tenantId;
|
||||||
|
}
|
||||||
|
//==========end 第三方登录/auth2登录需要传递租户id===========
|
||||||
return defHttp.get<LoginResultModel>(
|
return defHttp.get<LoginResultModel>(
|
||||||
{
|
{
|
||||||
url: `${Api.thirdLogin}/${params.token}/${params.thirdType}`,
|
url: `${Api.thirdLogin}/${params.token}/${params.thirdType}/${tenantId}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorMessageMode: mode,
|
errorMessageMode: mode,
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 398 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
|
@ -62,10 +62,13 @@
|
||||||
padding-left: 7px;
|
padding-left: 7px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
//左侧菜单模式和左侧菜单混合模式加渐变背景色
|
||||||
&.light {
|
&.jeecg-layout-mix-sider-logo,&.jeecg-layout-menu-logo{
|
||||||
border-bottom: 1px solid @border-color-base;
|
background:@sider-logo-bg-color;
|
||||||
}
|
}
|
||||||
|
// &.light {
|
||||||
|
// border-bottom: 1px solid @border-color-base;
|
||||||
|
// }
|
||||||
|
|
||||||
&.collapsed-show-title {
|
&.collapsed-show-title {
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@
|
||||||
&-input {
|
&-input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
font-size: 1.5em;
|
font-size: 1.3em;
|
||||||
color: #1c1e21;
|
color: #1c1e21;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
|
||||||
|
|
@ -222,7 +222,7 @@
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: @text-color-base;
|
color: @text-color-base;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: @component-background;
|
// background-color: @component-background;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 1px 3px 0 #d4d9e1;
|
box-shadow: 0 1px 3px 0 #d4d9e1;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,10 @@
|
||||||
cursor: move;
|
cursor: move;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
&.is-drawer {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
&-normal {
|
&-normal {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
import { withInstall } from '/@/utils';
|
import { withInstall } from '/@/utils';
|
||||||
import codeEditor from './src/CodeEditor.vue';
|
import codeEditor from './src/CodeEditor.vue';
|
||||||
import jsonPreview from './src/json-preview/JsonPreview.vue';
|
|
||||||
|
|
||||||
export const CodeEditor = withInstall(codeEditor);
|
export const CodeEditor = withInstall(codeEditor);
|
||||||
export const JsonPreview = withInstall(jsonPreview);
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import CodeMirrorEditor from './codemirror/CodeMirror.vue';
|
import CodeMirrorEditor from './codemirror/CodeMirror.vue';
|
||||||
import { isString } from '/@/utils/is';
|
import { isString } from '/@/utils/is';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
value: { type: [Object, String] as PropType<Record<string, any> | string> },
|
value: { type: [Object, String] as PropType<Record<string, any> | string> },
|
||||||
mode: { type: String, default: MODE.JSON },
|
mode: { type: String, default: MODE.JSON },
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
<template>
|
|
||||||
<vue-json-pretty :path="'res'" :deep="3" :showLength="true" :data="data" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import VueJsonPretty from 'vue-json-pretty';
|
|
||||||
import 'vue-json-pretty/lib/styles.css';
|
|
||||||
|
|
||||||
defineProps({
|
|
||||||
data: Object,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import CountButton from './CountButton.vue';
|
import CountButton from './CountButton.vue';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
import { useRuleFormItem } from '/@/hooks/component/useFormItemSingle';
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
value: { type: String },
|
value: { type: String },
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
import Cropper from 'cropperjs';
|
import Cropper from 'cropperjs';
|
||||||
import 'cropperjs/dist/cropper.css';
|
import 'cropperjs/dist/cropper.css';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useDebounceFn } from '@vueuse/shared';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
|
|
||||||
type Options = Cropper.Options;
|
type Options = Cropper.Options;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
components: { Drawer, ScrollContainer, DrawerFooter, DrawerHeader },
|
components: { Drawer, ScrollContainer, DrawerFooter, DrawerHeader },
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: basicProps,
|
props: basicProps,
|
||||||
emits: ['visible-change', 'ok', 'close', 'register'],
|
emits: ['visible-change', 'open-change', 'ok', 'close', 'register'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const visibleRef = ref(false);
|
const visibleRef = ref(false);
|
||||||
const attrs = useAttrs();
|
const attrs = useAttrs();
|
||||||
|
|
@ -63,12 +63,14 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
const getProps = computed((): DrawerProps => {
|
const getProps = computed((): DrawerProps => {
|
||||||
|
// update-begin--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||||
const opt = {
|
const opt = {
|
||||||
placement: 'right',
|
placement: 'right',
|
||||||
...unref(attrs),
|
...unref(attrs),
|
||||||
...unref(getMergeProps),
|
...unref(getMergeProps),
|
||||||
visible: unref(visibleRef),
|
open: unref(visibleRef),
|
||||||
};
|
};
|
||||||
|
// update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||||
opt.title = undefined;
|
opt.title = undefined;
|
||||||
let { isDetail, width, wrapClassName, getContainer } = opt;
|
let { isDetail, width, wrapClassName, getContainer } = opt;
|
||||||
if (isDetail) {
|
if (isDetail) {
|
||||||
|
|
@ -123,11 +125,20 @@
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.open,
|
||||||
|
(newVal, oldVal) => {
|
||||||
|
if (newVal !== oldVal) visibleRef.value = newVal;
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => visibleRef.value,
|
() => visibleRef.value,
|
||||||
(visible) => {
|
(visible) => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
emit('visible-change', visible);
|
emit('visible-change', visible);
|
||||||
|
emit('open-change', visible);
|
||||||
instance && drawerInstance.emitVisible?.(visible, instance.uid);
|
instance && drawerInstance.emitVisible?.(visible, instance.uid);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -152,6 +163,9 @@
|
||||||
if (Reflect.has(props, 'visible')) {
|
if (Reflect.has(props, 'visible')) {
|
||||||
visibleRef.value = !!props.visible;
|
visibleRef.value = !!props.visible;
|
||||||
}
|
}
|
||||||
|
if (Reflect.has(props, 'open')) {
|
||||||
|
visibleRef.value = !!props.open;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOk() {
|
function handleOk() {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<BasicTitle v-if="!isDetail" :class="prefixCls">
|
<BasicTitle v-if="!isDetail" :class="[prefixCls, 'is-drawer']">
|
||||||
<slot name="title"></slot>
|
<slot name="title"></slot>
|
||||||
{{ !$slots.title ? title : '' }}
|
{{ !$slots.title ? title : '' }}
|
||||||
</BasicTitle>
|
</BasicTitle>
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ export const basicProps = {
|
||||||
loadingText: { type: String },
|
loadingText: { type: String },
|
||||||
showDetailBack: { type: Boolean, default: true },
|
showDetailBack: { type: Boolean, default: true },
|
||||||
visible: { type: Boolean },
|
visible: { type: Boolean },
|
||||||
|
open: { type: Boolean },
|
||||||
loading: { type: Boolean },
|
loading: { type: Boolean },
|
||||||
maskClosable: { type: Boolean, default: true },
|
maskClosable: { type: Boolean, default: true },
|
||||||
getContainer: {
|
getContainer: {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ export interface ReturnMethods extends DrawerInstance {
|
||||||
openDrawer: <T = any>(visible?: boolean, data?: T, openOnSet?: boolean) => void;
|
openDrawer: <T = any>(visible?: boolean, data?: T, openOnSet?: boolean) => void;
|
||||||
closeDrawer: () => void;
|
closeDrawer: () => void;
|
||||||
getVisible?: ComputedRef<boolean>;
|
getVisible?: ComputedRef<boolean>;
|
||||||
|
getOpen?: ComputedRef<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void;
|
export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void;
|
||||||
|
|
@ -20,6 +21,7 @@ export interface ReturnInnerMethods extends DrawerInstance {
|
||||||
changeLoading: (loading: boolean) => void;
|
changeLoading: (loading: boolean) => void;
|
||||||
changeOkLoading: (loading: boolean) => void;
|
changeOkLoading: (loading: boolean) => void;
|
||||||
getVisible?: ComputedRef<boolean>;
|
getVisible?: ComputedRef<boolean>;
|
||||||
|
getOpen?: ComputedRef<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UseDrawerReturnType = [RegisterFn, ReturnMethods];
|
export type UseDrawerReturnType = [RegisterFn, ReturnMethods];
|
||||||
|
|
@ -74,6 +76,7 @@ export interface DrawerProps extends DrawerFooterProps {
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
showDetailBack?: boolean;
|
showDetailBack?: boolean;
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
|
open?: boolean;
|
||||||
/**
|
/**
|
||||||
* Built-in ScrollContainer component configuration
|
* Built-in ScrollContainer component configuration
|
||||||
* @type ScrollContainerOptions
|
* @type ScrollContainerOptions
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,16 @@ export function useDrawer(): UseDrawerReturnType {
|
||||||
return visibleData[~~unref(uid)];
|
return visibleData[~~unref(uid)];
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
getOpen: computed((): boolean => {
|
||||||
|
return visibleData[~~unref(uid)];
|
||||||
|
}),
|
||||||
|
|
||||||
openDrawer: <T = any>(visible = true, data?: T, openOnSet = true): void => {
|
openDrawer: <T = any>(visible = true, data?: T, openOnSet = true): void => {
|
||||||
|
// update-begin--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||||
getInstance()?.setDrawerProps({
|
getInstance()?.setDrawerProps({
|
||||||
visible: visible,
|
open: visible,
|
||||||
});
|
});
|
||||||
|
// update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
if (openOnSet) {
|
if (openOnSet) {
|
||||||
|
|
@ -75,7 +81,9 @@ export function useDrawer(): UseDrawerReturnType {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
closeDrawer: () => {
|
closeDrawer: () => {
|
||||||
getInstance()?.setDrawerProps({ visible: false });
|
// update-begin--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||||
|
getInstance()?.setDrawerProps({ open: false });
|
||||||
|
// update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -133,9 +141,11 @@ export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => {
|
||||||
getVisible: computed((): boolean => {
|
getVisible: computed((): boolean => {
|
||||||
return visibleData[~~unref(uidRef)];
|
return visibleData[~~unref(uidRef)];
|
||||||
}),
|
}),
|
||||||
|
getOpen: computed((): boolean => {
|
||||||
|
return visibleData[~~unref(uidRef)];
|
||||||
|
}),
|
||||||
closeDrawer: () => {
|
closeDrawer: () => {
|
||||||
getInstance()?.setDrawerProps({ visible: false });
|
getInstance()?.setDrawerProps({ open: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
setDrawerProps: (props: Partial<DrawerProps>) => {
|
setDrawerProps: (props: Partial<DrawerProps>) => {
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,28 @@
|
||||||
v-bind="getAttr(item.event)"
|
v-bind="getAttr(item.event)"
|
||||||
@click="handleClickMenu(item)"
|
@click="handleClickMenu(item)"
|
||||||
:disabled="item.disabled"
|
:disabled="item.disabled"
|
||||||
:class="[{ 'is-pop-confirm': item.popConfirm }, (item.class ?? [])]"
|
:class="[{ 'is-pop-confirm': item.popConfirm }, item.class ?? []]"
|
||||||
>
|
>
|
||||||
<a-popconfirm v-if="popconfirm && item.popConfirm" v-bind="getPopConfirmAttrs(item.popConfirm)">
|
<!-- update-begin--author:liaozhiyang---date:20231110---for:【issues/839】BasicTable表格的更多操作按钮禁用还能点击弹出气泡框 -->
|
||||||
|
<a-popconfirm :disabled="item.disabled" v-if="popconfirm && item.popConfirm" v-bind="getPopConfirmAttrs(item.popConfirm)">
|
||||||
|
<!-- update-end--author:liaozhiyang---date:20231110---for:【issues/839】BasicTable表格的更多操作按钮禁用还能点击弹出气泡框 -->
|
||||||
<template #icon v-if="item.popConfirm.icon">
|
<template #icon v-if="item.popConfirm.icon">
|
||||||
<Icon v-if="item.iconColor" :icon="item.popConfirm.icon" :color="item.iconColor"/>
|
<Icon v-if="item.iconColor" :icon="item.popConfirm.icon" :color="item.iconColor" />
|
||||||
<Icon v-else :icon="item.popConfirm.icon"/>
|
<Icon v-else :icon="item.popConfirm.icon" />
|
||||||
</template>
|
</template>
|
||||||
<div class="dropdown-event-area">
|
<div class="dropdown-event-area">
|
||||||
<Icon :icon="item.icon" v-if="item.icon && item.iconColor" :color="item.iconColor"/>
|
<Icon :icon="item.icon" v-if="item.icon && item.iconColor" :color="item.iconColor" />
|
||||||
<Icon :icon="item.icon" v-else-if="item.icon"/>
|
<Icon :icon="item.icon" v-else-if="item.icon" />
|
||||||
<span class="ml-1">{{ item.text }}</span>
|
<span class="ml-1">{{ item.text }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
|
<!-- 设置动态插槽 -->
|
||||||
|
<template v-else-if="item.slot">
|
||||||
|
<slot :name="item.slot" :label="item.text"></slot>
|
||||||
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<Icon :icon="item.icon" v-if="item.icon && item.iconColor" :color="item.iconColor"/>
|
<Icon :icon="item.icon" v-if="item.icon && item.iconColor" :color="item.iconColor" />
|
||||||
<Icon :icon="item.icon" v-else-if="item.icon"/>
|
<Icon :icon="item.icon" v-else-if="item.icon" />
|
||||||
<span class="ml-1">{{ item.text }}</span>
|
<span class="ml-1">{{ item.text }}</span>
|
||||||
</template>
|
</template>
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
|
|
@ -37,7 +43,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, PropType } from 'vue';
|
import { computed, PropType, ref } from 'vue';
|
||||||
import type { DropMenu } from './typing';
|
import type { DropMenu } from './typing';
|
||||||
import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';
|
import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';
|
||||||
import { Icon } from '/@/components/Icon';
|
import { Icon } from '/@/components/Icon';
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
:allDefaultValues="defaultValueRef"
|
:allDefaultValues="defaultValueRef"
|
||||||
:formModel="formModel"
|
:formModel="formModel"
|
||||||
:setFormModel="setFormModel"
|
:setFormModel="setFormModel"
|
||||||
|
:validateFields="validateFields"
|
||||||
>
|
>
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||||
<slot :name="item" v-bind="data || {}"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
|
|
@ -51,6 +52,8 @@
|
||||||
import { useModalContext } from '/@/components/Modal';
|
import { useModalContext } from '/@/components/Modal';
|
||||||
|
|
||||||
import { basicProps } from './props';
|
import { basicProps } from './props';
|
||||||
|
import componentSetting from '/@/settings/componentSetting';
|
||||||
|
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useDebounceFn } from '@vueuse/core';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
|
|
@ -88,6 +91,16 @@
|
||||||
mergeProps.labelCol = undefined;
|
mergeProps.labelCol = undefined;
|
||||||
}
|
}
|
||||||
//update-end-author:sunjianlei date:20220923 for: 如果用户设置了labelWidth,则使labelCol失效,解决labelWidth设置无效的问题
|
//update-end-author:sunjianlei date:20220923 for: 如果用户设置了labelWidth,则使labelCol失效,解决labelWidth设置无效的问题
|
||||||
|
// update-begin--author:liaozhiyang---date:20231017---for:【QQYUN-6566】BasicForm支持一行显示(inline)
|
||||||
|
if (mergeProps.layout === 'inline') {
|
||||||
|
if (mergeProps.labelCol === componentSetting.form.labelCol) {
|
||||||
|
mergeProps.labelCol = undefined;
|
||||||
|
}
|
||||||
|
if (mergeProps.wrapperCol === componentSetting.form.wrapperCol) {
|
||||||
|
mergeProps.wrapperCol = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231017---for:【QQYUN-6566】BasicForm支持一行显示(inline)
|
||||||
return mergeProps;
|
return mergeProps;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -252,10 +265,12 @@
|
||||||
const onFormSubmitWhenChange = useDebounceFn(handleSubmit, 300);
|
const onFormSubmitWhenChange = useDebounceFn(handleSubmit, 300);
|
||||||
function setFormModel(key: string, value: any) {
|
function setFormModel(key: string, value: any) {
|
||||||
formModel[key] = value;
|
formModel[key] = value;
|
||||||
const { validateTrigger } = unref(getBindValue);
|
// update-begin--author:liaozhiyang---date:20230922---for:【issues/752】表单校验dynamicRules 无法 使用失去焦点后校验 trigger: 'blur'
|
||||||
if (!validateTrigger || validateTrigger === 'change') {
|
// const { validateTrigger } = unref(getBindValue);
|
||||||
validateFields([key]).catch((_) => {});
|
// if (!validateTrigger || validateTrigger === 'change') {
|
||||||
}
|
// validateFields([key]).catch((_) => {});
|
||||||
|
// }
|
||||||
|
// update-end--author:liaozhiyang---date:20230922---for:【issues/752】表单校验dynamicRules 无法 使用失去焦点后校验 trigger: 'blur'
|
||||||
if(props.autoSearch === true){
|
if(props.autoSearch === true){
|
||||||
onFormSubmitWhenChange();
|
onFormSubmitWhenChange();
|
||||||
}
|
}
|
||||||
|
|
@ -377,5 +392,12 @@
|
||||||
margin-bottom: 8px !important;
|
margin-bottom: 8px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// update-begin--author:liaozhiyang---date:20231017---for:【QQYUN-6566】BasicForm支持一行显示(inline)
|
||||||
|
&.ant-form-inline {
|
||||||
|
& > .ant-row {
|
||||||
|
.ant-col { width:auto !important; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231017---for:【QQYUN-6566】BasicForm支持一行显示(inline)
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,9 @@ import JCodeEditor from './jeecg/components/JCodeEditor.vue';
|
||||||
import JCategorySelect from './jeecg/components/JCategorySelect.vue';
|
import JCategorySelect from './jeecg/components/JCategorySelect.vue';
|
||||||
import JSelectMultiple from './jeecg/components/JSelectMultiple.vue';
|
import JSelectMultiple from './jeecg/components/JSelectMultiple.vue';
|
||||||
import JPopup from './jeecg/components/JPopup.vue';
|
import JPopup from './jeecg/components/JPopup.vue';
|
||||||
|
// update-begin--author:liaozhiyang---date:20240130---for:【QQYUN-7961】popupDict字典
|
||||||
|
import JPopupDict from './jeecg/components/JPopupDict.vue';
|
||||||
|
// update-end--author:liaozhiyang---date:20240130---for:【QQYUN-7961】popupDict字典
|
||||||
import JSwitch from './jeecg/components/JSwitch.vue';
|
import JSwitch from './jeecg/components/JSwitch.vue';
|
||||||
import JTreeDict from './jeecg/components/JTreeDict.vue';
|
import JTreeDict from './jeecg/components/JTreeDict.vue';
|
||||||
import JInputPop from './jeecg/components/JInputPop.vue';
|
import JInputPop from './jeecg/components/JInputPop.vue';
|
||||||
|
|
@ -61,6 +64,7 @@ import JRangeNumber from './jeecg/components/JRangeNumber.vue';
|
||||||
import UserSelect from './jeecg/components/userSelect/index.vue';
|
import UserSelect from './jeecg/components/userSelect/index.vue';
|
||||||
import JRangeDate from './jeecg/components/JRangeDate.vue'
|
import JRangeDate from './jeecg/components/JRangeDate.vue'
|
||||||
import JRangeTime from './jeecg/components/JRangeTime.vue'
|
import JRangeTime from './jeecg/components/JRangeTime.vue'
|
||||||
|
import RoleSelectInput from './jeecg/components/roleSelect/RoleSelectInput.vue';
|
||||||
|
|
||||||
const componentMap = new Map<ComponentType, Component>();
|
const componentMap = new Map<ComponentType, Component>();
|
||||||
|
|
||||||
|
|
@ -115,6 +119,9 @@ componentMap.set('JCodeEditor', JCodeEditor);
|
||||||
componentMap.set('JCategorySelect', JCategorySelect);
|
componentMap.set('JCategorySelect', JCategorySelect);
|
||||||
componentMap.set('JSelectMultiple', JSelectMultiple);
|
componentMap.set('JSelectMultiple', JSelectMultiple);
|
||||||
componentMap.set('JPopup', JPopup);
|
componentMap.set('JPopup', JPopup);
|
||||||
|
// update-begin--author:liaozhiyang---date:20240130---for:【QQYUN-7961】popupDict字典
|
||||||
|
componentMap.set('JPopupDict', JPopupDict);
|
||||||
|
// update-end--author:liaozhiyang---date:20240130---for:【QQYUN-7961】popupDict字典
|
||||||
componentMap.set('JSwitch', JSwitch);
|
componentMap.set('JSwitch', JSwitch);
|
||||||
componentMap.set('JTreeDict', JTreeDict);
|
componentMap.set('JTreeDict', JTreeDict);
|
||||||
componentMap.set('JInputPop', JInputPop);
|
componentMap.set('JInputPop', JInputPop);
|
||||||
|
|
@ -131,6 +138,9 @@ componentMap.set('JRangeNumber', JRangeNumber);
|
||||||
componentMap.set('UserSelect', UserSelect);
|
componentMap.set('UserSelect', UserSelect);
|
||||||
componentMap.set('RangeDate', JRangeDate);
|
componentMap.set('RangeDate', JRangeDate);
|
||||||
componentMap.set('RangeTime', JRangeTime);
|
componentMap.set('RangeTime', JRangeTime);
|
||||||
|
componentMap.set('RoleSelect', RoleSelectInput);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function add(compName: ComponentType, component: Component) {
|
export function add(compName: ComponentType, component: Component) {
|
||||||
componentMap.set(compName, component);
|
componentMap.set(compName, component);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<Select @dropdownVisibleChange="handleFetch" v-bind="$attrs" @change="handleChange" :options="getOptions" v-model:value="state">
|
<Select @dropdownVisibleChange="handleFetch" v-bind="attrs_" @change="handleChange" :options="getOptions" v-model:value="state">
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||||
<slot :name="item" v-bind="data || {}"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -63,7 +63,30 @@
|
||||||
|
|
||||||
// Embedded in the form, just use the hook binding to perform form verification
|
// Embedded in the form, just use the hook binding to perform form verification
|
||||||
const [state, setState] = useRuleFormItem(props, 'value', 'change', emitData);
|
const [state, setState] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||||
|
// update-begin--author:liaozhiyang---date:20230830---for:【QQYUN-6308】解决警告
|
||||||
|
let vModalValue: any;
|
||||||
|
const attrs_ = computed(() => {
|
||||||
|
let obj: any = unref(attrs) || {};
|
||||||
|
if (obj && obj['onUpdate:value']) {
|
||||||
|
vModalValue = obj['onUpdate:value'];
|
||||||
|
delete obj['onUpdate:value'];
|
||||||
|
}
|
||||||
|
// update-begin--author:liaozhiyang---date:20231017---for:【issues/5467】ApiSelect修复覆盖了用户传递的方法
|
||||||
|
if (obj['filterOption'] === undefined) {
|
||||||
|
// update-begin--author:liaozhiyang---date:20230904---for:【issues/5305】无法按照预期进行搜索
|
||||||
|
obj['filterOption'] = (inputValue, option) => {
|
||||||
|
if (typeof option['label'] === 'string') {
|
||||||
|
return option['label'].toLowerCase().indexOf(inputValue.toLowerCase()) != -1;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// update-end--author:liaozhiyang---date:20230904---for:【issues/5305】无法按照预期进行搜索
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231017---for:【issues/5467】ApiSelect修复覆盖了用户传递的方法
|
||||||
|
return obj;
|
||||||
|
});
|
||||||
|
// update-begin--author:liaozhiyang---date:20230830---for:【QQYUN-6308】解决警告
|
||||||
const getOptions = computed(() => {
|
const getOptions = computed(() => {
|
||||||
const { labelField, valueField, numberToString } = props;
|
const { labelField, valueField, numberToString } = props;
|
||||||
return unref(options).reduce((prev, next: Recordable) => {
|
return unref(options).reduce((prev, next: Recordable) => {
|
||||||
|
|
@ -90,6 +113,10 @@
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
//监听数值修改,查询数据
|
||||||
|
watchEffect(() => {
|
||||||
|
props.value && handleFetch();
|
||||||
|
});
|
||||||
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
const api = props.api;
|
const api = props.api;
|
||||||
|
|
@ -140,10 +167,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleChange(_, ...args) {
|
function handleChange(_, ...args) {
|
||||||
|
vModalValue && vModalValue(_);
|
||||||
emitData.value = args;
|
emitData.value = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { state, attrs, getOptions, loading, t, handleFetch, handleChange };
|
return { state, attrs_, attrs, getOptions, loading, t, handleFetch, handleChange };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,9 @@
|
||||||
watch(
|
watch(
|
||||||
() => props.params,
|
() => props.params,
|
||||||
() => {
|
() => {
|
||||||
!unref(isFirstLoaded) && fetch();
|
//update-begin---author:wangshuai---date:2024-02-28---for:【QQYUN-8346】 ApiTreeSelect组件入参变化时,不及时刷新数据 #1054---
|
||||||
|
unref(isFirstLoaded) && fetch();
|
||||||
|
//update-end---author:wangshuai---date:2024-02-28---for:【QQYUN-8346】 ApiTreeSelect组件入参变化时,不及时刷新数据 #1054---
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@
|
||||||
actionSpan: propTypes.number.def(6),
|
actionSpan: propTypes.number.def(6),
|
||||||
isAdvanced: propTypes.bool,
|
isAdvanced: propTypes.bool,
|
||||||
hideAdvanceBtn: propTypes.bool,
|
hideAdvanceBtn: propTypes.bool,
|
||||||
|
layout: propTypes.oneOf(['horizontal', 'vertical', 'inline']).def('horizontal'),
|
||||||
},
|
},
|
||||||
emits: ['toggle-advanced'],
|
emits: ['toggle-advanced'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
|
|
@ -74,12 +75,18 @@
|
||||||
const { showAdvancedButton, actionSpan: span, actionColOptions } = props;
|
const { showAdvancedButton, actionSpan: span, actionColOptions } = props;
|
||||||
const actionSpan = 24 - span;
|
const actionSpan = 24 - span;
|
||||||
const advancedSpanObj = showAdvancedButton ? { span: actionSpan < 6 ? 24 : actionSpan } : {};
|
const advancedSpanObj = showAdvancedButton ? { span: actionSpan < 6 ? 24 : actionSpan } : {};
|
||||||
|
// update-begin--author:liaozhiyang---date:20240105---for:【QQYUN-6566】BasicForm支持一行显示(inline)
|
||||||
|
const defaultSpan = props.layout == 'inline' ? {} : { span: showAdvancedButton ? 6 : 4 };
|
||||||
|
// update-end--author:liaozhiyang---date:20240105---for:【QQYUN-6566】BasicForm支持一行显示(inline)
|
||||||
const actionColOpt: Partial<ColEx> = {
|
const actionColOpt: Partial<ColEx> = {
|
||||||
style: { textAlign: 'right' },
|
style: { textAlign: 'right' },
|
||||||
span: showAdvancedButton ? 6 : 4,
|
...defaultSpan,
|
||||||
...advancedSpanObj,
|
...advancedSpanObj,
|
||||||
...actionColOptions,
|
...actionColOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return actionColOpt;
|
return actionColOpt;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
|
import { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
|
||||||
import type { PropType, Ref } from 'vue';
|
import type { PropType, Ref } from 'vue';
|
||||||
import type { FormActionType, FormProps } from '../types/form';
|
import type { FormActionType, FormProps } from '../types/form';
|
||||||
import type { FormSchema } from '../types/form';
|
import type { FormSchema } from '../types/form';
|
||||||
|
|
@ -40,6 +41,10 @@
|
||||||
type: Function as PropType<(key: string, value: any) => void>,
|
type: Function as PropType<(key: string, value: any) => void>,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
validateFields: {
|
||||||
|
type: Function as PropType<(nameList?: NamePath[] | undefined, options?: ValidateOptions) => Promise<any>>,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
tableAction: {
|
tableAction: {
|
||||||
type: Object as PropType<TableActionType>,
|
type: Object as PropType<TableActionType>,
|
||||||
},
|
},
|
||||||
|
|
@ -79,10 +84,9 @@
|
||||||
componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
|
componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
|
||||||
}
|
}
|
||||||
if (schema.component === 'Divider') {
|
if (schema.component === 'Divider') {
|
||||||
componentProps = Object.assign({ type: 'horizontal' }, componentProps, {
|
//update-begin---author:wangshuai---date:2023-09-22---for:【QQYUN-6603】分割线标题位置显示不正确---
|
||||||
orientation: 'left',
|
componentProps = Object.assign({ type: 'horizontal',orientation:'left', plain: true, }, componentProps);
|
||||||
plain: true,
|
//update-end---author:wangshuai---date:2023-09-22---for:【QQYUN-6603】分割线标题位置显示不正确---
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return componentProps as Recordable;
|
return componentProps as Recordable;
|
||||||
});
|
});
|
||||||
|
|
@ -179,9 +183,12 @@
|
||||||
rule.required = false;
|
rule.required = false;
|
||||||
}
|
}
|
||||||
if (component) {
|
if (component) {
|
||||||
if (!Reflect.has(rule, 'type')) {
|
//update-begin---author:wangshuai---date:2024-02-01---for:【QQYUN-8176】编辑表单中,校验必填时,如果组件是ApiSelect,打开编辑页面时,即使该字段有值,也会提示请选择---
|
||||||
|
//https://github.com/vbenjs/vue-vben-admin/pull/3082 github修复原文
|
||||||
|
/*if (!Reflect.has(rule, 'type')) {
|
||||||
rule.type = component === 'InputNumber' ? 'number' : 'string';
|
rule.type = component === 'InputNumber' ? 'number' : 'string';
|
||||||
}
|
}*/
|
||||||
|
//update-end---author:wangshuai---date:2024-02-01---for:【QQYUN-8176】编辑表单中,校验必填时,如果组件是ApiSelect,打开编辑页面时,即使该字段有值,也会提示请选择---
|
||||||
|
|
||||||
rule.message = rule.message || defaultMsg;
|
rule.message = rule.message || defaultMsg;
|
||||||
|
|
||||||
|
|
@ -198,16 +205,37 @@
|
||||||
if (characterInx !== -1 && !rules[characterInx].validator) {
|
if (characterInx !== -1 && !rules[characterInx].validator) {
|
||||||
rules[characterInx].message = rules[characterInx].message || t('component.form.maxTip', [rules[characterInx].max] as Recordable);
|
rules[characterInx].message = rules[characterInx].message || t('component.form.maxTip', [rules[characterInx].max] as Recordable);
|
||||||
}
|
}
|
||||||
|
// update-begin--author:liaozhiyang---date:20241226---for:【QQYUN-7495】pattern由字符串改成正则传递给antd(因使用InputNumber时发现正则无效)
|
||||||
|
rules.forEach((item) => {
|
||||||
|
if (typeof item.pattern === 'string') {
|
||||||
|
try {
|
||||||
|
const reg = new Function('item', `return ${item.pattern}`)(item);
|
||||||
|
if (Object.prototype.toString.call(reg) === '[object RegExp]') {
|
||||||
|
item.pattern = reg;
|
||||||
|
} else {
|
||||||
|
item.pattern = new RegExp(item.pattern);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
item.pattern = new RegExp(item.pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// update-end--author:liaozhiyang---date:20231226---for:【QQYUN-7495】pattern由字符串改成正则传递给antd(因使用InputNumber时发现正则无效)
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderComponent() {
|
function renderComponent() {
|
||||||
const { renderComponentContent, component, field, changeEvent = 'change', valueField } = props.schema;
|
const { renderComponentContent, component, field, changeEvent = 'change', valueField, componentProps } = props.schema;
|
||||||
|
|
||||||
const isCheck = component && ['Switch', 'Checkbox'].includes(component);
|
const isCheck = component && ['Switch', 'Checkbox'].includes(component);
|
||||||
|
// update-begin--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
|
||||||
|
let isTrim = false;
|
||||||
|
if (component === 'Input' && componentProps && componentProps.trim) {
|
||||||
|
isTrim = true;
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
|
||||||
const eventKey = `on${upperFirst(changeEvent)}`;
|
const eventKey = `on${upperFirst(changeEvent)}`;
|
||||||
|
// update-begin--author:liaozhiyang---date:20230922---for:【issues/752】表单校验dynamicRules 无法 使用失去焦点后校验 trigger: 'blur'
|
||||||
const on = {
|
const on = {
|
||||||
[eventKey]: (...args: Nullable<Recordable>[]) => {
|
[eventKey]: (...args: Nullable<Recordable>[]) => {
|
||||||
const [e] = args;
|
const [e] = args;
|
||||||
|
|
@ -215,16 +243,35 @@
|
||||||
propsData[eventKey](...args);
|
propsData[eventKey](...args);
|
||||||
}
|
}
|
||||||
const target = e ? e.target : null;
|
const target = e ? e.target : null;
|
||||||
const value = target ? (isCheck ? target.checked : target.value) : e;
|
// update-begin--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
|
||||||
|
let value;
|
||||||
|
if (target) {
|
||||||
|
if (isCheck) {
|
||||||
|
value = target.checked;
|
||||||
|
} else {
|
||||||
|
value = isTrim ? target.value.trim() : target.value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = e;
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
|
||||||
props.setFormModel(field, value);
|
props.setFormModel(field, value);
|
||||||
|
//props.validateFields([field], { triggerName: 'change' }).catch((_) => {});
|
||||||
},
|
},
|
||||||
|
// onBlur: () => {
|
||||||
|
// props.validateFields([field], { triggerName: 'blur' }).catch((_) => {});
|
||||||
|
// },
|
||||||
};
|
};
|
||||||
|
// update-end--author:liaozhiyang---date:20230922---for:【issues/752】表单校验dynamicRules 无法 使用失去焦点后校验 trigger: 'blur'
|
||||||
const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>;
|
const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>;
|
||||||
|
|
||||||
const { autoSetPlaceHolder, size } = props.formProps;
|
const { autoSetPlaceHolder, size } = props.formProps;
|
||||||
const propsData: Recordable = {
|
const propsData: Recordable = {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
getPopupContainer: (trigger: Element) => trigger.parentNode,
|
getPopupContainer: (trigger: Element) => {
|
||||||
|
|
||||||
|
return trigger?.parentNode;
|
||||||
|
},
|
||||||
size,
|
size,
|
||||||
...unref(getComponentsProps),
|
...unref(getComponentsProps),
|
||||||
disabled: unref(getDisable),
|
disabled: unref(getDisable),
|
||||||
|
|
@ -347,10 +394,10 @@
|
||||||
// update-begin--author:liaozhiyang---date:20230803---for:【issues-641】调整表格搜索表单的span配置无效
|
// update-begin--author:liaozhiyang---date:20230803---for:【issues-641】调整表格搜索表单的span配置无效
|
||||||
const { getIsMobile } = useAppInject();
|
const { getIsMobile } = useAppInject();
|
||||||
let realColProps;
|
let realColProps;
|
||||||
if (colProps['span'] && !unref(getIsMobile)) {
|
|
||||||
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].forEach((name) => delete baseColProps[name]);
|
|
||||||
}
|
|
||||||
realColProps = { ...baseColProps, ...colProps };
|
realColProps = { ...baseColProps, ...colProps };
|
||||||
|
if (colProps['span'] && !unref(getIsMobile)) {
|
||||||
|
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].forEach((name) => delete realColProps[name]);
|
||||||
|
}
|
||||||
// update-end--author:liaozhiyang---date:20230803---for:【issues-641】调整表格搜索表单的span配置无效
|
// update-end--author:liaozhiyang---date:20230803---for:【issues-641】调整表格搜索表单的span配置无效
|
||||||
const { isIfShow, isShow } = getShow();
|
const { isIfShow, isShow } = getShow();
|
||||||
const values = unref(getValues);
|
const values = unref(getValues);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,12 @@ function genType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setComponentRuleType(rule: ValidationRule, component: ComponentType, valueFormat: string) {
|
export function setComponentRuleType(rule: ValidationRule, component: ComponentType, valueFormat: string) {
|
||||||
|
//update-begin---author:wangshuai---date:2024-02-01---for:【QQYUN-8176】编辑表单中,校验必填时,如果组件是ApiSelect,打开编辑页面时,即使该字段有值,也会提示请选择---
|
||||||
|
//https://github.com/vbenjs/vue-vben-admin/pull/3082 github修复原文
|
||||||
|
if (Reflect.has(rule, 'type')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//update-end---author:wangshuai---date:2024-02-01---for:【QQYUN-8176】编辑表单中,校验必填时,如果组件是ApiSelect,打开编辑页面时,即使该字段有值,也会提示请选择---
|
||||||
if (['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'].includes(component)) {
|
if (['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'].includes(component)) {
|
||||||
rule.type = valueFormat ? 'string' : 'object';
|
rule.type = valueFormat ? 'string' : 'object';
|
||||||
} else if (['RangePicker', 'Upload', 'CheckboxGroup', 'TimePicker'].includes(component)) {
|
} else if (['RangePicker', 'Upload', 'CheckboxGroup', 'TimePicker'].includes(component)) {
|
||||||
|
|
@ -61,6 +67,18 @@ export function handleInputNumberValue(component?: ComponentType, val?: any) {
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*liaozhiyang
|
||||||
|
*2023-12-26
|
||||||
|
*某些组件的传值需要把字符串类型转成数值类型
|
||||||
|
*/
|
||||||
|
export function handleInputStringValue(component?: ComponentType, val?: any) {
|
||||||
|
if (!component) return val;
|
||||||
|
if (['InputNumber'].includes(component) && typeof val === 'string') {
|
||||||
|
return Number(val);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 时间字段
|
* 时间字段
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form';
|
import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form';
|
||||||
import type { NamePath } from 'ant-design-vue/lib/form/interface';
|
import type { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
|
||||||
import type { DynamicProps } from '/#/utils';
|
import type { DynamicProps } from '/#/utils';
|
||||||
import { handleRangeValue } from '../utils/formUtils';
|
import { handleRangeValue } from '../utils/formUtils';
|
||||||
import { ref, onUnmounted, unref, nextTick, watch } from 'vue';
|
import { ref, onUnmounted, unref, nextTick, watch } from 'vue';
|
||||||
|
|
@ -10,7 +10,7 @@ import { add } from "/@/components/Form/src/componentMap";
|
||||||
//集成online专用控件
|
//集成online专用控件
|
||||||
import { OnlineSelectCascade, LinkTableCard, LinkTableSelect } from '@jeecg/online';
|
import { OnlineSelectCascade, LinkTableCard, LinkTableSelect } from '@jeecg/online';
|
||||||
|
|
||||||
export declare type ValidateFields = (nameList?: NamePath[]) => Promise<Recordable>;
|
export declare type ValidateFields = (nameList?: NamePath[], options?: ValidateOptions) => Promise<Recordable>;
|
||||||
|
|
||||||
type Props = Partial<DynamicProps<FormProps>>;
|
type Props = Partial<DynamicProps<FormProps>>;
|
||||||
|
|
||||||
|
|
@ -149,9 +149,9 @@ export function useForm(props?: Props): UseFormReturnType {
|
||||||
});
|
});
|
||||||
return values;
|
return values;
|
||||||
},
|
},
|
||||||
validateFields: async (nameList?: NamePath[]): Promise<Recordable> => {
|
validateFields: async (nameList?: NamePath[], options?: ValidateOptions): Promise<Recordable> => {
|
||||||
const form = await getForm();
|
const form = await getForm();
|
||||||
return form.validateFields(nameList);
|
return form.validateFields(nameList, options);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import type { ComputedRef, Ref } from 'vue';
|
import type { ComputedRef, Ref } from 'vue';
|
||||||
import type { FormProps, FormSchema, FormActionType } from '../types/form';
|
import type { FormProps, FormSchema, FormActionType } from '../types/form';
|
||||||
import type { NamePath } from 'ant-design-vue/lib/form/interface';
|
import type { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
|
||||||
import { unref, toRaw } from 'vue';
|
import { unref, toRaw } from 'vue';
|
||||||
import { isArray, isFunction, isObject, isString } from '/@/utils/is';
|
import { isArray, isFunction, isObject, isString } from '/@/utils/is';
|
||||||
import { deepMerge, getValueType } from '/@/utils';
|
import { deepMerge, getValueType } from '/@/utils';
|
||||||
import { dateItemType, handleInputNumberValue } from '../helper';
|
import { dateItemType, handleInputNumberValue, handleInputStringValue } from '../helper';
|
||||||
import { dateUtil } from '/@/utils/dateUtil';
|
import { dateUtil } from '/@/utils/dateUtil';
|
||||||
import { cloneDeep, uniqBy } from 'lodash-es';
|
import { cloneDeep, uniqBy } from 'lodash-es';
|
||||||
import { error } from '/@/utils/log';
|
import { error } from '/@/utils/log';
|
||||||
|
|
@ -65,6 +65,9 @@ export function useFormEvents({
|
||||||
const hasKey = Reflect.has(values, key);
|
const hasKey = Reflect.has(values, key);
|
||||||
|
|
||||||
value = handleInputNumberValue(schema?.component, value);
|
value = handleInputNumberValue(schema?.component, value);
|
||||||
|
// update-begin--author:liaozhiyang---date:20231226---for:【QQYUN-7535】popup回填字段inputNumber组件验证错误
|
||||||
|
value = handleInputStringValue(schema?.component, value);
|
||||||
|
// update-end--author:liaozhiyang---date:20231226---for:【QQYUN-7535】popup回填字段inputNumber组件验证错误
|
||||||
// 0| '' is allow
|
// 0| '' is allow
|
||||||
if (hasKey && fields.includes(key)) {
|
if (hasKey && fields.includes(key)) {
|
||||||
// time type
|
// time type
|
||||||
|
|
@ -207,8 +210,8 @@ export function useFormEvents({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function validateFields(nameList?: NamePath[] | undefined) {
|
async function validateFields(nameList?: NamePath[] | undefined, options?: ValidateOptions) {
|
||||||
return unref(formElRef)?.validateFields(nameList);
|
return unref(formElRef)?.validateFields(nameList, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function validate(nameList?: NamePath[] | undefined) {
|
async function validate(nameList?: NamePath[] | undefined) {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
},
|
},
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
value: propTypes.oneOfType([propTypes.object, propTypes.array]),
|
value: propTypes.oneOfType([propTypes.object, propTypes.array, propTypes.string]),
|
||||||
//是否显示区县
|
//是否显示区县
|
||||||
showArea: propTypes.bool.def(true),
|
showArea: propTypes.bool.def(true),
|
||||||
//是否是全部
|
//是否是全部
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
allowClear: propTypes.bool.def(false),
|
allowClear: propTypes.bool.def(false),
|
||||||
getPopupContainer: {
|
getPopupContainer: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: (node) => node.parentNode,
|
default: (node) => node?.parentNode,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ['change', 'update:value','update:area','update:city','update:province'],
|
emits: ['change', 'update:value','update:area','update:city','update:province'],
|
||||||
|
|
@ -152,11 +152,14 @@
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.area-select {
|
.area-select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
|
||||||
|
/* update-begin-author:taoyan date:2023-2-18 for: QQYUN-4292【online表单】高级查询 2.省市县样式问题 */
|
||||||
|
/* display: flex;*/
|
||||||
|
|
||||||
.ant-select {
|
.ant-select {
|
||||||
width: 33.3%;
|
width: calc(33.3% - 7px)
|
||||||
}
|
}
|
||||||
|
/* update-end-author:taoyan date:2023-2-18 for: QQYUN-4292【online表单】高级查询 2.省市县样式问题 */
|
||||||
|
|
||||||
.ant-select:not(:first-child) {
|
.ant-select:not(:first-child) {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<a-checkbox-group v-bind="attrs" v-model:value="checkboxArray" :options="checkOptions" @change="handleChange"></a-checkbox-group>
|
<a-checkbox-group v-bind="attrs" v-model:value="checkboxArray" :options="checkOptions" @change="handleChange">
|
||||||
|
<template #label="{label, value}">
|
||||||
|
<span :class="[useDicColor && getDicColor(value) ? 'colorText' : '']" :style="{ backgroundColor: `${getDicColor(value)}` }">{{ label }}</span>
|
||||||
|
</template>
|
||||||
|
</a-checkbox-group>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
@ -13,6 +17,7 @@
|
||||||
props: {
|
props: {
|
||||||
value:propTypes.oneOfType([propTypes.string, propTypes.number]),
|
value:propTypes.oneOfType([propTypes.string, propTypes.number]),
|
||||||
dictCode: propTypes.string,
|
dictCode: propTypes.string,
|
||||||
|
useDicColor: propTypes.bool.def(false),
|
||||||
options: {
|
options: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
|
|
@ -69,6 +74,7 @@
|
||||||
prev.push({
|
prev.push({
|
||||||
label: next['text'],
|
label: next['text'],
|
||||||
value: value,
|
value: value,
|
||||||
|
color: next['color'],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return prev;
|
return prev;
|
||||||
|
|
@ -84,8 +90,30 @@
|
||||||
emit('update:value', $event.join(','));
|
emit('update:value', $event.join(','));
|
||||||
emit('change', $event.join(','));
|
emit('change', $event.join(','));
|
||||||
}
|
}
|
||||||
|
const getDicColor = (value) => {
|
||||||
return { checkboxArray, checkOptions, attrs, handleChange };
|
if (props.useDicColor) {
|
||||||
|
const findItem = checkOptions.value.find((item) => item.value == value);
|
||||||
|
if (findItem) {
|
||||||
|
return findItem.color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
return { checkboxArray, checkOptions, attrs, handleChange, getDicColor };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
// update-begin--author:liaozhiyang---date:20230110---for:【QQYUN-7799】字典组件(原生组件除外)加上颜色配置
|
||||||
|
.colorText {
|
||||||
|
display: inline-block;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 0 6px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: red;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
// update-begin--author:liaozhiyang---date:20230110---for:【QQYUN-7799】字典组件(原生组件除外)加上颜色配置
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-bind="boxBindProps">
|
<div ref="containerRef" v-bind="boxBindProps">
|
||||||
<!-- 全屏按钮 -->
|
<!-- 全屏按钮 -->
|
||||||
<a-icon v-if="fullScreen" class="full-screen-icon" :type="fullScreenIcon" @click="onToggleFullScreen" />
|
<a-icon v-if="fullScreen" class="full-screen-icon" :type="fullScreenIcon" @click="onToggleFullScreen" />
|
||||||
<textarea ref="textarea" v-bind="getBindValue"></textarea>
|
<textarea ref="textarea" v-bind="getBindValue"></textarea>
|
||||||
|
|
@ -45,6 +45,8 @@
|
||||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { isJsonObjectString } from '/@/utils/is.ts';
|
import { isJsonObjectString } from '/@/utils/is.ts';
|
||||||
|
// 代码提示
|
||||||
|
import { useCodeHinting } from '../hooks/useCodeHinting';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'JCodeEditor',
|
name: 'JCodeEditor',
|
||||||
|
|
@ -58,12 +60,15 @@
|
||||||
// 是否显示全屏按钮
|
// 是否显示全屏按钮
|
||||||
fullScreen: propTypes.bool.def(false),
|
fullScreen: propTypes.bool.def(false),
|
||||||
// 全屏以后的z-index
|
// 全屏以后的z-index
|
||||||
zIndex: propTypes.any.def(999),
|
zIndex: propTypes.any.def(1500),
|
||||||
theme: propTypes.string.def('idea'),
|
theme: propTypes.string.def('idea'),
|
||||||
language: propTypes.string.def(''),
|
language: propTypes.string.def(''),
|
||||||
|
// 代码提示
|
||||||
|
keywords: propTypes.array.def([]),
|
||||||
},
|
},
|
||||||
emits: ['change', 'update:value'],
|
emits: ['change', 'update:value'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
|
const containerRef = ref(null);
|
||||||
const { prefixCls } = useDesign('code-editer');
|
const { prefixCls } = useDesign('code-editer');
|
||||||
const CodeMirror = window.CodeMirror || _CodeMirror;
|
const CodeMirror = window.CodeMirror || _CodeMirror;
|
||||||
const emitData = ref<object>();
|
const emitData = ref<object>();
|
||||||
|
|
@ -89,6 +94,9 @@
|
||||||
// 启用代码折叠相关功能:结束
|
// 启用代码折叠相关功能:结束
|
||||||
// 光标行高亮
|
// 光标行高亮
|
||||||
styleActiveLine: true,
|
styleActiveLine: true,
|
||||||
|
// update-begin--author:liaozhiyang---date:20231201---for:【issues/869】JCodeEditor组件初始化时没有设置mode
|
||||||
|
mode: props.language,
|
||||||
|
// update-begin--author:liaozhiyang---date:20231201---for:【issues/869】JCodeEditor组件初始化时没有设置mode
|
||||||
//代码格式化
|
//代码格式化
|
||||||
extraKeys: {
|
extraKeys: {
|
||||||
Tab: function autoFormat(editor) {
|
Tab: function autoFormat(editor) {
|
||||||
|
|
@ -121,6 +129,10 @@
|
||||||
}
|
}
|
||||||
return _props;
|
return _props;
|
||||||
});
|
});
|
||||||
|
// update-begin--author:liaozhiyang---date:20230904---for:【QQYUN-5955】online js增强,加入代码提示
|
||||||
|
const { codeHintingMount, codeHintingRegistry } = useCodeHinting(CodeMirror, props.keywords, props.language);
|
||||||
|
codeHintingRegistry();
|
||||||
|
// update-end--author:liaozhiyang---date:20230904---for:【QQYUN-5955】online js增强,加入代码提示
|
||||||
/**
|
/**
|
||||||
* 监听组件值
|
* 监听组件值
|
||||||
*/
|
*/
|
||||||
|
|
@ -171,6 +183,9 @@
|
||||||
coder.on('change', onChange);
|
coder.on('change', onChange);
|
||||||
// 初始化成功时赋值一次
|
// 初始化成功时赋值一次
|
||||||
setValue(innerValue, false);
|
setValue(innerValue, false);
|
||||||
|
// update-begin--author:liaozhiyang---date:20230904---for:【QQYUN-5955】online js增强,加入代码提示
|
||||||
|
codeHintingMount(coder);
|
||||||
|
// update-end--author:liaozhiyang---date:20230904---for:【QQYUN-5955】online js增强,加入代码提示
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换全屏状态
|
// 切换全屏状态
|
||||||
|
|
@ -205,7 +220,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//update-end-author:taoyan date:2022-10-18 for: VUEN-2480【严重bug】online vue3测试的问题 8、online js增强样式问题
|
//update-end-author:taoyan date:2022-10-18 for: VUEN-2480【严重bug】online vue3测试的问题 8、online js增强样式问题
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state,
|
state,
|
||||||
textarea,
|
textarea,
|
||||||
|
|
@ -215,7 +231,8 @@
|
||||||
isFullScreen,
|
isFullScreen,
|
||||||
fullScreenIcon,
|
fullScreenIcon,
|
||||||
onToggleFullScreen,
|
onToggleFullScreen,
|
||||||
refresh
|
refresh,
|
||||||
|
containerRef,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -295,4 +312,9 @@
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.CodeMirror-hints.idea {
|
||||||
|
z-index: 1001;
|
||||||
|
max-width: 600px;
|
||||||
|
max-height: 300px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
<a-radio-group v-if="compType === CompTypeEnum.Radio" v-bind="attrs" v-model:value="state" @change="handleChangeRadio">
|
<a-radio-group v-if="compType === CompTypeEnum.Radio" v-bind="attrs" v-model:value="state" @change="handleChangeRadio">
|
||||||
<template v-for="item in dictOptions" :key="`${item.value}`">
|
<template v-for="item in dictOptions" :key="`${item.value}`">
|
||||||
<a-radio :value="item.value">
|
<a-radio :value="item.value">
|
||||||
{{ item.label }}
|
<span :class="[useDicColor && item.color ? 'colorText' : '']" :style="{ backgroundColor: `${useDicColor && item.color}` }">
|
||||||
|
{{ item.label }}
|
||||||
|
</span>
|
||||||
</a-radio>
|
</a-radio>
|
||||||
</template>
|
</template>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
|
|
@ -41,7 +43,11 @@
|
||||||
<a-select-option v-if="showChooseOption" :value="null">请选择…</a-select-option>
|
<a-select-option v-if="showChooseOption" :value="null">请选择…</a-select-option>
|
||||||
<template v-for="item in dictOptions" :key="`${item.value}`">
|
<template v-for="item in dictOptions" :key="`${item.value}`">
|
||||||
<a-select-option :value="item.value">
|
<a-select-option :value="item.value">
|
||||||
<span style="display: inline-block; width: 100%" :title="item.label">
|
<span
|
||||||
|
:class="[useDicColor && item.color ? 'colorText' : '']"
|
||||||
|
:style="{ backgroundColor: `${useDicColor && item.color}` }"
|
||||||
|
:title="item.label"
|
||||||
|
>
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</span>
|
</span>
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
|
|
@ -69,9 +75,10 @@
|
||||||
type: propTypes.string,
|
type: propTypes.string,
|
||||||
placeholder: propTypes.string,
|
placeholder: propTypes.string,
|
||||||
stringToNumber: propTypes.bool,
|
stringToNumber: propTypes.bool,
|
||||||
|
useDicColor: propTypes.bool.def(false),
|
||||||
getPopupContainer: {
|
getPopupContainer: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: (node) => node.parentNode,
|
default: (node) => node?.parentNode,
|
||||||
},
|
},
|
||||||
// 是否显示【请选择】选项
|
// 是否显示【请选择】选项
|
||||||
showChooseOption: propTypes.bool.def(true),
|
showChooseOption: propTypes.bool.def(true),
|
||||||
|
|
@ -139,7 +146,8 @@
|
||||||
prev.push({
|
prev.push({
|
||||||
label: next['text'] || next['label'],
|
label: next['text'] || next['label'],
|
||||||
value: stringToNumber ? +value : value,
|
value: stringToNumber ? +value : value,
|
||||||
...omit(next, ['text', 'value']),
|
color: next['color'],
|
||||||
|
...omit(next, ['text', 'value', 'color']),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return prev;
|
return prev;
|
||||||
|
|
@ -185,11 +193,15 @@
|
||||||
|
|
||||||
/** 用于搜索下拉框中的内容 */
|
/** 用于搜索下拉框中的内容 */
|
||||||
function handleFilterOption(input, option) {
|
function handleFilterOption(input, option) {
|
||||||
// 在 label 中搜索
|
// update-begin--author:liaozhiyang---date:20230914---for:【QQYUN-6514】 配置的时候,Y轴不能输入多个字段了,控制台报错
|
||||||
let labelIf = option.children()[0]?.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
if (typeof option.children === 'function') {
|
||||||
if (labelIf) {
|
// 在 label 中搜索
|
||||||
return true;
|
let labelIf = option.children()[0]?.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||||
|
if (labelIf) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20230914---for:【QQYUN-6514】 配置的时候,Y轴不能输入多个字段了,控制台报错
|
||||||
// 在 value 中搜索
|
// 在 value 中搜索
|
||||||
return (option.value || '').toString().toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
return (option.value || '').toString().toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||||
}
|
}
|
||||||
|
|
@ -209,3 +221,17 @@
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped lang="less">
|
||||||
|
// update-begin--author:liaozhiyang---date:20230110---for:【QQYUN-7799】字典组件(原生组件除外)加上颜色配置
|
||||||
|
.colorText {
|
||||||
|
display: inline-block;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 0 6px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: red;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
// update-begin--author:liaozhiyang---date:20230110---for:【QQYUN-7799】字典组件(原生组件除外)加上颜色配置
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
value: propTypes.oneOfType([propTypes.string, propTypes.array]),
|
value: propTypes.oneOfType([propTypes.string, propTypes.number, propTypes.array]),
|
||||||
length: propTypes.number.def(25),
|
length: propTypes.number.def(25),
|
||||||
});
|
});
|
||||||
//显示的文本
|
//显示的文本
|
||||||
|
|
|
||||||
|
|
@ -25,19 +25,19 @@
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel()">
|
<a-modal :open="previewVisible" :footer="null" @cancel="handleCancel()">
|
||||||
<img alt="example" style="width: 100%" :src="previewImage" />
|
<img alt="example" style="width: 100%" :src="previewImage" />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted } from 'vue';
|
import { defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted, nextTick } from 'vue';
|
||||||
import { LoadingOutlined, UploadOutlined } from '@ant-design/icons-vue';
|
import { LoadingOutlined, UploadOutlined } from '@ant-design/icons-vue';
|
||||||
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { getFileAccessHttpUrl, getRandom } from '/@/utils/common/compUtils';
|
import { getFileAccessHttpUrl, getHeaders, getRandom } from '/@/utils/common/compUtils';
|
||||||
import { uploadUrl } from '/@/api/common/api';
|
import { uploadUrl } from '/@/api/common/api';
|
||||||
import { getToken } from '/@/utils/auth';
|
import { getToken } from '/@/utils/auth';
|
||||||
|
|
||||||
|
|
@ -94,9 +94,7 @@
|
||||||
return path.substring(path.lastIndexOf('/') + 1);
|
return path.substring(path.lastIndexOf('/') + 1);
|
||||||
};
|
};
|
||||||
//token
|
//token
|
||||||
const headers = ref<object>({
|
const headers = getHeaders();
|
||||||
'X-Access-Token': getToken(),
|
|
||||||
});
|
|
||||||
//上传状态
|
//上传状态
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
//是否是初始化加载
|
//是否是初始化加载
|
||||||
|
|
@ -177,28 +175,36 @@
|
||||||
*/
|
*/
|
||||||
function handleChange({ file, fileList, event }) {
|
function handleChange({ file, fileList, event }) {
|
||||||
initTag.value = false;
|
initTag.value = false;
|
||||||
uploadFileList.value = fileList;
|
// update-begin--author:liaozhiyang---date:20231116---for:【issues/846】上传多个列表只显示一个
|
||||||
|
// uploadFileList.value = fileList;
|
||||||
if (file.status === 'error') {
|
if (file.status === 'error') {
|
||||||
createMessage.error(`${file.name} 上传失败.`);
|
createMessage.error(`${file.name} 上传失败.`);
|
||||||
}
|
}
|
||||||
let fileUrls = [];
|
let fileUrls = [];
|
||||||
//上传完成
|
let noUploadingFileCount = 0;
|
||||||
if (file.status != 'uploading') {
|
if (file.status != 'uploading') {
|
||||||
fileList.forEach((file) => {
|
fileList.forEach((file) => {
|
||||||
if (file.status === 'done') {
|
if (file.status === 'done') {
|
||||||
//update-begin---author:wangshuai ---date:20221121 for:[issues/248]原生表单内使用图片组件,关闭弹窗图片组件值不会被清空------------
|
|
||||||
initTag.value = true;
|
|
||||||
//update-end---author:wangshuai ---date:20221121 for:[issues/248]原生表单内使用图片组件,关闭弹窗图片组件值不会被清空------------
|
|
||||||
fileUrls.push(file.response.message);
|
fileUrls.push(file.response.message);
|
||||||
}
|
}
|
||||||
|
if (file.status != 'uploading') {
|
||||||
|
noUploadingFileCount++;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (file.status === 'removed') {
|
if (file.status === 'removed') {
|
||||||
handleDelete(file);
|
handleDelete(file);
|
||||||
}
|
}
|
||||||
|
if (noUploadingFileCount == fileList.length) {
|
||||||
|
state.value = fileUrls.join(',');
|
||||||
|
emit('update:value', fileUrls.join(','));
|
||||||
|
// update-begin---author:wangshuai ---date:20221121 for:[issues/248]原生表单内使用图片组件,关闭弹窗图片组件值不会被清空------------
|
||||||
|
nextTick(() => {
|
||||||
|
initTag.value = true;
|
||||||
|
});
|
||||||
|
// update-end---author:wangshuai ---date:20221121 for:[issues/248]原生表单内使用图片组件,关闭弹窗图片组件值不会被清空------------
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// emitData.value = fileUrls.join(',');
|
// update-end--author:liaozhiyang---date:20231116---for:【issues/846】上传多个列表只显示一个
|
||||||
state.value = fileUrls.join(',');
|
|
||||||
emit('update:value', fileUrls.join(','));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
<div>
|
<div>
|
||||||
<BasicModal v-bind="$attrs" @register="register" title="导入EXCEL" :width="600" @cancel="handleClose" :confirmLoading="uploading" destroyOnClose>
|
<BasicModal v-bind="$attrs" @register="register" title="导入EXCEL" :width="600" @cancel="handleClose" :confirmLoading="uploading" destroyOnClose>
|
||||||
<!--是否校验-->
|
<!--是否校验-->
|
||||||
<div style="margin: 0 5px 1px" v-if="online">
|
<div style="margin: 0 5px 5px" v-if="online">
|
||||||
<span style="display: inline-block; height: 32px; line-height: 32px; vertical-align: middle">是否开启校验:</span>
|
<span style="display: inline-block; height: 32px; line-height: 32px; vertical-align: middle">是否开启校验:</span>
|
||||||
<span style="margin-left: 6px">
|
<span style="margin-left: 6px">
|
||||||
<a-switch :checked="validateStatus == 1" @change="handleChangeValidateStatus" checked-children="是" un-checked-children="否" size="small" />
|
<a-switch :checked="validateStatus == 1" @change="handleChangeValidateStatus" checked-children="是" un-checked-children="否" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!--上传-->
|
<!--上传-->
|
||||||
<a-upload name="file" accept=".xls,.xlsx" :multiple="true" :fileList="fileList" :remove="handleRemove" :beforeUpload="beforeUpload">
|
<a-upload name="file" accept=".xls,.xlsx" :multiple="true" :fileList="fileList" @remove="handleRemove" :beforeUpload="beforeUpload">
|
||||||
<a-button preIcon="ant-design:upload-outlined">选择导入文件</a-button>
|
<a-button preIcon="ant-design:upload-outlined">选择导入文件</a-button>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
<!--页脚-->
|
<!--页脚-->
|
||||||
|
|
@ -81,7 +81,10 @@
|
||||||
|
|
||||||
//关闭方法
|
//关闭方法
|
||||||
function handleClose() {
|
function handleClose() {
|
||||||
closeModal() && reset();
|
// update-begin--author:liaozhiyang---date:20231226---for:【QQYUN-7477】关闭弹窗清空内容(之前上传失败关闭后不会清除)
|
||||||
|
closeModal();
|
||||||
|
reset();
|
||||||
|
// update-end--author:liaozhiyang---date:20231226---for:【QQYUN-7477】关闭弹窗清空内容(之前上传失败关闭后不会清除)
|
||||||
}
|
}
|
||||||
|
|
||||||
//校验状态切换
|
//校验状态切换
|
||||||
|
|
@ -139,6 +142,8 @@
|
||||||
} else {
|
} else {
|
||||||
createMessage.warning(res.message);
|
createMessage.warning(res.message);
|
||||||
}
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
uploading.value = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType, ref, watchEffect, unref, watch } from 'vue';
|
import { defineComponent, PropType, ref, watchEffect, unref, watch, computed } from 'vue';
|
||||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
import { JInputTypeEnum } from '/@/enums/jeecgEnum.ts';
|
import { JInputTypeEnum } from '/@/enums/jeecgEnum.ts';
|
||||||
|
import { omit } from 'lodash-es';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'JInput',
|
name: 'JInput',
|
||||||
|
|
@ -22,8 +23,12 @@
|
||||||
const attrs = useAttrs();
|
const attrs = useAttrs();
|
||||||
//表单值
|
//表单值
|
||||||
const showText = ref('');
|
const showText = ref('');
|
||||||
|
// update-begin--author:liaozhiyang---date:20231026---for:【issues/803】JIput updateSchema不生效
|
||||||
//绑定属性
|
//绑定属性
|
||||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
const getBindValue = computed(() => {
|
||||||
|
return omit(Object.assign({}, unref(props), unref(attrs)), ['value']);
|
||||||
|
});
|
||||||
|
// update-end--author:liaozhiyang---date:20231026---for:【issues/803】JIput updateSchema不生效
|
||||||
//监听类型变化
|
//监听类型变化
|
||||||
watch(
|
watch(
|
||||||
() => props.type,
|
() => props.type,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<a-popover
|
<a-popover
|
||||||
trigger="contextmenu"
|
trigger="contextmenu"
|
||||||
v-model:visible="visible"
|
v-model:open="visible"
|
||||||
:overlayClassName="`${prefixCls}-popover`"
|
:overlayClassName="`${prefixCls}-popover`"
|
||||||
:getPopupContainer="getPopupContainer"
|
:getPopupContainer="getPopupContainer"
|
||||||
:placement="position"
|
:placement="position"
|
||||||
|
|
@ -80,7 +80,7 @@
|
||||||
// 获取弹出框挂载的元素
|
// 获取弹出框挂载的元素
|
||||||
function getPopupContainer(node) {
|
function getPopupContainer(node) {
|
||||||
if (!props.popContainer) {
|
if (!props.popContainer) {
|
||||||
return node.parentNode;
|
return node?.parentNode;
|
||||||
} else if (typeof props.popContainer === 'function') {
|
} else if (typeof props.popContainer === 'function') {
|
||||||
return props.popContainer(node);
|
return props.popContainer(node);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ['update:value', 'register', 'change','focus' ],
|
emits: ['update:value', 'register', 'popUpChange', 'focus'],
|
||||||
setup(props, { emit, refs }) {
|
setup(props, { emit, refs }) {
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
const attrs = useAttrs();
|
const attrs = useAttrs();
|
||||||
|
|
@ -115,7 +115,10 @@
|
||||||
//匹配popup设置的回调值
|
//匹配popup设置的回调值
|
||||||
let values = {};
|
let values = {};
|
||||||
for (let item of fieldConfig) {
|
for (let item of fieldConfig) {
|
||||||
let val = rows.map((row) => row[item.source]).join(',');
|
let val = rows.map((row) => row[item.source]);
|
||||||
|
// update-begin--author:liaozhiyang---date:20230831---for:【QQYUN-7535】数组只有一个且是number类型,join会改变值的类型为string
|
||||||
|
val = val.length == 1 ? val[0] : val.join(',');
|
||||||
|
// update-begin--author:liaozhiyang---date:20230831---for:【QQYUN-7535】数组只有一个且是number类型,join会改变值的类型为string
|
||||||
item.target.split(',').forEach((target) => {
|
item.target.split(',').forEach((target) => {
|
||||||
values[target] = val;
|
values[target] = val;
|
||||||
});
|
});
|
||||||
|
|
@ -124,9 +127,11 @@
|
||||||
props.formElRef && props.formElRef.setFieldsValue(values);
|
props.formElRef && props.formElRef.setFieldsValue(values);
|
||||||
//传入赋值方法方式赋值
|
//传入赋值方法方式赋值
|
||||||
props.setFieldsValue && props.setFieldsValue(values);
|
props.setFieldsValue && props.setFieldsValue(values);
|
||||||
|
// update-begin--author:liaozhiyang---date:20230831---for:【issues/5288】popup弹框,无法将选择的数据填充到自身
|
||||||
// update-begin--author:liaozhiyang---date:20230811---for:【issues/5213】JPopup抛出change事件
|
// update-begin--author:liaozhiyang---date:20230811---for:【issues/5213】JPopup抛出change事件
|
||||||
emit('change', values);
|
emit('popUpChange', values);
|
||||||
// update-end--author:liaozhiyang---date:20230811---for:【issues/5213】JPopup抛出change事件
|
// update-end--author:liaozhiyang---date:20230811---for:【issues/5213】JPopup抛出change事件
|
||||||
|
// update-begin--author:liaozhiyang---date:20230831---for:【issues/5288】popup弹框,无法将选择的数据填充到自身
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,217 @@
|
||||||
|
<!--popup组件-->
|
||||||
|
<template>
|
||||||
|
<div class="components-input-demo-presuffix">
|
||||||
|
<!--输入框-->
|
||||||
|
<a-select v-model:value="showText" v-bind="attrs" :mode="multi ? 'multiple' : ''" @click="handleOpen" readOnly :loading="loading">
|
||||||
|
<a-select-option v-for="item in options" :value="item.value">{{ item.text }}</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<!--popup弹窗-->
|
||||||
|
<JPopupOnlReportModal
|
||||||
|
@register="regModal"
|
||||||
|
:code="code"
|
||||||
|
:multi="multi"
|
||||||
|
:sorter="sorter"
|
||||||
|
:groupId="''"
|
||||||
|
:param="param"
|
||||||
|
@ok="callBack"
|
||||||
|
:getContainer="getContainer"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import JPopupOnlReportModal from './modal/JPopupOnlReportModal.vue';
|
||||||
|
import { defineComponent, ref, nextTick, watch, reactive, unref } from 'vue';
|
||||||
|
import { useModal } from '/@/components/Modal';
|
||||||
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
|
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||||
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
//定义请求url信息
|
||||||
|
const configUrl = reactive({
|
||||||
|
getColumns: '/online/cgreport/api/getRpColumns/',
|
||||||
|
getData: '/online/cgreport/api/getData/',
|
||||||
|
});
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'JPopupDict',
|
||||||
|
components: {
|
||||||
|
JPopupOnlReportModal,
|
||||||
|
},
|
||||||
|
inheritAttrs: false,
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* 示例:demo,name,id
|
||||||
|
* demo: online报表编码
|
||||||
|
* name: online报表的字段,用户显示的label
|
||||||
|
* id: online报表的字段,用于存储key
|
||||||
|
*/
|
||||||
|
dictCode: propTypes.string.def(''),
|
||||||
|
value: propTypes.string.def(''),
|
||||||
|
sorter: propTypes.string.def(''),
|
||||||
|
multi: propTypes.bool.def(false),
|
||||||
|
param: propTypes.object.def({}),
|
||||||
|
spliter: propTypes.string.def(','),
|
||||||
|
getContainer: propTypes.func,
|
||||||
|
},
|
||||||
|
emits: ['update:value', 'register', 'change'],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const { createMessage } = useMessage();
|
||||||
|
const attrs = useAttrs();
|
||||||
|
const showText = ref<any>(props.multi ? [] : '');
|
||||||
|
const options = ref<any>([]);
|
||||||
|
const cgRpConfigId = ref('');
|
||||||
|
const loading = ref(false);
|
||||||
|
const code = props.dictCode.split(',')[0];
|
||||||
|
const labelFiled = props.dictCode.split(',')[1];
|
||||||
|
const valueFiled = props.dictCode.split(',')[2];
|
||||||
|
if (!code || !valueFiled || !labelFiled) {
|
||||||
|
createMessage.error('popupDict参数未正确配置!');
|
||||||
|
}
|
||||||
|
//注册model
|
||||||
|
const [regModal, { openModal }] = useModal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开pop弹出框
|
||||||
|
*/
|
||||||
|
function handleOpen() {
|
||||||
|
!props.disabled && openModal(true);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 监听value数值
|
||||||
|
*/
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
(val) => {
|
||||||
|
const callBack = () => {
|
||||||
|
if (props.multi) {
|
||||||
|
showText.value = val && val.length > 0 ? val.split(props.spliter) : [];
|
||||||
|
} else {
|
||||||
|
showText.value = val ?? '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (props.value || props.defaultValue) {
|
||||||
|
if (cgRpConfigId.value) {
|
||||||
|
loadData({ callBack });
|
||||||
|
} else {
|
||||||
|
loadColumnsInfo({ callBack });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callBack();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => showText.value,
|
||||||
|
(val) => {
|
||||||
|
let result;
|
||||||
|
if (props.multi) {
|
||||||
|
result = val.join(',');
|
||||||
|
} else {
|
||||||
|
result = val;
|
||||||
|
}
|
||||||
|
nextTick(() => {
|
||||||
|
emit('change', result);
|
||||||
|
emit('update:value', result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* 加载列信息
|
||||||
|
*/
|
||||||
|
function loadColumnsInfo({ callBack }) {
|
||||||
|
loading.value = true;
|
||||||
|
let url = `${configUrl.getColumns}${code}`;
|
||||||
|
defHttp
|
||||||
|
.get({ url }, { isTransformResponse: false, successMessageMode: 'none' })
|
||||||
|
.then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
cgRpConfigId.value = res.result.cgRpConfigId;
|
||||||
|
loadData({ callBack });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
loading.value = false;
|
||||||
|
callBack?.();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function loadData({ callBack }) {
|
||||||
|
loading.value = true;
|
||||||
|
let url = `${configUrl.getData}${unref(cgRpConfigId)}`;
|
||||||
|
defHttp
|
||||||
|
.get(
|
||||||
|
{ url, params: { ['force_' + valueFiled]: props.value || props.defaultValue } },
|
||||||
|
{ isTransformResponse: false, successMessageMode: 'none' }
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.result;
|
||||||
|
if (data.records?.length) {
|
||||||
|
options.value = data.records.map((item) => {
|
||||||
|
return { value: item[valueFiled], text: item[labelFiled] };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
callBack?.();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 传值回调
|
||||||
|
*/
|
||||||
|
function callBack(rows) {
|
||||||
|
const dataOptions: any = [];
|
||||||
|
const dataValue: any = [];
|
||||||
|
let result;
|
||||||
|
rows.forEach((item) => {
|
||||||
|
dataOptions.push({ value: item[valueFiled], text: item[labelFiled] });
|
||||||
|
dataValue.push(item[valueFiled]);
|
||||||
|
});
|
||||||
|
options.value = dataOptions;
|
||||||
|
if (props.multi) {
|
||||||
|
showText.value = dataValue;
|
||||||
|
result = dataValue.join(props.spliter);
|
||||||
|
} else {
|
||||||
|
showText.value = dataValue[0];
|
||||||
|
result = dataValue[0];
|
||||||
|
}
|
||||||
|
nextTick(() => {
|
||||||
|
emit('change', result);
|
||||||
|
emit('update:value', result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
showText,
|
||||||
|
attrs,
|
||||||
|
regModal,
|
||||||
|
handleOpen,
|
||||||
|
callBack,
|
||||||
|
code,
|
||||||
|
options,
|
||||||
|
loading,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.components-input-demo-presuffix {
|
||||||
|
:deep(.ant-select-dropdown) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.components-input-demo-presuffix .anticon-close-circle {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #ccc;
|
||||||
|
transition: color 0.3s;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-input-demo-presuffix .anticon-close-circle:hover {
|
||||||
|
color: #f5222d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-input-demo-presuffix .anticon-close-circle:active {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
allowClear
|
allowClear
|
||||||
:getPopupContainer="getParentContainer"
|
:getPopupContainer="getParentContainer"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:filterOption="false"
|
:filterOption="isDictTable ? false : filterOption"
|
||||||
:notFoundContent="loading ? undefined : null"
|
:notFoundContent="loading ? undefined : null"
|
||||||
@search="loadData"
|
@search="loadData"
|
||||||
@change="handleAsyncChange"
|
@change="handleAsyncChange"
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
pageSize: propTypes.number.def(10),
|
pageSize: propTypes.number.def(10),
|
||||||
getPopupContainer: {
|
getPopupContainer: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: (node) => node.parentNode,
|
default: (node) => node?.parentNode,
|
||||||
},
|
},
|
||||||
//默认开启Y轴溢出位置调整,因此在可视空间不足时下拉框位置会自动上移,导致Select的输入框被遮挡。需要注意的是,默认情况是是可视空间,而不是所拥有的空间
|
//默认开启Y轴溢出位置调整,因此在可视空间不足时下拉框位置会自动上移,导致Select的输入框被遮挡。需要注意的是,默认情况是是可视空间,而不是所拥有的空间
|
||||||
//update-begin-author:liusq date:2023-04-04 for:[issue/286]下拉搜索框遮挡问题
|
//update-begin-author:liusq date:2023-04-04 for:[issue/286]下拉搜索框遮挡问题
|
||||||
|
|
@ -83,18 +83,37 @@
|
||||||
setup(props, { emit, refs }) {
|
setup(props, { emit, refs }) {
|
||||||
const options = ref<any[]>([]);
|
const options = ref<any[]>([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const attrs = useAttrs();
|
// update-begin--author:liaozhiyang---date:20231205---for:【issues/897】JSearchSelect组件添加class/style样式不生效
|
||||||
|
const attrs = useAttrs({'excludeDefaultKeys': false});
|
||||||
|
// update-end--author:liaozhiyang---date:20231205---for:【issues/897】JSearchSelect组件添加class/style样式不生效
|
||||||
const selectedValue = ref([]);
|
const selectedValue = ref([]);
|
||||||
const selectedAsyncValue = ref([]);
|
const selectedAsyncValue = ref([]);
|
||||||
const lastLoad = ref(0);
|
const lastLoad = ref(0);
|
||||||
// 是否根据value加载text
|
// 是否根据value加载text
|
||||||
const loadSelectText = ref(true);
|
const loadSelectText = ref(true);
|
||||||
|
|
||||||
|
// 是否是字典表
|
||||||
|
const isDictTable = computed(() => {
|
||||||
|
if (props.dict) {
|
||||||
|
return props.dict.split(',').length >= 2
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听字典code
|
* 监听字典code
|
||||||
*/
|
*/
|
||||||
watchEffect(() => {
|
watch(() => props.dict, () => {
|
||||||
props.dict && initDictData();
|
if (!props.dict) {
|
||||||
});
|
return
|
||||||
|
}
|
||||||
|
if (isDictTable.value) {
|
||||||
|
initDictTableData();
|
||||||
|
} else {
|
||||||
|
initDictCodeData();
|
||||||
|
}
|
||||||
|
}, {immediate: true});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听value
|
* 监听value
|
||||||
*/
|
*/
|
||||||
|
|
@ -116,7 +135,7 @@
|
||||||
watch(
|
watch(
|
||||||
() => props.dictOptions,
|
() => props.dictOptions,
|
||||||
(val) => {
|
(val) => {
|
||||||
if (val && val.length > 0) {
|
if (val && val.length >= 0) {
|
||||||
options.value = [...val];
|
options.value = [...val];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -126,6 +145,9 @@
|
||||||
* 异步查询数据
|
* 异步查询数据
|
||||||
*/
|
*/
|
||||||
async function loadData(value) {
|
async function loadData(value) {
|
||||||
|
if (!isDictTable.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
lastLoad.value += 1;
|
lastLoad.value += 1;
|
||||||
const currentLoad = unref(lastLoad);
|
const currentLoad = unref(lastLoad);
|
||||||
options.value = [];
|
options.value = [];
|
||||||
|
|
@ -188,7 +210,7 @@
|
||||||
/**
|
/**
|
||||||
* 初始化字典下拉数据
|
* 初始化字典下拉数据
|
||||||
*/
|
*/
|
||||||
async function initDictData() {
|
async function initDictTableData() {
|
||||||
let { dict, async, dictOptions, pageSize } = props;
|
let { dict, async, dictOptions, pageSize } = props;
|
||||||
if (!async) {
|
if (!async) {
|
||||||
//如果字典项集合有数据
|
//如果字典项集合有数据
|
||||||
|
|
@ -231,6 +253,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询数据字典
|
||||||
|
*/
|
||||||
|
async function initDictCodeData() {
|
||||||
|
options.value = await initDictOptions(props.dict);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步改变事件
|
* 同步改变事件
|
||||||
* */
|
* */
|
||||||
|
|
@ -286,7 +316,7 @@
|
||||||
if (typeof props.getPopupContainer === 'function') {
|
if (typeof props.getPopupContainer === 'function') {
|
||||||
return props.getPopupContainer(node);
|
return props.getPopupContainer(node);
|
||||||
} else {
|
} else {
|
||||||
return node.parentNode;
|
return node?.parentNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// update-end-author:taoyan date:20220407 for: getPopupContainer一直有值 导致popContainer的逻辑永远走不进去,把它挪到前面判断
|
// update-end-author:taoyan date:20220407 for: getPopupContainer一直有值 导致popContainer的逻辑永远走不进去,把它挪到前面判断
|
||||||
|
|
@ -314,6 +344,7 @@
|
||||||
attrs,
|
attrs,
|
||||||
options,
|
options,
|
||||||
loading,
|
loading,
|
||||||
|
isDictTable,
|
||||||
selectedValue,
|
selectedValue,
|
||||||
selectedAsyncValue,
|
selectedAsyncValue,
|
||||||
loadData: useDebounceFn(loadData, 800),
|
loadData: useDebounceFn(loadData, 800),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<JSelectBiz @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs" @change="handleChange"/>
|
<JSelectBiz @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs" @change="handleChange"/>
|
||||||
<DeptSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue" />
|
<DeptSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue" :multiple="multiple" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
:getPopupContainer="getParentContainer"
|
:getPopupContainer="getParentContainer"
|
||||||
>
|
>
|
||||||
<a-select-option v-for="(item, index) in dictOptions" :key="index" :getPopupContainer="getParentContainer" :value="item.value">
|
<a-select-option v-for="(item, index) in dictOptions" :key="index" :getPopupContainer="getParentContainer" :value="item.value">
|
||||||
{{ item.text || item.label }}
|
<span :class="[useDicColor && item.color ? 'colorText' : '']" :style="{ backgroundColor: `${useDicColor && item.color}` }">{{ item.text || item.label }}</span>
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -68,6 +68,10 @@
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
useDicColor: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
emits: ['options-change', 'change', 'input', 'update:value'],
|
emits: ['options-change', 'change', 'input', 'update:value'],
|
||||||
setup(props, { emit, refs }) {
|
setup(props, { emit, refs }) {
|
||||||
|
|
@ -118,7 +122,7 @@
|
||||||
|
|
||||||
function getParentContainer(node) {
|
function getParentContainer(node) {
|
||||||
if (!props.popContainer) {
|
if (!props.popContainer) {
|
||||||
return node.parentNode;
|
return node?.parentNode;
|
||||||
} else {
|
} else {
|
||||||
return document.querySelector(props.popContainer);
|
return document.querySelector(props.popContainer);
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +139,7 @@
|
||||||
//update-end-author:taoyan date:2022-6-21 for: 字典数据请求前将参数编码处理,但是不能直接编码,因为可能之前已经编码过了
|
//update-end-author:taoyan date:2022-6-21 for: 字典数据请求前将参数编码处理,但是不能直接编码,因为可能之前已经编码过了
|
||||||
getDictItems(temp).then((res) => {
|
getDictItems(temp).then((res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
dictOptions.value = res.map((item) => ({ value: item.value, label: item.text }));
|
dictOptions.value = res.map((item) => ({ value: item.value, label: item.text, color:item.color }));
|
||||||
//console.info('res', dictOptions.value);
|
//console.info('res', dictOptions.value);
|
||||||
} else {
|
} else {
|
||||||
console.error('getDictItems error: : ', res);
|
console.error('getDictItems error: : ', res);
|
||||||
|
|
@ -162,3 +166,15 @@
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped lang='less'>
|
||||||
|
.colorText{
|
||||||
|
display: inline-block;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 0 6px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: red;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
},
|
},
|
||||||
rowKey: {
|
rowKey: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'code',
|
default: 'id',
|
||||||
},
|
},
|
||||||
params: {
|
params: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<JSelectBiz @change="handleChange" @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs"></JSelectBiz>
|
<JSelectBiz @change="handleChange" @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs"></JSelectBiz>
|
||||||
<UserSelectModal :rowKey="rowKey" @register="regModal" @getSelectResult="setValue" v-bind="getBindValue"></UserSelectModal>
|
<UserSelectModal :rowKey="rowKey" @register="regModal" @getSelectResult="setValue" v-bind="getBindValue" :excludeUserIdList="excludeUserIdList"></UserSelectModal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
@ -37,6 +37,13 @@
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
|
//update-begin---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
||||||
|
//排除用户id的集合
|
||||||
|
excludeUserIdList:{
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
}
|
||||||
|
//update-end---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
||||||
},
|
},
|
||||||
emits: ['options-change', 'change', 'update:value'],
|
emits: ['options-change', 'change', 'update:value'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
|
|
@ -84,6 +91,17 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//update-begin---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
||||||
|
const excludeUserIdList = ref<any>([]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要监听一下excludeUserIdList,否则modal获取不到
|
||||||
|
*/
|
||||||
|
watch(()=>props.excludeUserIdList,(data)=>{
|
||||||
|
excludeUserIdList.value = data;
|
||||||
|
},{ immediate: true })
|
||||||
|
//update-end---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打卡弹出框
|
* 打卡弹出框
|
||||||
*/
|
*/
|
||||||
|
|
@ -141,6 +159,7 @@
|
||||||
regModal,
|
regModal,
|
||||||
setValue,
|
setValue,
|
||||||
handleOpen,
|
handleOpen,
|
||||||
|
excludeUserIdList,
|
||||||
handleChange,
|
handleChange,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,14 @@
|
||||||
() => props.value,
|
() => props.value,
|
||||||
(val) => {
|
(val) => {
|
||||||
if (!props.query) {
|
if (!props.query) {
|
||||||
if (!val) {
|
// update-begin--author:liaozhiyang---date:20231226---for:【QQYUN-7473】options使用[0,1],导致开关无法切换
|
||||||
|
if (!val && !props.options.includes(val)) {
|
||||||
checked.value = false;
|
checked.value = false;
|
||||||
emitValue(props.options[1]);
|
emitValue(props.options[1]);
|
||||||
} else {
|
} else {
|
||||||
checked.value = props.options[0] == val;
|
checked.value = props.options[0] == val;
|
||||||
}
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231226---for:【QQYUN-7473】options使用[0,1],导致开关无法切换
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
allowClear
|
allowClear
|
||||||
labelInValue
|
labelInValue
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:getPopupContainer="(node) => node.parentNode"
|
:getPopupContainer="(node) => node?.parentNode"
|
||||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:loadData="asyncLoadTreeData"
|
:loadData="asyncLoadTreeData"
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
<div class="ant-upload-text">{{ text }}</div>
|
<div class="ant-upload-text">{{ text }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<a-button v-else-if="buttonVisible" :disabled="isMaxCount || disabled">
|
<a-button v-else-if="buttonVisible" :disabled="buttonDisabled">
|
||||||
<Icon icon="ant-design:upload-outlined" />
|
<Icon icon="ant-design:upload-outlined" />
|
||||||
<span>{{ text }}</span>
|
<span>{{ text }}</span>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { UploadTypeEnum } from './upload.data';
|
import { UploadTypeEnum } from './upload.data';
|
||||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
import { getFileAccessHttpUrl, getHeaders } from '/@/utils/common/compUtils';
|
||||||
import UploadItemActions from './components/UploadItemActions.vue';
|
import UploadItemActions from './components/UploadItemActions.vue';
|
||||||
|
|
||||||
const { createMessage, createConfirm } = useMessage();
|
const { createMessage, createConfirm } = useMessage();
|
||||||
|
|
@ -67,11 +67,11 @@
|
||||||
removeConfirm: propTypes.bool.def(false),
|
removeConfirm: propTypes.bool.def(false),
|
||||||
beforeUpload: propTypes.func,
|
beforeUpload: propTypes.func,
|
||||||
disabled: propTypes.bool.def(false),
|
disabled: propTypes.bool.def(false),
|
||||||
|
// 替换前一个文件,用于超出最大数量依然允许上传
|
||||||
|
replaceLastOne: propTypes.bool.def(false),
|
||||||
});
|
});
|
||||||
|
|
||||||
const headers = reactive({
|
const headers = getHeaders();
|
||||||
'X-Access-Token': getToken(),
|
|
||||||
});
|
|
||||||
const fileList = ref<any[]>([]);
|
const fileList = ref<any[]>([]);
|
||||||
const uploadGoOn = ref<boolean>(true);
|
const uploadGoOn = ref<boolean>(true);
|
||||||
// refs
|
// refs
|
||||||
|
|
@ -80,6 +80,20 @@
|
||||||
const isMaxCount = computed(() => props.maxCount > 0 && fileList.value.length >= props.maxCount);
|
const isMaxCount = computed(() => props.maxCount > 0 && fileList.value.length >= props.maxCount);
|
||||||
// 当前是否是上传图片模式
|
// 当前是否是上传图片模式
|
||||||
const isImageMode = computed(() => props.fileType === UploadTypeEnum.image);
|
const isImageMode = computed(() => props.fileType === UploadTypeEnum.image);
|
||||||
|
// 上传按钮是否禁用
|
||||||
|
const buttonDisabled = computed(()=>{
|
||||||
|
if(props.disabled === true){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isMaxCount.value === true){
|
||||||
|
if(props.replaceLastOne === true){
|
||||||
|
return false
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
});
|
||||||
// 合并 props 和 attrs
|
// 合并 props 和 attrs
|
||||||
const bindProps = computed(() => {
|
const bindProps = computed(() => {
|
||||||
//update-begin-author:liusq date:20220411 for: [issue/455]上传组件传入accept限制上传文件类型无效
|
//update-begin-author:liusq date:20220411 for: [issue/455]上传组件传入accept限制上传文件类型无效
|
||||||
|
|
@ -112,7 +126,13 @@
|
||||||
parseArrayValue(val);
|
parseArrayValue(val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parsePathsValue(val);
|
//update-begin---author:liusq ---date:20230914 for:[issues/5327]Upload组件returnUrl为false时上传的字段值返回了一个'[object Object]' ------------
|
||||||
|
if (props.returnUrl) {
|
||||||
|
parsePathsValue(val);
|
||||||
|
} else {
|
||||||
|
val && parseArrayValue(JSON.parse(val));
|
||||||
|
}
|
||||||
|
//update-end---author:liusq ---date:20230914 for:[issues/5327]Upload组件returnUrl为false时上传的字段值返回了一个'[object Object]' ------------
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
|
@ -305,7 +325,9 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emitValue(newFileList);
|
//update-begin---author:liusq ---date:20230914 for:[issues/5327]Upload组件returnUrl为false时上传的字段值返回了一个'[object Object]' ------------
|
||||||
|
emitValue(JSON.stringify(newFileList));
|
||||||
|
//update-end---author:liusq ---date:20230914 for:[issues/5327]Upload组件returnUrl为false时上传的字段值返回了一个'[object Object]' ------------
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<!--部门选择框-->
|
<!--部门选择框-->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<BasicModal v-bind="$attrs" @register="register" :title="modalTitle" width="500px" @ok="handleOk" destroyOnClose @visible-change="visibleChange">
|
<BasicModal v-bind="$attrs" @register="register" :title="modalTitle" width="500px" :maxHeight="maxHeight" @ok="handleOk" destroyOnClose @visible-change="visibleChange">
|
||||||
<BasicTree
|
<BasicTree
|
||||||
ref="treeRef"
|
ref="treeRef"
|
||||||
:treeData="treeData"
|
:treeData="treeData"
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
@check="onCheck"
|
@check="onCheck"
|
||||||
:fieldNames="fieldNames"
|
:fieldNames="fieldNames"
|
||||||
:checkedKeys="checkedKeys"
|
:checkedKeys="checkedKeys"
|
||||||
|
:multiple="multiple"
|
||||||
:checkStrictly="getCheckStrictly"
|
:checkStrictly="getCheckStrictly"
|
||||||
/>
|
/>
|
||||||
<!--树操作部分-->
|
<!--树操作部分-->
|
||||||
|
|
@ -39,6 +40,7 @@
|
||||||
import { BasicTree, TreeActionType } from '/@/components/Tree';
|
import { BasicTree, TreeActionType } from '/@/components/Tree';
|
||||||
import { useTreeBiz } from '/@/components/Form/src/jeecg/hooks/useTreeBiz';
|
import { useTreeBiz } from '/@/components/Form/src/jeecg/hooks/useTreeBiz';
|
||||||
import {propTypes} from "/@/utils/propTypes";
|
import {propTypes} from "/@/utils/propTypes";
|
||||||
|
import { omit } from 'lodash-es';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'DeptSelectModal',
|
name: 'DeptSelectModal',
|
||||||
|
|
@ -53,6 +55,12 @@
|
||||||
type: String,
|
type: String,
|
||||||
default: '部门选择',
|
default: '部门选择',
|
||||||
},
|
},
|
||||||
|
// update-begin--author:liaozhiyang---date:20231220---for:【QQYUN-7678】部门组件内容过多没有滚动条(给一个默认最大高)
|
||||||
|
maxHeight: {
|
||||||
|
type: Number,
|
||||||
|
default: 500,
|
||||||
|
},
|
||||||
|
// update-end--author:liaozhiyang---date:20231220---for:【QQYUN-7678】部门组件内容过多没有滚动条(给一个默认最大高)
|
||||||
value: propTypes.oneOfType([propTypes.string, propTypes.array])
|
value: propTypes.oneOfType([propTypes.string, propTypes.array])
|
||||||
},
|
},
|
||||||
emits: ['register', 'getSelectResult'],
|
emits: ['register', 'getSelectResult'],
|
||||||
|
|
@ -65,13 +73,14 @@
|
||||||
//update-begin-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
|
//update-begin-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
|
||||||
let propValue = props.value === ''?[]:props.value;
|
let propValue = props.value === ''?[]:props.value;
|
||||||
//update-begin-author:liusq date:2023-05-26 for: [issues/538]JSelectDept组件受 dynamicDisabled 影响
|
//update-begin-author:liusq date:2023-05-26 for: [issues/538]JSelectDept组件受 dynamicDisabled 影响
|
||||||
const getBindValue = Object.assign({}, unref(props), unref(attrs), {value: propValue},{disabled: false});
|
let temp = Object.assign({}, unref(props), unref(attrs), {value: propValue},{disabled: false});
|
||||||
|
const getBindValue = omit(temp, 'multiple');
|
||||||
//update-end-author:liusq date:2023-05-26 for: [issues/538]JSelectDept组件受 dynamicDisabled 影响
|
//update-end-author:liusq date:2023-05-26 for: [issues/538]JSelectDept组件受 dynamicDisabled 影响
|
||||||
//update-end-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
|
//update-end-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
|
||||||
|
|
||||||
const queryUrl = getQueryUrl();
|
const queryUrl = getQueryUrl();
|
||||||
const [{ visibleChange, checkedKeys, getCheckStrictly, getSelectTreeData, onCheck, onLoadData, treeData, checkALL, expandAll, onSelect }] =
|
const [{ visibleChange, checkedKeys, getCheckStrictly, getSelectTreeData, onCheck, onLoadData, treeData, checkALL, expandAll, onSelect }] =
|
||||||
useTreeBiz(treeRef, queryUrl, getBindValue);
|
useTreeBiz(treeRef, queryUrl, getBindValue, props);
|
||||||
const searchInfo = ref(props.params);
|
const searchInfo = ref(props.params);
|
||||||
const tree = ref([]);
|
const tree = ref([]);
|
||||||
//替换treeNode中key字段为treeData中对应的字段
|
//替换treeNode中key字段为treeData中对应的字段
|
||||||
|
|
|
||||||
|
|
@ -151,10 +151,12 @@
|
||||||
watch(
|
watch(
|
||||||
() => props.param,
|
() => props.param,
|
||||||
() => {
|
() => {
|
||||||
if (visible) {
|
// update-begin--author:liaozhiyang---date:20231213---for:【issues/901】JPopup组件配置param参数后异常
|
||||||
|
if (visible.value) {
|
||||||
dynamicParamHandler();
|
dynamicParamHandler();
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231213---for:【issues/901】JPopup组件配置param参数后异常
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
/**
|
/**
|
||||||
|
|
@ -202,6 +204,9 @@
|
||||||
closeModal();
|
closeModal();
|
||||||
checkedKeys.value = [];
|
checkedKeys.value = [];
|
||||||
selectRows.value = [];
|
selectRows.value = [];
|
||||||
|
// update-begin--author:liaozhiyang---date:20230908---for:【issues/742】选择后删除默认仍然存在
|
||||||
|
tableRef.value.clearSelectedRowKeys();
|
||||||
|
// update-end--author:liaozhiyang---date:20230908---for:【issues/742】选择后删除默认仍然存在
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -282,7 +287,7 @@
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:deep .jeecg-basic-table .ant-table-wrapper .ant-table-title {
|
:deep(.jeecg-basic-table .ant-table-wrapper .ant-table-title){
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
@register="register"
|
@register="register"
|
||||||
:title="modalTitle"
|
:title="modalTitle"
|
||||||
width="900px"
|
width="1100px"
|
||||||
wrapClassName="j-user-select-modal"
|
wrapClassName="j-user-select-modal"
|
||||||
@ok="handleOk"
|
@ok="handleOk"
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
|
|
@ -78,7 +78,8 @@
|
||||||
canResize: false,
|
canResize: false,
|
||||||
bordered: true,
|
bordered: true,
|
||||||
size: 'small',
|
size: 'small',
|
||||||
rowKey: 'code',
|
//改成读取rowKey,自定义传递参数
|
||||||
|
rowKey: props.rowKey,
|
||||||
};
|
};
|
||||||
const getBindValue = Object.assign({}, unref(props), unref(attrs), config);
|
const getBindValue = Object.assign({}, unref(props), unref(attrs), config);
|
||||||
const [{ rowSelection, visibleChange, indexColumnProps, getSelectResult, handleDeleteSelected, selectRows }] = useSelectBiz(
|
const [{ rowSelection, visibleChange, indexColumnProps, getSelectResult, handleDeleteSelected, selectRows }] = useSelectBiz(
|
||||||
|
|
@ -89,7 +90,7 @@
|
||||||
//查询form
|
//查询form
|
||||||
const formConfig = {
|
const formConfig = {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
span: 8,
|
span: 4,
|
||||||
},
|
},
|
||||||
baseColProps: {
|
baseColProps: {
|
||||||
xs: 24,
|
xs: 24,
|
||||||
|
|
@ -99,6 +100,16 @@
|
||||||
xl: 10,
|
xl: 10,
|
||||||
xxl: 10,
|
xxl: 10,
|
||||||
},
|
},
|
||||||
|
//update-begin-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
|
actionColOptions: {
|
||||||
|
xs: 24,
|
||||||
|
sm: 8,
|
||||||
|
md: 8,
|
||||||
|
lg: 8,
|
||||||
|
xl: 8,
|
||||||
|
xxl: 8,
|
||||||
|
},
|
||||||
|
//update-end-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
schemas: [
|
schemas: [
|
||||||
{
|
{
|
||||||
label: '职务名称',
|
label: '职务名称',
|
||||||
|
|
@ -176,6 +187,7 @@
|
||||||
selectedTable,
|
selectedTable,
|
||||||
selectRows,
|
selectRows,
|
||||||
handleDeleteSelected,
|
handleDeleteSelected,
|
||||||
|
searchInfo,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -67,11 +67,21 @@
|
||||||
xl: 14,
|
xl: 14,
|
||||||
xxl: 14,
|
xxl: 14,
|
||||||
},
|
},
|
||||||
|
//update-begin-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
|
actionColOptions: {
|
||||||
|
xs: 24,
|
||||||
|
sm: 8,
|
||||||
|
md: 8,
|
||||||
|
lg: 8,
|
||||||
|
xl: 8,
|
||||||
|
xxl: 8,
|
||||||
|
},
|
||||||
|
//update-end-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
schemas: [
|
schemas: [
|
||||||
{
|
{
|
||||||
label: '角色名称',
|
label: '角色名称',
|
||||||
field: 'roleName',
|
field: 'roleName',
|
||||||
component: 'JInput',
|
component: 'Input',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,16 @@
|
||||||
xl: 6,
|
xl: 6,
|
||||||
xxl: 10,
|
xxl: 10,
|
||||||
},
|
},
|
||||||
|
//update-begin-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
|
actionColOptions: {
|
||||||
|
xs: 24,
|
||||||
|
sm: 12,
|
||||||
|
md: 12,
|
||||||
|
lg: 12,
|
||||||
|
xl: 8,
|
||||||
|
xxl: 8,
|
||||||
|
},
|
||||||
|
//update-end-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
schemas: [
|
schemas: [
|
||||||
{
|
{
|
||||||
label: '账号',
|
label: '账号',
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
@register="register"
|
@register="register"
|
||||||
:title="modalTitle"
|
:title="modalTitle"
|
||||||
width="900px"
|
:width="showSelected ? '1200px' : '900px'"
|
||||||
wrapClassName="j-user-select-modal"
|
wrapClassName="j-user-select-modal"
|
||||||
@ok="handleOk"
|
@ok="handleOk"
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
:searchInfo="searchInfo"
|
:searchInfo="searchInfo"
|
||||||
:rowSelection="rowSelection"
|
:rowSelection="rowSelection"
|
||||||
:indexColumnProps="indexColumnProps"
|
:indexColumnProps="indexColumnProps"
|
||||||
|
:afterFetch="afterFetch"
|
||||||
>
|
>
|
||||||
<!-- update-begin-author:taoyan date:2022-5-25 for: VUEN-1112一对多 用户选择 未显示选择条数,及清空 -->
|
<!-- update-begin-author:taoyan date:2022-5-25 for: VUEN-1112一对多 用户选择 未显示选择条数,及清空 -->
|
||||||
<template #tableTitle></template>
|
<template #tableTitle></template>
|
||||||
|
|
@ -48,7 +49,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, unref, ref } from 'vue';
|
import { defineComponent, unref, ref, watch } from 'vue';
|
||||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||||
import { getUserList } from '/@/api/common/api';
|
import { getUserList } from '/@/api/common/api';
|
||||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||||
|
|
@ -72,6 +73,13 @@
|
||||||
type: String,
|
type: String,
|
||||||
default: '选择用户',
|
default: '选择用户',
|
||||||
},
|
},
|
||||||
|
//update-begin---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
||||||
|
//排除用户id的集合
|
||||||
|
excludeUserIdList: {
|
||||||
|
type: Array,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
//update-end---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
||||||
},
|
},
|
||||||
emits: ['register', 'getSelectResult'],
|
emits: ['register', 'getSelectResult'],
|
||||||
setup(props, { emit, refs }) {
|
setup(props, { emit, refs }) {
|
||||||
|
|
@ -107,6 +115,15 @@
|
||||||
getBindValue
|
getBindValue
|
||||||
);
|
);
|
||||||
const searchInfo = ref(props.params);
|
const searchInfo = ref(props.params);
|
||||||
|
// update-begin--author:liaozhiyang---date:20230811---for:【issues/657】右侧选中列表删除无效
|
||||||
|
watch(rowSelection.selectedRowKeys, (newVal) => {
|
||||||
|
//update-begin---author:wangshuai ---date: 20230829 for:null指针异常导致控制台报错页面不显示------------
|
||||||
|
if(tableRef.value){
|
||||||
|
tableRef.value.setSelectedRowKeys(newVal);
|
||||||
|
}
|
||||||
|
//update-end---author:wangshuai ---date: 20230829 for:null指针异常导致控制台报错页面不显示------------
|
||||||
|
});
|
||||||
|
// update-end--author:liaozhiyang---date:20230811---for:【issues/657】右侧选中列表删除无效
|
||||||
//查询form
|
//查询form
|
||||||
const formConfig = {
|
const formConfig = {
|
||||||
baseColProps: {
|
baseColProps: {
|
||||||
|
|
@ -209,6 +226,29 @@
|
||||||
closeModal();
|
closeModal();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
||||||
|
/**
|
||||||
|
* 用户返回结果逻辑查询
|
||||||
|
*/
|
||||||
|
function afterFetch(record) {
|
||||||
|
let excludeList = props.excludeUserIdList;
|
||||||
|
if(!excludeList){
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
let arr:any[] = [];
|
||||||
|
//如果存在过滤用户id集合,并且后台返回的数据不为空
|
||||||
|
if(excludeList.length>0 && record && record.length>0){
|
||||||
|
for(let item of record){
|
||||||
|
if(excludeList.indexOf(item.id)<0){
|
||||||
|
arr.push({...item})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
//update-end---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
||||||
|
|
||||||
return {
|
return {
|
||||||
//config,
|
//config,
|
||||||
|
|
@ -227,6 +267,7 @@
|
||||||
handleDeleteSelected,
|
handleDeleteSelected,
|
||||||
tableScroll,
|
tableScroll,
|
||||||
tableRef,
|
tableRef,
|
||||||
|
afterFetch,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,232 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div @click="showModal" :class="disabled ? 'select-input disabled-select' : 'select-input'">
|
||||||
|
<template v-if="selectedList.length > 0">
|
||||||
|
<template v-for="(item, index) in selectedList">
|
||||||
|
<SelectedUserItem v-if="index < maxCount" :info="item" @unSelect="unSelect" query />
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<span v-else style="height: 30px; line-height: 30px; display: inline-block; margin-left: 7px; color: #bfbfbf">请选择</span>
|
||||||
|
<div v-if="ellipsisInfo.status" class="user-selected-item">
|
||||||
|
<div class="user-select-ellipsis">
|
||||||
|
<span style="color: red">+{{ ellipsisInfo.count }}...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<RoleSelectModal :appId="currentAppId" :multi="multi" :getContainer="getContainer" title="选择组织角色" @register="registerRoleModal" @selected="onSelected" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { useModal } from '/@/components/Modal';
|
||||||
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
import { computed, ref, watch, watchEffect, defineComponent } from 'vue';
|
||||||
|
import RoleSelectModal from './RoleSelectModal.vue';
|
||||||
|
import SelectedUserItem from '../userSelect/SelectedUserItem.vue';
|
||||||
|
import { Form } from 'ant-design-vue';
|
||||||
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
|
||||||
|
const maxCount = 2;
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'RoleSelectInput',
|
||||||
|
components: {
|
||||||
|
RoleSelectModal,
|
||||||
|
SelectedUserItem,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
store: {
|
||||||
|
type: String,
|
||||||
|
default: 'id',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
multi: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
getContainer: {
|
||||||
|
type: Function,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
appId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ['update:value', 'change'],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const formItemContext = Form.useInjectFormItemContext();
|
||||||
|
const selectedList = ref<any[]>([]);
|
||||||
|
const loading = ref(true);
|
||||||
|
|
||||||
|
const [registerRoleModal, { openModal: openRoleModal, closeModal: closeRoleModal }] = useModal();
|
||||||
|
function showModal(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
let list = selectedList.value.map((item) => item.id);
|
||||||
|
openRoleModal(true, {
|
||||||
|
list,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const ellipsisInfo = computed(() => {
|
||||||
|
let max = maxCount;
|
||||||
|
let len = selectedList.value.length;
|
||||||
|
if (len > max) {
|
||||||
|
return { status: true, count: len - max };
|
||||||
|
} else {
|
||||||
|
return { status: false };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function unSelect(id) {
|
||||||
|
console.log('unSelectUser', id);
|
||||||
|
loading.value = false;
|
||||||
|
let arr = selectedList.value;
|
||||||
|
let index = -1;
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
if (arr[i].id == id) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index >= 0) {
|
||||||
|
arr.splice(index, 1);
|
||||||
|
selectedList.value = arr;
|
||||||
|
onSelectedChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSelectedChange() {
|
||||||
|
let temp: any[] = [];
|
||||||
|
let arr = selectedList.value;
|
||||||
|
if (arr && arr.length > 0) {
|
||||||
|
temp = arr.map((k) => {
|
||||||
|
return k[props.store];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let str = temp.join(',');
|
||||||
|
emit('update:value', str);
|
||||||
|
emit('change', str);
|
||||||
|
formItemContext.onFieldChange();
|
||||||
|
console.log('选中数据', str);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSelected(_v, values) {
|
||||||
|
console.log('角色选择完毕:', values);
|
||||||
|
loading.value = false;
|
||||||
|
if (values && values.length > 0) {
|
||||||
|
selectedList.value = values;
|
||||||
|
} else {
|
||||||
|
selectedList.value = [];
|
||||||
|
}
|
||||||
|
onSelectedChange();
|
||||||
|
closeRoleModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 目前仅用于数据重新加载的一个状态
|
||||||
|
const currentAppId = ref('');
|
||||||
|
const userStore = useUserStore();
|
||||||
|
watchEffect(() => {
|
||||||
|
let tenantId = userStore.getTenant;
|
||||||
|
let appId = props.appId;
|
||||||
|
if (appId) {
|
||||||
|
currentAppId.value = appId;
|
||||||
|
} else {
|
||||||
|
currentAppId.value = new Date().getTime() + '-' + tenantId;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
async (val) => {
|
||||||
|
if (val) {
|
||||||
|
if (loading.value === true) {
|
||||||
|
await getRoleList(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedList.value = [];
|
||||||
|
}
|
||||||
|
loading.value = true;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取角色列表
|
||||||
|
* @param ids
|
||||||
|
*/
|
||||||
|
async function getRoleList(ids) {
|
||||||
|
const url = '/sys/role/listByTenant';
|
||||||
|
let params = {
|
||||||
|
[props.store]: ids,
|
||||||
|
pageSize: 200
|
||||||
|
};
|
||||||
|
// 特殊条件处理(因为后台实体是roleCode,所以折中一下,不能直接改,会出问题)
|
||||||
|
if (props.store === 'code') {
|
||||||
|
params.roleCode = ids;
|
||||||
|
}
|
||||||
|
selectedList.value = [];
|
||||||
|
const data = await defHttp.get({ url, params }, { isTransformResponse: false });
|
||||||
|
console.log('getRoleList>>', data);
|
||||||
|
if (data.success) {
|
||||||
|
const { records } = data.result;
|
||||||
|
let arr: any[] = [];
|
||||||
|
if (records && records.length > 0) {
|
||||||
|
for (let item of records) {
|
||||||
|
arr.push({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name || item.roleName,
|
||||||
|
code: item.roleCode,
|
||||||
|
checked: true,
|
||||||
|
selectType: 'sys_role',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectedList.value = arr;
|
||||||
|
} else {
|
||||||
|
console.error(data.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectedList,
|
||||||
|
ellipsisInfo,
|
||||||
|
maxCount,
|
||||||
|
registerRoleModal,
|
||||||
|
closeRoleModal,
|
||||||
|
showModal,
|
||||||
|
onSelected,
|
||||||
|
unSelect,
|
||||||
|
currentAppId,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.select-input {
|
||||||
|
padding: 0 5px;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
color: #9e9e9e;
|
||||||
|
font-size: 14px;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
min-height: 32px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
&.disabled-select {
|
||||||
|
cursor: not-allowed;
|
||||||
|
background-color: #f5f5f5 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -99,19 +99,25 @@
|
||||||
|
|
||||||
|
|
||||||
// 弹窗事件
|
// 弹窗事件
|
||||||
const [register] = useModalInner(() => {
|
const [register] = useModalInner((data) => {
|
||||||
let list = dataList.value;
|
let list = dataList.value;
|
||||||
if(!list || list.length ==0 ){
|
if(!list || list.length ==0 ){
|
||||||
}
|
}else{
|
||||||
for(let item of list){
|
let selectedIdList = data.list || [];
|
||||||
item.checked = false
|
for(let item of list){
|
||||||
|
if(selectedIdList.indexOf(item.id)>=0){
|
||||||
|
item.checked = true;
|
||||||
|
}else{
|
||||||
|
item.checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 确定事件
|
// 确定事件
|
||||||
function handleOk() {
|
function handleOk() {
|
||||||
let arr = toRaw(selectedIdList.value);
|
let arr = toRaw(selectedIdList.value);
|
||||||
emit('selected', arr);
|
emit('selected', arr, toRaw(selectedList.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataList = ref<any[]>([]);
|
const dataList = ref<any[]>([]);
|
||||||
|
|
@ -161,6 +167,7 @@
|
||||||
arr.push({
|
arr.push({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name || item.roleName,
|
name: item.name || item.roleName,
|
||||||
|
code: item.roleCode,
|
||||||
selectType: props.type,
|
selectType: props.type,
|
||||||
checked: false
|
checked: false
|
||||||
})
|
})
|
||||||
|
|
@ -177,6 +184,13 @@
|
||||||
function onSelect(e, item) {
|
function onSelect(e, item) {
|
||||||
prevent(e);
|
prevent(e);
|
||||||
console.log('onselect');
|
console.log('onselect');
|
||||||
|
// 单选判断 只能选中一条数据 其余数据置false
|
||||||
|
if(props.multi === false){
|
||||||
|
let list = dataList.value;
|
||||||
|
for(let item of list){
|
||||||
|
item.checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
item.checked = !item.checked;
|
item.checked = !item.checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,12 @@
|
||||||
<span style="width: 24px; height: 24px; line-height: 20px; margin-right: 3px; display: inline-block">
|
<span style="width: 24px; height: 24px; line-height: 20px; margin-right: 3px; display: inline-block">
|
||||||
<a-avatar v-if="info.avatar" :src="getFileAccessHttpUrl(info.avatar)" :size="24"></a-avatar>
|
<a-avatar v-if="info.avatar" :src="getFileAccessHttpUrl(info.avatar)" :size="24"></a-avatar>
|
||||||
|
|
||||||
|
<a-avatar v-else-if="info.avatarIcon" class="ant-btn-primary" :size="24" >
|
||||||
|
<template #icon>
|
||||||
|
<Icon :icon=" 'ant-design:'+info.avatarIcon " style="font-size: 16px;margin-top: 4px"/>
|
||||||
|
</template>
|
||||||
|
</a-avatar>
|
||||||
|
|
||||||
<a-avatar v-else-if="info.selectType == 'sys_role'" :size="24" style="background-color: rgb(255, 173, 0);">
|
<a-avatar v-else-if="info.selectType == 'sys_role'" :size="24" style="background-color: rgb(255, 173, 0);">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<team-outlined style="font-size: 16px"/>
|
<team-outlined style="font-size: 16px"/>
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,17 @@
|
||||||
<template #renderItem="{ item }">
|
<template #renderItem="{ item }">
|
||||||
<a-list-item style="padding: 3px 0">
|
<a-list-item style="padding: 3px 0">
|
||||||
<div class="user-select-user-info" @click="(e) => onClickUser(e, item)">
|
<div class="user-select-user-info" @click="(e) => onClickUser(e, item)">
|
||||||
<div>
|
<div style="margin-left: 10px">
|
||||||
<a-checkbox v-model:checked="checkStatus[item.id]" />
|
<a-checkbox v-model:checked="checkStatus[item.id]" v-if="multi" />
|
||||||
|
<a-radio v-model:checked="checkStatus[item.id]" v-else />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a-avatar v-if="item.avatar" :src="getFileAccessHttpUrl(item.avatar)"></a-avatar>
|
<a-avatar v-if="item.avatar" :src="getFileAccessHttpUrl(item.avatar)"></a-avatar>
|
||||||
|
<a-avatar v-else-if="item.avatarIcon" class="ant-btn-primary">
|
||||||
|
<template #icon>
|
||||||
|
<Icon :icon=" 'ant-design:'+item.avatarIcon " style="margin-top: 4px;font-size: 24px;"/>
|
||||||
|
</template>
|
||||||
|
</a-avatar>
|
||||||
<a-avatar v-else>
|
<a-avatar v-else>
|
||||||
<template #icon><UserOutlined /></template>
|
<template #icon><UserOutlined /></template>
|
||||||
</a-avatar>
|
</a-avatar>
|
||||||
|
|
@ -15,9 +21,10 @@
|
||||||
<div :style="nameStyle">
|
<div :style="nameStyle">
|
||||||
{{ item.realname }}
|
{{ item.realname }}
|
||||||
</div>
|
</div>
|
||||||
<div :style="departStyle">
|
<div :style="departStyle" class="ellipsis" :title="item.orgCodeTxt">
|
||||||
{{ item.orgCodeTxt }}
|
{{ item.orgCodeTxt }}
|
||||||
</div>
|
</div>
|
||||||
|
<div style="width: 1px"></div>
|
||||||
</div>
|
</div>
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -32,6 +39,10 @@
|
||||||
export default {
|
export default {
|
||||||
name: 'UserList',
|
name: 'UserList',
|
||||||
props: {
|
props: {
|
||||||
|
multi: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
dataList: {
|
dataList: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
|
|
@ -126,8 +137,8 @@
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
|
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||||
function records2DataList() {
|
/* function records2DataList() {
|
||||||
let arr:any[] = [];
|
let arr:any[] = [];
|
||||||
let excludeList = props.excludeUserIdList;
|
let excludeList = props.excludeUserIdList;
|
||||||
let records = props.dataList;
|
let records = props.dataList;
|
||||||
|
|
@ -139,13 +150,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
const showDataList = computed(()=>{
|
const showDataList = computed(()=>{
|
||||||
let excludeList = props.excludeUserIdList;
|
/* let excludeList = props.excludeUserIdList;
|
||||||
if(excludeList && excludeList.length>0){
|
if(excludeList && excludeList.length>0){
|
||||||
return records2DataList();
|
return records2DataList();
|
||||||
}
|
}*/
|
||||||
|
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||||
return props.dataList;
|
return props.dataList;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -166,10 +178,16 @@
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.user-select-user-info {
|
.user-select-user-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
> div {
|
> div {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
.ellipsis {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,15 @@
|
||||||
v-model:expandedKeys="expandedKeys"
|
v-model:expandedKeys="expandedKeys"
|
||||||
@select="onSelect"
|
@select="onSelect"
|
||||||
>
|
>
|
||||||
|
<template #title="{ title, key }">
|
||||||
|
<FolderFilled style="color: #9e9e9e"/><span style="margin-left: 5px">{{ title }}</span>
|
||||||
|
</template>
|
||||||
</a-tree>
|
</a-tree>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12" style="padding-left: 10px">
|
<a-col :span="12" style="padding-left: 10px">
|
||||||
<div :style="containerStyle">
|
<div :style="containerStyle">
|
||||||
<user-list :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" @selected="onSelectUser" @unSelect="unSelectUser" />
|
<user-list :multi="multi" :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" @selected="onSelectUser" @unSelect="unSelectUser" />
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
@ -27,11 +30,13 @@
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
import UserList from './UserList.vue';
|
import UserList from './UserList.vue';
|
||||||
|
import { FolderFilled } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DepartUserList',
|
name: 'DepartUserList',
|
||||||
components: {
|
components: {
|
||||||
UserList,
|
UserList,
|
||||||
|
FolderFilled
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
searchText: {
|
searchText: {
|
||||||
|
|
@ -45,6 +50,10 @@
|
||||||
excludeUserIdList:{
|
excludeUserIdList:{
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
|
},
|
||||||
|
multi: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['loaded', 'selected', 'unSelect'],
|
emits: ['loaded', 'selected', 'unSelect'],
|
||||||
|
|
@ -132,7 +141,7 @@
|
||||||
const url = '/sys/user/selectUserList';
|
const url = '/sys/user/selectUserList';
|
||||||
let params = {
|
let params = {
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 99,
|
||||||
};
|
};
|
||||||
if (props.searchText) {
|
if (props.searchText) {
|
||||||
params['keyword'] = props.searchText;
|
params['keyword'] = props.searchText;
|
||||||
|
|
@ -140,6 +149,11 @@
|
||||||
if (selectedDepartId.value) {
|
if (selectedDepartId.value) {
|
||||||
params['departId'] = selectedDepartId.value;
|
params['departId'] = selectedDepartId.value;
|
||||||
}
|
}
|
||||||
|
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||||
|
if(props.excludeUserIdList && props.excludeUserIdList.length>0){
|
||||||
|
params['excludeUserIdList'] = props.excludeUserIdList.join(",");
|
||||||
|
}
|
||||||
|
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||||
const data = await defHttp.get({ url, params }, { isTransformResponse: false });
|
const data = await defHttp.get({ url, params }, { isTransformResponse: false });
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
const { records } = data.result;
|
const { records } = data.result;
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,16 @@
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<div :style="containerStyle">
|
<div :style="containerStyle">
|
||||||
<a-tree v-if="treeData.length > 0" showIcon :treeData="treeData" :selectedKeys="selectedKeys" @select="onSelect"> </a-tree>
|
<a-tree v-if="treeData.length > 0" showIcon :treeData="treeData" :selectedKeys="selectedKeys" @select="onSelect">
|
||||||
|
<template #title="{ title, key }">
|
||||||
|
<UserOutlined style="color: #9e9e9e"/><span style="margin-left: 5px">{{ title }}</span>
|
||||||
|
</template>
|
||||||
|
</a-tree>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12" style="padding-left: 10px">
|
<a-col :span="12" style="padding-left: 10px">
|
||||||
<div :style="containerStyle">
|
<div :style="containerStyle">
|
||||||
<user-list :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" @selected="onSelectUser" @unSelect="unSelectUser" />
|
<user-list :multi="multi" :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" @selected="onSelectUser" @unSelect="unSelectUser" />
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
@ -17,11 +21,13 @@
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
import UserList from './UserList.vue';
|
import UserList from './UserList.vue';
|
||||||
|
import { UserOutlined } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'RoleUserList',
|
name: 'RoleUserList',
|
||||||
components: {
|
components: {
|
||||||
UserList,
|
UserList,
|
||||||
|
UserOutlined
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
searchText: {
|
searchText: {
|
||||||
|
|
@ -35,6 +41,10 @@
|
||||||
excludeUserIdList:{
|
excludeUserIdList:{
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
|
},
|
||||||
|
multi: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['selected', 'unSelect'],
|
emits: ['selected', 'unSelect'],
|
||||||
|
|
@ -80,7 +90,7 @@
|
||||||
const url = '/sys/user/selectUserList';
|
const url = '/sys/user/selectUserList';
|
||||||
let params = {
|
let params = {
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 99,
|
||||||
};
|
};
|
||||||
if (props.searchText) {
|
if (props.searchText) {
|
||||||
params['keyword'] = props.searchText;
|
params['keyword'] = props.searchText;
|
||||||
|
|
@ -88,6 +98,11 @@
|
||||||
if (selectedRoleId.value) {
|
if (selectedRoleId.value) {
|
||||||
params['roleId'] = selectedRoleId.value;
|
params['roleId'] = selectedRoleId.value;
|
||||||
}
|
}
|
||||||
|
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||||
|
if(props.excludeUserIdList && props.excludeUserIdList.length>0){
|
||||||
|
params['excludeUserIdList'] = props.excludeUserIdList.join(",");
|
||||||
|
}
|
||||||
|
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||||
const data = await defHttp.get({ url, params }, { isTransformResponse: false });
|
const data = await defHttp.get({ url, params }, { isTransformResponse: false });
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
const { records } = data.result;
|
const { records } = data.result;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
<a-tabs v-model:activeKey="myActiveKey" :centered="true" @change="onChangeTab">
|
<a-tabs v-model:activeKey="myActiveKey" :centered="true" @change="onChangeTab">
|
||||||
<!-- 所有用户 -->
|
<!-- 所有用户 -->
|
||||||
<a-tab-pane key="1" tab="全部" forceRender>
|
<a-tab-pane key="1" tab="全部" forceRender>
|
||||||
<user-list :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" depart @selected="onSelectUser" @unSelect="unSelectUser" />
|
<user-list :multi="multi" :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" depart @selected="onSelectUser" @unSelect="unSelectUser" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
|
||||||
<!-- 部门用户 -->
|
<!-- 部门用户 -->
|
||||||
|
|
@ -92,8 +92,10 @@
|
||||||
const APagination = Pagination;
|
const APagination = Pagination;
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
|
||||||
import { computed, ref, toRaw } from 'vue';
|
import {computed, ref, toRaw, unref} from 'vue';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
import { mySelfData } from './useUserSelect'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'UserSelectModal',
|
name: 'UserSelectModal',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -120,6 +122,11 @@
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
//是否在高级查询中作为条件 可以选择当前用户表达式
|
||||||
|
inSuperQuery:{
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
emits: ['selected', 'register'],
|
emits: ['selected', 'register'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
|
|
@ -154,6 +161,8 @@
|
||||||
if (props.izExcludeMy) {
|
if (props.izExcludeMy) {
|
||||||
excludeUserIdList.value.push(userStore.getUserInfo.id);
|
excludeUserIdList.value.push(userStore.getUserInfo.id);
|
||||||
}
|
}
|
||||||
|
//加载用户列表
|
||||||
|
loadUserList();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 确定事件
|
// 确定事件
|
||||||
|
|
@ -213,16 +222,31 @@
|
||||||
if (selectedDepart.value) {
|
if (selectedDepart.value) {
|
||||||
params['departId'] = selectedDepart.value;
|
params['departId'] = selectedDepart.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||||
|
if(unref(excludeUserIdList) && unref(excludeUserIdList).length>0){
|
||||||
|
params['excludeUserIdList'] = excludeUserIdList.value.join(",");
|
||||||
|
}
|
||||||
|
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||||
|
|
||||||
const data = await defHttp.get({ url, params }, { isTransformResponse: false });
|
const data = await defHttp.get({ url, params }, { isTransformResponse: false });
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
const { records, total } = data.result;
|
let { records, total } = data.result;
|
||||||
totalRecord.value = total;
|
totalRecord.value = total;
|
||||||
|
initCurrentUserData(records);
|
||||||
userDataList.value = records;
|
userDataList.value = records;
|
||||||
} else {
|
} else {
|
||||||
console.error(data.message);
|
console.error(data.message);
|
||||||
}
|
}
|
||||||
console.log('loadUserList', data);
|
console.log('loadUserList', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 往用户列表中添加一个 当前用户选项
|
||||||
|
function initCurrentUserData(records) {
|
||||||
|
if(pageNo.value==1 && props.inSuperQuery === true){
|
||||||
|
records.unshift({...mySelfData})
|
||||||
|
}
|
||||||
|
}
|
||||||
/*--------------加载数据---------------*/
|
/*--------------加载数据---------------*/
|
||||||
|
|
||||||
/*--------------选中/取消选中---------------*/
|
/*--------------选中/取消选中---------------*/
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
<a-button v-if="showAddButton" shape="circle" @click="onShowModal"><PlusOutlined /></a-button>
|
<a-button v-if="showAddButton" shape="circle" @click="onShowModal"><PlusOutlined /></a-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<user-select-modal :multi="multi" :getContainer="getContainer" @register="registerModal" @selected="onSelected" :izExcludeMy="izExcludeMy"></user-select-modal>
|
<user-select-modal :inSuperQuery="inSuperQuery" :multi="multi" :getContainer="getContainer" @register="registerModal" @selected="onSelected" :izExcludeMy="izExcludeMy"></user-select-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
import UserSelectModal from './UserSelectModal.vue';
|
import UserSelectModal from './UserSelectModal.vue';
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
import SelectedUserItem from './SelectedUserItem.vue';
|
import SelectedUserItem from './SelectedUserItem.vue';
|
||||||
|
import { mySelfExpress, mySelfData } from './useUserSelect'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'UserSelect',
|
name: 'UserSelect',
|
||||||
|
|
@ -74,6 +75,11 @@
|
||||||
izExcludeMy:{
|
izExcludeMy:{
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
},
|
||||||
|
//是否在高级查询中作为条件 可以选择当前用户
|
||||||
|
inSuperQuery:{
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:value', 'change'],
|
emits: ['update:value', 'change'],
|
||||||
|
|
@ -150,19 +156,41 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
async function getUserList(ids) {
|
async function getUserList(ids) {
|
||||||
const url = '/sys/user/list';
|
let hasUserExpress = false;
|
||||||
let params = {
|
let paramIds = ids;
|
||||||
[props.store]: ids,
|
let idList = [];
|
||||||
};
|
|
||||||
selectedUserList.value = [];
|
selectedUserList.value = [];
|
||||||
const data = await defHttp.get({ url, params }, { isTransformResponse: false });
|
if(ids){
|
||||||
if (data.success) {
|
// update-begin-author:sunjianlei date:20230330 for: 修复用户选择器逗号分割回显不生效的问题
|
||||||
const { records } = data.result;
|
let tempArray = ids.split(',').map(s => s.trim()).filter(s => s != '');
|
||||||
selectedUserList.value = records;
|
if (tempArray.includes(mySelfExpress)) {
|
||||||
} else {
|
hasUserExpress = true;
|
||||||
console.error(data.message);
|
idList = tempArray.filter(item => item != mySelfExpress);
|
||||||
|
} else {
|
||||||
|
idList = tempArray;
|
||||||
|
}
|
||||||
|
// update-end-author:sunjianlei date:20230330 for: 修复用户选择器逗号分割回显不生效的问题
|
||||||
|
}
|
||||||
|
|
||||||
|
if(idList.length>0){
|
||||||
|
paramIds = idList.join(',')
|
||||||
|
const url = '/sys/user/list';
|
||||||
|
let params = {
|
||||||
|
[props.store]: paramIds,
|
||||||
|
};
|
||||||
|
const data = await defHttp.get({ url, params }, { isTransformResponse: false });
|
||||||
|
console.log('getUserList', data);
|
||||||
|
if (data.success) {
|
||||||
|
const { records } = data.result;
|
||||||
|
selectedUserList.value = records;
|
||||||
|
} else {
|
||||||
|
console.error(data.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hasUserExpress){
|
||||||
|
let temp = selectedUserList.value;
|
||||||
|
temp.push({...mySelfData})
|
||||||
}
|
}
|
||||||
console.log('getUserList', data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const showAddButton = computed(() => {
|
const showAddButton = computed(() => {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* 用户选择组件支持选择 我自己,以表达式的形式传值
|
||||||
|
*/
|
||||||
|
export const mySelfExpress = '#{sys_user_code}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户列表 我自己的数据
|
||||||
|
*/
|
||||||
|
export const mySelfData = {
|
||||||
|
id: mySelfExpress, username: mySelfExpress, realname: '当前用户', avatarIcon: 'idcard-outlined', avatarColor: 'rgb(75 176 79)'
|
||||||
|
}
|
||||||