25 Commits

Author SHA1 Message Date
zhangdaiscott
df478e7779 群满,新增QQ群 ⑦791696430 2023-04-18 09:55:01 +08:00
zhangdaiscott
be6a1a7544 项目功能预留图 2023-04-17 23:01:40 +08:00
zhangdaiscott
b9dcb6821a 系统截图 2023-04-17 22:56:46 +08:00
zhangdaiscott
bb68975dc0 图片功能 2023-04-17 22:54:27 +08:00
zhangdaiscott
2449f805ec 预计3.5.1正式发布时间 2023-04-20 2023-04-17 15:37:37 +08:00
zhangdaiscott
4112e58577 出现严重问题,暂时回购此修改【issues/423】修复 JVxeTypes.hidden 不能赋值 2023-04-17 14:43:58 +08:00
zhangdaiscott
0daa05e8d0 3.5.1 版本发布 2023-04-14 15:23:35 +08:00
zhangdaiscott
7efc12fc65 【issues/395】升级esline版本,解决eslint报错问题和打印控件升级 2023-04-12 21:46:53 +08:00
zhangdaiscott
e9df85908a 【issues/423】修复 JVxeTypes.hidden 不能赋值 2023-04-12 21:45:16 +08:00
zhangdaiscott
41e48c5113 【issues/209】VXETable自带的tooltip会错位,所以替换成原生的title 2023-04-12 21:44:50 +08:00
zhangdaiscott
9d1ade6336 文档变更为: http://help.jeecg.com 2023-04-12 17:08:06 +08:00
zhangdaiscott
3818c31e55 更新文档地址 http://help.jeecg.com 2023-04-11 23:10:38 +08:00
zhangdaiscott
2ae47e898b [/issues/409]导出功能没有按排序结果导出,设置导出默认排序,创建时间倒序 2023-04-11 22:04:11 +08:00
zhangdaiscott
6d768d8320 [issue/4550]分类字典数据量过多会造成数据查询时间过长 2023-04-11 22:03:13 +08:00
zhangdaiscott
f48e1125d0 [issue/455]上传组件传入accept限制上传文件类型无效 2023-04-11 22:02:51 +08:00
zhangdaiscott
ccbdd0cf6d 【issues/448】暗夜模式不完整,有bug 2023-04-10 21:18:54 +08:00
zhangdaiscott
eae59a5501 【issues/435】代码生成的日期控件赋默认值报错,判断一下,浏览器提示警告 2023-04-10 21:06:21 +08:00
zhangdaiscott
f9c999ae2f [issue/430]弹出页面出现自动吸顶,无法移动和显示头部 2023-04-08 17:31:29 +08:00
zhangdaiscott
f95e4521ad 【issues/397】在表单中使用v-model:value绑定JSelectDept组件时无法清除已选择的数据 2023-04-06 21:29:19 +08:00
zhangdaiscott
0306b8669e 修复一系列bug
[issue/289]新增通知公告提交指定用户参数有undefined
[issue/382]省市区组件JAreaLinkage数据不回显
[issue/397]在表单中使用v-model:value绑定JSelectDept组件时无法清除已选择的数据
[issue/286]下拉搜索框问题
[issue/426]引入的回归错误 JPopupOnlReportModal.vue 中未修改
[issue/429]树搜索点击事件失效
【issues/394】所属部门树操作全部勾选不生效/【issues/4646】部门全部勾选后,点击确认按钮,部门信息丢失
【issues/424】开启右侧列表后,在右侧列表中删除用户时,逻辑有问题
【issues/4507】JDictSelectTag组件使用时,浏览器给出警告提示:Expected Function, got Array
2023-04-05 11:51:09 +08:00
zhangdaiscott
0b53292cfa 租户邀请人加入改成采用手机号 2023-03-15 11:34:00 +08:00
zhangdaiscott
7bfd40ae04 职务维护去掉不需要的字段 2023-03-15 11:33:54 +08:00
zhangdaiscott
4c8f5c8afd 角色查询增加角色编码条件 2023-03-15 11:33:46 +08:00
zhangdaiscott
2b79265fd3 租户套餐用户维护关系功能缺失 2023-03-13 16:15:12 +08:00
zhangdaiscott
e24ab230e7 版本补充说明 2023-03-08 13:37:57 +08:00
40 changed files with 742 additions and 164 deletions

18
LICENSE
View File

@@ -22,15 +22,11 @@ SOFTWARE.
<developers>
<developer>
<name>北京敲敲云科技有限公司</name>
<email>jeecgos@163.com</email>
</developer>
</developers>
开源协议补充
JeecgBoot 是由 北京敲敲云科技有限公司 发行的软件。 总部位于北京地址中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱jeecgos@163.com
本软件受适用的国家软件著作权法(包括国际条约)和双重保护许可。
<scm>
<connection>http://www.jeecg.com</connection>
<developerConnection>https://qiaoqiaoyun.com</developerConnection>
<url>http://www.jeecg.com/vip</url>
</scm>
1.允许基于本平台软件开展业务系统开发。
2.不得基于该平台软件的基础修改包装成一个与JeecgBoot平台软件功能类似的产品进行发布、销售或与JeecgBoot参与同类软件产品市场的竞争。
违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。
解释权归:http://www.jeecg.com

112
README.md
View File

