Compare commits
116 Commits
v3.4.2
...
v3.4.4last
Author | SHA1 | Date | |
---|---|---|---|
![]() |
95ca88b47c | ||
![]() |
30855ad4a0 | ||
![]() |
19931fb273 | ||
![]() |
787e763b9d | ||
![]() |
104e975a13 | ||
![]() |
136e30360c | ||
![]() |
c402eec726 | ||
![]() |
1b5f6caa41 | ||
![]() |
7b7bcba3b4 | ||
![]() |
e4c952c81c | ||
![]() |
ad08851397 | ||
![]() |
2f94ba9ddb | ||
![]() |
f0fd265554 | ||
![]() |
836070b165 | ||
![]() |
565957033e | ||
![]() |
74bf90014d | ||
![]() |
bc4fbad872 | ||
![]() |
04a7630564 | ||
![]() |
822b20fb15 | ||
![]() |
6f0b9421d9 | ||
![]() |
147fb3450c | ||
![]() |
2e199de1aa | ||
![]() |
5a0980e6b0 | ||
![]() |
8890e52e47 | ||
![]() |
7abd3e5204 | ||
![]() |
32ffd19dc4 | ||
![]() |
3c3353da4f | ||
![]() |
78fa18f5aa | ||
![]() |
0674a32fe9 | ||
![]() |
e59303f3bb | ||
![]() |
8ffe88ea8b | ||
![]() |
d619e7a123 | ||
![]() |
1072347d40 | ||
![]() |
d8d23560f3 | ||
![]() |
a9aadae545 | ||
![]() |
503475c7ae | ||
![]() |
79571477cf | ||
![]() |
d9eaf06d7d | ||
![]() |
abdc9da743 | ||
![]() |
0168d71154 | ||
![]() |
155b817346 | ||
![]() |
6a28a0fa58 | ||
![]() |
8309e171d4 | ||
![]() |
4da6c77856 | ||
![]() |
e76080d176 | ||
![]() |
1563ae28ad | ||
![]() |
7b0c76d1b1 | ||
![]() |
ef3cb6a2ad | ||
![]() |
9889c1ccca | ||
![]() |
73f1a28df3 | ||
![]() |
602aac5bf0 | ||
![]() |
4a78bef74b | ||
![]() |
924d26910d | ||
![]() |
67d937f74f | ||
![]() |
c9362f142e | ||
![]() |
088f72db62 | ||
![]() |
737312e959 | ||
![]() |
5b4a37cf95 | ||
![]() |
b19ddbd449 | ||
![]() |
f9365883c0 | ||
![]() |
5dacdeb939 | ||
![]() |
b7da59c0b7 | ||
![]() |
c21f4e7f82 | ||
![]() |
90e2c6cd68 | ||
![]() |
e581f7f7eb | ||
![]() |
166f7e1888 | ||
![]() |
22e656daf3 | ||
![]() |
cbe7ea4bb5 | ||
![]() |
ae55451395 | ||
![]() |
ecfe531b3d | ||
![]() |
6dfcfbcf2a | ||
![]() |
61d2ff490d | ||
![]() |
300387d380 | ||
![]() |
bc9bb7304e | ||
![]() |
6882eef000 | ||
![]() |
147055fba2 | ||
![]() |
8472f42126 | ||
![]() |
335c82e08a | ||
![]() |
6bf259427c | ||
![]() |
f19a3025e1 | ||
![]() |
fea9146b1a | ||
![]() |
1dff1f0d93 | ||
![]() |
1ae94cf036 | ||
![]() |
c112e703b6 | ||
![]() |
455b6672d2 | ||
![]() |
616b4c01fb | ||
![]() |
48499d1af7 | ||
![]() |
78230e1d0e | ||
![]() |
1213e7e2c8 | ||
![]() |
a91c7d39f7 | ||
![]() |
30bfbfc308 | ||
![]() |
c669bee385 | ||
![]() |
e7371ddb43 | ||
![]() |
2e84090b7d | ||
![]() |
83791978ed | ||
![]() |
6adeb05d07 | ||
![]() |
908cae7235 | ||
![]() |
c6e48c1c43 | ||
![]() |
052e63d875 | ||
![]() |
6686287991 | ||
![]() |
433a4bfab9 | ||
![]() |
23c3ec8294 | ||
![]() |
ae5787d1df | ||
![]() |
75029d0a2c | ||
![]() |
af1fd634f3 | ||
![]() |
2db96af605 | ||
![]() |
d92041fa37 | ||
![]() |
91bb10a861 | ||
![]() |
5b806bc70d | ||
![]() |
e036565709 | ||
![]() |
d6130b685d | ||
![]() |
013f6c2e81 | ||
![]() |
3ac00df8e5 | ||
![]() |
c968aac7ed | ||
![]() |
8e33da231e | ||
![]() |
43db6d8b2e |
@@ -4,8 +4,8 @@ VOLUME /tmp
|
||||
ENV LANG en_US.UTF-8
|
||||
RUN echo "server { \
|
||||
listen 80; \
|
||||
location /jeecgboot { \
|
||||
proxy_pass http://jeecg-boot-system:8080/jeecg-boot; \
|
||||
location /jeecgboot/ { \
|
||||
proxy_pass http://jeecg-boot-system:8080/jeecg-boot/; \
|
||||
proxy_redirect off; \
|
||||
proxy_set_header Host jeecg-boot-system; \
|
||||
proxy_set_header X-Real-IP \$remote_addr; \
|
||||
@@ -27,4 +27,4 @@ RUN echo "server { \
|
||||
|
||||
ADD dist/ /var/www/html/
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
EXPOSE 443
|
||||
|
161
README.md
161
README.md
@@ -1,57 +1,55 @@
|
||||
JEECG BOOT 低代码开发平台(Vue3前端)
|
||||
===============
|
||||
当前最新版本: 3.4.2(发布时间:20220922)
|
||||
> 变更大版本号与后台同步 3.3.X,后续单独发布版本会更新小版本号。
|
||||
|
||||
当前最新版本: 3.4.4(发布时间:2022-11-21)
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://www.jeecg.com)
|
||||
[](https://my.oschina.net/jeecg)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](http://www.jeecg.com)
|
||||
[](https://jeecg.blog.csdn.net)
|
||||
[](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-Vue、TypeScript 等新技术方案,包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能。
|
||||
是在 Vben-Admin 基础上研发的,适合于JeecgBoot低代码平台的VUE3版前端解决方案,目前已是稳定版本,可用于生产项目。
|
||||
JeecgBoot-Vue3采用 Vue3.0、Vite、 Ant-Design-Vue3、TypeScript 等新技术方案,包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能。
|
||||
是采用Vben实现的 JeecgBoot低代码平台的全新vue3版本。
|
||||
|
||||
> 强大的代码生成器让前后端代码一键生成! JeecgBoot引领低代码开发模式(OnlineCoding-> 代码生成-> 手工MERGE), 帮助解决Java项目70%的重复工作,让开发更多关注业务。既能快速提高效率,节省成本,同时又不失灵活性
|
||||
|
||||
## 项目源码
|
||||
## 技术支持
|
||||
|
||||
| 仓库 |前端源码Vue3版 | 前端源码Vue2版 | 后端源码 |
|
||||
|-|-|-|-|
|
||||
| Github | [jeecgboot-vue3](https://github.com/jeecgboot/jeecgboot-vue3) | [ant-design-vue-jeecg](https://github.com/jeecgboot/ant-design-vue-jeecg) | [jeecg-boot](https://github.com/jeecgboot/jeecg-boot) |
|
||||
| 码云 | [jeecgboot-vue3](https://gitee.com/jeecg/jeecgboot-vue3) | [ant-design-vue-jeecg](https://gitee.com/jeecg/ant-design-vue-jeecg) | [jeecg-boot](https://gitee.com/jeecg/jeecg-boot) |
|
||||
关闭Gitee的issue通道,使用中遇到问题或者BUG可以在 [Github上提Issues](https://github.com/jeecgboot/jeecgboot-vue3/issues/new)
|
||||
|
||||
官方支持: http://jeecg.com/doc/help
|
||||
|
||||
|
||||
## 源码下载
|
||||
|
||||
- 后台源码 :https://github.com/jeecgboot/jeecg-boot
|
||||
- 前端源码 :https://github.com/jeecgboot/jeecgboot-vue3
|
||||
|
||||
##### 项目说明
|
||||
|
||||
| 项目名 | 说明 |
|
||||
|--------------------|------------------------|
|
||||
| `jeecgboot-vue3` | Vue3版前端代码 |
|
||||
| `jeecg-boot` | JAVA后台(支持微服务) |
|
||||
| `ant-design-vue-jeecg` |Vue2版前端代码 |
|
||||
|
||||
|
||||
|
||||
> 入门必看>>[切换Vue3路由](http://vue3.jeecg.com/2671576)
|
||||
| `jeecg-boot` | SpringBoot后台项目(支持微服务) |
|
||||
|
||||
|
||||
## 技术文档
|
||||
|
||||
- 开发文档:[http://vue3.jeecg.com](http://vue3.jeecg.com)
|
||||
- 官方文档:[http://vue3.jeecg.com](http://vue3.jeecg.com)
|
||||
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
- 在线演示:[http://boot3.jeecg.com](http://boot3.jeecg.com)
|
||||
- 快速入门:[入门视频](https://www.bilibili.com/video/BV1V34y187Y9 "入门视频") | [ 代码生成](http://vue3.jeecg.com/2677352)
|
||||
- 在线演示:[低代码演示](http://boot3.jeecg.com) | [敲敲云零代码](https://www.qiaoqiaoyun.com)
|
||||
- 快速入门:[常见问题](http://vue3.jeecg.com/2426559) | [入门视频](https://www.bilibili.com/video/BV1V34y187Y9 "入门视频") | [ 代码生成](http://vue3.jeecg.com/2677352)
|
||||
- QQ交流群:683903138
|
||||
|
||||
## 安装与使用
|
||||
|
||||
|
||||
> 环境要求: Node.js版本要求12.x以上,且不能为13.x版本,这里推荐14.x及以上。
|
||||
> 环境要求: 版本要求Node 14.18+ / 16+ 版本以上,不再支持 Node 12 / 13 / 15。
|
||||
> 建议使用pnpm,如果使用yarn,请用Yarn1.x版本,否则依赖可能安装不上。
|
||||
|
||||
|
||||
- Get the project code
|
||||
@@ -65,26 +63,30 @@ git clone https://github.com/jeecgboot/jeecgboot-vue3.git
|
||||
```bash
|
||||
cd jeecgboot-vue3
|
||||
|
||||
yarn install
|
||||
|
||||
pnpm install
|
||||
```
|
||||
|
||||
- 配置后台接口地址
|
||||
- 配置接口地址 `.env.development`
|
||||
|
||||
```bash
|
||||
.env.development
|
||||
VITE_PROXY = [["/jeecgboot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]]
|
||||
VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot
|
||||
```
|
||||
|
||||
> 说明:把`http://localhost:8080/jeecg-boot` 换成自己地址,其他不用改。
|
||||
|
||||
|
||||
- run
|
||||
|
||||
```bash
|
||||
yarn serve
|
||||
pnpm serve
|
||||
```
|
||||
|
||||
|
||||
- build
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
pnpm build
|
||||
```
|
||||
|
||||
|
||||
@@ -92,11 +94,13 @@ yarn build
|
||||
|
||||
- host设置
|
||||
|
||||
>注意: 需要把`127.0.0.1`替换成真实IP 比如`192.`开头,不然后端不通。
|
||||
|
||||
```bash
|
||||
127.0.0.1 jeecg-boot-system
|
||||
127.0.0.1 jeecg-boot-gateway
|
||||
```
|
||||
>注意: 需要把`127.0.0.1`替换成真实IP 比如`192.`开头,不然后端不通。
|
||||
|
||||
|
||||
- 下载项目
|
||||
|
||||
@@ -104,10 +108,9 @@ yarn build
|
||||
git clone https://github.com/jeecgboot/jeecgboot-vue3.git
|
||||
|
||||
cd jeecgboot-vue3
|
||||
|
||||
```
|
||||
- 修改后台域名
|
||||
.env.production
|
||||
|
||||
- 配置接口域名 `.env.production`
|
||||
|
||||
```bash
|
||||
VITE_GLOB_API_URL=/jeecgboot
|
||||
@@ -118,9 +121,9 @@ VITE_GLOB_DOMAIN_URL=http://jeecg-boot-system:8080/jeecg-boot
|
||||
- 编译项目
|
||||
|
||||
```bash
|
||||
yarn install
|
||||
pnpm install
|
||||
|
||||
yarn build
|
||||
pnpm build
|
||||
```
|
||||
|
||||
- 启动容器
|
||||
@@ -160,6 +163,42 @@ VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 入门必备
|
||||
|
||||
本项目需要一定前端基础知识,请确保掌握 Vue 的基础知识,以便能处理一些常见的问题。 建议在开发前先学一下以下内容,提前了解和学习这些知识,会对项目理解非常有帮助:
|
||||
|
||||
* [JeecgBoot-Vue3文档](http://vue3.jeecg.com)
|
||||
* [Vue3 文档](https://cn.vuejs.org/)
|
||||
* [Vben文档](https://doc.vvbin.cn)
|
||||
* [Ant-Design-Vue](https://www.antdv.com/docs/vue/introduce-cn/)
|
||||
* [TypeScript](https://www.typescriptlang.org/)
|
||||
* [Vue-router](https://router.vuejs.org/zh)
|
||||
* [Es6](https://es6.ruanyifeng.com/)
|
||||
* [Vitejs](https://cn.vitejs.dev/guide/)
|
||||
* [Pinia(vuex替代方案)](https://pinia.esm.dev/introduction.html)
|
||||
* [Vue-RFCS](https://github.com/vuejs/rfcs)
|
||||
* [Vue2 迁移到 3](https://v3.vuejs.org/guide/migration/introduction.html)
|
||||
* [vxetable文档](https://vxetable.cn)
|
||||
* [~~WindiCss~~](https://windicss.netlify.app/)
|
||||
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
**本地开发**推荐使用`Chrome 最新版`浏览器,**不支持**`Chrome 90`以下版本。
|
||||
|
||||
**生产环境**支持现代浏览器,不支持 IE。
|
||||
|
||||
| [](http://godban.github.io/browsers-support-badges/)IE | [](http://godban.github.io/browsers-support-badges/)Edge | [](http://godban.github.io/browsers-support-badges/)Firefox | [](http://godban.github.io/browsers-support-badges/)Chrome | [](http://godban.github.io/browsers-support-badges/)Safari |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
|
||||
|
||||
## 功能模块
|
||||
> vue3版本已经实现了系统管理、系统监控、报表、各种组件、前端权限、GUI代码生成、Online表单、Online报表等平台功能,完全可以用于生产环境。
|
||||
|
||||
@@ -269,11 +308,9 @@ VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999
|
||||
│ ├─Online在线表单 - 功能已开放
|
||||
│ ├─Online代码生成器 - 功能已开放
|
||||
│ ├─Online在线报表 - 功能已开放
|
||||
│ ├─Online在线图表(未开源)
|
||||
│ ├─Online图表模板配置(未开源)
|
||||
│ ├─Online布局设计(未开源)
|
||||
│ ├─多数据源管理 - 功能已开放
|
||||
│─流程模块功能 (未开源)
|
||||
│ ├─Online在线图表(暂未开源)
|
||||
│ ├─多数据源管理
|
||||
│─流程模块功能 (暂未开源)
|
||||
│ ├─流程设计器
|
||||
│ ├─表单设计器
|
||||
│ ├─大屏设计器
|
||||
@@ -287,18 +324,13 @@ VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999
|
||||
│ └─我发起的流程
|
||||
│ └─我的抄送
|
||||
│ └─流程委派、抄送、跳转
|
||||
│ └─。。。
|
||||
│─OA办公组件 (未开源)
|
||||
│ ├─更多功能
|
||||
│ └─。。。
|
||||
└─其他模块 (暂不开源)
|
||||
│ └─OA办公组件
|
||||
└─其他模块
|
||||
└─更多功能开发中。。
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## 系统效果
|
||||
系统后台
|
||||
|
||||
@@ -335,12 +367,6 @@ Online表单&Online报表&代码生成
|
||||

|
||||

|
||||
|
||||
报表设计
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
大屏模板
|
||||
@@ -353,32 +379,3 @@ Online表单&Online报表&代码生成
|
||||
|
||||
|
||||
|
||||
## 入门必备
|
||||
|
||||
本项目需要一定前端基础知识,请确保掌握 Vue 的基础知识,以便能处理一些常见的问题。 建议在开发前先学一下以下内容,提前了解和学习这些知识,会对项目理解非常有帮助:
|
||||
|
||||
* [Vue3 文档](https://v3.vuejs.org/)
|
||||
* [TypeScript](https://www.typescriptlang.org/)
|
||||
* [Vue-router](https://next.router.vuejs.org/)
|
||||
* [Ant-Design-Vue](https://2x.antdv.com/docs/vue/introduce-cn/)
|
||||
* [Vben文档](https://vvbin.cn/doc-next)
|
||||
* [Es6](https://es6.ruanyifeng.com/)
|
||||
* [Vitejs](https://vitejs.dev/)
|
||||
* [Pinia(vuex替代方案)](https://pinia.esm.dev/introduction.html)
|
||||
* [Vue-RFCS](https://github.com/vuejs/rfcs)
|
||||
* [Vue2 迁移到 3](https://v3.vuejs.org/guide/migration/introduction.html)
|
||||
* [~~WindiCss~~](https://windicss.netlify.app/)
|
||||
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
**本地开发**推荐使用`Chrome 最新版`浏览器,**不支持**`Chrome 80`以下版本。
|
||||
|
||||
**生产环境**支持现代浏览器,不支持 IE。
|
||||
|
||||
| [](http://godban.github.io/browsers-support-badges/)IE | [](http://godban.github.io/browsers-support-badges/)Edge | [](http://godban.github.io/browsers-support-badges/)Firefox | [](http://godban.github.io/browsers-support-badges/)Chrome | [](http://godban.github.io/browsers-support-badges/)Safari |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
|
||||
|
||||
|
@@ -1,21 +0,0 @@
|
||||
// TODO
|
||||
import type { GetManualChunk } from 'rollup';
|
||||
|
||||
//
|
||||
const vendorLibs: { match: string[]; output: string }[] = [
|
||||
// {
|
||||
// match: ['xlsx'],
|
||||
// output: 'xlsx',
|
||||
// },
|
||||
];
|
||||
|
||||
// @ts-ignore
|
||||
export const configManualChunk: GetManualChunk = (id: string) => {
|
||||
if (/[\\/]node_modules[\\/]/.test(id)) {
|
||||
const matchItem = vendorLibs.find((item) => {
|
||||
const reg = new RegExp(`[\\/]node_modules[\\/]_?(${item.match.join('|')})(.*)`, 'ig');
|
||||
return reg.test(id);
|
||||
});
|
||||
return matchItem ? matchItem.output : null;
|
||||
}
|
||||
};
|
@@ -1,25 +0,0 @@
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Temporarily solve the Vite circular dependency problem, and wait for a better solution to fix it later. I don't know what problems this writing will bring.
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export function configHmrPlugin(): Plugin {
|
||||
return {
|
||||
name: 'singleHMR',
|
||||
handleHotUpdate({ modules, file }) {
|
||||
if (file.match(/xml$/)) return [];
|
||||
|
||||
modules.forEach((m) => {
|
||||
if (!m.url.match(/\.(css|less)/)) {
|
||||
m.importedModules = new Set();
|
||||
m.importers = new Set();
|
||||
}
|
||||
});
|
||||
|
||||
return modules;
|
||||
},
|
||||
};
|
||||
}
|
@@ -15,6 +15,8 @@ import { configVisualizerConfig } from './visualizer';
|
||||
import { configThemePlugin } from './theme';
|
||||
import { configImageminPlugin } from './imagemin';
|
||||
import { configSvgIconsPlugin } from './svgSprite';
|
||||
import OptimizationPersist from 'vite-plugin-optimize-persist'
|
||||
import PkgConfig from 'vite-plugin-package-config'
|
||||
|
||||
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;
|
||||
@@ -71,5 +73,8 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||
vitePlugins.push(configPwaConfig(viteEnv));
|
||||
}
|
||||
|
||||
//vite-plugin-theme【解决vite首次打开界面加载慢问题】
|
||||
vitePlugins.push(PkgConfig());
|
||||
vitePlugins.push(OptimizationPersist());
|
||||
return vitePlugins;
|
||||
}
|
||||
|
@@ -5,9 +5,9 @@
|
||||
import { createStyleImportPlugin } from 'vite-plugin-style-import';
|
||||
|
||||
export function configStyleImportPlugin(_isBuild: boolean) {
|
||||
// if (!isBuild) {
|
||||
// return [];
|
||||
// }
|
||||
if (!_isBuild) {
|
||||
return [];
|
||||
}
|
||||
const styleImportPlugin = createStyleImportPlugin({
|
||||
libs: [
|
||||
{
|
||||
|
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import type { PluginOption } from 'vite';
|
||||
import path from 'path';
|
||||
import { viteThemePlugin, antdDarkThemePlugin, mixLighten, mixDarken, tinycolor } from 'vite-plugin-theme';
|
||||
import { viteThemePlugin, antdDarkThemePlugin, mixLighten, mixDarken, tinycolor } from '@rys-fe/vite-plugin-theme';
|
||||
import { getThemeColors, generateColors } from '../../config/themeConfig';
|
||||
import { generateModifyVars } from '../../generate/generateModifyVars';
|
||||
|
||||
|
@@ -1,16 +0,0 @@
|
||||
## 切换到 Vue3菜单路由
|
||||
|
||||
- 第一步:执行SQL脚本
|
||||
```
|
||||
alter table sys_permission rename as sys_permission_v2;
|
||||
alter table sys_permission_v3 rename as sys_permission;
|
||||
```
|
||||
|
||||
> 这个 sql 脚本做了什么?
|
||||
> - 1、把表名 sys_permission 备份改为 sys_permission_v2
|
||||
> - 2、把 sys_permission_v3 改为 sys_permission
|
||||
> 说明:因为 vue3 和 vue2 的菜单配置不一样,所以通过切换表来实现 vue3 和 vue2 的切换。
|
||||
|
||||
- 第二步:登录进系统
|
||||
|
||||
> 从 jeecgboot3.3.0 版本默认 vue3 和 vue2 的权限都已经分配好, 不需要再手工授权。
|
@@ -1,13 +1,13 @@
|
||||
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';
|
||||
|
||||
const modules = import.meta.globEager('./**/*.ts');
|
||||
const modules = import.meta.glob('./**/*.ts', { eager: true });
|
||||
|
||||
const mockModules: any[] = [];
|
||||
Object.keys(modules).forEach((key) => {
|
||||
if (key.includes('/_')) {
|
||||
return;
|
||||
}
|
||||
mockModules.push(...modules[key].default);
|
||||
mockModules.push(...(modules as Recordable)[key].default);
|
||||
});
|
||||
|
||||
/**
|
||||
|
41497
package-lock.json
generated
41497
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
39
package.json
39
package.json
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"name": "jeecgboot-vue3",
|
||||
"version": "3.4.2",
|
||||
"version": "3.4.4",
|
||||
"author": {
|
||||
"name": "jeecg",
|
||||
"email": "jeecgos@163.com",
|
||||
"url": "https://github.com/jeecgboot/jeecgboot-vue3"
|
||||
},
|
||||
"scripts": {
|
||||
"bootstrap": "yarn install",
|
||||
"bootstrap": "pnpm install",
|
||||
"serve": "npm run dev",
|
||||
"dev": "vite",
|
||||
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
|
||||
"clean:lib": "rimraf node_modules",
|
||||
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && esno ./build/script/postBuild.ts",
|
||||
"build:test": "cross-env vite build --mode test && esno ./build/script/postBuild.ts",
|
||||
"build:no-cache": "yarn clean:cache && npm run build",
|
||||
"build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test && esno ./build/script/postBuild.ts",
|
||||
"build:no-cache": "pnpm clean:cache && npm run build",
|
||||
"report": "cross-env REPORT=true npm run build",
|
||||
"type:check": "vue-tsc --noEmit --skipLibCheck",
|
||||
"preview": "npm run build && vite preview",
|
||||
"preview:dist": "vite preview",
|
||||
"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",
|
||||
"lint: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/",
|
||||
@@ -29,12 +29,12 @@
|
||||
"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 yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
|
||||
"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": {
|
||||
"@jeecg/online": "1.0.1",
|
||||
"@jeecg/online": "3.4.4-RC",
|
||||
"@iconify/iconify": "^2.2.1",
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
"@ant-design/icons-vue": "^6.1.0",
|
||||
@@ -45,7 +45,7 @@
|
||||
"@vueuse/shared": "^8.3.0",
|
||||
"@vueuse/core": "^8.3.0",
|
||||
"@zxcvbn-ts/core": "^2.0.1",
|
||||
"ant-design-vue": "3.2.12",
|
||||
"ant-design-vue": "^3.2.12",
|
||||
"axios": "^0.26.1",
|
||||
"china-area-data": "^5.0.1",
|
||||
"clipboard": "^2.0.8",
|
||||
@@ -59,10 +59,8 @@
|
||||
"emoji-mart-vue-fast": "^11.1.1",
|
||||
"enquire.js": "^2.1.6",
|
||||
"intro.js": "^5.1.0",
|
||||
"js-cookie": "^2.2.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.pick": "^4.4.0",
|
||||
"md5": "^2.3.0",
|
||||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
@@ -87,7 +85,7 @@
|
||||
"vue-types": "^4.1.1",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vxe-table": "4.1.0",
|
||||
"vxe-table-plugin-antd": "^3.0.5",
|
||||
"vxe-table-plugin-antd": "3.0.5",
|
||||
"xe-utils": "^3.3.1",
|
||||
"vue-json-pretty": "^2.0.6",
|
||||
"xss": "^1.0.13"
|
||||
@@ -113,8 +111,8 @@
|
||||
"@types/sortablejs": "^1.10.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.20.0",
|
||||
"@typescript-eslint/parser": "^5.20.0",
|
||||
"@vitejs/plugin-legacy": "^1.8.1",
|
||||
"@vitejs/plugin-vue": "^2.3.1",
|
||||
"@vitejs/plugin-legacy": "^2.0.0",
|
||||
"@vitejs/plugin-vue": "^3.0.1",
|
||||
"@vitejs/plugin-vue-jsx": "^1.3.10",
|
||||
"@vue/compiler-sfc": "^3.2.33",
|
||||
"@vue/test-utils": "^2.0.0-rc.21",
|
||||
@@ -159,28 +157,27 @@
|
||||
"ts-jest": "^27.0.7",
|
||||
"ts-node": "^10.7.0",
|
||||
"typescript": "^4.6.3",
|
||||
"vite": "^2.9.5",
|
||||
"vite": "^3.0.2",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"vite-plugin-imagemin": "^0.6.1",
|
||||
"vite-plugin-mkcert": "1.6.0",
|
||||
"vite-plugin-mkcert": "^1.10.1",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
"vite-plugin-optimize-persist": "^0.1.2",
|
||||
"vite-plugin-package-config": "^0.1.1",
|
||||
"vite-plugin-purge-icons": "^0.8.1",
|
||||
"vite-plugin-pwa": "^0.11.13",
|
||||
"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-theme": "^0.8.6",
|
||||
"@rys-fe/vite-plugin-theme": "^0.8.6",
|
||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||
"vite-plugin-windicss": "^1.8.4",
|
||||
"vite-plugin-windicss": "^1.8.7",
|
||||
"vue-eslint-parser": "^8.3.0",
|
||||
"vue-tsc": "^0.33.9"
|
||||
},
|
||||
"resolutions": {
|
||||
"//": "Used to install imagemin dependencies, because imagemin may not be installed in China. If it is abroad, you can delete it",
|
||||
"bin-wrapper": "npm:bin-wrapper-china",
|
||||
"rollup": "^2.56.3"
|
||||
"rollup": "^2.72.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
16279
pnpm-lock.yaml
generated
Normal file
16279
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/assets/images/link.png
Normal file
BIN
src/assets/images/link.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
@@ -120,7 +120,7 @@
|
||||
-webkit-transition: opacity 0.4s;
|
||||
transition: opacity 0.4s;
|
||||
|
||||
::v-deep(svg) {
|
||||
:deep(svg) {
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
@@ -113,15 +113,28 @@
|
||||
const getSchema = computed((): FormSchema[] => {
|
||||
const schemas: FormSchema[] = unref(schemaRef) || (unref(getProps).schemas as any);
|
||||
for (const schema of schemas) {
|
||||
const { defaultValue, component } = schema;
|
||||
const { defaultValue, component, componentProps } = schema;
|
||||
// handle date type
|
||||
if (defaultValue && dateItemType.includes(component)) {
|
||||
const { valueFormat } = componentProps
|
||||
if (!Array.isArray(defaultValue)) {
|
||||
schema.defaultValue = dateUtil(defaultValue);
|
||||
//update-begin---author:wangshuai ---date:20221124 for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
|
||||
if(valueFormat){
|
||||
schema.defaultValue = dateUtil(defaultValue).format(valueFormat);
|
||||
}else{
|
||||
schema.defaultValue = dateUtil(defaultValue);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20221124 for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
|
||||
} else {
|
||||
const def: dayjs.Dayjs[] = [];
|
||||
defaultValue.forEach((item) => {
|
||||
def.push(dateUtil(item));
|
||||
//update-begin---author:wangshuai ---date:20221124 for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
|
||||
if(valueFormat){
|
||||
def.push(dateUtil(item).format(valueFormat));
|
||||
}else{
|
||||
def.push(dateUtil(item));
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20221124 for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
|
||||
});
|
||||
schema.defaultValue = def;
|
||||
}
|
||||
@@ -322,7 +335,24 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*【美化表单】form的字体改小一号*/
|
||||
.ant-form-item-label > label{
|
||||
font-size: 13px;
|
||||
}
|
||||
.ant-form-item .ant-select {
|
||||
font-size: 13px;
|
||||
}
|
||||
.ant-select-item-option-selected {
|
||||
font-size: 13px;
|
||||
}
|
||||
.ant-select-item-option-content {
|
||||
font-size: 13px;
|
||||
}
|
||||
.ant-input {
|
||||
font-size: 13px;
|
||||
}
|
||||
/*【美化表单】form的字体改小一号*/
|
||||
|
||||
.ant-form-explain {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
@@ -58,6 +58,7 @@ import JSearchSelect from './jeecg/components/JSearchSelect.vue';
|
||||
import JAddInput from './jeecg/components/JAddInput.vue';
|
||||
import { Time } from '/@/components/Time';
|
||||
import JRangeNumber from './jeecg/components/JRangeNumber.vue';
|
||||
import JRangeDate from './jeecg/components/JRangeDate.vue'
|
||||
|
||||
const componentMap = new Map<ComponentType, Component>();
|
||||
|
||||
@@ -125,6 +126,7 @@ componentMap.set('JUpload', JUpload);
|
||||
componentMap.set('JSearchSelect', JSearchSelect);
|
||||
componentMap.set('JAddInput', JAddInput);
|
||||
componentMap.set('JRangeNumber', JRangeNumber);
|
||||
componentMap.set('RangeDate', JRangeDate);
|
||||
|
||||
export function add(compName: ComponentType, component: Component) {
|
||||
componentMap.set(compName, component);
|
||||
|
@@ -5,7 +5,8 @@
|
||||
<RadioGroup v-bind="attrs" v-model:value="state" button-style="solid">
|
||||
<template v-for="item in getOptions" :key="`${item.value}`">
|
||||
<RadioButton :value="item.value" :disabled="item.disabled">
|
||||
{{ item.label }}
|
||||
<Icon v-if="item.icon" :icon="item.icon" />
|
||||
{{ item.label ? item.label : '' }}
|
||||
</RadioButton>
|
||||
</template>
|
||||
</RadioGroup>
|
||||
@@ -16,8 +17,13 @@
|
||||
import { isString } from '/@/utils/is';
|
||||
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
|
||||
type OptionsItem = { label: string; value: string | number | boolean; disabled?: boolean };
|
||||
import { Icon } from '/@/components/Icon';
|
||||
type OptionsItem = {
|
||||
icon?: string;
|
||||
label?: string;
|
||||
value: string | number | boolean;
|
||||
disabled?: boolean;
|
||||
};
|
||||
type RadioItem = string | OptionsItem;
|
||||
|
||||
export default defineComponent({
|
||||
@@ -25,6 +31,7 @@
|
||||
components: {
|
||||
RadioGroup: Radio.Group,
|
||||
RadioButton: Radio.Button,
|
||||
Icon,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
|
@@ -6,6 +6,9 @@ import { ref, onUnmounted, unref, nextTick, watch } from 'vue';
|
||||
import { isProdMode } from '/@/utils/env';
|
||||
import { error } from '/@/utils/log';
|
||||
import { getDynamicProps, getValueType } from '/@/utils';
|
||||
import { add } from "/@/components/Form/src/componentMap";
|
||||
//集成online专用控件
|
||||
import { OnlineSelectCascade, LinkTableCard, LinkTableSelect } from '@jeecg/online';
|
||||
|
||||
export declare type ValidateFields = (nameList?: NamePath[]) => Promise<Recordable>;
|
||||
|
||||
@@ -15,6 +18,11 @@ export function useForm(props?: Props): UseFormReturnType {
|
||||
const formRef = ref<Nullable<FormActionType>>(null);
|
||||
const loadedRef = ref<Nullable<boolean>>(false);
|
||||
|
||||
//集成online专用控件
|
||||
add("OnlineSelectCascade", OnlineSelectCascade)
|
||||
add("LinkTableCard", LinkTableCard)
|
||||
add("LinkTableSelect", LinkTableSelect)
|
||||
|
||||
async function getForm() {
|
||||
const form = unref(formRef);
|
||||
if (!form) {
|
||||
@@ -89,7 +97,12 @@ export function useForm(props?: Props): UseFormReturnType {
|
||||
if(values){
|
||||
Object.keys(values).map(key=>{
|
||||
if (values[key] instanceof Array) {
|
||||
values[key] = values[key].join(',');
|
||||
// update-begin-author:sunjianlei date:20221205 for: 【issues/4330】判断如果是对象数组,则不拼接
|
||||
let isObject = typeof (values[key][0] || '') === 'object';
|
||||
if (!isObject) {
|
||||
values[key] = values[key].join(',');
|
||||
}
|
||||
// update-end-author:sunjianlei date:20221205 for: 【issues/4330】判断如果是对象数组,则不拼接
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -251,7 +251,11 @@ export function useFormEvents({
|
||||
const res = handleFormValues(values);
|
||||
emit('submit', res);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
//update-begin-author:taoyan date:2022-11-4 for: 列表查询表单会触发校验错误导致重置失败,原因不明
|
||||
emit('submit', {});
|
||||
console.error('query form validate error, please ignore!', error)
|
||||
//throw new Error(error);
|
||||
//update-end-author:taoyan date:2022-11-4 for: 列表查询表单会触发校验错误导致重置失败,原因不明
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@ export function useItemLabelWidth(schemaItemRef: Ref<FormSchema>, propsRef: Ref<
|
||||
const { labelCol = {}, wrapperCol = {} } = schemaItem.itemProps || {};
|
||||
const { labelWidth, disabledLabelWidth } = schemaItem;
|
||||
|
||||
const { labelWidth: globalLabelWidth, labelCol: globalLabelCol, wrapperCol: globWrapperCol } = unref(propsRef);
|
||||
const { labelWidth: globalLabelWidth, labelCol: globalLabelCol, wrapperCol: globWrapperCol,layout } = unref(propsRef);
|
||||
|
||||
// update-begin--author:sunjianlei---date:20211104---for: 禁用全局 labelWidth,不自动设置 textAlign --------
|
||||
if (disabledLabelWidth) {
|
||||
@@ -34,8 +34,11 @@ export function useItemLabelWidth(schemaItemRef: Ref<FormSchema>, propsRef: Ref<
|
||||
}
|
||||
|
||||
return {
|
||||
labelCol: { style: { width }, ...col },
|
||||
wrapperCol: { style: { width: `calc(100% - ${width})` }, ...wrapCol },
|
||||
labelCol: { style: { width: width ? width : '100%' }, ...col },
|
||||
wrapperCol: {
|
||||
style: { width: layout === 'vertical' ? '100%' : `calc(100% - ${width})` },
|
||||
...wrapCol,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@@ -58,8 +58,7 @@
|
||||
}
|
||||
|
||||
function handleChange(array, ...args) {
|
||||
emitData.value = args;
|
||||
console.info(emitData);
|
||||
// emitData.value = args;
|
||||
//update-begin-author:taoyan date:2022-6-27 for: VUEN-1424【vue3】树表、单表、jvxe、erp 、内嵌子表省市县 选择不上
|
||||
// 上面改的v-model:value导致选中数据没有显示
|
||||
state.value = array;
|
||||
|
@@ -1,24 +1,26 @@
|
||||
<template>
|
||||
<div class="area-select">
|
||||
<!--省份-->
|
||||
<a-select v-model:value="province" @change="proChange" allowClear :disabled="disabled">
|
||||
<template v-for="item in provinceOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">{{ item.label }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
<!--城市-->
|
||||
<a-select v-if="level >= 2" v-model:value="city" @change="cityChange" :disabled="disabled">
|
||||
<template v-for="item in cityOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">{{ item.label }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
<!--地区-->
|
||||
<a-select v-if="level >= 3" v-model:value="area" @change="areaChange" :disabled="disabled">
|
||||
<template v-for="item in areaOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">{{ item.label }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</div>
|
||||
<a-form-item-rest>
|
||||
<div class="area-select">
|
||||
<!--省份-->
|
||||
<a-select v-model:value="province" @change="proChange" allowClear :disabled="disabled">
|
||||
<template v-for="item in provinceOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">{{ item.label }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
<!--城市-->
|
||||
<a-select v-if="level >= 2" v-model:value="city" @change="cityChange" :disabled="disabled">
|
||||
<template v-for="item in cityOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">{{ item.label }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
<!--地区-->
|
||||
<a-select v-if="level >= 3" v-model:value="area" @change="areaChange" :disabled="disabled">
|
||||
<template v-for="item in areaOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">{{ item.label }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</div>
|
||||
</a-form-item-rest>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted, onUnmounted, toRefs } from 'vue';
|
||||
@@ -35,8 +37,17 @@
|
||||
area: [String],
|
||||
level: propTypes.number.def(3),
|
||||
disabled: propTypes.bool.def(false),
|
||||
codeField: propTypes.string,
|
||||
size: propTypes.string,
|
||||
placeholder: propTypes.string,
|
||||
formValues: propTypes.any,
|
||||
allowClear: propTypes.bool.def(false),
|
||||
getPopupContainer: {
|
||||
type: Function,
|
||||
default: (node) => node.parentNode,
|
||||
},
|
||||
},
|
||||
emits: ['change', 'update:value'],
|
||||
emits: ['change', 'update:value','update:area','update:city','update:province'],
|
||||
setup(props, { emit, refs }) {
|
||||
const emitData = ref<any[]>([]);
|
||||
//下拉框的选择值
|
||||
|
@@ -76,7 +76,8 @@
|
||||
console.info(props);
|
||||
const emitData = ref<any[]>([]);
|
||||
const treeData = ref<any[]>([]);
|
||||
const treeValue = ref('');
|
||||
const treeValue = ref();
|
||||
treeValue.value = '';
|
||||
const attrs = useAttrs();
|
||||
const [state] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
watch(
|
||||
@@ -118,7 +119,11 @@
|
||||
|
||||
function loadItemByCode() {
|
||||
if (!props.value || props.value == '0') {
|
||||
treeValue.value = [];
|
||||
if(props.multiple){
|
||||
treeValue.value = [];
|
||||
}else{
|
||||
treeValue.value = '';
|
||||
}
|
||||
} else {
|
||||
loadDictItem({ ids: props.value }).then((res) => {
|
||||
let values = props.value.split(',');
|
||||
@@ -127,6 +132,9 @@
|
||||
value: values[index],
|
||||
label: item,
|
||||
}));
|
||||
if(!props.multiple){
|
||||
treeValue.value = treeValue.value[0];
|
||||
}
|
||||
onLoadTriggleChange(res[0]);
|
||||
});
|
||||
}
|
||||
|
@@ -197,6 +197,15 @@
|
||||
});
|
||||
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
||||
|
||||
//update-begin-author:taoyan date:2022-10-18 for: VUEN-2480【严重bug】online vue3测试的问题 8、online js增强样式问题
|
||||
function refresh(){
|
||||
if(coder){
|
||||
coder.refresh();
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-10-18 for: VUEN-2480【严重bug】online vue3测试的问题 8、online js增强样式问题
|
||||
|
||||
return {
|
||||
state,
|
||||
textarea,
|
||||
@@ -206,6 +215,7 @@
|
||||
isFullScreen,
|
||||
fullScreenIcon,
|
||||
onToggleFullScreen,
|
||||
refresh
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -279,5 +289,10 @@
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/** VUEN-2344【vue3】这个样式有问题,是不是加个边框 */
|
||||
.CodeMirror{
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a-radio-group v-if="compType === CompTypeEnum.Radio" v-bind="attrs" v-model:value="state" @change="handleChange">
|
||||
<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}`">
|
||||
<a-radio :value="item.value">
|
||||
{{ item.label }}
|
||||
@@ -7,7 +7,13 @@
|
||||
</template>
|
||||
</a-radio-group>
|
||||
|
||||
<a-radio-group v-else-if="compType === CompTypeEnum.RadioButton" v-bind="attrs" v-model:value="state" buttonStyle="solid" @change="handleChange">
|
||||
<a-radio-group
|
||||
v-else-if="compType === CompTypeEnum.RadioButton"
|
||||
v-bind="attrs"
|
||||
v-model:value="state"
|
||||
buttonStyle="solid"
|
||||
@change="handleChangeRadio"
|
||||
>
|
||||
<template v-for="item in dictOptions" :key="`${item.value}`">
|
||||
<a-radio-button :value="item.value">
|
||||
{{ item.label }}
|
||||
@@ -44,7 +50,6 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted, nextTick } from 'vue';
|
||||
import { Form } from 'ant-design-vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import { initDictOptions } from '/@/utils/dict';
|
||||
@@ -78,11 +83,9 @@
|
||||
},
|
||||
emits: ['options-change', 'change'],
|
||||
setup(props, { emit, refs }) {
|
||||
const { onFieldChange } = Form.useInjectFormItemContext();
|
||||
const emitData = ref<any[]>([]);
|
||||
const dictOptions = ref<any[]>([]);
|
||||
const attrs = useAttrs();
|
||||
const [state] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
const [state, , , formItemContext] = useRuleFormItem(props, 'value', 'change');
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
||||
// 是否正在加载回显数据
|
||||
const loadingEcho = ref<boolean>(false);
|
||||
@@ -118,7 +121,7 @@
|
||||
() => {
|
||||
if (props.value === '') {
|
||||
emit('change', '');
|
||||
nextTick(() => onFieldChange());
|
||||
nextTick(() => formItemContext.onFieldChange());
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -142,14 +145,37 @@
|
||||
}
|
||||
|
||||
function handleChange(e) {
|
||||
emitData.value = [e?.target?.value || e];
|
||||
nextTick(() => onFieldChange());
|
||||
const { mode } = unref<Recordable>(getBindValue);
|
||||
// 兼容多选模式
|
||||
if (mode === 'multiple') {
|
||||
state.value = e?.target?.value ?? e;
|
||||
} else {
|
||||
state.value = [e?.target?.value ?? e];
|
||||
}
|
||||
// 过滤掉空值
|
||||
if (state.value == null || state.value === '') {
|
||||
state.value = [];
|
||||
}
|
||||
if (Array.isArray(state.value)) {
|
||||
state.value = state.value.filter((item) => item != null && item !== '');
|
||||
}
|
||||
//update-begin---author:wangshuai ---date:20221123 for:单选模式要改成字符串------------
|
||||
if(mode !== 'multiple' && state.value && state.value.length>0){
|
||||
state.value = state.value[0];
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20221123 for:单选模式要改成字符串--------------
|
||||
// nextTick(() => formItemContext.onFieldChange());
|
||||
}
|
||||
|
||||
/** 单选radio的值变化事件 */
|
||||
function handleChangeRadio(e) {
|
||||
state.value = e?.target?.value ?? e;
|
||||
}
|
||||
|
||||
/** 用于搜索下拉框中的内容 */
|
||||
function handleFilterOption(input, option) {
|
||||
// 在 label 中搜索
|
||||
let labelIf = option?.children[0]?.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
let labelIf = option.children()[0]?.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
if (labelIf) {
|
||||
return true;
|
||||
}
|
||||
@@ -166,6 +192,7 @@
|
||||
dictOptions,
|
||||
CompTypeEnum,
|
||||
handleChange,
|
||||
handleChangeRadio,
|
||||
handleFilterOption,
|
||||
};
|
||||
},
|
||||
|
@@ -14,6 +14,11 @@
|
||||
|
||||
.item {
|
||||
margin-top: 5px;
|
||||
font-size: 14px;
|
||||
|
||||
span {
|
||||
padding: 0 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.choice {
|
||||
|
@@ -24,12 +24,13 @@
|
||||
<InputNumber v-model:value="valueLoop.interval" v-bind="typeLoopAttrs" />
|
||||
<span> 日 </span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a-radio :value="TypeEnum.work" v-bind="beforeRadioAttrs">工作日</a-radio>
|
||||
<span> 本月 </span>
|
||||
<InputNumber v-model:value="valueWork" v-bind="typeWorkAttrs" />
|
||||
<span> 日,最近的工作日 </span>
|
||||
</div>
|
||||
<!-- 工作日暂不支持,会报错,先隐藏了 -->
|
||||
<!-- <div class="item">-->
|
||||
<!-- <a-radio :value="TypeEnum.work" v-bind="beforeRadioAttrs">工作日</a-radio>-->
|
||||
<!-- <span> 本月 </span>-->
|
||||
<!-- <InputNumber v-model:value="valueWork" v-bind="typeWorkAttrs" />-->
|
||||
<!-- <span> 日,最近的工作日 </span>-->
|
||||
<!-- </div>-->
|
||||
<div class="item">
|
||||
<a-radio :value="TypeEnum.last" v-bind="beforeRadioAttrs">最后一日</a-radio>
|
||||
</div>
|
||||
|
@@ -21,7 +21,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
<style lang="less">
|
||||
.jeecg-form-container-disabled {
|
||||
cursor: not-allowed;
|
||||
|
||||
@@ -42,6 +42,12 @@
|
||||
.ant-upload-list {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
fieldset[disabled]{
|
||||
.anticon-delete{
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.jeecg-form-container-disabled fieldset[disabled] .ant-upload-list {
|
||||
|
@@ -182,6 +182,9 @@
|
||||
if (file.status != 'uploading') {
|
||||
fileList.forEach((file) => {
|
||||
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);
|
||||
}
|
||||
});
|
||||
@@ -189,7 +192,7 @@
|
||||
handleDelete(file);
|
||||
}
|
||||
}
|
||||
emitData.value = fileUrls.join(',');
|
||||
// emitData.value = fileUrls.join(',');
|
||||
state.value = fileUrls.join(',');
|
||||
emit('update:value', fileUrls.join(','));
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
:groupId="uniqGroupId"
|
||||
:param="param"
|
||||
@ok="callBack"
|
||||
:getContainer="getContainer"
|
||||
></JPopupOnlReportModal>
|
||||
</div>
|
||||
</template>
|
||||
@@ -50,6 +51,7 @@
|
||||
groupId: propTypes.string.def(''),
|
||||
formElRef: propTypes.object,
|
||||
setFieldsValue: propTypes.func,
|
||||
getContainer: propTypes.func,
|
||||
fieldConfig: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
|
65
src/components/Form/src/jeecg/components/JRangeDate.vue
Normal file
65
src/components/Form/src/jeecg/components/JRangeDate.vue
Normal file
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<a-range-picker v-model:value="rangeValue" @change="handleChange" :show-time="datetime" :placeholder="placeholder" :valueFormat="valueFormat"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, watch, computed } from 'vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { Form } from 'ant-design-vue';
|
||||
|
||||
const placeholder = ['最小值', '最大值']
|
||||
/**
|
||||
* 用于范围查询
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: "JRangeDate",
|
||||
props:{
|
||||
value: propTypes.string.def(''),
|
||||
datetime: propTypes.bool.def(false),
|
||||
placeholder: propTypes.string.def(''),
|
||||
},
|
||||
emits:['change', 'update:value'],
|
||||
setup(props, {emit}){
|
||||
const rangeValue = ref([])
|
||||
const formItemContext = Form.useInjectFormItemContext();
|
||||
|
||||
watch(()=>props.value, (val)=>{
|
||||
if(val){
|
||||
rangeValue.value = val.split(',')
|
||||
}else{
|
||||
rangeValue.value = []
|
||||
}
|
||||
}, {immediate: true});
|
||||
|
||||
const valueFormat = computed(()=>{
|
||||
if(props.datetime === true){
|
||||
return 'YYYY-MM-DD HH:mm:ss'
|
||||
}else{
|
||||
return 'YYYY-MM-DD'
|
||||
}
|
||||
});
|
||||
|
||||
function handleChange(arr){
|
||||
let str = ''
|
||||
if(arr && arr.length>0){
|
||||
if(arr[1] && arr[0]){
|
||||
str = arr.join(',')
|
||||
}
|
||||
}
|
||||
emit('change', str);
|
||||
emit('update:value', str);
|
||||
formItemContext.onFieldChange();
|
||||
}
|
||||
return {
|
||||
rangeValue,
|
||||
placeholder,
|
||||
valueFormat,
|
||||
handleChange
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<a-input-group>
|
||||
<a-input :value="beginValue" style="width: calc(50% - 15px)" placeholder="请输入最小值" @change="handleChangeBegin" />
|
||||
<a-input :value="beginValue" style="width: calc(50% - 15px)" placeholder="最小值" @change="handleChangeBegin" />
|
||||
<a-input style="width: 30px; border-left: 0; pointer-events: none; background-color: #fff" placeholder="~" disabled />
|
||||
<a-input :value="endValue" style="width: calc(50% - 15px); border-left: 0" placeholder="请输入最大值" @change="handleChangeEnd" />
|
||||
<a-input :value="endValue" style="width: calc(50% - 15px); border-left: 0" placeholder="最大值" @change="handleChangeEnd" />
|
||||
</a-input-group>
|
||||
</template>
|
||||
|
||||
@@ -11,19 +11,20 @@
|
||||
* 查询条件用-数值范围查询
|
||||
*/
|
||||
import { ref, watch } from 'vue';
|
||||
import { Form } from 'ant-design-vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
|
||||
export default {
|
||||
name: 'JRangeNumber',
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: ['', ''],
|
||||
},
|
||||
value: propTypes.oneOfType([propTypes.string, propTypes.array]),
|
||||
},
|
||||
emits: ['change'],
|
||||
emits: ['change', 'update:value'],
|
||||
setup(props, { emit }) {
|
||||
const beginValue = ref('');
|
||||
const endValue = ref('');
|
||||
|
||||
const formItemContext = Form.useInjectFormItemContext();
|
||||
|
||||
function handleChangeBegin(e) {
|
||||
beginValue.value = e.target.value;
|
||||
emitArray();
|
||||
@@ -41,19 +42,21 @@
|
||||
arr.push(begin);
|
||||
arr.push(end);
|
||||
emit('change', arr);
|
||||
emit('update:value', arr);
|
||||
formItemContext.onFieldChange();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(val) => {
|
||||
if (val.length == 2) {
|
||||
if (val && val.length == 2) {
|
||||
beginValue.value = val[0];
|
||||
endValue.value = val[1];
|
||||
} else {
|
||||
beginValue.value = '';
|
||||
endValue.value = '';
|
||||
}
|
||||
}
|
||||
}, {immediate: true}
|
||||
);
|
||||
|
||||
return {
|
||||
|
@@ -260,7 +260,17 @@
|
||||
* 过滤选中option
|
||||
*/
|
||||
function filterOption(input, option) {
|
||||
return option?.children[0]?.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
//update-begin-author:taoyan date:2022-11-8 for: issues/218 所有功能表单的下拉搜索框搜索无效
|
||||
let value = '', label = '';
|
||||
try {
|
||||
value = option.value;
|
||||
label = option.children()[0].children;
|
||||
}catch (e) {
|
||||
console.log('获取下拉项失败', e)
|
||||
}
|
||||
let str = input.toLowerCase();
|
||||
return value.toLowerCase().indexOf(str) >= 0 || label.toLowerCase().indexOf(str) >= 0;
|
||||
//update-end-author:taoyan date:2022-11-8 for: issues/218 所有功能表单的下拉搜索框搜索无效
|
||||
}
|
||||
|
||||
function getParentContainer(node) {
|
||||
|
@@ -150,7 +150,7 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.ant-select-search__field) {
|
||||
:deep(.ant-select-search__field) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
@@ -146,7 +146,7 @@
|
||||
|
||||
//update-begin-author:taoyan date:2022-5-31 for: VUEN-1145 下拉多选,搜索时,查不到数据
|
||||
function filterOption(input, option) {
|
||||
return option.children[0].el.data.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
return option.children()[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
}
|
||||
//update-end-author:taoyan date:2022-5-31 for: VUEN-1145 下拉多选,搜索时,查不到数据
|
||||
|
||||
|
@@ -142,7 +142,7 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.ant-select-search__field) {
|
||||
:deep(.ant-select-search__field) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
@@ -147,7 +147,7 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.ant-select-search__field) {
|
||||
:deep(.ant-select-search__field) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
@@ -150,7 +150,7 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.ant-select-search__field) {
|
||||
:deep(.ant-select-search__field) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
@@ -146,7 +146,7 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.ant-select-search__field) {
|
||||
:deep(.ant-select-search__field) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<div :class="prefixCls">
|
||||
<a-select
|
||||
v-if="query"
|
||||
v-model:value="value"
|
||||
v-model:value="state"
|
||||
:options="selectOptions"
|
||||
:disabled="disabled"
|
||||
style="width: 100%"
|
||||
@@ -18,7 +18,7 @@
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
||||
const { prefixCls } = useDesign('j-switch');
|
||||
const props = defineProps({
|
||||
// v-model:value
|
||||
@@ -36,7 +36,7 @@
|
||||
const emit = defineEmits(['change', 'update:value']);
|
||||
|
||||
const checked = ref<boolean>(false);
|
||||
|
||||
const [state] = useRuleFormItem(props, 'value', 'change');
|
||||
watch(
|
||||
() => props.value,
|
||||
(val) => {
|
||||
|
@@ -48,6 +48,10 @@
|
||||
multiple: propTypes.bool.def(false),
|
||||
loadTriggleChange: propTypes.bool.def(false),
|
||||
reload: propTypes.number.def(1),
|
||||
//update-begin-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
|
||||
url: propTypes.string.def(''),
|
||||
params: propTypes.object.def({})
|
||||
//update-end-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
|
||||
});
|
||||
const attrs = useAttrs();
|
||||
const emit = defineEmits(['change', 'update:value']);
|
||||
@@ -103,17 +107,23 @@
|
||||
treeValue.value = null;
|
||||
}
|
||||
} else {
|
||||
let params = { key: props.value };
|
||||
let result = await defHttp.get({ url: `${Api.view}${props.dict}`, params }, { isTransformResponse: false });
|
||||
if (result.success) {
|
||||
let values = props.value.split(',');
|
||||
treeValue.value = result.result.map((item, index) => ({
|
||||
key: values[index],
|
||||
value: values[index],
|
||||
label: item,
|
||||
}));
|
||||
onLoadTriggleChange(result.result[0]);
|
||||
//update-begin-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
|
||||
if(props.url){
|
||||
getItemFromTreeData();
|
||||
}else{
|
||||
let params = { key: props.value };
|
||||
let result = await defHttp.get({ url: `${Api.view}${props.dict}`, params }, { isTransformResponse: false });
|
||||
if (result.success) {
|
||||
let values = props.value.split(',');
|
||||
treeValue.value = result.result.map((item, index) => ({
|
||||
key: values[index],
|
||||
value: values[index],
|
||||
label: item,
|
||||
}));
|
||||
onLoadTriggleChange(result.result[0]);
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +177,9 @@
|
||||
if (treeNode.dataRef.children) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if(props.url){
|
||||
return Promise.resolve();
|
||||
}
|
||||
let pid = treeNode.dataRef.key;
|
||||
let params = {
|
||||
pid: pid,
|
||||
@@ -262,6 +275,67 @@
|
||||
});
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
|
||||
watch(()=>props.url, async (val)=>{
|
||||
if(val){
|
||||
await loadRootByUrl();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 根据自定义的请求地址加载数据
|
||||
*/
|
||||
async function loadRootByUrl(){
|
||||
let url = props.url;
|
||||
let params = props.params;
|
||||
let res = await defHttp.get({ url, params }, { isTransformResponse: false });
|
||||
if (res.success && res.result) {
|
||||
for (let i of res.result) {
|
||||
i.key = i.value;
|
||||
i.isLeaf = !!i.leaf;
|
||||
}
|
||||
treeData.value = [...res.result];
|
||||
} else {
|
||||
console.log('数根节点查询结果异常', res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据已有的树数据 翻译选项
|
||||
*/
|
||||
function getItemFromTreeData(){
|
||||
let data = treeData.value;
|
||||
let arr = []
|
||||
findChildrenNode(data, arr);
|
||||
if(arr.length>0){
|
||||
treeValue.value = arr
|
||||
onLoadTriggleChange(arr[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归找子节点
|
||||
* @param data
|
||||
* @param arr
|
||||
*/
|
||||
function findChildrenNode(data, arr){
|
||||
let val = props.value;
|
||||
if(data && data.length){
|
||||
for(let item of data){
|
||||
if(val===item.value){
|
||||
arr.push({
|
||||
key: item.key,
|
||||
value: item.value,
|
||||
label: item.label||item.title
|
||||
})
|
||||
}else{
|
||||
findChildrenNode(item.children, arr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
|
||||
|
||||
// onCreated
|
||||
validateProp().then(() => {
|
||||
initDictInfo();
|
||||
|
@@ -6,8 +6,8 @@
|
||||
:action="uploadUrl"
|
||||
:fileList="fileList"
|
||||
:disabled="disabled"
|
||||
:remove="onRemove"
|
||||
v-bind="bindProps"
|
||||
@remove="onRemove"
|
||||
@change="onFileChange"
|
||||
@preview="onFilePreview"
|
||||
>
|
||||
@@ -291,6 +291,8 @@
|
||||
fileSize: item.size,
|
||||
};
|
||||
newFileList.push(fileJson);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
emitValue(newFileList);
|
||||
|
@@ -115,7 +115,7 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.ant-select-search__field) {
|
||||
:deep(.ant-select-search__field) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
@@ -84,7 +84,7 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.ant-select-search__field) {
|
||||
:deep(.ant-select-search__field) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@
|
||||
import { treeProps } from '/@/components/Form/src/jeecg/props/props';
|
||||
import { BasicTree, TreeActionType } from '/@/components/Tree';
|
||||
import { useTreeBiz } from '/@/components/Form/src/jeecg/hooks/useTreeBiz';
|
||||
import {propTypes} from "/@/utils/propTypes";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DeptSelectModal',
|
||||
@@ -52,6 +53,7 @@
|
||||
type: String,
|
||||
default: '部门选择',
|
||||
},
|
||||
value: propTypes.oneOfType([propTypes.string, propTypes.array])
|
||||
},
|
||||
emits: ['register', 'getSelectResult'],
|
||||
setup(props, { emit, refs }) {
|
||||
@@ -59,7 +61,12 @@
|
||||
const [register, { closeModal }] = useModalInner();
|
||||
const attrs = useAttrs();
|
||||
const treeRef = ref<Nullable<TreeActionType>>(null);
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
||||
|
||||
//update-begin-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
|
||||
let propValue = props.value === ''?[]:props.value;
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs), {value: propValue});
|
||||
//update-end-author:taoyan date:2022-10-28 for: 部门选择警告类型不匹配
|
||||
|
||||
const queryUrl = getQueryUrl();
|
||||
const [{ visibleChange, checkedKeys, getCheckStrictly, getSelectTreeData, onCheck, onLoadData, treeData, checkALL, expandAll, onSelect }] =
|
||||
useTreeBiz(treeRef, queryUrl, getBindValue);
|
||||
|
@@ -68,6 +68,10 @@ export function useSelectBiz(getList, props) {
|
||||
columnWidth: 20,
|
||||
selectedRowKeys: checkedKeys,
|
||||
onChange: onSelectChange,
|
||||
//update-begin-author:wangshuai---date:20221102--for: [VUEN-2562]用户选择,跨页选择后,只有当前页人员 ---
|
||||
//table4.4.0新增属性选中之后是否清空上一页下一页的数据,默认false
|
||||
preserveSelectedRowKeys:true,
|
||||
//update-end-author:wangshuai---date:20221102--for: [VUEN-2562]用户选择,跨页选择后,只有当前页人员 ---
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -89,7 +89,8 @@ export function useTreeBiz(treeRef, getList, props) {
|
||||
if (info.checked) {
|
||||
//update-begin-author:taoyan date:20220408 for: 单选模式下,设定rowKey,无法选中数据-
|
||||
checkedKeys.value = [info.node.eventKey];
|
||||
let temp = info.checkedNodes.find((n) => n.key === info.node.eventKey);
|
||||
let rowKey = props.rowKey;
|
||||
let temp = info.checkedNodes.find((n) => n[rowKey] === info.node.eventKey);
|
||||
selectRows.value = [temp];
|
||||
//update-end-author:taoyan date:20220408 for: 单选模式下,设定rowKey,无法选中数据-
|
||||
} else {
|
||||
|
@@ -141,4 +141,6 @@ export type ComponentType =
|
||||
| 'JSearchSelect'
|
||||
| 'JAddInput'
|
||||
| 'Time'
|
||||
| 'RangeDate'
|
||||
| 'RangeNumber'
|
||||
| 'JRangeNumber';
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -22,4 +22,6 @@ export async function registerJVxeCustom() {
|
||||
await registerAsyncComponent(JVxeTypes.userSelect, import('./src/components/JVxeUserSelectCell.vue'));
|
||||
// 注册【部门选择】组件
|
||||
await registerAsyncComponent(JVxeTypes.departSelect, import('./src/components/JVxeDepartSelectCell.vue'));
|
||||
// 注册【省市区选择】组件
|
||||
await registerAsyncComponent(JVxeTypes.pca, import('./src/components/JVxePcaCell.vue'));
|
||||
}
|
||||
|
77
src/components/JVxeCustom/src/components/JVxePcaCell.vue
Normal file
77
src/components/JVxeCustom/src/components/JVxePcaCell.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<a-cascader v-bind="getProps" class="pca-select" @change="handleChange" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { regionData, getRealCode } from '/@/components/Form/src/utils/areaDataUtil';
|
||||
import { JVxeComponent } from '/@/components/jeecg/JVxeTable/types';
|
||||
import { useJVxeComponent, useJVxeCompProps } from '/@/components/jeecg/JVxeTable/hooks';
|
||||
import { dispatchEvent } from '/@/components/jeecg/JVxeTable/utils';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'JVxePcaCell',
|
||||
props: useJVxeCompProps(),
|
||||
setup(props: JVxeComponent.Props) {
|
||||
const { innerValue, cellProps, handleChangeCommon } = useJVxeComponent(props);
|
||||
|
||||
const selectedValue = computed(() => {
|
||||
let val: any = innerValue.value;
|
||||
if (!val) {
|
||||
return []
|
||||
}
|
||||
let arr = getRealCode(val, 3);
|
||||
return arr;
|
||||
});
|
||||
|
||||
const getProps = computed(() => {
|
||||
return {
|
||||
...cellProps.value,
|
||||
options: regionData,
|
||||
showOverflow: false,
|
||||
value: selectedValue.value,
|
||||
};
|
||||
});
|
||||
|
||||
function handleChange(arr) {
|
||||
let str = '';
|
||||
if(arr && arr.length==3){
|
||||
str = arr[2];
|
||||
}
|
||||
handleChangeCommon(str);
|
||||
}
|
||||
|
||||
return {
|
||||
handleChange,
|
||||
selectedValue,
|
||||
getProps
|
||||
};
|
||||
},
|
||||
// 【组件增强】注释详见:JVxeComponent.Enhanced
|
||||
enhanced: {
|
||||
switches: {
|
||||
visible: true,
|
||||
},
|
||||
translate: {
|
||||
enabled: false,
|
||||
},
|
||||
aopEvents: {
|
||||
editActived({ $event }) {
|
||||
dispatchEvent({
|
||||
$event,
|
||||
props: this.props,
|
||||
className: '.ant-select .ant-select-selection-search-input',
|
||||
isClick: true,
|
||||
});
|
||||
},
|
||||
},
|
||||
} as JVxeComponent.EnhancedPartial,
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
.pca-select{
|
||||
.ant-select-selection-placeholder{
|
||||
color: #bfbfbf !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -42,7 +42,8 @@ export const DictSearchInputCell = defineComponent({
|
||||
// 筛选函数
|
||||
const filterOption = computed(() => {
|
||||
if (isAsync.value) {
|
||||
return null;
|
||||
//【jeecgboot-vue3/issues/I5QRT8】JVxeTypes.selectDictSearch sync问题
|
||||
return ()=>true;
|
||||
}
|
||||
return (input, option) => option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
});
|
||||
|
@@ -15,6 +15,7 @@
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { Menu } from 'ant-design-vue';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { checkChildrenHidden } from '/@/utils/common/compUtils';
|
||||
import { itemProps } from '../props';
|
||||
import BasicMenuItem from './BasicMenuItem.vue';
|
||||
import MenuItemContent from './MenuItemContent.vue';
|
||||
@@ -38,11 +39,13 @@
|
||||
Reflect.has(menuTreeItem, 'children') &&
|
||||
!!menuTreeItem.children &&
|
||||
menuTreeItem.children.length > 0
|
||||
&&checkChildrenHidden(menuTreeItem)
|
||||
);
|
||||
}
|
||||
return {
|
||||
prefixCls,
|
||||
menuHasChildren,
|
||||
checkChildrenHidden,
|
||||
getShowMenu,
|
||||
};
|
||||
},
|
||||
|
@@ -17,7 +17,7 @@
|
||||
</template>
|
||||
|
||||
<!-- update-begin-author:taoyan date:2022-7-18 for: modal弹窗 支持评论 slot -->
|
||||
<a-row v-if="getProps.enableComment" class="jeecg-modal-wrapper">
|
||||
<a-row class="jeecg-modal-wrapper">
|
||||
<a-col :span="24-commentSpan" class="jeecg-modal-content">
|
||||
<ModalWrapper
|
||||
:useWrapper="getProps.useWrapper"
|
||||
@@ -36,31 +36,14 @@
|
||||
<slot></slot>
|
||||
</ModalWrapper>
|
||||
</a-col>
|
||||
|
||||
|
||||
<a-col :span="commentSpan" class="jeecg-comment-outer">
|
||||
<slot name="comment"></slot>
|
||||
</a-col>
|
||||
|
||||
|
||||
</a-row>
|
||||
<ModalWrapper
|
||||
v-else
|
||||
:useWrapper="getProps.useWrapper"
|
||||
:footerOffset="wrapperFooterOffset"
|
||||
:fullScreen="fullScreenRef"
|
||||
ref="modalWrapperRef"
|
||||
:loading="getProps.loading"
|
||||
:loading-tip="getProps.loadingTip"
|
||||
:minHeight="getProps.minHeight"
|
||||
:height="getWrapperHeight"
|
||||
:visible="visibleRef"
|
||||
:modalFooterHeight="footer !== undefined && !footer ? 0 : undefined"
|
||||
v-bind="omit(getProps.wrapperProps, 'visible', 'height', 'modalFooterHeight')"
|
||||
@ext-height="handleExtHeight"
|
||||
@height-change="handleHeightChange">
|
||||
<slot></slot>
|
||||
</ModalWrapper>
|
||||
<!-- update-end-author:taoyan date:2022-7-18 for: modal弹窗 支持评论 slot -->
|
||||
|
||||
|
||||
<template #[item]="data" v-for="item in Object.keys(omit($slots, 'default'))">
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
@@ -282,4 +265,4 @@
|
||||
.jeecg-modal-content {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</style>
|
@@ -122,8 +122,8 @@
|
||||
if (isUrl(key)) {
|
||||
// update-begin--author:sunjianlei---date:20220408---for: 【VUEN-656】配置外部网址打不开,原因是带了#号,需要替换一下
|
||||
let url = key.replace(URL_HASH_TAB, '#');
|
||||
openWindow(url);
|
||||
// openWindow(key);
|
||||
window.open(url)
|
||||
//openWindow(url);
|
||||
// update-begin--author:sunjianlei---date:20220408---for: 【VUEN-656】配置外部网址打不开,原因是带了#号,需要替换一下
|
||||
return;
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import Icon from '/@/components/Icon/index';
|
||||
|
||||
import { checkChildrenHidden } from '/@/utils/common/compUtils';
|
||||
import MenuItem from './components/MenuItem.vue';
|
||||
import SubMenu from './components/SubMenuItem.vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
@@ -79,18 +79,20 @@
|
||||
];
|
||||
});
|
||||
|
||||
function menuHasChildren(menuTreeItem: Menu): boolean {
|
||||
function menuHasChildren(menuTreeItem): boolean {
|
||||
return (
|
||||
!menuTreeItem.meta?.hideChildrenInMenu &&
|
||||
Reflect.has(menuTreeItem, 'children') &&
|
||||
!!menuTreeItem.children &&
|
||||
menuTreeItem.children.length > 0
|
||||
&&checkChildrenHidden(menuTreeItem)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
prefixCls,
|
||||
menuHasChildren,
|
||||
checkChildrenHidden,
|
||||
getShowMenu,
|
||||
getIcon,
|
||||
getI18nName,
|
||||
|
@@ -17,7 +17,7 @@
|
||||
<!-- antd v3 升级兼容,阻止数据的收集,防止控制台报错 -->
|
||||
<!-- https://antdv.com/docs/vue/migration-v3-cn -->
|
||||
<a-form-item-rest>
|
||||
<Table ref="tableElRef" v-bind="getBindValues" :rowClassName="getRowClassName" v-show="getEmptyDataIsShowTable" @change="handleTableChange">
|
||||
<Table ref="tableElRef" v-bind="getBindValues" :rowClassName="getRowClassName" v-show="getEmptyDataIsShowTable" @resizeColumn="handleResizeColumn" @change="handleTableChange">
|
||||
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
@@ -289,6 +289,9 @@
|
||||
wrapRef,
|
||||
tableAction,
|
||||
redoHeight,
|
||||
handleResizeColumn: (w, col) => {
|
||||
col.width = w;
|
||||
},
|
||||
getFormProps: getFormProps as any,
|
||||
replaceFormSlotKey,
|
||||
getFormSlotKeys,
|
||||
@@ -406,8 +409,8 @@
|
||||
//表格选择工具栏样式
|
||||
.alert {
|
||||
height: 38px;
|
||||
background-color: #f3f3f3;
|
||||
border-color: #e3e3e3;
|
||||
background-color: #e6f7ff;
|
||||
border-color: #91d5ff;
|
||||
}
|
||||
&--inset {
|
||||
.ant-table-wrapper {
|
||||
|
@@ -149,7 +149,10 @@
|
||||
.@{prefix-cls} {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
/* update-begin-author:taoyan date:2022-11-18 for: 表格默认行高比官方示例多出2px*/
|
||||
height: 22px;
|
||||
/* update-end-author:taoyan date:2022-11-18 for: 表格默认行高比官方示例多出2px*/
|
||||
|
||||
.action-divider {
|
||||
display: table;
|
||||
}
|
||||
|
@@ -28,7 +28,10 @@
|
||||
<a-alert type="info" show-icon class="alert" v-if="openRowSelection != null">
|
||||
<template #message>
|
||||
<template v-if="selectRowKeys.length > 0">
|
||||
<span>已选中 {{ selectRowKeys.length }} 条记录(可跨页)</span>
|
||||
<span>
|
||||
<span>已选中 {{ selectRowKeys.length }} 条记录</span>
|
||||
<span v-if="isAcrossPage">(可跨页)</span>
|
||||
</span>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="setSelectedRowKeys([])">清空</a>
|
||||
<slot name="alertAfter" />
|
||||
@@ -86,8 +89,10 @@
|
||||
const { getSelectRowKeys, setSelectedRowKeys, getRowSelection } = useTableContext();
|
||||
const selectRowKeys = computed(() => getSelectRowKeys());
|
||||
const openRowSelection = computed(() => getRowSelection());
|
||||
// 是否允许跨页选择
|
||||
const isAcrossPage = computed(() => openRowSelection.value?.preserveSelectedRowKeys === true);
|
||||
|
||||
return { prefixCls, handleColumnChange, selectRowKeys, setSelectedRowKeys, openRowSelection };
|
||||
return { prefixCls, handleColumnChange, selectRowKeys, setSelectedRowKeys, openRowSelection, isAcrossPage };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@@ -142,8 +142,10 @@
|
||||
setup(props, { emit, attrs }) {
|
||||
const { t } = useI18n();
|
||||
const table = useTableContext();
|
||||
const popoverVisible = ref(false);
|
||||
|
||||
const popoverVisible = ref(true);
|
||||
// update-begin--author:sunjianlei---date:20221101---for: 修复第一次进入时列表配置不能拖拽
|
||||
nextTick(() => popoverVisible.value = false);
|
||||
// update-end--author:sunjianlei---date:20221101---for: 修复第一次进入时列表配置不能拖拽
|
||||
const defaultRowSelection = omit(table.getRowSelection(), 'selectedRowKeys');
|
||||
let inited = false;
|
||||
|
||||
|
@@ -172,11 +172,11 @@ export function useDataSource(
|
||||
}
|
||||
|
||||
function insertTableDataRecord(record: Recordable, index: number): Recordable | undefined {
|
||||
if (!dataSourceRef.value || dataSourceRef.value.length == 0) return;
|
||||
//【issues/136】同步Vben:BasicTable 调用插入函数异常插入两条记录]
|
||||
// if (!dataSourceRef.value || dataSourceRef.value.length == 0) return;
|
||||
index = index ?? dataSourceRef.value?.length;
|
||||
unref(dataSourceRef).splice(index, 0, record);
|
||||
unref(propsRef).dataSource?.splice(index, 0, record);
|
||||
return unref(propsRef).dataSource;
|
||||
return unref(dataSourceRef);
|
||||
}
|
||||
function findTableDataRecord(rowKey: string | number) {
|
||||
if (!dataSourceRef.value || dataSourceRef.value.length == 0) return;
|
||||
|
@@ -16,6 +16,10 @@ export function useRowSelection(propsRef: ComputedRef<BasicTableProps>, tableDat
|
||||
}
|
||||
|
||||
return {
|
||||
// AntDV3.0 之后使用远程加载数据进行分页时,
|
||||
// 默认会清空上一页选择的行数据(导致无法跨页选择),
|
||||
// 将此属性设置为 true 即可解决。
|
||||
preserveSelectedRowKeys: true,
|
||||
selectedRowKeys: unref(selectedRowKeysRef),
|
||||
onChange: (selectedRowKeys: string[]) => {
|
||||
setSelectedRowKeys(selectedRowKeys);
|
||||
|
@@ -61,9 +61,15 @@ export function useTable(tableProps?: Props): [
|
||||
}
|
||||
return table as TableActionType;
|
||||
}
|
||||
|
||||
function getTableRef(){
|
||||
return tableRef;
|
||||
}
|
||||
|
||||
const methods: TableActionType & {
|
||||
getForm: () => FormActionType;
|
||||
} & {
|
||||
getTableRef: () => any;
|
||||
} = {
|
||||
reload: async (opt?: FetchParams) => {
|
||||
return await getTableInstance().reload(opt);
|
||||
@@ -153,6 +159,9 @@ export function useTable(tableProps?: Props): [
|
||||
collapseAll: () => {
|
||||
getTableInstance().collapseAll();
|
||||
},
|
||||
getTableRef: () => {
|
||||
return getTableRef();
|
||||
}
|
||||
};
|
||||
|
||||
return [register, methods];
|
||||
|
@@ -20,7 +20,7 @@ export const basicProps = {
|
||||
},
|
||||
showTableSetting: propTypes.bool,
|
||||
autoCreateKey: propTypes.bool.def(true),
|
||||
striped: propTypes.bool.def(true),
|
||||
striped: propTypes.bool.def(false),
|
||||
showSummary: propTypes.bool,
|
||||
summaryFunc: {
|
||||
type: [Function, Array] as PropType<(...arg: any[]) => any[]>,
|
||||
|
@@ -447,6 +447,8 @@ export interface BasicColumn extends ColumnProps {
|
||||
auth?: RoleEnum | RoleEnum[] | string | string[];
|
||||
// 业务控制是否显示
|
||||
ifShow?: boolean | ((column: BasicColumn) => boolean);
|
||||
//compType-用于记录类型
|
||||
compType?: string;
|
||||
}
|
||||
|
||||
export type ColumnChangeParam = {
|
||||
|
@@ -59,7 +59,8 @@
|
||||
const collapsed = ref(true);
|
||||
// 配置的按钮
|
||||
const btns = computed(() => {
|
||||
let btns = props.toolbarConfig?.btn || ['add', 'remove', 'clearSelection'];
|
||||
let { btn, btns } = props.toolbarConfig || {};
|
||||
btns = btn || btns || ['add', 'remove', 'clearSelection'];
|
||||
// 排除掉没有授权的按钮
|
||||
return btns.filter((btn) => {
|
||||
// 系统默认的批量删除编码配置为 batch_delete 此处需要兼容一下
|
||||
|
@@ -45,7 +45,7 @@
|
||||
<style scoped lang="less">
|
||||
// 关闭进度条的动画,防止滚动时动态赋值出现问题
|
||||
.j-vxe-progress.no-animation {
|
||||
::v-deep(.ant-progress-bg) {
|
||||
:deep(.ant-progress-bg) {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
@@ -39,6 +39,11 @@ export function useDragSort(props: JVxeTableProps, methods: JVxeTableMethods) {
|
||||
if (oldIndex === newIndex) {
|
||||
return;
|
||||
}
|
||||
// 【VUEN-2505】获取当前行数据
|
||||
let rowNode = xTable.getRowNode(e.item);
|
||||
if (!rowNode) {
|
||||
return;
|
||||
}
|
||||
let from = e.from;
|
||||
let element = startChildren[oldIndex];
|
||||
let target = null;
|
||||
@@ -54,6 +59,12 @@ export function useDragSort(props: JVxeTableProps, methods: JVxeTableMethods) {
|
||||
from.removeChild(element);
|
||||
from.insertBefore(element, target);
|
||||
nextTick(() => {
|
||||
// 【VUEN-2505】算出因虚拟滚动导致的偏移量
|
||||
let diffIndex = rowNode!.index - oldIndex;
|
||||
if (diffIndex > 0) {
|
||||
oldIndex = oldIndex + diffIndex;
|
||||
newIndex = newIndex + diffIndex;
|
||||
}
|
||||
methods.doSort(oldIndex, newIndex);
|
||||
methods.trigger('dragged', { oldIndex, newIndex });
|
||||
});
|
||||
|
@@ -28,8 +28,8 @@ export function useJVxeComponent(props: JVxeComponent.Props) {
|
||||
const column = computed(() => props.params.column);
|
||||
// 用户配置的原始 column
|
||||
const originColumn = computed(() => column.value.params);
|
||||
const rowIndex = computed(() => props.params.$rowIndex);
|
||||
const columnIndex = computed(() => props.params.columnIndex);
|
||||
const rowIndex = computed(() => props.params._rowIndex);
|
||||
const columnIndex = computed(() => props.params._columnIndex);
|
||||
// 表格数据长度
|
||||
const fullDataLength = computed(() => props.params.$table.internalData.tableFullData.length);
|
||||
// 是否正在滚动中
|
||||
|
@@ -94,5 +94,9 @@
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
/*【美化表单】行编辑table的title字体改小一号*/
|
||||
.vxe-header--column.col--ellipsis>.vxe-cell .vxe-cell--title{
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -44,6 +44,8 @@ export enum JVxeTypes {
|
||||
radio = 'radio',
|
||||
image = 'image',
|
||||
file = 'file',
|
||||
// 省市区
|
||||
pca = 'pca',
|
||||
}
|
||||
|
||||
// 为了防止和 vxe 内置的类型冲突,所以加上一个前缀
|
||||
|
@@ -5,22 +5,22 @@
|
||||
<a-row :gutter="24">
|
||||
<template v-for="(item, index) in queryInfo">
|
||||
<template v-if="item.hidden === '1'">
|
||||
<a-col :md="8" :sm="24" :key="'query' + index" v-show="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24" :key="'query' + index" v-show="toggleSearchStatus">
|
||||
<SearchFormItem :formElRef="formRef" :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></SearchFormItem>
|
||||
</a-col>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-col :md="8" :sm="24" :key="'query' + index">
|
||||
<a-col :md="6" :sm="24" :key="'query' + index">
|
||||
<SearchFormItem :formElRef="formRef" :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></SearchFormItem>
|
||||
</a-col>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<a-col :md="8" :sm="8">
|
||||
<a-col :md="6" :sm="8">
|
||||
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
||||
<a-col :lg="6">
|
||||
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset">重置</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery" style="margin-left: 8px">查询</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
|
||||
@@ -63,7 +63,8 @@
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import { usePopBiz } from '/@/components/jeecg/OnLine/hooks/usePopBiz';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'JPopupOnlReport',
|
||||
components: {
|
||||
@@ -89,7 +90,10 @@
|
||||
const toggleSearchStatus = ref(false);
|
||||
const attrs = useAttrs();
|
||||
const tableScroll = ref({ x: true });
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
||||
const route = useRoute();
|
||||
console.log('route.query = ',route.query)
|
||||
const getBindValue = Object.assign({}, {routeQuery: route.query}, unref(props), unref(attrs));
|
||||
|
||||
const [
|
||||
{
|
||||
visibleChange,
|
||||
|
@@ -44,7 +44,7 @@
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-date-picker
|
||||
placeholder="1选择开始时间"
|
||||
placeholder="选择开始时间"
|
||||
:show-time="true"
|
||||
valueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
v-model:value="queryParam[item.field + '_begin']"
|
||||
@@ -52,7 +52,7 @@
|
||||
></a-date-picker>
|
||||
<span class="group-query-strig" style="width: auto; padding: 0 4px">~</span>
|
||||
<a-date-picker
|
||||
placeholder="2选择结束时间"
|
||||
placeholder="选择结束时间"
|
||||
:show-time="true"
|
||||
valueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
v-model:value="queryParam[item.field + '_end']"
|
||||
@@ -131,16 +131,8 @@
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<JDictSelectTag v-if="item.config === '1'" v-model:value="queryParam[item.field]" :placeholder="'请选择' + item.label" :dict="getDictCode(item)">
|
||||
</JDictSelectTag>
|
||||
<!--TODO 新需要的组件-->
|
||||
<!-- <j-online-search-select
|
||||
v-else
|
||||
:ref="item.field+'_search'"
|
||||
v-model="queryParam[item.field]"
|
||||
:placeholder=" '请选择'+item.label "
|
||||
:sql="getSqlByDictCode(item)">
|
||||
</j-online-search-select>-->
|
||||
<JOnlineSearchSelect v-model:value="queryParam[item.field]" :placeholder="'请选择' + item.label" :sql="item.sql">
|
||||
</JOnlineSearchSelect>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if="item.view === CompTypeEnum.SelUser" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
@@ -202,7 +194,10 @@
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<template v-if="single_mode === item.mode">
|
||||
<template v-if="single_mode === item.mode && 'string'== item.view">
|
||||
<j-input :placeholder="'请输入' + item.label" v-model:value="queryParam[item.field]"></j-input>
|
||||
</template>
|
||||
<template v-else-if="single_mode === item.mode">
|
||||
<a-input :placeholder="'请输入' + item.label" v-model:value="queryParam[item.field]"></a-input>
|
||||
</template>
|
||||
<template v-else>
|
||||
@@ -218,7 +213,7 @@
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { DateTypeEnum } from '/@/enums/DateTypeEnum.ts';
|
||||
import { CompTypeEnum } from '/@/enums/CompTypeEnum.ts';
|
||||
import { JDictSelectTag, JTreeSelect, JCategorySelect, JSelectUserByDept, JSelectDept, JPopup, JAreaLinkage } from '/@/components/Form';
|
||||
import { JDictSelectTag, JTreeSelect, JCategorySelect, JSelectUserByDept, JSelectDept, JPopup, JAreaLinkage,JInput,JSearchSelect } from '/@/components/Form';
|
||||
export default defineComponent({
|
||||
name: 'JPopupOnlReport',
|
||||
components: {
|
||||
@@ -230,6 +225,7 @@
|
||||
JSelectDept,
|
||||
JPopup,
|
||||
JAreaLinkage,
|
||||
JInput,
|
||||
},
|
||||
props: {
|
||||
formElRef: {
|
||||
@@ -313,16 +309,16 @@
|
||||
}
|
||||
|
||||
/* 查询条件左对齐样式设置 */
|
||||
.jeecg-online-search ::v-deep .ant-form-item-label {
|
||||
.jeecg-online-search :deep(.ant-form-item-label) {
|
||||
flex: 0 0 auto !important;
|
||||
width: auto;
|
||||
}
|
||||
.jeecg-online-search ::v-deep .ant-form-item-control {
|
||||
.jeecg-online-search :deep(.ant-form-item-control) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* label显示宽度 超出显示... */
|
||||
.jeecg-online-search ::v-deep .label-text {
|
||||
.jeecg-online-search :deep(.label-text) {
|
||||
max-width: v-bind(labelTextMaxWidth);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
@@ -512,6 +512,8 @@ export function usePopBiz(props, tableRef?) {
|
||||
//查询条件加载后再请求数据
|
||||
if (data) {
|
||||
setDataSource(data);
|
||||
//传递路由参数和动态参数,不生效,
|
||||
loadData(1);
|
||||
} else {
|
||||
//没有传递data时查询数据
|
||||
loadData(1);
|
||||
@@ -531,6 +533,7 @@ export function usePopBiz(props, tableRef?) {
|
||||
pagination.current = 1;
|
||||
}
|
||||
let params = getQueryParams(); //查询条件
|
||||
console.log('params', params);
|
||||
loading.value = true;
|
||||
let url = `${configUrl.getData}${unref(cgRpConfigId)}`;
|
||||
//缓存key
|
||||
@@ -597,6 +600,11 @@ export function usePopBiz(props, tableRef?) {
|
||||
}
|
||||
queryParam.value = { ...queryTemp };
|
||||
}
|
||||
// 合并路由参数
|
||||
if (props.routeQuery) {
|
||||
queryParam.value = Object.assign(queryParam.value, props.routeQuery);
|
||||
}
|
||||
|
||||
let dynamicTemp = {};
|
||||
if (props.param) {
|
||||
Object.keys(props.param).map((key) => {
|
||||
|
@@ -75,15 +75,15 @@
|
||||
/**
|
||||
* 评论列表
|
||||
*/
|
||||
import { defineComponent, ref, onMounted, watch, watchEffect } from 'vue';
|
||||
import { defineComponent, ref, onMounted, watch, watchEffect ,inject } from 'vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import dayjs from 'dayjs';
|
||||
import 'dayjs/locale/zh.js';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
dayjs.locale('zh');
|
||||
dayjs.extend(relativeTime);
|
||||
dayjs.extend(customParseFormat);
|
||||
// import dayjs from 'dayjs';
|
||||
// import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
// import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
// dayjs.locale('zh');
|
||||
// dayjs.extend(relativeTime);
|
||||
// dayjs.extend(customParseFormat);
|
||||
|
||||
import { MessageOutlined } from '@ant-design/icons-vue';
|
||||
import { Comment, Tooltip } from 'ant-design-vue';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
@@ -113,6 +113,8 @@
|
||||
const { createMessage } = useMessage();
|
||||
const dataList = ref([]);
|
||||
const { userInfo } = useUserStore();
|
||||
const dayjs = inject('$dayjs')
|
||||
|
||||
/**
|
||||
* 获取当前用户名称
|
||||
*/
|
||||
@@ -245,7 +247,8 @@
|
||||
}
|
||||
});
|
||||
|
||||
const { getHtml } = useEmojiHtml();
|
||||
const storageEmojiIndex = inject('$globalEmojiIndex')
|
||||
const { getHtml } = useEmojiHtml(storageEmojiIndex);
|
||||
const bottomCommentRef = ref()
|
||||
function handleClickItem(){
|
||||
bottomCommentRef.value.changeActive()
|
||||
|
@@ -87,7 +87,7 @@
|
||||
}
|
||||
}
|
||||
//antd3升级后,表单右侧讨论样式调整
|
||||
::v-deep(.ant-tabs-top .ant-tabs-nav, .ant-tabs-bottom .ant-tabs-nav, .ant-tabs-top div .ant-tabs-nav, .ant-tabs-bottom div .ant-tabs-nav) {
|
||||
:deep(.ant-tabs-top .ant-tabs-nav, .ant-tabs-bottom .ant-tabs-nav, .ant-tabs-top div .ant-tabs-nav, .ant-tabs-bottom div .ant-tabs-nav) {
|
||||
margin: 0 16px 0;
|
||||
}
|
||||
</style>
|
||||
|
@@ -28,16 +28,15 @@
|
||||
<script>
|
||||
import { PlusOutlined, EditOutlined } from '@ant-design/icons-vue';
|
||||
import { getModalHeight, getLogList } from './useComment'
|
||||
import {ref, watchEffect} from 'vue'
|
||||
import {inject, ref, watchEffect} from 'vue'
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { Tooltip } from 'ant-design-vue';
|
||||
import dayjs from 'dayjs';
|
||||
import 'dayjs/locale/zh.js';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
dayjs.locale('zh');
|
||||
dayjs.extend(relativeTime);
|
||||
dayjs.extend(customParseFormat);
|
||||
// import dayjs from 'dayjs';
|
||||
// import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
// import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
// dayjs.locale('zh');
|
||||
// dayjs.extend(relativeTime);
|
||||
// dayjs.extend(customParseFormat);
|
||||
|
||||
export default {
|
||||
name: "DataLogList",
|
||||
@@ -52,6 +51,7 @@
|
||||
datetime: propTypes.number.def(1),
|
||||
},
|
||||
setup(props){
|
||||
const dayjs = inject('$dayjs')
|
||||
const winHeight = getModalHeight();
|
||||
const height = ref(300);
|
||||
height.value = winHeight - 46 - 57 -53 - 30;
|
||||
@@ -174,4 +174,4 @@
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@@ -45,14 +45,13 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ref, watch, computed } from 'vue';
|
||||
import {ref, watch, computed, inject} from 'vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { UserAddOutlined, PaperClipOutlined, SmileOutlined } from '@ant-design/icons-vue';
|
||||
import { Tooltip } from 'ant-design-vue';
|
||||
import UserSelectModal from '/@/components/Form/src/jeecg/components/modal/UserSelectModal.vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import UploadChunk from './UploadChunk.vue';
|
||||
import { Picker } from 'emoji-mart-vue-fast/src';
|
||||
import 'emoji-mart-vue-fast/css/emoji-mart.css';
|
||||
import { useEmojiHtml } from './useComment';
|
||||
|
||||
@@ -79,7 +78,6 @@
|
||||
PaperClipOutlined,
|
||||
UploadChunk,
|
||||
SmileOutlined,
|
||||
Picker,
|
||||
},
|
||||
props: {
|
||||
inner: propTypes.bool.def(false),
|
||||
@@ -221,8 +219,9 @@
|
||||
e.stopPropagation();
|
||||
visibleEmoji.value = !visibleEmoji.value;
|
||||
}
|
||||
|
||||
const { emojiIndex, getHtml } = useEmojiHtml();
|
||||
|
||||
const emojiIndex = inject('$globalEmojiIndex')
|
||||
const { getHtml } = useEmojiHtml(emojiIndex);
|
||||
|
||||
const commentHtml = computed(() => {
|
||||
let temp = myComment.value;
|
||||
|
@@ -13,8 +13,6 @@ import txt from '/@/assets/svg/fileType/txt.svg';
|
||||
import word from '/@/assets/svg/fileType/word.svg';
|
||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { createImgPreview } from '/@/components/Preview';
|
||||
import {EmojiIndex} from "emoji-mart-vue-fast/src";
|
||||
import data from "emoji-mart-vue-fast/data/apple.json";
|
||||
|
||||
enum Api {
|
||||
list = '/sys/comment/listByForm',
|
||||
@@ -365,16 +363,9 @@ export function useFileList() {
|
||||
/**
|
||||
* 用于emoji渲染
|
||||
*/
|
||||
export function useEmojiHtml(){
|
||||
export function useEmojiHtml(globalEmojiIndex){
|
||||
const COLONS_REGEX = new RegExp('([^:]+)?(:[a-zA-Z0-9-_+]+:(:skin-tone-[2-6]:)?)','g');
|
||||
let emojisToShowFilter = function() {
|
||||
return true;
|
||||
}
|
||||
let emojiIndex = new EmojiIndex(data, {
|
||||
emojisToShowFilter,
|
||||
exclude:['recent','people','nature','foods','activity','places','objects','symbols','flags']
|
||||
});
|
||||
|
||||
|
||||
function getHtml(text) {
|
||||
if(!text){
|
||||
return ''
|
||||
@@ -384,7 +375,7 @@ export function useEmojiHtml(){
|
||||
if (endsWith(before, 'alt="') || endsWith(before, 'data-text="')) {
|
||||
return match
|
||||
}
|
||||
let emoji = emojiIndex.findEmoji(p2)
|
||||
let emoji = globalEmojiIndex.findEmoji(p2)
|
||||
if (!emoji) {
|
||||
return match
|
||||
}
|
||||
@@ -403,7 +394,7 @@ export function useEmojiHtml(){
|
||||
}
|
||||
|
||||
return {
|
||||
emojiIndex,
|
||||
globalEmojiIndex,
|
||||
getHtml
|
||||
}
|
||||
}
|
||||
|
@@ -50,7 +50,9 @@ html[data-theme='dark'] {
|
||||
.ant-pagination-next,
|
||||
.ant-pagination-item {
|
||||
margin: 0 4px !important;
|
||||
background-color: #f4f4f5 !important;
|
||||
//update-begin---author:scott ---date:2022-09-30 for:【美化】Table分页页面默认背景色丑,去掉-----------
|
||||
//background-color: #f4f4f5 !important;
|
||||
//update-end---author:scott ---date::2022-09-30 for:【美化】Table分页页面默认背景色丑,去掉------------
|
||||
border: none;
|
||||
border-radius: none !important;
|
||||
|
||||
|
@@ -6,7 +6,23 @@ html[data-theme='light'] {
|
||||
.text-secondary {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
/*【美化】自定义table字体颜色*/
|
||||
.ant-table {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
/*【美化】自定义table字体颜色*/
|
||||
/*【美化】自定义form字体颜色*/
|
||||
.ant-select-multiple .ant-select-selection-item-content {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
.ant-input-affix-wrapper > input.ant-input {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
.ant-select-single.ant-select-show-arrow .ant-select-selection-item, .ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder{
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
/*【美化】自定义form字体颜色*/
|
||||
|
||||
.ant-alert-success {
|
||||
background-color: #f6ffed;
|
||||
border: 1px solid #b7eb8f;
|
||||
|
@@ -17,7 +17,7 @@ export enum CompTypeEnum {
|
||||
//分类字典树
|
||||
CatTree = 'cat_tree',
|
||||
//下拉搜索
|
||||
SelSearch = 'sel_search',
|
||||
SelSearch = 'search',
|
||||
//用户现在框
|
||||
SelUser = 'sel_user',
|
||||
//复选框
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import type { UnwrapRef, Ref, WritableComputedRef, DeepReadonly } from 'vue';
|
||||
import { reactive, readonly, computed, getCurrentInstance, watchEffect, unref, nextTick, toRaw } from 'vue';
|
||||
import { Form } from 'ant-design-vue';
|
||||
import { FormItemContext } from 'ant-design-vue/es/form/FormItemContext';
|
||||
|
||||
import { isEqual } from 'lodash-es';
|
||||
export function useRuleFormItem<T extends Recordable, K extends keyof T, V = UnwrapRef<T[K]>>(
|
||||
@@ -7,10 +9,11 @@ export function useRuleFormItem<T extends Recordable, K extends keyof T, V = Unw
|
||||
key?: K,
|
||||
changeEvent?,
|
||||
emitData?: Ref<any[] | undefined>
|
||||
): [WritableComputedRef<V>, (val: V) => void, DeepReadonly<V>];
|
||||
): [WritableComputedRef<V>, (val: V) => void, DeepReadonly<V>, FormItemContext];
|
||||
export function useRuleFormItem<T extends Recordable>(props: T, key: keyof T = 'value', changeEvent = 'change', emitData?: Ref<any[]>) {
|
||||
const instance = getCurrentInstance();
|
||||
const emit = instance?.emit;
|
||||
const formItemContext = Form.useInjectFormItemContext();
|
||||
|
||||
const innerState = reactive({
|
||||
value: props[key],
|
||||
@@ -28,8 +31,8 @@ export function useRuleFormItem<T extends Recordable>(props: T, key: keyof T = '
|
||||
|
||||
const state: any = computed({
|
||||
get() {
|
||||
//修复多选时空值显示问题
|
||||
return innerState.value === '' ? [] : innerState.value;
|
||||
//修复多选时空值显示问题(兼容值为0的情况)
|
||||
return innerState.value == null || innerState.value === '' ? [] : innerState.value;
|
||||
},
|
||||
set(value) {
|
||||
if (isEqual(value, defaultState.value)) return;
|
||||
@@ -37,9 +40,12 @@ export function useRuleFormItem<T extends Recordable>(props: T, key: keyof T = '
|
||||
innerState.value = value as T[keyof T];
|
||||
nextTick(() => {
|
||||
emit?.(changeEvent, value, ...(toRaw(unref(emitData)) || []));
|
||||
// https://antdv.com/docs/vue/migration-v3-cn
|
||||
// antDv3升级后需要调用这个方法更新校验的值
|
||||
nextTick(() => formItemContext.onFieldChange());
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return [state, setState, defaultState];
|
||||
return [state, setState, defaultState, formItemContext];
|
||||
}
|
||||
|
@@ -50,6 +50,9 @@ export function useHeaderSetting() {
|
||||
const getShowBread = computed(() => {
|
||||
return unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit);
|
||||
});
|
||||
const getShowBreadTitle = computed(() => {
|
||||
return unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && !unref(getShowBreadCrumb) && !unref(getSplit);
|
||||
});
|
||||
|
||||
const getShowHeaderLogo = computed(() => {
|
||||
return unref(getShowLogo) && !unref(getIsSidebarType) && !unref(getIsMixSidebar);
|
||||
@@ -82,5 +85,6 @@ export function useHeaderSetting() {
|
||||
getShowInsetHeaderRef,
|
||||
getUnFixedAndFull,
|
||||
getHeaderBgColor,
|
||||
getShowBreadTitle
|
||||
};
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ export function useJvxeMethod(requestAddOrEdit, classifyIntoFormData, tableRefs,
|
||||
getAllTable()
|
||||
.then((tables) => {
|
||||
let values = formRef.value.getFieldsValue();
|
||||
return validateFormModelAndTables(formRef.value.validate, values, tables, formRef.value.getProps);
|
||||
return validateFormModelAndTables(formRef.value.validate, values, tables, formRef.value.getProps, false);
|
||||
})
|
||||
.then((allValues) => {
|
||||
/** 一次性验证一对一的所有子表 */
|
||||
@@ -61,7 +61,13 @@ export function useJvxeMethod(requestAddOrEdit, classifyIntoFormData, tableRefs,
|
||||
.catch((e) => {
|
||||
if (e.error === VALIDATE_FAILED) {
|
||||
// 如果有未通过表单验证的子表,就自动跳转到它所在的tab
|
||||
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index];
|
||||
//update-begin-author:taoyan date:2022-11-22 for: VUEN-2866【代码生成】Tab风格 一对多子表校验不通过时,点击提交表单空白了,流程附加页面也有此问题
|
||||
if(e.paneKey){
|
||||
activeKey.value = e.paneKey
|
||||
}else{
|
||||
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index];
|
||||
}
|
||||
//update-end-author:taoyan date:2022-11-22 for: VUEN-2866【代码生成】Tab风格 一对多子表校验不通过时,点击提交表单空白了,流程附加页面也有此问题
|
||||
} else {
|
||||
console.error(e);
|
||||
}
|
||||
|
@@ -235,7 +235,7 @@ export function useListTable(tableProps: TableProps): [
|
||||
},
|
||||
},
|
||||
// 斑马纹
|
||||
striped: true,
|
||||
striped: false,
|
||||
// 是否可以自适应高度
|
||||
canResize: true,
|
||||
// 表格最小高度
|
||||
|
@@ -47,8 +47,15 @@ export const useRedo = (_router?: Router) => {
|
||||
return;
|
||||
}
|
||||
if (name && Object.keys(params).length > 0) {
|
||||
params['_redirect_type'] = 'name';
|
||||
params['path'] = String(name);
|
||||
//update-begin-author:taoyan date:2022-10-19 for: VUEN-2356 【vue3】online表单、表单设计器 功能测试 右键刷新时 404
|
||||
if(isDynamicRoute(params, name)){
|
||||
params['_redirect_type'] = 'path';
|
||||
params['path'] = fullPath;
|
||||
}else{
|
||||
params['_redirect_type'] = 'name';
|
||||
params['path'] = String(name);
|
||||
}
|
||||
//update-end-author:taoyan date:2022-10-19 for: VUEN-2356 【vue3】online表单、表单设计器 功能测试 右键刷新时 404
|
||||
} else {
|
||||
params['_redirect_type'] = 'path';
|
||||
params['path'] = fullPath;
|
||||
@@ -58,3 +65,21 @@ export const useRedo = (_router?: Router) => {
|
||||
}
|
||||
return redo;
|
||||
};
|
||||
|
||||
/**
|
||||
* 判断是不是动态路由的跳转
|
||||
* @param params
|
||||
* @param name
|
||||
*/
|
||||
function isDynamicRoute(params, name){
|
||||
let arr = Object.keys(params);
|
||||
let flag = false;
|
||||
for(let i=0;i<arr.length;i++){
|
||||
let key = '@'+arr[i];
|
||||
if((name as string).indexOf(key)>0){
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
@@ -162,7 +162,7 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
::v-deep(.ant-pagination-disabled) {
|
||||
:deep(.ant-pagination-disabled) {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
|
@@ -57,7 +57,6 @@
|
||||
}
|
||||
return count;
|
||||
});
|
||||
const chatRef = ref();
|
||||
|
||||
const [registerMessageModal, { openModal: openMessageModal }] = useModal();
|
||||
function clickBadge(){
|
||||
@@ -96,7 +95,6 @@
|
||||
//update-begin-author:taoyan date:2022-8-30 for: 消息数量改变触发chat组件事件
|
||||
let msgCount = anntMsgTotal+sysMsgTotal;
|
||||
//update-begin-author:wangshuai date:2022-09-02 for: 消息未读数为0也需要传递,因为聊天需要计算总数
|
||||
chatRef.value.updateMessageCount(msgCount);
|
||||
messageCount.value = msgCount
|
||||
//update-end-author:wangshuai date:2022-09-02 for: 消息未读数为0也需要传递,因为聊天需要计算总数
|
||||
//update-end-author:taoyan date:2022-8-30 for: 消息数量改变触发chat组件事件
|
||||
@@ -164,12 +162,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息未读数
|
||||
*/
|
||||
function getSystemUnreadNum() {
|
||||
chatRef.value.updateMessageCount(messageCount.value);
|
||||
}
|
||||
|
||||
return {
|
||||
prefixCls,
|
||||
@@ -184,8 +176,6 @@
|
||||
popoverVisible,
|
||||
registerDetail,
|
||||
dynamicNoticeProps,
|
||||
chatRef,
|
||||
getSystemUnreadNum
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -57,7 +57,7 @@
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
let params = Object.assign({ username: unref(username) }, values);
|
||||
defHttp.put({ url: 'sys/user/updatePassword', params }, { isTransformResponse: false }).then((res) => {
|
||||
defHttp.put({ url: '/sys/user/updatePassword', params }, { isTransformResponse: false }).then((res) => {
|
||||
if (res.success) {
|
||||
$message.createMessage.success(res.message);
|
||||
//关闭弹窗
|
||||
|
@@ -10,6 +10,8 @@
|
||||
:sider="false"
|
||||
/>
|
||||
<LayoutBreadcrumb v-if="getShowContent && getShowBread" :theme="getHeaderTheme" />
|
||||
<!-- 欢迎语 -->
|
||||
<span v-if="getShowContent && getShowBreadTitle" :class="[prefixCls, `${prefixCls}--${getHeaderTheme}`,'headerIntroductionClass']"> 欢迎进入 {{ title }} </span>
|
||||
</div>
|
||||
<!-- left end -->
|
||||
|
||||
@@ -42,7 +44,7 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, unref, computed, ref, onMounted, toRaw } from 'vue';
|
||||
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
|
||||
import { Layout } from 'ant-design-vue';
|
||||
@@ -98,7 +100,8 @@
|
||||
const userStore = useUserStore();
|
||||
const { getShowTopMenu, getShowHeaderTrigger, getSplit, getIsMixMode, getMenuWidth, getIsMixSidebar } = useMenuSetting();
|
||||
const { getUseErrorHandle, getShowSettingButton, getSettingButtonPosition } = useRootSetting();
|
||||
|
||||
const { title } = useGlobSetting();
|
||||
|
||||
const {
|
||||
getHeaderTheme,
|
||||
getShowFullScreen,
|
||||
@@ -109,6 +112,7 @@
|
||||
getShowHeader,
|
||||
getShowSearch,
|
||||
getUseLockPage,
|
||||
getShowBreadTitle,
|
||||
} = useHeaderSetting();
|
||||
|
||||
const { getShowLocalePicker } = useLocale();
|
||||
@@ -185,6 +189,7 @@
|
||||
getHeaderTheme,
|
||||
getShowHeaderTrigger,
|
||||
getIsMobile,
|
||||
getShowBreadTitle,
|
||||
getShowBread,
|
||||
getShowContent,
|
||||
getSplitType,
|
||||
@@ -203,10 +208,43 @@
|
||||
getUseLockPage,
|
||||
loginSelectOk,
|
||||
loginSelectRef,
|
||||
title
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
@import './index.less';
|
||||
//update-begin---author:scott ---date:2022-09-30 for:默认隐藏顶部菜单面包屑-----------
|
||||
//顶部欢迎语展示样式
|
||||
@prefix-cls: ~'@{namespace}-layout-header';
|
||||
|
||||
.@{prefix-cls} {
|
||||
display: flex;
|
||||
padding: 0 8px;
|
||||
align-items: center;
|
||||
|
||||
.headerIntroductionClass {
|
||||
margin-right: 4px;
|
||||
margin-bottom: 2px;
|
||||
border-bottom: 0px;
|
||||
border-left: 0px;
|
||||
}
|
||||
|
||||
&--light {
|
||||
.headerIntroductionClass {
|
||||
color: @breadcrumb-item-normal-color;
|
||||
}
|
||||
}
|
||||
|
||||
&--dark {
|
||||
.headerIntroductionClass {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
.anticon {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
//update-end---author:scott ---date::2022-09-30 for:默认隐藏顶部菜单面包屑--------------
|
||||
}
|
||||
</style>
|
||||
|
@@ -201,3 +201,28 @@ html[data-theme='light'] {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-tabs-dropdown-menu {
|
||||
&-title-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.@{prefix-cls} {
|
||||
&-content__info {
|
||||
width: auto;
|
||||
margin-left: 0;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-item-remove {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.multiple-tabs__dropdown {
|
||||
.ant-dropdown-content {
|
||||
width: 172px;
|
||||
}
|
||||
}
|
||||
|
@@ -2,10 +2,10 @@ import { genMessage } from '../helper';
|
||||
import antdLocale from 'ant-design-vue/es/locale/en_US';
|
||||
//import momentLocale from 'moment/dist/locale/eu';
|
||||
|
||||
const modules = import.meta.globEager('./en/**/*.ts');
|
||||
const modules = import.meta.glob('./en/**/*.ts', { eager: true });
|
||||
export default {
|
||||
message: {
|
||||
...genMessage(modules, 'en'),
|
||||
...genMessage(modules as Recordable<Recordable>, 'en'),
|
||||
antdLocale,
|
||||
},
|
||||
dateLocale: null,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import { genMessage } from '../helper';
|
||||
import antdLocale from 'ant-design-vue/es/locale/zh_CN';
|
||||
|
||||
const modules = import.meta.globEager('./zh-CN/**/*.ts');
|
||||
const modules = import.meta.glob('./zh-CN/**/*.ts', { eager: true });
|
||||
export default {
|
||||
message: {
|
||||
...genMessage(modules, 'zh-CN'),
|
||||
...genMessage(modules as Recordable<Recordable>, 'zh-CN'),
|
||||
antdLocale,
|
||||
},
|
||||
};
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { darkCssIsReady, loadDarkThemeCss } from 'vite-plugin-theme/es/client';
|
||||
import { darkCssIsReady, loadDarkThemeCss } from '@rys-fe/vite-plugin-theme/es/client';
|
||||
import { addClass, hasClass, removeClass } from '/@/utils/domUtils';
|
||||
|
||||
export async function updateDarkTheme(mode: string | null = 'light') {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { getThemeColors, generateColors } from '../../../build/config/themeConfig';
|
||||
|
||||
import { replaceStyleVariables } from 'vite-plugin-theme/es/client';
|
||||
import { mixLighten, mixDarken, tinycolor } from 'vite-plugin-theme/es/colorUtils';
|
||||
import { replaceStyleVariables } from '@rys-fe/vite-plugin-theme/es/client';
|
||||
import { mixLighten, mixDarken, tinycolor } from '@rys-fe/vite-plugin-theme/es/colorUtils';
|
||||
|
||||
export async function changeTheme(color: string) {
|
||||
const colors = generateColors({
|
||||
|
@@ -61,6 +61,7 @@ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMappi
|
||||
meta: node.meta,
|
||||
name: title,
|
||||
hideMenu,
|
||||
alwaysShow:node.alwaysShow||false,
|
||||
path: node.path,
|
||||
...(node.redirect ? { redirect: node.redirect } : {}),
|
||||
};
|
||||
|
@@ -8,6 +8,7 @@ import { createRouter, createWebHashHistory } from 'vue-router';
|
||||
import { getTenantId, getToken } from '/@/utils/auth';
|
||||
import { URL_HASH_TAB } from '/@/utils';
|
||||
import { packageViews } from '/@/utils/monorepo/dynamicRouter';
|
||||
import {useI18n} from "/@/hooks/web/useI18n";
|
||||
|
||||
export type LayoutMapKey = 'LAYOUT';
|
||||
const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue');
|
||||
@@ -31,6 +32,17 @@ function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
|
||||
}
|
||||
if (!routes) return;
|
||||
routes.forEach((item) => {
|
||||
|
||||
//【jeecg-boot/issues/I5N2PN】左侧动态菜单怎么做国际化处理 2022-10-09
|
||||
//菜单支持国际化翻译
|
||||
if (item?.meta?.title) {
|
||||
const { t } = useI18n();
|
||||
if(item.meta.title.includes('t(\'') && t){
|
||||
item.meta.title = eval(item.meta.title);
|
||||
//console.log('译后: ',item.meta.title)
|
||||
}
|
||||
}
|
||||
|
||||
// update-begin--author:sunjianlei---date:20210918---for:适配旧版路由选项 --------
|
||||
// @ts-ignore 适配隐藏路由
|
||||
if (item?.hidden) {
|
||||
|
@@ -10,12 +10,12 @@ import { router } from '/@/router';
|
||||
import { PermissionModeEnum } from '/@/enums/appEnum';
|
||||
import { pathToRegexp } from 'path-to-regexp';
|
||||
|
||||
const modules = import.meta.globEager('./modules/**/*.ts');
|
||||
const modules = import.meta.glob('./modules/**/*.ts', { eager: true });
|
||||
|
||||
const menuModules: MenuModule[] = [];
|
||||
|
||||
Object.keys(modules).forEach((key) => {
|
||||
const mod = modules[key].default || {};
|
||||
const mod = (modules as Recordable)[key].default || {};
|
||||
const modList = Array.isArray(mod) ? [...mod] : [mod];
|
||||
menuModules.push(...modList);
|
||||
});
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user