Compare commits

...

17 Commits

Author SHA1 Message Date
48805484d4 MK编辑器,无法上传多个图片 2024-09-24 22:47:44 +08:00
7fecdf94e5 修改柱体颜色 2024-09-24 22:47:04 +08:00
a3997dfd16 【issues/7200】basicTable选中后没有选中样式 --- 2024-09-24 22:43:44 +08:00
c868d90c2f 【issues/7209】顶部左侧组合菜单关闭之后左侧导航没还原 --- 2024-09-24 22:43:06 +08:00
77aebf5dd2 租户套餐的菜单名称没国际化 2024-09-24 22:42:21 +08:00
e770524f3a 【issues/7203】自动生成一对多表单代码中,省市区回显问题-- 2024-09-24 22:41:34 +08:00
c5fee07cba 【issues/7136】单元格上的tooltip提示,如果表格有滚动条,会不跟着单元格滚动 2024-09-24 22:40:47 +08:00
9fd20fde9e 【issues/7250】自动锁屏无法解锁 2024-09-24 22:39:52 +08:00
2af9451b7f 【issues/7217】BasicTable树形表格设置checkStrictly无效 ---
【issues/7200】basicTable选中后没有选中样式 ---
2024-09-24 22:38:24 +08:00
575baa8d49 JeecgBoot3.7XSS漏洞处理 2024-09-14 14:15:31 +08:00
48bc76cce7 在线演示地址 2024-09-14 11:46:03 +08:00
58c0882329 更新README.md 2024-09-13 09:52:02 +08:00
c400ec8482 前端环境,要求Node 20+ 版本以上 2024-09-13 09:31:37 +08:00
2068bdc112 前端环境要求Node.js 版本建议v20.15.0 2024-09-13 09:29:01 +08:00
ffe806352e 前端环境要求Node.js 版本建议v20.15.0 2024-09-13 09:20:28 +08:00
167a6c458c 前端环境要求Node.js 版本建议v20.15.0 2024-09-13 09:18:36 +08:00
872e6ed024 开源协议中文释意 2024-09-13 09:10:45 +08:00
21 changed files with 248 additions and 104 deletions

10
LICENSE
View File

@ -201,3 +201,13 @@
limitations under the License.
In any case, you must not make any such use of this software as to develop software which may be considered competitive with this software.
JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京地址中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱jeecgos@163.com
本软件受适用的国家软件著作权法(包括国际条约)和开源协议 双重保护许可。
开源协议中文释意如下:
1.JeecgBoot开源版本无任何限制在遵循本开源协议条款下允许商用使用不会造成侵权行为。
2.允许基于本平台软件开展业务系统开发。
3.在任何情况下,您不得使用本软件开发可能被认为与本软件竞争的软件。
最终解释权归http://www.jeecg.com

View File