@@ -1,11 +1,11 @@
JEECG BOOT 低代码开发平台Vue3前端
===============
当前最新版本: 3.5.0发布时间2023-03-08
当前最新版本: 3.5.1发布时间2023-04-20
[![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
[![](https://img.shields.io/badge/Author-北京敲敲云科技-orange.svg)](http://www.jeecg.com)
[![](https://img.shields.io/badge/Blog-官方博客-blue.svg)](https://jeecg.blog.csdn.net)
[![](https://img.shields.io/badge/version-3.5.0-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
[![](https://img.shields.io/badge/version-3.5.1-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot)
@@ -39,11 +39,11 @@ JeecgBoot-Vue3采用 Vue3.0、Vite、 Ant-Design-Vue3、TypeScript 等新技术
## 技术文档
- 官方文档:[http://vue3.jeecg.com](http://vue3.jeecg.com)
- 官方文档:[http://help.jeecg.com](http://help.jeecg.com)
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
- 在线演示:[低代码演示](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
- 快速入门:[常见问题](http://help.jeecg.com/qa.html) | [入门视频](https://www.bilibili.com/video/BV1V34y187Y9 "入门视频") | [ 代码生成](http://help.jeecg.com/vue3/codegen/online.html)
- QQ交流群⑦791696430、683903138
## 安装与使用
@@ -116,7 +116,7 @@ cd jeecgboot-vue3
VITE_GLOB_API_URL=/jeecgboot
VITE_GLOB_DOMAIN_URL=http://jeecg-boot-system:8080/jeecg-boot
```
后台单体启动 [见此文档](http://doc.jeecg.com/2043889)
后台单体启动 [见此文档](https://help.jeecg.com/java/setup/docker/up.html)
- 编译项目
@@ -147,7 +147,7 @@ VITE_GLOB_API_URL=/jeecgboot
VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999
```
后台微服务启动 [见此文档](http://doc.jeecg.com/2656147)
后台微服务启动 [见此文档](https://help.jeecg.com/java/springcloud/docker.html)
- 区别2. 修改Dockerfile文件
@@ -172,7 +172,7 @@ VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999
本项目需要一定前端基础知识,请确保掌握 Vue 的基础知识,以便能处理一些常见的问题。 建议在开发前先学一下以下内容,提前了解和学习这些知识,会对项目理解非常有帮助:
* [JeecgBoot-Vue3文档](http://vue3.jeecg.com)
* [JeecgBoot-Vue3文档](http://help.jeecg.com)
* [Vue3 文档](https://cn.vuejs.org/)
* [Vben文档](https://doc.vvbin.cn)
* [Ant-Design-Vue](https://www.antdv.com/docs/vue/introduce-cn/)
@@ -334,25 +334,93 @@ VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999
## 系统效果
系统后台
![输入图片说明](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/site/vue3_20220310142327.png "在这里输入图片标题")
![](https://oscimg.oschina.net/oscnet/up-000530d95df337b43089ac77e562494f454.png)
![输入图片说明](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/site/vue3_20220310142354.png "在这里输入图片标题")
![输入图片说明](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/site/vue3_20220310142339.png "在这里输入图片标题")
![输入图片说明](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/site/vue3_20220310142409.png "在这里输入图片标题")
![输入图片说明](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/site/vue3_20220310142401.png "在这里输入图片标题")
![输入图片说明](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/site/vue3_11.png "在这里输入图片标题")
Online表单&Online报表&代码生成
Online开发&代码生成
![](https://oscimg.oschina.net/oscnet/up-e8862f2c3c14eace9090c20a8fb928234a4.png)
![](https://oscimg.oschina.net/oscnet/up-e3b3a736236bc66f255a9a32ab3f9b7196b.png)
![](https://oscimg.oschina.net/oscnet/up-221b8cbdea3c17d31a1365023a73d3d439f.png)
![](https://oscimg.oschina.net/oscnet/up-14092f6f213b26ab145cf70b2dc6dec5635.png)
系统交互
![](https://oscimg.oschina.net/oscnet/up-78b151fc888d4319377bf1cc311fe826871.png)
![](https://oscimg.oschina.net/oscnet/up-16c07e000278329b69b228ae3189814b8e9.png)
流程设计
![](https://oscimg.oschina.net/oscnet/up-981ce174e4fbb48c8a2ce4ccfd7372e2994.png)
![输入图片说明](https://static.oschina.net/uploads/img/201907/05165142_yyQ7.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160917_9Ftz.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160633_u59G.png "在这里输入图片标题")
简版流程设计
![](https://oscimg.oschina.net/oscnet/up-1dc0d052149ec675f3e4fad632b82b48add.png)
![](https://oscimg.oschina.net/oscnet/up-de31bc2f9d9b8332c554b0954cc73d79593.png)
![](https://oscimg.oschina.net/oscnet/up-7f83b25159663686d67ed080eb16068c3b4.png)
仪表盘设计器
![](https://oscimg.oschina.net/oscnet/up-9c9d41288c31398d76b390bdd400f13a582.png)
![](https://oscimg.oschina.net/oscnet/up-fad98d42b2cf92f92a903c9cff7579f18ec.png)
报表设计器
![](https://oscimg.oschina.net/oscnet/up-64648de000851f15f6c7b9573d107ebb5f8.png)
![](https://oscimg.oschina.net/oscnet/up-fa52b44445db281c51d3f267dce7450d21b.gif)
![](https://oscimg.oschina.net/oscnet/up-68a19149d640f1646c8ed89ed4375e3326c.png)
![](https://oscimg.oschina.net/oscnet/up-f7e9cb2e3740f2d19ff63b40ec2dd554f96.png)
表单设计器
![](https://oscimg.oschina.net/oscnet/up-5f8cb657615714b02190b355e59f60c5937.png)
![](https://oscimg.oschina.net/oscnet/up-d9659b2f324e33218476ec98c9b400e6508.png)
![](https://oscimg.oschina.net/oscnet/up-4868615395272d3206dbb960ade02dbc291.png)
大屏设计器
![](https://oscimg.oschina.net/oscnet/up-402a6034124474bfef8dfc5b4b2bac1ce5c.png)
![](https://oscimg.oschina.net/oscnet/up-6f7ba2e2ebbeea0d203db8d69fd87644c9f.png)
![](https://oscimg.oschina.net/oscnet/up-ee8d34f318da466b8a6070a6e3111d12ce7.png)
![](https://oscimg.oschina.net/oscnet/up-6b81781b43086819049c4421206810667c5.png)
报表效果
![](https://static.oschina.net/uploads/img/201904/14160828_pkFr.png "")
![](https://static.oschina.net/uploads/img/201904/14160834_Lo23.png "")
![](https://static.oschina.net/uploads/img/201904/14160842_QK7B.png "")
![](https://static.oschina.net/uploads/img/201904/14160849_GBm5.png "")
![](https://static.oschina.net/uploads/img/201904/14160858_6RAM.png "")
接口文档
@@ -360,22 +428,14 @@ Online表单&Online报表&代码生成
![](https://oscimg.oschina.net/oscnet/up-e6ea09dbaa01b8458c2e23614077ba9507f.png)
流程设计&表单设计
手机端
![](https://oscimg.oschina.net/oscnet/da543c5d0d57baab0cecaa4670c8b68c521.jpg)
![](https://oscimg.oschina.net/oscnet/fda4bd82cab9d682de1c1fbf2060bf14fa6.jpg)
![](https://oscimg.oschina.net/oscnet/up-fe98e9f766e5abb6759f6f13d5f9186f0cf.png)
![](https://static.oschina.net/uploads/img/201904/14160917_9Ftz.png "")
![](https://static.oschina.net/uploads/img/201904/14160633_u59G.png "")
![](https://static.oschina.net/uploads/img/201907/05165142_yyQ7.png "")
大屏模板
![](https://static.oschina.net/uploads/img/201912/25133248_Ag1C.jpg "")
![](https://static.oschina.net/uploads/img/201912/25133301_k9Kc.jpg "")
![](https://oscimg.oschina.net/oscnet/up-649cb79c01eb95d5c2217a5dad28515da82.png)
PAD端
![](https://oscimg.oschina.net/oscnet/e90fef970a8c33790ab03ffd6c4c7cec225.jpg)
![](https://oscimg.oschina.net/oscnet/d78218803a9e856a0aa82b45efc49849a0c.jpg)
![](https://oscimg.oschina.net/oscnet/59c23b230f52384e588ee16309b44fa20de.jpg)

View File

@@ -1,6 +1,6 @@
{
"name": "jeecgboot-vue3",
"version": "3.5.0",
"version": "3.5.1",
"author": {
"name": "jeecg",
"email": "jeecgos@163.com",
@@ -81,7 +81,7 @@
"vue-cropperjs": "^5.0.0",
"vue-i18n": "^9.1.9",
"vue-infinite-scroll": "^2.0.2",
"vue-print-nb-jeecg": "^1.0.10",
"vue-print-nb-jeecg": "^1.0.12",
"vue-router": "^4.0.14",
"vue-types": "^4.1.1",
"vuedraggable": "^4.1.0",
@@ -125,12 +125,12 @@
"cz-git": "^1.3.9",
"czg": "^1.3.9",
"dotenv": "^16.0.0",
"eslint": "^8.13.0",
"eslint-config-prettier": "^8.5.0",
"eslint-define-config": "^1.1.1",
"eslint-plugin-jest": "^25.2.2",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.6.0",
"eslint": "^8.22.0",
"eslint-config-prettier": "^8.6.0",
"eslint-define-config": "^1.14.0",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.9.0",
"esno": "^0.14.1",
"fs-extra": "^10.1.0",
"http-server": "^14.0.0",

View File

@@ -117,7 +117,15 @@
const { defaultValue, component, componentProps } = schema;
// handle date type
if (defaultValue && dateItemType.includes(component)) {
const { valueFormat } = componentProps
//update-begin---author:wangshuai ---date:20230410 for【issues/435】代码生成的日期控件赋默认值报错------------
let valueFormat:string = "";
if(componentProps){
valueFormat = componentProps?.valueFormat;
}
if(!valueFormat){
console.warn("未配置valueFormat,可能导致格式化错误!");
}
//update-end---author:wangshuai ---date:20230410 for【issues/435】代码生成的日期控件赋默认值报错------------
if (!Array.isArray(defaultValue)) {
//update-begin---author:wangshuai ---date:20221124 for[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
if(valueFormat){

View File

@@ -81,7 +81,7 @@
required: false,
},
},
emits: ['options-change', 'change'],
emits: ['options-change', 'change','update:value'],
setup(props, { emit, refs }) {
const dictOptions = ref<any[]>([]);
const attrs = useAttrs();
@@ -164,6 +164,10 @@
changeValue = e?.target?.value ?? e;
}
state.value = changeValue;
//update-begin---author:wangshuai ---date:20230403 for【issues/4507】JDictSelectTag组件使用时浏览器给出警告提示Expected Function, got Array------------
emit('update:value',changeValue)
//update-end---author:wangshuai ---date:20230403 for【issues/4507】JDictSelectTag组件使用时浏览器给出警告提示Expected Function, got Array述------------
//update-end---author:wangshuai ---date:20230216 for[QQYUN-4290]公文发文:选择机关代字报错,是因为值改变触发了change事件三次导致数据发生改变------------
// nextTick(() => formItemContext.onFieldChange());

View File

@@ -2,6 +2,7 @@
<div class="clearfix">
<a-upload
:listType="listType"
accept="image/*"
:multiple="multiple"
:action="uploadUrl"
:headers="headers"

View File

@@ -29,6 +29,7 @@
:placeholder="placeholder"
:filterOption="filterOption"
:notFoundContent="loading ? undefined : null"
:dropdownAlign="{overflow: {adjustY: adjustY }}"
@change="handleChange"
>
<template #notFoundContent>
@@ -64,6 +65,10 @@
type: Function,
default: (node) => node.parentNode,
},
//默认开启Y轴溢出位置调整因此在可视空间不足时下拉框位置会自动上移导致Select的输入框被遮挡。需要注意的是默认情况是是可视空间而不是所拥有的空间
//update-begin-author:liusq date:2023-04-04 for:[issue/286]下拉搜索框遮挡问题
adjustY:propTypes.bool.def(true),
//update-end-author:liusq date:2023-04-04 for:[issue/286]下拉搜索框遮挡问题
//是否在有值后立即触发change
immediateChange: propTypes.bool.def(false),
//update-begin-author:taoyan date:2022-8-15 for: VUEN-1971 【online 专项测试】关联记录和他表字段 1

View File

@@ -1,7 +1,7 @@
<!--部门选择组件-->
<template>
<div>
<JSelectBiz @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs" />
<JSelectBiz @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs" @change="handleChange"/>
<DeptSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue" />
</div>
</template>
@@ -119,6 +119,17 @@
emit('update:value', values.join(','));
}
const getBindValue = Object.assign({}, unref(props), unref(attrs));
//update-begin---author:wangshuai ---date:20230406 for【issues/397】在表单中使用v-model:value绑定JSelectDept组件时无法清除已选择的数据------------
/**
* 值改变事件更新value值
* @param values
*/
function handleChange(values) {
emit('update:value', values);
}
//update-end---author:wangshuai ---date:20230406 for【issues/397】在表单中使用v-model:value绑定JSelectDept组件时无法清除已选择的数据------------
return {
state,
attrs,
@@ -130,6 +141,7 @@
regModal,
setValue,
handleOpen,
handleChange
};
},
});

View File

@@ -26,7 +26,7 @@
</template>
<script lang="ts" setup>
import { ref, reactive, computed, watch, nextTick, createApp } from 'vue';
import { ref, reactive, computed, watch, nextTick, createApp,unref } from 'vue';
import { Icon } from '/@/components/Icon';
import { getToken } from '/@/utils/auth';
import { uploadUrl } from '/@/api/common/api';
@@ -82,7 +82,10 @@
const isImageMode = computed(() => props.fileType === UploadTypeEnum.image);
// 合并 props 和 attrs
const bindProps = computed(() => {
const bind: any = Object.assign({}, props, attrs);
//update-begin-author:liusq date:20220411 for: [issue/455]上传组件传入accept限制上传文件类型无效
const bind: any = Object.assign({}, props, unref(attrs));
//update-end-author:liusq date:20220411 for: [issue/455]上传组件传入accept限制上传文件类型无效
bind.name = 'file';
bind.listType = isImageMode.value ? 'picture-card' : 'text';
bind.class = [bind.class, { 'upload-disabled': props.disabled }];

View File

@@ -129,7 +129,7 @@
queryParam,
dictOptions,
},
] = usePopBiz(getBindValue);
] = usePopBiz(getBindValue,tableRef);
const showSearchFlag = computed(() => unref(queryInfo) && unref(queryInfo).length > 0);
/**

View File

@@ -138,8 +138,10 @@ export function useSelectBiz(getList, props) {
}
//删除已选择的信息
function handleDeleteSelected(record) {
checkedKeys.value = checkedKeys.value.splice(checkedKeys.value.indexOf(record['id']), 1);
selectRows.value = selectRows.value.filter((item) => item['id'] !== record['id']);
//update-begin---author:wangshuai ---date:20230404 for【issues/424】开启右侧列表后在右侧列表中删除用户时逻辑有问题------------
checkedKeys.value = checkedKeys.value.filter((item) => item != record[props.rowKey]);
selectRows.value = selectRows.value.filter((item) => item[props.rowKey] !== record[props.rowKey]);
//update-end---author:wangshuai ---date:20230404 for【issues/424】开启右侧列表后在右侧列表中删除用户时逻辑有问题------------
}
//清空选择项
function reset() {

View File

@@ -115,8 +115,31 @@ export function useTreeBiz(treeRef, getList, props) {
/**
* 勾选全部
*/
function checkALL(checkAll) {
async function checkALL(checkAll) {
getTree().checkAll(checkAll);
//update-begin---author:wangshuai ---date:20230403 for【issues/394】所属部门树操作全部勾选不生效/【issues/4646】部门全部勾选后点击确认按钮部门信息丢失------------
await nextTick();
checkedKeys.value = getTree().getCheckedKeys();
if(checkAll){
getTreeRow();
}else{
selectRows.value = [];
}
//update-end---author:wangshuai ---date:20230403 for【issues/394】所属部门树操作全部勾选不生效/【issues/4646】部门全部勾选后点击确认按钮部门信息丢失------------
}
/**
* 获取数列表
* @param res
*/
function getTreeRow() {
let ids = "";
if(unref(checkedKeys).length>0){
ids = checkedKeys.value.join(",");
}
getList({ids:ids}).then((res) =>{
selectRows.value = res;
})
}
/**

View File

@@ -56,15 +56,17 @@ class Area {
}
}
}
getText(code) {
//update-begin-author:liusq---date:20230404--for: [issue/382]省市区组件JAreaLinkage数据不回显---
getText(code,index=3) {
if (!code || code.length == 0) {
return '';
}
let arr = [];
this.getAreaBycode(code, arr, 3);
this.getAreaBycode(code, arr, index);
return arr.join('/');
}
//update-end-author:liusq---date:20230404--for: [issue/382]省市区组件JAreaLinkage数据不回显---
getRealCode(code) {
let arr = [];
@@ -98,12 +100,14 @@ const jeecgAreaData = new Area();
// 根据code找文本
const getAreaTextByCode = function (code) {
let index = 3;
//update-begin-author:liusq---date:20220531--for: 判断code是否是多code逗号分割的字符串是的话获取最后一位的code ---
if (code && code.includes(',')) {
index = code.split(",").length;
code = code.substr(code.lastIndexOf(',') + 1);
}
//update-end-author:liusq---date:20220531--for: 判断code是否是多code逗号分割的字符串是的话获取最后一位的code ---
return jeecgAreaData.getText(code);
return jeecgAreaData.getText(code,index);
};
export { getAreaTextByCode };

View File

@@ -36,7 +36,12 @@ export function useModalDragMove(context: UseModalDragMoveContext) {
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
const minDragDomTop = dragDom.offsetTop;
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
let maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
//update-begin-author:liusq---date:20230407--for: [issue/430]弹出页面出现自动吸顶,无法移动和显示头部---
if(maxDragDomTop<0){
maxDragDomTop = screenHeight - dragDom.offsetTop
}
//update-end-author:liusq---date:20230407--for: [issue/430]弹出页面出现自动吸顶,无法移动和显示头部---
// 获取到的值带px 正则匹配替换
const domLeft = getStyle(dragDom, 'left');
const domTop = getStyle(dragDom, 'top');

View File

@@ -90,11 +90,13 @@
onCheck: (v: CheckKeys, e) => {
let currentValue = toRaw(state.checkedKeys) as KeyType[];
if (isArray(currentValue) && searchState.startSearch) {
const { key } = unref(getFieldNames);
currentValue = difference(currentValue, getChildrenKeys(e.node.$attrs.node[key]));
//update-begin-author:liusq---date:20230404--for: [issue/429]树搜索点击事件失效---
const value = e.node.eventKey;
currentValue = difference(currentValue, getChildrenKeys(value));
if (e.checked) {
currentValue.push(e.node.$attrs.node[key]);
currentValue.push(value);
}
//update-begin-author:liusq---date:20230404--for: [issue/429]树搜索点击事件失效---
state.checkedKeys = currentValue;
} else {
state.checkedKeys = v;

View File

@@ -17,10 +17,14 @@ export function useData(props: JVxeTableProps): JVxeDataProps {
rowId: props.rowKey,
// 高亮hover的行
highlightHoverRow: true,
// --- 【issues/209】自带的tooltip会错位所以替换成原生的title ---
// 溢出隐藏并显示tooltip
showOverflow: true,
showOverflow: "title",
// 表头溢出隐藏并显示tooltip
showHeaderOverflow: true,
showHeaderOverflow: "title",
// --- 【issues/209】自带的tooltip会错位所以替换成原生的title ---
showFooterOverflow: true,
// 可编辑配置
editConfig: {

View File

@@ -5,7 +5,7 @@ import { filterMultiDictText } from '/@/utils/dict/JDictSelectUtil.js';
import { useMessage } from '/@/hooks/web/useMessage';
import { OnlineColumn } from '/@/components/jeecg/OnLine/types/onlineConfig';
import { h } from 'vue';
import { useRouter } from 'vue-router';
import { useRouter, useRoute } from 'vue-router';
import { useMethods } from '/@/hooks/system/useMethods';
import { importViewsFile } from '/@/utils';
@@ -33,6 +33,8 @@ export function usePopBiz(props, tableRef?) {
const dataSource = ref<Array<object>>([]);
//定义表格信息
const columns = ref<Array<object>>([]);
// 当前路由
const route = useRoute();
//定义请求url信息
const configUrl = reactive({
//列表页加载column和data
@@ -533,6 +535,7 @@ export function usePopBiz(props, tableRef?) {
pagination.current = 1;
}
let params = getQueryParams(); //查询条件
params['onlRepUrlParamStr'] = getUrlParamString();
console.log('params', params);
loading.value = true;
let url = `${configUrl.getData}${unref(cgRpConfigId)}`;
@@ -546,6 +549,20 @@ export function usePopBiz(props, tableRef?) {
});
}
/**
* 获取地址栏的参数
*/
function getUrlParamString() {
let query = route.query;
let arr:any[] = []
if(query && Object.keys(query).length>0){
Object.keys(query).map(k=>{
arr.push(`${k}=${query[k]}`)
})
}
return arr.join('&')
}
/**
* 设置dataSource
*/
@@ -560,9 +577,11 @@ export function usePopBiz(props, tableRef?) {
}
dataSource.value = data.records;
//update-begin-author:taoyan date:2023-2-11 for:issues/356 在线报表分页有问题
tableRef.value && tableRef.value.setPagination({
//update-begin-author:liusq date:2023-4-04 for:issues/426 修复356时候引入的回归错误 JPopupOnlReportModal.vue 中未修改
tableRef?.value && tableRef?.value?.setPagination({
total: Number(data.total)
})
//update-end-author:liusq date:2023-4-04 for:issues/426 修复356时候引入的回归错误 JPopupOnlReportModal.vue 中未修改
//update-end-author:taoyan date:2023-2-11 for:issues/356 在线报表分页有问题
} else {
pagination.total = 0;

View File

@@ -69,13 +69,20 @@ export function useListPage(options: ListPageOptions) {
if (realUrl) {
let title = typeof name === 'function' ? name() : name;
//update-begin-author:taoyan date:20220507 for: erp代码生成 子表 导出报错,原因未知-
let paramsForm = {};
let paramsForm:any = {};
try {
paramsForm = await getForm().validate();
} catch (e) {
console.error(e);
}
//update-end-author:taoyan date:20220507 for: erp代码生成 子表 导出报错,原因未知-
//update-begin-author:liusq date:20230410 for:[/issues/409]导出功能没有按排序结果导出,设置导出默认排序,创建时间倒序
if(!paramsForm?.column){
Object.assign(paramsForm,{column:'createTime',order:'desc'});
}
//update-begin-author:liusq date:20230410 for: [/issues/409]导出功能没有按排序结果导出,设置导出默认排序,创建时间倒序
//如果参数不为空,则整合到一起
//update-begin-author:taoyan date:20220507 for: erp代码生成 子表 导出动态设置mainId
if (params) {
@@ -90,6 +97,7 @@ export function useListPage(options: ListPageOptions) {
if (selectedRowKeys.value && selectedRowKeys.value.length > 0) {
paramsForm['selections'] = selectedRowKeys.value.join(',');
}
console.log()
return handleExportXls(title as string, realUrl, filterObj(paramsForm));
//update-end---author:wangshuai ---date:20220411 for导出新增自定义参数--------------
} else {

View File

@@ -2,7 +2,7 @@
export const GITHUB_URL = 'https://github.com/jeecgboot/jeecgboot-vue3';
// vue-Jeecg-admin-next-doc
export const DOC_URL = 'http://vue3.jeecg.com';
export const DOC_URL = 'http://help.jeecg.com';
// site url
export const SITE_URL = 'http://www.jeecg.com';

View File

@@ -4,7 +4,7 @@
<DepartLeftTree ref="leftTree" @select="onTreeSelect" />
</a-col>
<a-col :xl="18" :lg="24" :md="24" style="margin-bottom: 10px">
<div style="height: 100%; background-color: white">
<div style="height: 100%;" class="address-book">
<!--引用表格-->
<BasicTable @register="registerTable">
<template #post="{ text }">
@@ -86,4 +86,10 @@
<style lang="less" scoped>
@import './index.less';
/*begin 兼容暗夜模式*/
.address-book{
background-color: @component-background !important;
}
/*end 兼容暗夜模式*/
</style>

View File

@@ -14,6 +14,7 @@
const isUpdate = ref(true);
const expandedRowKeys = ref([]);
const treeData = ref([]);
const isSubAdd = ref(false);
//表单配置
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
schemas: formSchema,
@@ -34,6 +35,7 @@
expandedRowKeys.value = [];
setModalProps({ confirmLoading: false, minHeight: 80 });
isUpdate.value = !!data?.isUpdate;
isSubAdd.value = !!!data?.isUpdate && data.record.id;
if (data?.record) {
//表单赋值
await setFieldsValue({
@@ -79,7 +81,7 @@
//展开的节点信息
await getExpandKeysByPid(values['pid'], unref(treeData));
//刷新列表(isUpdate:是否编辑;values:表单信息;expandedArr:展开的节点信息)
emit('success', { isUpdate: unref(isUpdate), values: { ...values }, expandedArr: unref(expandedRowKeys).reverse() });
emit('success', { isUpdate: unref(isUpdate), isSubAdd:unref(isSubAdd), values: { ...values }, expandedArr: unref(expandedRowKeys).reverse() });
} finally {
setModalProps({ confirmLoading: false });
}

View File

@@ -145,7 +145,7 @@
/**
* 成功回调
*/
async function handleSuccess({ isUpdate, values, expandedArr }) {
async function handleSuccess({ isUpdate,isSubAdd, values, expandedArr }) {
if (isUpdate) {
//编辑回调
updateTableDataRecord(values.id, values);
@@ -155,9 +155,15 @@
reload();
} else {
//新增子集
expandedRowKeys.value = [];
for (let key of unref(expandedArr)) {
await expandTreeNode(key);
//update-begin-author:liusq---date:20230411--for: [issue/4550]分类字典数据量过多会造成数据查询时间过长---
if(isSubAdd){
await expandTreeNode(values.pid);
//update-end-author:liusq---date:20230411--for: [issue/4550]分类字典数据量过多会造成数据查询时间过长---
}else{
expandedRowKeys.value = [];
for (let key of unref(expandedArr)) {
await expandTreeNode(key);
}
}
}
}
@@ -247,8 +253,12 @@
*操作表格后处理树节点展开合并
* */
async function expandTreeNode(key) {
let record = findTableDataRecord(key);
expandedRowKeys.value.push(key);
let record:any = findTableDataRecord(key);
//update-begin-author:liusq---date:20230411--for: [issue/4550]分类字典数据量过多会造成数据查询时间过长,显示“接口请求超时,请刷新页面重试!”---
if(!expandedRowKeys.value.includes(key)){
expandedRowKeys.value.push(key);
}
//update-end-author:liusq---date:20230411--for: [issue/4550]分类字典数据量过多会造成数据查询时间过长,显示“接口请求超时,请刷新页面重试!”---
let result = await getChildList({ pid: key });
if (result && result.length > 0) {
record.children = getDataByResult(result);

View File

@@ -112,3 +112,11 @@
}
}
</script>
<style lang="less" scoped>
/*begin 兼容暗夜模式*/
.j-box-bottom-button-float{
background-color: @component-background;
border-top: 1px solid @border-color-base;
}
/*end 兼容暗夜模式*/
</style>

View File

@@ -166,4 +166,11 @@
.depart-rule-tree :deep(.scrollbar__bar) {
pointer-events: none;
}
/*begin 兼容暗夜模式*/
.j-box-bottom-button-float{
background-color: @component-background;
border-top: 1px solid @border-color-base;
}
/*end 兼容暗夜模式*/
</style>

View File

@@ -4,7 +4,7 @@
<DepartLeftTree ref="leftTree" @select="onTreeSelect" @rootTreeData="onRootTreeData" />
</a-col>
<a-col :xl="12" :lg="24" :md="24" style="margin-bottom: 10px">
<div style="height: 100%; background-color: white">
<div style="height: 100%;" class="depart-manage">
<a-tabs v-show="departData != null" defaultActiveKey="base-info">
<a-tab-pane tab="基本信息" key="base-info" forceRender style="position: relative">
<div style="padding: 20px">
@@ -61,3 +61,10 @@
<style lang="less">
@import './index.less';
</style>
<style lang="less" scoped>
/*begin 兼容暗夜模式*/
.depart-manage{
background-color: @component-background;
}
/*end 兼容暗夜模式*/
</style>

View File

@@ -11,6 +11,7 @@
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
import { useI18n } from '/@/hooks/web/useI18n';
import {getTenantId} from "/@/utils/auth";
const isOAuth = ref<boolean>(isOAuth2AppEnv());
const env = ref<any>({ thirdApp: false, wxWork: false, dingtalk: false });
@@ -50,7 +51,7 @@
if (route.query.oauth2LoginToken) {
let token = route.query.oauth2LoginToken;
//执行登录操作
thirdLogin({ token, thirdType: route.query.thirdType });
thirdLogin({ token, thirdType: route.query.thirdType,tenantId: getTenantId });
} else if (env.value.wxWork) {
sysOAuth2Login('wechat_enterprise');
} else if (env.value.dingtalk) {
@@ -83,4 +84,4 @@
}
});
}
</script>
</script>

View File

@@ -41,7 +41,13 @@
let values = await validate();
setModalProps({ confirmLoading: true });
//提交表单
values.userIds += ',';
//update-begin-author:liusq---date:20230404--for: [issue#429]新增通知公告提交指定用户参数有undefined ---
if(values.msgType==='ALL'){
values.userIds = '';
}else{
values.userIds += ',';
}
//update-end-author:liusq---date:20230404--for: [issue#429]新增通知公告提交指定用户参数有undefined ---
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();

View File

@@ -2,22 +2,22 @@ import { BasicColumn, FormSchema } from '/@/components/Table';
import { rules } from '/@/utils/helper/validator';
export const columns: BasicColumn[] = [
{
title: '职务编码',
dataIndex: 'code',
width: 200,
align: 'left',
},
// {
// title: '职务编码',
// dataIndex: 'code',
// width: 200,
// align: 'left',
// },
{
title: '职务名称',
dataIndex: 'name',
width: 200,
},
{
title: '职务等级',
dataIndex: 'postRank_dictText',
width: 100,
},
// {
// title: '职务等级',
// dataIndex: 'postRank_dictText',
// width: 100,
// },
];
export const searchFormSchema: FormSchema[] = [
@@ -36,35 +36,35 @@ export const formSchema: FormSchema[] = [
component: 'Input',
show: false,
},
{
label: '职级',
field: 'postRank',
component: 'JDictSelectTag',
required: true,
componentProps: {
dictCode: 'position_rank',
dropdownStyle: {
maxHeight: '100vh',
},
getPopupContainer: () => document.body,
},
},
// {
// label: '职级',
// field: 'postRank',
// component: 'JDictSelectTag',
// required: true,
// componentProps: {
// dictCode: 'position_rank',
// dropdownStyle: {
// maxHeight: '100vh',
// },
// getPopupContainer: () => document.body,
// },
// },
{
field: 'name',
label: '职务名称',
component: 'Input',
required: true,
},
{
field: 'code',
label: '职务编码',
component: 'Input',
required: true,
dynamicDisabled: ({ values }) => {
return !!values.id;
},
dynamicRules: ({ model, schema }) => {
return rules.duplicateCheckRule('sys_position', 'code', model, schema, true);
},
},
// {
// field: 'code',
// label: '职务编码',
// component: 'Input',
// required: true,
// dynamicDisabled: ({ values }) => {
// return !!values.id;
// },
// dynamicRules: ({ model, schema }) => {
// return rules.duplicateCheckRule('sys_position', 'code', model, schema, true);
// },
// },
];

View File

@@ -42,6 +42,12 @@ export const searchFormSchema: FormSchema[] = [
component: 'Input',
colProps: { span: 6 },
},
{
field: 'roleCode',
label: '角色编码',
component: 'Input',
colProps: { span: 6 },
},
];
/**
* 角色用户搜索form

View File

@@ -0,0 +1,63 @@
<template>
<BasicModal @register="registerModal" :width="500" :title="title" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts">
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'TenantInviteUserModal',
components: {
BasicModal,
BasicForm,
},
setup(props, { emit }) {
const title = ref<string>('邀请成员');
const [registerForm, { resetFields, validate }] = useForm({
schemas: [
{
label: '手机号',
field: 'phone',
component: 'Input',
dynamicRules: () => {
return [
{ required: true, message: '请填写手机号' },
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' },
];
},
},
],
showActionButtonGroup: false,
labelCol: { span: 24 },
wrapperCol: { span: 24 },
});
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ minHeight: 100 });
});
/**
* 提交返回给租户list页面
*/
async function handleSubmit() {
let values = await validate();
emit('inviteOk',values.phone);
closeModal();
}
return {
title,
registerModal,
registerForm,
handleSubmit,
};
},
});
</script>
<style scoped></style>

View File

@@ -18,9 +18,10 @@
</BasicTable>
</BasicModal>
<TenantPackMenuModal @register="registerPackMenu" @success="success" />
<TenantPackUserModal @register="registerPackUser" @success="success" />
</template>
<script lang="ts" setup name="tenant-pack-modal">
import { ref, unref } from 'vue';
import { reactive, ref, unref } from 'vue';
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
import { packColumns, userColumns, packFormSchema } from './tenant.data';
import { getTenantUserList, leaveTenant, packList, deletePackPermissions } from './tenant.api';
@@ -28,8 +29,11 @@
import { BasicTable, TableAction } from '/@/components/Table';
import TenantPackMenuModal from './TenantPackMenuModal.vue';
import {Modal} from "ant-design-vue";
import TenantPackUserModal from './TenantPackUserModal.vue';
import {useMessage} from "/@/hooks/web/useMessage";
const [registerPackMenu, { openModal }] = useModal();
const [registerPackUser, { openModal: packUserOpenModal }] = useModal();
const tenantId = ref<number>(0);
// 列表页面公共参数、方法
const { prefixCls, tableContext } = useListPage({
@@ -57,12 +61,14 @@
},
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
const [registerTable, { reload }, { rowSelection, selectedRowKeys, selectedRows }] = tableContext;
// Emits声明
const emit = defineEmits(['register', 'success']);
const createBy = ref<string>('');
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
tenantId.value = data.tenantId;
createBy.value = data.createBy;
success();
});
//设置标题
@@ -75,6 +81,10 @@
function getActions(record) {
return [
{
label: '用户',
onClick: seeTenantPackUser.bind(null, record),
},
{
label: '编辑',
onClick: handleEdit.bind(null, record),
@@ -83,7 +93,7 @@
label: '删除',
popConfirm: {
title: '是否确认删除租户产品包',
confirm: handleDelete.bind(null, record.id),
confirm: handleDelete.bind(null, record),
},
},
];
@@ -108,18 +118,37 @@
});
}
//默认系统产品包不允许删除,包含(超级管理员、组织账户管理员、组织应用管理员)
const packCode = reactive<any>(['superAdmin','accountAdmin','appAdmin']);
const { createMessage } = useMessage();
/**
* 删除产品包
* @param 删除
*/
async function handleDelete(id) {
await deletePackPermissions({ ids: id }, success);
async function handleDelete(record) {
//update-begin---author:wangshuai ---date:20230222 for系统默认产品包不允许删除------------
if(packCode.indexOf(record.packCode) != -1){
createMessage.warning("默认系统产品包不允许删除");
return;
}
//update-end---author:wangshuai ---date:20230222 for系统默认产品包不允许删除------------
await deletePackPermissions({ ids: record.id }, success);
}
/**
* 批量删除产品包
*/
async function handlePackBatch() {
let value = selectedRows.value;
if(value && value.length>0){
for (let i = 0; i < value.length; i++) {
if(packCode.indexOf(value[i].packCode) != -1){
createMessage.warning("默认系统产品包不允许删除");
return;
}
}
}
Modal.confirm({
title: '删除租户产品包',
content: '是否删除租户产品包',
@@ -141,4 +170,15 @@
tenantId: unref(tenantId),
});
}
/**
* 产品包下面的用户
* @param record
*/
function seeTenantPackUser(record) {
record.createBy = unref(createBy);
packUserOpenModal(true,{
record:record
})
}
</script>

View File

@@ -0,0 +1,173 @@
<template>
<BasicModal @register="registerModal" destroyOnClose :title="title" :width="1000" @ok="handleSubmit">
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #departNames="{ text, record }">
<template v-if="text && text.length > 0">
{{ getName(text) }}
</template>
</template>
<template #positionNames="{ text, record }">
<template v-if="text && text.length > 0">
{{ getName(text) }}
</template>
</template>
<template #tableTitle>
<a-button preIcon="ant-design:usergroup-add-outlined" type="primary" @click="addUser">邀请成员</a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<user-select-modal :multi="true" @register="registerUserModal" @selected="onSelected"></user-select-modal>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from 'vue';
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { tenantPackUserColumns } from './tenant.data';
import { queryTenantPackUserList, deleteTenantPackUser, addTenantPackUser } from './tenant.api';
import UserSelectModal from '/@/components/Form/src/jeecg/components/userSelect/UserSelectModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { useUserStore } from '/@/store/modules/user';
export default defineComponent({
name: 'TenantPackUserModal',
components: { BasicModal, BasicTable, TableAction, UserSelectModal },
setup() {
//产品包信息
const tenantPackData = reactive<any>({});
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
setModalProps({ confirmLoading: false, showCancelBtn: true, showOkBtn: false });
Object.assign(tenantPackData, data.record);
await reload();
});
const { createMessage } = useMessage();
//设置标题
const title = ref<string>('用户');
//注册table数据
const { tableContext } = useListPage({
tableProps: {
api: queryTenantPackUserList,
immediate: false,
columns: tenantPackUserColumns,
canResize: false,
useSearchForm: false,
beforeFetch: (params) => {
params.tenantId = tenantPackData.tenantId;
params.packId = tenantPackData.id;
params.status = 1;
return params;
},
actionColumn: {
width: 120,
fixed: 'right',
},
},
});
const [registerUserModal, { openModal: openUserModal, closeModal: closeUserModal }] = useModal();
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
/**
* 获取部门/职务名称
* @param value
*/
function getName(value) {
return value.join(',');
}
/**
* 表格操作列
* @param record
*/
function getTableAction(record) {
const userStore = useUserStore();
let username = userStore.getUserInfo.username;
if (username != tenantPackData.createBy) {
}
return [
{
label: '移除',
popConfirm: {
title: '是否确认移除',
confirm: handleDelete.bind(null, record),
},
ifShow: username == tenantPackData.createBy,
},
{
label: '---',
ifShow: username != tenantPackData.createBy,
},
];
}
/**
* 删除
*/
async function handleDelete(record) {
let params = {
packId: record.packId,
packName: record.packName,
tenantId: record.tenantId,
userId: record.id,
realname: record.realname,
};
await deleteTenantPackUser(params);
await reload();
}
/**
* 添加用户弹窗
*/
function addUser() {
openUserModal(true, {
list: [],
});
}
/**
* 邀请人回调事件
* @param arr
*/
async function onSelected(arr) {
if (arr && arr.length > 0) {
let names: any[] = [];
let ids: any[] = [];
for (let u of arr) {
names.push(u.realname);
ids.push(u.id);
}
console.log(tenantPackData);
let params = {
packId: tenantPackData.id,
packName: tenantPackData.packName,
tenantId: tenantPackData.tenantId,
userId: ids.join(','),
realname: names.join(','),
};
await addTenantPackUser(params);
await reload();
}
closeUserModal();
}
return {
title,
registerModal,
registerTable,
rowSelection,
getName,
getTableAction,
registerUserModal,
addUser,
onSelected,
};
},
});
</script>
<style lang="less" scoped></style>

View File

@@ -40,7 +40,7 @@
</template>
</BasicTable>
<TenantModal @register="registerModal" @success="reload" />
<UserSelectModal rowKey="id" @register="registerSelUserModal" @getSelectResult="onSelectOk" />
<TenantInviteUserModal @register="registerSelUserModal" @inviteOk="handleInviteUserOk"/>
<TenantUserModal @register="registerTenUserModal" />
<!-- 产品包 -->
<TenantPackModal @register="registerPackModal" />
@@ -57,7 +57,7 @@
import TenantModal from './TenantModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { useListPage } from '/@/hooks/system/useListPage';
import UserSelectModal from '/@/components/Form/src/jeecg/components/modal/UserSelectModal.vue';
import TenantInviteUserModal from './TenantInviteUserModal.vue';
import TenantUserModal from './TenantUserModal.vue';
import TenantPackModal from './TenantPackModal.vue';
import TenantRecycleBinModal from './TenantRecycleBinModal.vue';
@@ -86,7 +86,7 @@
}
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
const [registerTable, { reload }, { rowSelection, selectedRowKeys, selectedRows }] = tableContext;
/**
* 操作列定义
@@ -156,14 +156,14 @@
/**
* 用户选择回调事件
* @param options
* @param values
* @param value
*/
async function onSelectOk(options, values) {
if (values && values.length > 0) {
await invitationUserJoin({ ids: selectedRowKeys.value.join(','), userIds: values.join(',') });
} else {
createMessage.warn('请选择用户!');
async function handleInviteUserOk(value) {
//update-begin---author:wangshuai ---date:20230314 for【QQYUN-4605】后台的邀请谁加入租户没办法选不是租户下的用户------------
if (value) {
await invitationUserJoin({ ids: selectedRowKeys.value.join(','), phone: value });
}
//update-end---author:wangshuai ---date:20230314 for【QQYUN-4605】后台的邀请谁加入租户没办法选不是租户下的用户------------
}
/**
@@ -186,6 +186,8 @@
}
packModal(true, {
tenantId: unref(selectedRowKeys.value.join(',')),
//将租户创建人(拥有者)传递过去,产品包下的用户不允许非拥有者删除
createBy: selectedRows.value[0].createBy
});
}

View File

@@ -19,6 +19,10 @@ enum Api {
recycleBinPageList = '/sys/tenant/recycleBinPageList',
deleteLogicDeleted = '/sys/tenant/deleteLogicDeleted',
revertTenantLogic = '/sys/tenant/revertTenantLogic',
//用户产品包关系api
queryTenantPackUserList = '/sys/tenant/queryTenantPackUserList',
deleteTenantPackUser = '/sys/tenant/deleteTenantPackUser',
addTenantPackUser = '/sys/tenant/addTenantPackUser',
}
/**
@@ -174,3 +178,27 @@ export const revertTenantLogic = (params,handleSuccess) => {
handleSuccess();
})
};
/**
* 获取租户产品包下面的用户
* @param params
*/
export const queryTenantPackUserList = (params) => {
return defHttp.get({ url: Api.queryTenantPackUserList, params });
};
/**
* 移除用户和产品包的关系数据
* @param params
*/
export const deleteTenantPackUser = (params)=>{
return defHttp.put({ url: Api.deleteTenantPackUser, params });
}
/**
* 添加用户和产品包的关系数据
* @param params
*/
export const addTenantPackUser = (params)=>{
return defHttp.post({ url: Api.addTenantPackUser, params });
}

View File

@@ -49,6 +49,11 @@ export const columns: BasicColumn[] = [
title: '部门',
width: 150
},
{
dataIndex: 'createBy_dictText',
title: '创建者(拥有者)',
width: 150
},
/* {
title: '开始时间',
dataIndex: 'beginDate',
@@ -300,6 +305,7 @@ export const packMenuFormSchema: FormSchema[] = [
pidField: 'parent_id',
multiple: true,
treeCheckAble:true,
treeCheckStrictly: true,
getPopupContainer: () => document.body,
},
},
@@ -372,3 +378,26 @@ export const searchRecycleFormSchema : FormSchema[] = [
component: 'Input',
},
]
//产品包用户列表
export const tenantPackUserColumns: BasicColumn[] = [
{
title: '用户',
dataIndex: 'realname',
width: 200,
},
{
title: '部门',
dataIndex: 'departNames',
width: 200,
ellipsis: true,
slots: { customRender: 'departNames' }
},
{
title: '职位',
dataIndex: 'positionNames',
ellipsis: true,
width: 200,
slots: { customRender: 'positionNames' }
}
]

View File

@@ -284,7 +284,12 @@ export const formSchema: FormSchema[] = [
label: '邮箱',
field: 'email',
component: 'Input',
rules: rules.rule('email', false),
dynamicRules: ({ model, schema }) => {
return [
{ ...rules.duplicateCheckRule('sys_user', 'email', model, schema, true)[0] },
{ ...rules.rule('email', false)[0] },
];
},
},
{
label: '手机号码',

View File

@@ -22,16 +22,6 @@
<span class="pointer blue-e5" style="margin-left: 10px" @click="updatePassWord">修改</span>
</div>
<div class="account-row-item">
<div class="account-label gray-75">账号绑定</div>
<span>
<WechatFilled :style="!wechatData.bindWechat ? { color: '#9e9e9e' } : { color: '#1ec563' }" />
<span class="gray-75" style="margin-left: 12px">微信</span>
<span class="gray-75" style="margin-left: 8px" v-if="wechatData.bindWechat">{{ '已绑定' + wechatData.name }}</span>
<span class="blue-e5 pointer" style="margin-left: 24px" @click="wechatBind">{{ !wechatData.bindWechat ? '绑定' : '解绑' }}</span>
</span>
</div>
<div class="account-row-item clearfix">
<div class="account-label gray-75">账户注销</div>
<span style="color: red" class="pointer" @click="cancellation">注销</span>
@@ -145,7 +135,9 @@ onMounted(() => {
<style lang="less" scoped>
.account-row-item {
align-items: center;
border-bottom: 1px solid #eaeaea;
/*begin 兼容暗夜模式*/
border-bottom: 1px solid @border-color-base;
/*end 兼容暗夜模式*/
box-sizing: border-box;
display: flex;
height: 71px;
@@ -158,7 +150,9 @@ onMounted(() => {
}
.gray-75 {
color: #757575 !important;
/*begin 兼容暗夜模式*/
color: @text-color !important;
/*end 兼容暗夜模式*/
}
.pointer {
@@ -188,7 +182,9 @@ onMounted(() => {
.my-account{
font-size: 17px;
font-weight: 700!important;
color: #333!important;
/*begin 兼容暗夜模式*/
color: @text-color;
/*end 兼容暗夜模式*/
margin-bottom: 20px;
}
</style>

View File

@@ -30,7 +30,7 @@
<div class="account-data">
<!-- 详细资料 -->
<div class="account-detail">
<div class="font-size-15 font-bold" style="color: #333!important;margin-bottom: 16px">详细资料</div>
<div class="font-size-15 font-bold font-color-gray" style="margin-bottom: 16px">详细资料</div>
<div class="margin-bottom-10 font-size-13">
<span class="gray-75 item-label">生日</span>
<span class="gray-3">{{ userInfo.birthday }}</span>
@@ -50,7 +50,7 @@
</div>
<!-- 联系信息 -->
<div class="account-info">
<div class="font-size-15 font-bold" style="color: #333!important;margin-bottom: 16px">联系信息</div>
<div class="font-size-15 font-bold font-color-gray" style="margin-bottom: 16px">联系信息</div>
<div class="margin-bottom-10 font-size-13">
<span class="gray-75 item-label">邮箱</span>
<span class="gray-3">{{ userInfo.email ? userInfo.email : "未填写" }}</span>
@@ -219,7 +219,7 @@ onMounted(async () => {
.user-setting-top {
padding-top: 40px;
width: 100%;
border-bottom: 1px solid #eaeaea;
border-bottom: 1px solid @border-color-base;
display: flex;
padding-bottom: 40px;
}
@@ -261,7 +261,9 @@ onMounted(async () => {
width: 200px;
text-overflow: ellipsis;
line-height: 32px!important;
color: #333;
/*begin 兼容暗夜模式*/
color: @text-color;
/*end 兼容暗夜模式*/
font-weight: 500;
}
@@ -300,13 +302,15 @@ onMounted(async () => {
margin-bottom: 10px;
}
/*begin 兼容暗夜模式*/
.gray-75 {
color: #757575 !important;
color: @text-color !important;
}
.gray-3 {
color: #333333;
color: @text-color;
}
/*end 兼容暗夜模式*/
.account-info {
width: 60%;
@@ -335,7 +339,9 @@ onMounted(async () => {
}
.use-day{
color: #333;
/*begin 兼容暗夜模式*/
color: @text-color;
/*end 兼容暗夜模式*/
margin-top: 10px;
font-size: 13px;
span{
@@ -346,4 +352,9 @@ onMounted(async () => {
.font-size-13{
font-size: 13px;
}
/*begin 兼容暗夜模式*/
.font-color-gray{
color: @text-color;
}
/*end 兼容暗夜模式*/
</style>

View File

@@ -420,7 +420,9 @@ onMounted(() => {
.my-tenant{
font-size: 17px;
font-weight: 700!important;
color: #333!important;
/*begin 兼容暗夜模式*/
color: @text-color;
/*end 兼容暗夜模式*/
margin-bottom: 20px;
}
.tenant-list{
@@ -430,7 +432,9 @@ onMounted(() => {
overflow-x: hidden;
}
.tenant-list-item{
border: 1px solid #eaeaea;
/*begin 兼容暗夜模式*/
border: 1px solid @border-color-base;
/*end 兼容暗夜模式*/
box-sizing: border-box;
display: flex;
flex-direction: column;
@@ -446,7 +450,9 @@ onMounted(() => {
padding: 14px 0;
cursor: pointer;
font-size:17px;
color: #333!important;
/*begin 兼容暗夜模式*/
color: @text-color;
/*end 兼容暗夜模式*/
font-weight: 700!important;
}
}
@@ -472,14 +478,18 @@ onMounted(() => {
transition: ease-in 2s;
.content-box {
border-top: 1px solid #eaeaea;
/*begin 兼容暗夜模式*/
border-top: 1px solid @border-color-base;
/*end 兼容暗夜模式*/
box-sizing: border-box;
display: flex;
padding: 24px 0;
}
.content-name {
color: #757575;
/*begin 兼容暗夜模式*/
color: @text-color;
/*end 兼容暗夜模式*/
text-align: center;
width: 100px;
font-size: 13px;
@@ -491,7 +501,9 @@ onMounted(() => {
}
.content-des-text {
color: #757575;
/*begin 兼容暗夜模式*/
color: @text-color;
/*end 兼容暗夜模式*/
text-align: left;
width: 76px;
font-size: 13px;
@@ -504,7 +516,9 @@ onMounted(() => {
}
.footer-box {
border-top: 1px solid #eaeaea;
/*begin 兼容暗夜模式*/
border-top: 1px solid @border-color-base;
/*end 兼容暗夜模式*/
box-sizing: border-box;
display: flex;
padding: 24px 0;
@@ -515,18 +529,20 @@ onMounted(() => {
margin-right: 40px;
}
/*begin 兼容暗夜模式*/
.font-color333 {
color: #333333;
color: @text-color;
font-weight: normal;
}
.font-color9e {
color: #9e9e9e;
color: @text-color;
}
.font-color75 {
color: #757575;
color: @text-color;
}
/*end 兼容暗夜模式*/
.font-size13 {
font-size: 13px;

View File

@@ -74,14 +74,18 @@ export default defineComponent({
}
//tabs弹窗左边样式
:deep(.ant-tabs-nav){
background-color: #FFFFFF;
/*begin 兼容暗夜模式*/
background-color: @component-background;
/*end 兼容暗夜模式*/
height: 260px;
}
//tabs弹窗右边边样式
:deep(.ant-tabs-content-holder){
position: relative;
left: 12px;
background: #FFFFFF;
/*begin 兼容暗夜模式*/
background: @component-background;
/*end 兼容暗夜模式*/
height: auto !important;
}
}
@@ -105,6 +109,8 @@ export default defineComponent({
padding-right:14px;
}
.icon-font-color{
color: #9e9e9e;
/*begin 兼容暗夜模式*/
color: @text-color;
/*end 兼容暗夜模式*/
}
</style>