【重要升级】3.4.4 online低代码功能,依赖升级 & 升级封装组件库

具体升级内容:
支持高级查询控件
online表单附表支持省市区组件
online表单开发是否支持多租户
online表单,支持快速配置菜单
online报表,支持快速配置菜单
online表单扩展配置优化使用体验
online表单 js增强输入多个hook报错处理
online表单,值规则的JS增强写法执行报错 #251
online表单,用户选择 控件的单选控制没有效果 #242
pull/340/head
zhangdaiscott 2022-11-24 10:27:53 +08:00
parent 1b5f6caa41
commit c402eec726
14 changed files with 312 additions and 28 deletions

View File

@ -34,7 +34,7 @@
"gen:icon": "esno ./build/generate/icon/index.ts"
},
"dependencies": {
"@jeecg/online": "3.4.3-GA",
"@jeecg/online": "3.4.4-RC",
"@iconify/iconify": "^2.2.1",
"@ant-design/colors": "^6.0.0",
"@ant-design/icons-vue": "^6.1.0",

View File

@ -11,7 +11,7 @@ specifiers:
'@commitlint/config-conventional': ^16.2.1
'@iconify/iconify': ^2.2.1
'@iconify/json': ^2.1.30
'@jeecg/online': 3.4.3-GA
'@jeecg/online': 3.4.4-RC
'@logicflow/core': ^1.1.13
'@logicflow/extension': ^1.1.13
'@purge-icons/generated': ^0.8.1
@ -148,7 +148,7 @@ dependencies:
'@ant-design/colors': registry.npmmirror.com/@ant-design/colors/6.0.0
'@ant-design/icons-vue': registry.npmmirror.com/@ant-design/icons-vue/6.1.0_vue@3.2.43
'@iconify/iconify': registry.npmmirror.com/@iconify/iconify/2.2.1
'@jeecg/online': registry.npmmirror.com/@jeecg/online/3.4.3-GA
'@jeecg/online': registry.npmmirror.com/@jeecg/online/3.4.4-RC
'@logicflow/core': registry.npmmirror.com/@logicflow/core/1.1.30
'@logicflow/extension': registry.npmmirror.com/@logicflow/extension/1.1.30
'@vue/runtime-core': registry.npmmirror.com/@vue/runtime-core/3.2.43
@ -2306,10 +2306,10 @@ packages:
engines: {node: '>=8'}
dev: true
registry.npmmirror.com/@jeecg/online/3.4.3-GA:
resolution: {integrity: sha512-MtZD7ue8gLB8d0HSclzMwpyzHLbBlhYw5hOCSQBAPjbySFAXj+ajKtZgvcl1uk7loTaK2pPJWmoUPBP/CUPWbw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jeecg/online/-/online-3.4.3-GA.tgz}
registry.npmmirror.com/@jeecg/online/3.4.4-RC:
resolution: {integrity: sha512-EjibCo++GszsWuLn3+kqaxt12Zim7f0XWSiHzypef4aAqBKYDnG30Z5K3j5W1g4g22fjVUkrb1rQ8rSLTlPdBw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jeecg/online/-/online-3.4.4-RC.tgz}
name: '@jeecg/online'
version: 3.4.3-GA
version: 3.4.4-RC
dev: false
registry.npmmirror.com/@jest/console/27.5.1:

View File

@ -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);

View 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>

View File

@ -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 {

View File

@ -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 JTreeSelectchangeOptions
url: propTypes.string.def(''),
params: propTypes.object.def({})
//update-end-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelectchangeOptions
});
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 JTreeSelectchangeOptions
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 JTreeSelectchangeOptions
}
}
@ -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 JTreeSelectchangeOptions
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 JTreeSelectchangeOptions
// onCreated
validateProp().then(() => {
initDictInfo();

View File

@ -141,4 +141,6 @@ export type ComponentType =
| 'JSearchSelect'
| 'JAddInput'
| 'Time'
| 'RangeDate'
| 'RangeNumber'
| 'JRangeNumber';

View File

@ -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'));
}

View 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>

View File

@ -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;
}

View File

@ -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 = {

View File

@ -44,6 +44,8 @@ export enum JVxeTypes {
radio = 'radio',
image = 'image',
file = 'file',
// 省市区
pca = 'pca',
}
// 为了防止和 vxe 内置的类型冲突,所以加上一个前缀

View File

@ -33,6 +33,9 @@
<template #dargVerify="{ model, field }">
<BasicDragVerify v-model:value="model[field]" />
</template>
<template #superQuery="{ model, field }">
<super-query :config="superQueryConfig" @search="(value)=>handleSuperQuery(value, model, field)"/>
</template>
</BasicForm>
</template>
<script lang="ts">
@ -74,8 +77,22 @@
function onSearch(value: string) {
keyword.value = value;
}
const superQueryConfig = {
name:{ title: "名称", view: "text", type: "string", order: 1 },
birthday:{ title: "生日", view: "date", type: "string", order: 2 },
age:{ title: "年龄", view: "number", type: "number", order: 4 },
sex:{ title: "性别", view: "list", type: "string", dictCode: "sex", order: 5 },
bpmStatus:{ title: "流程状态", view: "list_multi", type: "string", dictCode: "bpm_status", order: 6 },
}
function handleSuperQuery(value, model, field){
if(value){
let str = decodeURI(value.superQueryParams)
console.log(str)
model[field] = str
}
}
return {
schemas,
formElRef,
@ -84,6 +101,7 @@
submitButtonOptions,
onSearch: useDebounceFn(onSearch, 300),
searchParams,
superQueryConfig,
handleReset: () => {
keyword.value = '';
},

View File

@ -645,4 +645,38 @@ export const schemas: FormSchema[] = [
label: '选中值',
colProps: { span: 12 },
},
{
field: 'radioButtonGroup',
component: 'RadioButtonGroup',
label: 'RadioButtonGroup',
helpMessage: ['component模式'],
colProps: { span: 12 },
defaultValue: '0',
componentProps: {
options: [
{ value: '0',icon: 'ant-design:setting'},
{ label: '停用', value: '1',icon: 'mdi:home' },
],
},
},
{
field: 'radioButtonGroup',
component: 'JEllipsis',
label: '选中值',
colProps: { span: 12 },
},
{
field: 'superQuery',
component: 'Input',
label: '高级查询',
helpMessage: ['插槽模式'],
slot: 'superQuery',
colProps: { span: 12 },
},
{
field: 'superQuery',
component: 'JEllipsis',
label: '选中值',
colProps: { span: 12 },
},
];