@ -72,10 +72,11 @@ Technical documentation
-----------------------------------
- Website [http://www.jeecg.com](http://www.jeecg.com)
- Demo [OnlineDemo](http://boot3.jeecg.com) | [APP](http://jeecg.com/appIndex)
- Doc [http://help.jeecg.com](http://help.jeecg.com)
- Newbie guide [Quick start](http://www.jeecg.com/doc/quickstart) | [Q&A ](http://www.jeecg.com/doc/qa) | [1 minute experience](https://my.oschina.net/jeecg/blog/3083313)
- QQ group ⑨808791225、⑧825232878、⑦791696430、⑥730954414(full)、683903138(full)、⑤860162132(full)、④774126647(full)、③816531124(full)、②769925425(full)、①284271917(full)
- Demo [OnlineDemo](http://boot3.jeecg.com) | [APP](http://jeecg.com/appIndex)
@ -195,7 +196,7 @@ Technical Architecture:
- Persistence layer framework: MybatisPlus 3.5.3.2
- Report tool: JimuReport 1.7.6
- Report tool: JimuReport 1.8.1
- Security framework: Apache Shiro 1.12.0, Jwt 3.11.0
@ -212,6 +213,12 @@ Technical Architecture:
- TechnologyStack`Vue3.0+TypeScript+Vite+AntDesignVue+pinia+echarts`
#### Front-end environment requirements
* `Node.js 、npm 、pnpm`
* Node.js Version suggestion: `v20.15.0`
` ( Since Vite5 no longer supports EOL Node.js 14/16/17/19, Node.js 18/20 + is now required )`
#### Support library
| database | support |
@ -223,6 +230,7 @@ Technical Architecture:
| MariaDB | √ |
| 达梦 | √ |
| 人大金仓 | √ |
| TiDB | √ |
## Microservice solutions

View File

@ -47,11 +47,12 @@ Jeecg-Boot低代码开发平台可以应用在任何J2EE项目的开发中
-----------------------------------
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
- 在线演示 [在线演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex)
- 开发文档: [https://help.jeecg.com](https://help.jeecg.com)
- 反馈问题: [在Github上提Issues](https://github.com/jeecgboot/JeecgBoot/issues/new)
- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [入门视频](http://jeecg.com/doc/video)
- QQ交流群 ⑨808791225、其他(满)
- 在线演示 [在线演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex)
@ -73,7 +74,7 @@ Jeecg-Boot低代码开发平台可以应用在任何J2EE项目的开发中
- 基础框架Spring Boot 2.7.18
- 微服务框架: Spring Cloud Alibaba 2021.0.1.0
- 持久层框架MybatisPlus 3.5.3.2
- 报表工具: JimuReport 1.7.6
- 报表工具: JimuReport 1.8.1
- 安全框架Apache Shiro 1.12.0Jwt 3.11.0
- 微服务技术栈Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywalking
- 数据库连接池阿里巴巴Druid 1.1.22
@ -87,11 +88,18 @@ Jeecg-Boot低代码开发平台可以应用在任何J2EE项目的开发中
#### 前端
- 前端IDE建议WebStorm、Vscode
- 采用 Vue3.0+TypeScript+Vite+Ant-Design-Vue等新技术方案包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能
- 采用 Vue3.0+TypeScript+Vite5+Ant-Design-Vue等新技术方案包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能
- 最新技术栈Vue3.0 + TypeScript + Vite5 + ant-design-vue4 + pinia + echarts + unocss + vxe-table + qiankun + es6
- 依赖管理node、npm、pnpm
#### 前端环境要求
* 本地环境安装 `Node.js 、npm 、pnpm`
* Node.js 版本建议`v20.15.0`,要求`Node 20+` 版本以上
` ( 因为Vite5 不再支持已 EOL 的 Node.js 14 / 16 / 17 / 19现在需要 Node.js 18 / 20+ )`
#### 支持库
@ -102,9 +110,10 @@ Jeecg-Boot低代码开发平台可以应用在任何J2EE项目的开发中
| Sqlserver2017 | √ |
| PostgreSQL | √ |
| MariaDB | √ |
| MariaDB | √ |
| 达梦 | √ |
| 人大金仓 | √ |
| TiDB | √ |
## 微服务解决方案

View File

@ -201,3 +201,13 @@
limitations under the License.
In any case, you must not make any such use of this software as to develop software which may be considered competitive with this software.
JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京地址中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱jeecgos@163.com
本软件受适用的国家软件著作权法(包括国际条约)和开源协议 双重保护许可。
开源协议中文释意如下:
1.JeecgBoot开源版本无任何限制在遵循本开源协议条款下允许商用使用不会造成侵权行为。
2.允许基于本平台软件开展业务系统开发。
3.在任何情况下,您不得使用本软件开发可能被认为与本软件竞争的软件。
最终解释权归http://www.jeecg.com

View File

@ -66,7 +66,7 @@ JeecgBoot 是一款基于代码生成器的`低代码开发平台`!前后端
- 基础框架Spring Boot 2.7.18
- 微服务框架: Spring Cloud Alibaba 2021.0.1.0
- 持久层框架MybatisPlus 3.5.3.2
- 报表工具: JimuReport 1.7.6
- 报表工具: JimuReport 1.8.1
- 安全框架Apache Shiro 1.12.0Jwt 3.11.0
- 微服务技术栈Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywalking
- 数据库连接池阿里巴巴Druid 1.1.22
@ -97,6 +97,7 @@ JeecgBoot 是一款基于代码生成器的`低代码开发平台`!前后端
| MariaDB | √ |
| 达梦 | √ |
| 人大金仓 | √ |
| TiDB | √ |

View File

@ -3,6 +3,8 @@ package org.jeecg.modules.system.controller;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.system.util.XssUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -23,8 +25,13 @@ public class WechatVerifyController {
*/
@RequestMapping(value = "/WW_verify_{code}.txt")
public void mpVerify(@PathVariable("code") String code, HttpServletResponse response) {
if(StringUtils.isEmpty(code)){
log.error("企业微信证书验证失败!(code为空)");
return;
}
try {
PrintWriter writer = response.getWriter();
code = XssUtils.scriptXss(code);
writer.write(code);
writer.close();
} catch (Exception e) {

View File

@ -21,3 +21,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
In any case, you must not make any such use of this software as to develop software which may be considered competitive with this software.
JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京地址中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱jeecgos@163.com
本软件受适用的国家软件著作权法(包括国际条约)和开源协议 双重保护许可。
开源协议中文释意如下:
1.JeecgBoot开源版本无任何限制在遵循本开源协议条款下允许商用使用不会造成侵权行为。
2.允许基于本平台软件开展业务系统开发。
3.在任何情况下,您不得使用本软件开发可能被认为与本软件竞争的软件。
最终解释权归http://www.jeecg.com

View File

@ -34,9 +34,11 @@ JeecgBoot-Vue3采用 Vue3.0、Vite、 Ant-Design-Vue4、TypeScript 等新技术
## 安装与使用
* 本地环境安装 `Node.js 、npm 、pnpm`
* Node.js 版本建议`v20.15.0`,要求`Node 20+` 版本以上
` ( 因为Vite5 不再支持已 EOL 的 Node.js 14 / 16 / 17 / 19现在需要 Node.js 18 / 20+ )`
> 环境要求: 版本要求Node 14.18+ / 16+ 版本以上,不再支持 Node 12 / 13 / 15。
> 建议使用pnpm如果使用yarn,请用Yarn1.x版本否则依赖可能安装不上。
- Get the project code
@ -76,80 +78,6 @@ pnpm dev
pnpm build
```
## Docker镜像启动前端(单体模式)
- host设置
>注意: 需要把`127.0.0.1`替换成真实IP 比如`192.`开头,不然后端不通。
```bash
127.0.0.1 jeecg-boot-system
127.0.0.1 jeecg-boot-gateway
```
- 下载项目
```bash
git clone https://github.com/jeecgboot/JeecgBoot.git
cd JeecgBoot/jeecgboot-vue3
```
- 配置接口域名 `.env.production`
```bash
VITE_GLOB_API_URL=/jeecgboot
VITE_GLOB_DOMAIN_URL=http://jeecg-boot-system:8080/jeecg-boot
```
后台单体启动 [见此文档](https://help.jeecg.com/java/setup/docker/up.html)
- 编译项目
```bash
pnpm install
pnpm build
```
- 启动容器
```bash
docker build -t jeecgboot-vue3 .
docker run --name jeecgboot-vue3-nginx -p 80:80 -d jeecgboot-vue3
```
- 访问前台
http://localhost
## Docker镜像启动前端(微服务模式)
> 这里只写与单体的区别步骤
- 区别1. 修改后台域名
.env.production
```bash
VITE_GLOB_API_URL=/jeecgboot
VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999
```
后台微服务启动 [见此文档](https://help.jeecg.com/java/springcloud/docker.html)
- 区别2. 修改Dockerfile文件
```bash
- 把`http://jeecg-boot-system:8080/jeecg-boot`替换成 `http://jeecg-boot-gateway:9999`
- 把`jeecg-boot-system`替换成 `jeecg-boot-gateway`
```
- 其他与单体模式一样
```bash
镜像需要重现构建最好把单体的镜像删掉重新构建docker镜像。
```
## 入门必备
本项目需要一定前端基础知识,请确保掌握 Vue 的基础知识,以便能处理一些常见的问题。 建议在开发前先学一下以下内容,提前了解和学习这些知识,会对项目理解非常有帮助:
@ -164,9 +92,7 @@ VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999
* [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/)
## 浏览器支持

View File

@ -169,6 +169,6 @@
},
"homepage": "https://www.jeecg.com",
"engines": {
"node": "^12 || >=14"
"node": "^18 || >=20"
}
}

View File

@ -33,7 +33,7 @@
import { TreeSelect } from 'ant-design-vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { isObject } from '/@/utils/is';
import { useI18n } from '/@/hooks/web/useI18n';
enum Api {
url = '/sys/dict/loadTreeData',
view = '/sys/dict/loadDictItem/',
@ -65,6 +65,7 @@
hiddenNodeKey: propTypes.string.def(''),
});
const attrs = useAttrs();
const { t } = useI18n();
const emit = defineEmits(['change', 'update:value']);
const slots = defineSlots();
const { createMessage } = useMessage();
@ -151,10 +152,10 @@
treeValue.value = result.result.map((item, index) => ({
key: values[index],
value: values[index],
label: item,
label: translateTitle(item),
}));
}else{
treeValue.value = { key: props.value, value: props.value, label: result.result[0] };
treeValue.value = { key: props.value, value: props.value, label: translateTitle(result.result[0]) };
}
//update-end-author:liaozhiyang date:2023-7-17 for:【issues/5141】使用JtreeSelect 组件 控制台报错
onLoadTriggleChange(result.result[0]);
@ -198,6 +199,7 @@
let res = await defHttp.get({ url: Api.url, params }, { isTransformResponse: false });
if (res.success && res.result) {
for (let i of res.result) {
i.title = translateTitle(i.title);
i.value = i.key;
i.isLeaf = !!i.leaf;
}
@ -210,6 +212,16 @@
}
}
/**
* 翻译
* @param text
*/
function translateTitle(text) {
if (text.includes("t('") && t) {
return new Function('t', `return ${text}`)(t);
}
return text;
}
/**
* 异步加载数据
*/
@ -234,6 +246,7 @@
let res = await defHttp.get({ url: Api.url, params }, { isTransformResponse: false });
if (res.success) {
for (let i of res.result) {
i.title = translateTitle(i.title);
i.value = i.key;
i.isLeaf = !!i.leaf;
}
@ -334,6 +347,7 @@
let res = await defHttp.get({ url, params }, { isTransformResponse: false });
if (res.success && res.result) {
for (let i of res.result) {
i.title = translateTitle(i.title);
i.key = i.value;
i.isLeaf = !!i.leaf;
}

View File

@ -12,6 +12,7 @@
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
import { getTenantId, getToken } from '/@/utils/auth';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { uploadFile } from '@/api/common/api';
type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined;
@ -161,7 +162,7 @@
//update-begin-author:taoyan date:2022-5-24 for: VUEN-1090 markdown 无法上传
upload: {
accept: 'image/*',
url: uploadUrl,
//url: uploadUrl,
fieldName: 'file',
extraData: { biz: 'markdown' },
setHeaders() {
@ -173,6 +174,23 @@
format(files, response) {
return formatResult(files, response);
},
// 遍历文件上传并展示
async handler(files) {
const uploadSuccess = (res) => {
// {"success":true,"message":"markdown/aa_1653391146501.png","code":0,"result":null,"timestamp":1653391146501}'
if (res.success) {
vditorRef.value?.insertValue(`![${res.message}](${getFileAccessHttpUrl(res.message)})`);
}
};
for (const file of files) {
let params = {
file: file,
filename: file.name,
data: { biz: 'markdown' },
};
await uploadFile(params, uploadSuccess);
}
},
},
//update-end-author:taoyan date:2022-5-24 for: VUEN-1090 markdown 无法上传
input: (v) => {

View File

@ -113,10 +113,17 @@
const val = unref(currentValueRef);
const value = isCheckValue ? (isNumber(val) && isBoolean(val) ? val : !!val) : val;
//update-begin---author:wangshuai---date:2024-09-19---for:【issues/7136】单元格上的tooltip提示如果表格有滚动条会不跟着单元格滚动---
let tooltipPosition:any = unref(table?.wrapRef.value)?.parentElement?.querySelector('.ant-table-body');
if(tooltipPosition){
tooltipPosition.style.position = 'relative';
}
//update-end---author:wangshuai---date:2024-09-19---for:【issues/7136】单元格上的tooltip提示如果表格有滚动条会不跟着单元格滚动---
return {
size: 'small',
getPopupContainer: () => unref(table?.wrapRef.value) ?? document.body,
//update-begin---author:wangshuai---date:2024-09-19---for:【issues/7136】单元格上的tooltip提示如果表格有滚动条会不跟着单元格滚动---
getPopupContainer: () => tooltipPosition ?? document.body,
//update-end---author:wangshuai---date:2024-09-19---for:【issues/7136】单元格上的tooltip提示如果表格有滚动条会不跟着单元格滚动---
getCalendarContainer: () => unref(table?.wrapRef.value) ?? document.body,
placeholder: createPlaceholderMessage(unref(getComponent)),
...apiSelectProps,

View File

@ -43,6 +43,8 @@ export function useCustomSelection(
let changeRows: Recordable[] = [];
let allSelected: boolean = false;
let timer;
// 扁平化数据children数据也会放到一起
const flattedData = computed(() => {
// update-begin--author:liaozhiyang---date:20231016---for【QQYUN-6774】解决checkbox禁用后全选仍能勾选问题
@ -122,7 +124,7 @@ export function useCustomSelection(
selectedLength: flattedData.value.filter((data) => selectedKeys.value.includes(getRecordKey(data))).length,
// update-begin--author:liaozhiyang---date:20240511---for【QQYUN-9289】解决表格条数不足pageSize数量时行数全部勾选但是全选框不勾选
// 【TV360X-53】为空时会报错加强判断
pageSize: tableData.value?.length ?? 0,
pageSize: flattedData.value?.length ?? 0,
// update-end--author:liaozhiyang---date:20240511---for【QQYUN-9289】解决表格条数不足pageSize数量时行数全部勾选但是全选框不勾选
// 【QQYUN-6774】解决checkbox禁用后全选仍能勾选问题
disabled: flattedData.value.length == 0,
@ -317,6 +319,7 @@ export function useCustomSelection(
function onSelect(record, checked) {
onSelectChild(record, checked);
updateSelected(record, checked);
onSelectParent(record, checked);
emitChange();
}
@ -339,6 +342,12 @@ export function useCustomSelection(
selectedRows.value.splice(index, 1);
}
}
// update-begin--author:liaozhiyang---date:20240919---for【issues/7200】basicTable选中后没有选中样式
clearTimeout(timer);
timer = setTimeout(() => {
selectedKeys.value = [...selectedKeys.value];
}, 0);
// update-end--author:liaozhiyang---date:20240919---for【issues/7200】basicTable选中后没有选中样式
}
// 调用用户自定义的onChange事件
@ -372,7 +381,7 @@ export function useCustomSelection(
* @param checked
*/
function onSelectChild(record, checked) {
if (unref(propsRef)?.isTreeTable && unref(propsRef)?.rowSelection?.checkStrictly && !isRadio.value) {
if (unref(propsRef)?.isTreeTable && unref(propsRef)?.rowSelection?.checkStrictly === false && !isRadio.value) {
if (record[childrenColumnName.value] && record[childrenColumnName.value].length > 0) {
record[childrenColumnName.value].forEach((children) => {
updateSelected(children, checked);
@ -384,6 +393,59 @@ export function useCustomSelection(
}
}
// update-end--author:liusq---date:20240819---for树形表格设置层级关联不生效
/**
* 2024-09-24
* liaozhiyang
* 层级关联时,选中上级数据
* 【issues/7217】BasicTable树形表格设置checkStrictly无效
* */
function onSelectParent(record, checked) {
if (unref(propsRef)?.isTreeTable && unref(propsRef)?.rowSelection?.checkStrictly === false && !isRadio.value) {
let condition = true,
currentRecord = record;
while (condition) {
const parentRecord: any = findParent(tableData.value, currentRecord, childrenColumnName.value);
if (parentRecord) {
const childrenRecordKeys: any = [];
parentRecord[childrenColumnName.value].forEach((item) => {
childrenRecordKeys.push(getRecordKey(item));
});
if (checked === true) {
const isSubSet = childrenRecordKeys.every((item) => selectedKeys.value.includes(item));
isSubSet && updateSelected(parentRecord, checked);
} else if (checked === false) {
updateSelected(parentRecord, checked);
}
if (tableData.value.find((item) => getRecordKey(item) === getRecordKey(parentRecord))) {
// 循环终止
condition = false;
} else {
currentRecord = parentRecord;
}
} else {
// 循环终止
condition = false;
}
}
}
function findParent(tree, record, children = 'children') {
let parent = null;
function search(nodes) {
for (let node of nodes) {
if (node[children]?.some((child) => getRecordKey(child) === getRecordKey(record))) {
parent = node;
return true;
}
if (node[children] && search(node[children])) {
return true;
}
}
return false;
}
search(tree);
return parent;
}
}
// 用于判断是否是自定义选择列
function isCustomSelection(column: BasicColumn) {
return column.key === CUS_SEL_COLUMN_KEY;

View File

@ -2,8 +2,40 @@ import type { ComputedRef } from 'vue';
import type { BasicTableProps, TableCustomRecord } from '../types/table';
import { unref } from 'vue';
import { isFunction } from '/@/utils/is';
import { ROW_KEY } from '/@/components/Table/src/const';
export function useTableStyle(propsRef: ComputedRef<BasicTableProps>, prefixCls: string) {
/**
* 2024-09-19
* liaozhiyang
* 【issues/7200】basicTable选中后没有选中样式
* */
const isChecked = (propsRef, record) => {
const getAutoCreateKey = () => {
return unref(propsRef).autoCreateKey && !unref(propsRef).rowKey;
};
const getRowKey = () => {
const { rowKey } = unref(propsRef);
return getAutoCreateKey() ? ROW_KEY : rowKey;
};
// 获取行的key字段数据
const getRecordKey = (record) => {
const key = getRowKey();
if (!key) {
return record[ROW_KEY];
} else if (isFunction(key)) {
return key(record);
} else {
return record[key];
}
};
const { rowSelection } = unref(propsRef);
if (rowSelection?.selectedRowKeys?.length) {
return rowSelection.selectedRowKeys.includes(getRecordKey(record));
}
return false;
};
function getRowClassName(record: TableCustomRecord, index: number) {
const { striped, rowClassName } = unref(propsRef);
const classNames: string[] = [];
@ -13,6 +45,11 @@ export function useTableStyle(propsRef: ComputedRef<BasicTableProps>, prefixCls:
if (rowClassName && isFunction(rowClassName)) {
classNames.push(rowClassName(record, index));
}
// update-begin--author:liaozhiyang---date:20240919---for【issues/7200】basicTable选中后没有选中样式
if (isChecked(propsRef, record)) {
classNames.push('ant-table-row-selected');
}
// update-end--author:liaozhiyang---date:20240919---for【issues/7200】basicTable选中后没有选中样式
return classNames.filter((cls) => !!cls).join(' ');
}

View File

@ -24,6 +24,10 @@
type: String as PropType<string>,
default: 'calc(100vh - 78px)',
},
customColor: {
type: Array,
default: () => [],
}
},
setup(props) {
const chartRef = ref<HTMLDivElement | null>(null);
@ -68,12 +72,15 @@
//轴数据
let xAxisData = Array.from(new Set(props.chartData.map((item) => item.name)));
let seriesData = [];
typeArr.forEach((type) => {
typeArr.forEach((type,index) => {
let obj = { name: type };
let chartArr = props.chartData.filter((item) => type === item.type);
//data数据
obj['data'] = chartArr.map((item) => item.value);
obj['type'] = chartArr[0].seriesType;
if(props?.customColor && props?.customColor[index]){
obj['color'] = props.customColor[index];
}
seriesData.push(obj);
});
option.series = seriesData;

View File

@ -7,6 +7,7 @@ import { JVxeRenderType } from '../types/JVxeTypes';
import { isBoolean, isFunction, isObject, isPromise } from '/@/utils/is';
import { JVxeComponent } from '../types/JVxeComponent';
import { filterDictText } from '/@/utils/dict/JDictSelectUtil';
import { getAreaTextByCode } from "@/components/Form/src/utils/Area";
export function useJVxeCompProps() {
return {
@ -160,6 +161,14 @@ export function useJVxeComponent(props: JVxeComponent.Props) {
return;
}
// update-end--author:liaozhiyang---date:20240509---for【QQYUN-9205】一对多(jVxetable组件date)支持年,年月,年度度,年周
//update-begin---author:wangshuai---date:2024-09-18---for:【issues/7203】自动生成一对多表单代码中省市区回显问题---
if (props.type === 'pca' && props.renderType === JVxeRenderType.spaner) {
innerValue.value = getAreaTextByCode(newValue);
return;
}
//update-end---author:wangshuai---date:2024-09-18---for:【issues/7203】自动生成一对多表单代码中省市区回显问题---
// 判断是否启用翻译
if (props.renderType === JVxeRenderType.spaner && enhanced.translate.enabled === true) {
if (isFunction(enhanced.translate.handler)) {

View File

@ -62,7 +62,9 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
watch(
() => getSplit.value,
() => {
if (unref(splitNotLeft)) return;
// update-begin--author:liaozhiyang---date:20240919---for【issues/7209】顶部左侧组合菜单关闭之后左侧导航没还原
// if (unref(splitNotLeft)) return;
// update-end--author:liaozhiyang---date:20240919---for【issues/7209】顶部左侧组合菜单关闭之后左侧导航没还原
genMenus();
}
);

View File

@ -1,7 +1,7 @@
<template>
<div :class="prefixCls">
<span> {{ title }}</span>
<InputNumber v-bind="$attrs" size="small" :class="`${prefixCls}-input-number`" @change="handleChange" />
<InputNumber :max="7200" v-bind="$attrs" size="small" :class="`${prefixCls}-input-number`" @change="handleChange" />
</div>
</template>
<script lang="ts">

View File

@ -21,6 +21,8 @@ import {
import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting';
import { toRaw } from 'vue';
import { pick, omit } from 'lodash-es';
import { PageEnum } from '/@/enums/pageEnum';
import { router } from '/@/router';
interface BasicStore {
[TOKEN_KEY]: string | number | null | undefined;
@ -60,9 +62,11 @@ export class Persistent {
static getLocal<T>(key: LocalKeys) {
//update-begin---author:scott ---date:2022-10-27 fortoken过期退出重新登录online菜单还是提示token过期----------
const globalCache = ls.get(APP_LOCAL_CACHE_KEY);
if(globalCache){
// update-begin--author:liaozhiyang---date:20240920---for【issues/7250】自动锁屏无法解锁
if (globalCache && router?.currentRoute?.value.path !== PageEnum.BASE_LOGIN) {
localMemory.setCache(globalCache);
}
// update-end--author:liaozhiyang---date:20240920---for【issues/7250】自动锁屏无法解锁
//update-end---author:scott ---date::2022-10-27 fortoken过期退出重新登录online菜单还是提示token过期----------
return localMemory.get(key)?.value as Nullable<T>;
}

View File

@ -1,8 +1,10 @@
const colors = ['#4db6ac', '#ffb74d', '#64b5f6', '#e57373', '#9575cd', '#a1887f', '#90a4ae', '#4dd0e1', '#81c784', '#ff8a65'];
export const getData = (() => {
let dottedBase = +new Date();
const barDataSource: any[] = [];
const barMultiData: any[] = [];
const barLineData: any[] = [];
const barLineColors: any[] = [];
for (let i = 0; i < 20; i++) {
let obj = { name: '', value: 0 };
@ -44,6 +46,7 @@ export const getData = (() => {
obj.value = Math.random() * 200;
barLineData.push(obj);
}
barLineColors.push(colors[j]);
}
return { barDataSource, barMultiData, pieData, barLineData, radarData };
return { barDataSource, barMultiData, pieData, barLineData, barLineColors,radarData };
})();

View File

@ -38,7 +38,7 @@
<Gauge :chartData="{ name: '出勤率', value: 70 }" height="50vh"></Gauge>
</a-tab-pane>
<a-tab-pane key="10" tab="折柱图">
<BarAndLine :chartData="barLineData" height="50vh"></BarAndLine>
<BarAndLine :chartData="barLineData" :customColor="barLineColors" height="50vh"></BarAndLine>
</a-tab-pane>
<a-tab-pane key="11" tab="排名列表">
<RankList title="门店销售排行榜" :list="rankList" style="width: 600px; margin: 0 auto"></RankList>
@ -71,7 +71,7 @@
import BarAndLine from '/@/components/chart/BarAndLine.vue';
const activeKey = ref('1');
const { barDataSource, barMultiData, pieData, barLineData, radarData } = getData;
const { barDataSource, barMultiData, pieData, barLineData, radarData,barLineColors } = getData;
const multiBarOption = {
title: { text: '多列柱状图', left: 'center' },
};