style: lint格式化文件
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -1,83 +1,83 @@
|
||||
<template>
|
||||
<div class="ah-container">
|
||||
<a-layout-header class="btn-bar">
|
||||
<slot></slot>
|
||||
<a-button v-if="$attrs.uploadJson" type="link" size="small" @click="$emit('uploadJson')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="import" :size="14" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('导入JSON') }}
|
||||
</a-button>
|
||||
<a-button v-if="$attrs.generateJson" type="link" size="small" @click="$emit('generateJson')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="printer" :size="14" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('生成JSON') }}
|
||||
</a-button>
|
||||
<a-button v-if="$attrs.clearable" type="link" size="small" @click="$emit('clearable')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="clearable" :size="14" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('清空') }}
|
||||
</a-button>
|
||||
<a-button v-if="$attrs.preview" type="link" size="small" @click="$emit('preview')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="action" :size="14" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('预览') }}
|
||||
</a-button>
|
||||
<div class="ah-container">
|
||||
<a-layout-header class="btn-bar">
|
||||
<slot></slot>
|
||||
<a-button v-if="$attrs.uploadJson" type="link" size="small" @click="$emit('uploadJson')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="import" :size="14" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('导入JSON') }}
|
||||
</a-button>
|
||||
<a-button v-if="$attrs.generateJson" type="link" size="small" @click="$emit('generateJson')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="printer" :size="14" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('生成JSON') }}
|
||||
</a-button>
|
||||
<a-button v-if="$attrs.clearable" type="link" size="small" @click="$emit('clearable')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="clearable" :size="14" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('清空') }}
|
||||
</a-button>
|
||||
<a-button v-if="$attrs.preview" type="link" size="small" @click="$emit('preview')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="action" :size="14" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('预览') }}
|
||||
</a-button>
|
||||
|
||||
<a-button v-if="$attrs.generateCode" type="link" size="small" @click="$emit('generateCode')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="generate-code" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('生成代码') }}
|
||||
</a-button>
|
||||
</a-layout-header>
|
||||
</div>
|
||||
<a-button v-if="$attrs.generateCode" type="link" size="small" @click="$emit('generateCode')">
|
||||
<template #icon>
|
||||
<div class="btn-icon">
|
||||
<SvgIcon name="generate-code" />
|
||||
</div>
|
||||
</template>
|
||||
{{ t('生成代码') }}
|
||||
</a-button>
|
||||
</a-layout-header>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
|
||||
defineEmits(['uploadJson', 'clearable', 'preview', 'generateJson', 'generateCode']);
|
||||
defineEmits(['uploadJson', 'clearable', 'preview', 'generateJson', 'generateCode']);
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.ah-container {
|
||||
padding: 0 10px;
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
}
|
||||
|
||||
.btn-bar {
|
||||
line-height: 46px;
|
||||
height: 46px;
|
||||
padding: 0 20px;
|
||||
background-color: #fff;
|
||||
text-align: right;
|
||||
|
||||
.btn-icon {
|
||||
display: inline-block;
|
||||
border: 1px solid;
|
||||
border-radius: 50%;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
.ah-container {
|
||||
padding: 0 10px;
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-btn) > span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
// @import '/@/assets/style/designer/index.css';
|
||||
.btn-bar {
|
||||
line-height: 46px;
|
||||
height: 46px;
|
||||
padding: 0 20px;
|
||||
background-color: #fff;
|
||||
text-align: right;
|
||||
|
||||
.btn-icon {
|
||||
display: inline-block;
|
||||
border: 1px solid;
|
||||
border-radius: 50%;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-btn) > span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
// @import '/@/assets/style/designer/index.css';
|
||||
</style>
|
||||
|
||||
@ -1,493 +1,448 @@
|
||||
<template>
|
||||
<div class="awf-container-center">
|
||||
<div class="widget-form-container">
|
||||
<div v-if="!widgetForm.list" class="form-empty">从左侧拖拽来添加字段</div>
|
||||
<a-form
|
||||
:layout="widgetForm.config.layout"
|
||||
:labelAlign="widgetForm.config.labelAlign"
|
||||
:labelCol="widgetForm.config.labelCol"
|
||||
:disabled="true"
|
||||
>
|
||||
<Draggable
|
||||
class="widget-form-list"
|
||||
item-key="key"
|
||||
ghostClass="ghost"
|
||||
handle=".drag-widget"
|
||||
:animation="200"
|
||||
:group="{ name: 'people' }"
|
||||
:list="widgetForm.list"
|
||||
@add="handleMoveAdd"
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<transition-group name="fade" tag="div">
|
||||
<AntdWidgetFormItem
|
||||
v-if="element.key"
|
||||
:key="element.key"
|
||||
class="drag-widget"
|
||||
:element="element"
|
||||
:config="widgetForm.config"
|
||||
:selectWidget="widgetFormSelect"
|
||||
@click="handleItemClick(element)"
|
||||
@copy="handleCopyClick(index, widgetForm.list)"
|
||||
@delete="handleDeleteClick(index, widgetForm.list)"
|
||||
@addRow="handleAddClick(element, 'row')"
|
||||
@addCol="handleAddClick(element, 'col')"
|
||||
/>
|
||||
</transition-group>
|
||||
</template>
|
||||
</Draggable>
|
||||
</a-form>
|
||||
<div class="awf-container-center">
|
||||
<div class="widget-form-container">
|
||||
<div v-if="!widgetForm.list" class="form-empty">从左侧拖拽来添加字段</div>
|
||||
<a-form :layout="widgetForm.config.layout" :labelAlign="widgetForm.config.labelAlign" :labelCol="widgetForm.config.labelCol" :disabled="true">
|
||||
<Draggable class="widget-form-list" item-key="key" ghostClass="ghost" handle=".drag-widget" :animation="200" :group="{ name: 'people' }" :list="widgetForm.list" @add="handleMoveAdd">
|
||||
<template #item="{ element, index }">
|
||||
<transition-group name="fade" tag="div">
|
||||
<AntdWidgetFormItem
|
||||
v-if="element.key"
|
||||
:key="element.key"
|
||||
class="drag-widget"
|
||||
:element="element"
|
||||
:config="widgetForm.config"
|
||||
:selectWidget="widgetFormSelect"
|
||||
@click="handleItemClick(element)"
|
||||
@copy="handleCopyClick(index, widgetForm.list)"
|
||||
@delete="handleDeleteClick(index, widgetForm.list)"
|
||||
@addRow="handleAddClick(element, 'row')"
|
||||
@addCol="handleAddClick(element, 'col')"
|
||||
/>
|
||||
</transition-group>
|
||||
</template>
|
||||
</Draggable>
|
||||
</a-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, nextTick, PropType, toRaw, inject, Ref, ref } from 'vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
import AntdWidgetFormItem from './AntdWidgetFormItem.vue';
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import {
|
||||
WidgetForm,
|
||||
gridComponents,
|
||||
TableInfo,
|
||||
noHaveTableAndField,
|
||||
noHaveField,
|
||||
TableCell,
|
||||
TableTh,
|
||||
} from '../types';
|
||||
import { buildUUID } from '/@/utils/uuid';
|
||||
import { error } from '/@/utils/log';
|
||||
import { changeToPinyin } from '/@/utils/event/design';
|
||||
import { random } from 'lodash-es';
|
||||
import { defineComponent, nextTick, PropType, toRaw, inject, Ref, ref } from 'vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
import AntdWidgetFormItem from './AntdWidgetFormItem.vue';
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { WidgetForm, gridComponents, TableInfo, noHaveTableAndField, noHaveField, TableCell, TableTh } from '../types';
|
||||
import { buildUUID } from '/@/utils/uuid';
|
||||
import { error } from '/@/utils/log';
|
||||
import { changeToPinyin } from '/@/utils/event/design';
|
||||
import { random } from 'lodash-es';
|
||||
|
||||
const handleListInsert = (key: string, list: any[], obj: any) => {
|
||||
const newList: any[] = [];
|
||||
list.forEach((item) => {
|
||||
if (item.key === key) {
|
||||
newList.push(item);
|
||||
newList.push(obj);
|
||||
} else {
|
||||
if (item.columns) {
|
||||
item.columns = item.columns.map((col: any) => ({
|
||||
...col,
|
||||
list: handleListInsert(key, col.list, obj),
|
||||
}));
|
||||
}
|
||||
newList.push(item);
|
||||
}
|
||||
});
|
||||
return newList;
|
||||
};
|
||||
|
||||
const handleListDelete = (key: string, list: any[]) => {
|
||||
const newList: any[] = [];
|
||||
list.forEach((item) => {
|
||||
if (item.key !== key) {
|
||||
if (item.columns) {
|
||||
item.columns = item.columns.map((col: any) => ({
|
||||
...col,
|
||||
list: handleListDelete(key, col.list),
|
||||
}));
|
||||
}
|
||||
newList.push(item);
|
||||
}
|
||||
});
|
||||
return newList;
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AntdWidgetForm',
|
||||
components: {
|
||||
SvgIcon,
|
||||
Draggable,
|
||||
AntdWidgetFormItem,
|
||||
},
|
||||
props: {
|
||||
widgetForm: {
|
||||
type: Object as PropType<WidgetForm>,
|
||||
required: true,
|
||||
},
|
||||
widgetFormSelect: {
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
emits: ['update:widgetForm', 'update:widgetFormSelect'],
|
||||
setup(props, context) {
|
||||
const state = inject('state') as any;
|
||||
const tableInfo = inject<Ref<TableInfo[]>>('tableInfo') as Ref<TableInfo[]>;
|
||||
const isFieldUpper = inject<Ref<boolean>>('isFieldUpper', ref(false));
|
||||
const designType = inject('designType') as string;
|
||||
const tablecell = inject<Ref<TableCell>>('tableCell');
|
||||
const tableth = inject<Ref<TableTh>>('tableTh');
|
||||
let mainTableName;
|
||||
if (designType !== 'data') {
|
||||
mainTableName = inject<string>('mainTableName');
|
||||
}
|
||||
|
||||
const handleItemClick = (row: any) => {
|
||||
state.widgetFormSelect = row;
|
||||
if (row.type === 'table-layout') {
|
||||
if (tablecell) tablecell.value = {};
|
||||
if (tableth) tableth.value = {};
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddClick = (row: any, type: string) => {
|
||||
let tdMax = 0;
|
||||
row.layout[0].list.forEach((o) => {
|
||||
if (o.colspan) {
|
||||
tdMax = tdMax + o.colspan;
|
||||
} else {
|
||||
tdMax += 1;
|
||||
}
|
||||
const handleListInsert = (key: string, list: any[], obj: any) => {
|
||||
const newList: any[] = [];
|
||||
list.forEach((item) => {
|
||||
if (item.key === key) {
|
||||
newList.push(item);
|
||||
newList.push(obj);
|
||||
} else {
|
||||
if (item.columns) {
|
||||
item.columns = item.columns.map((col: any) => ({
|
||||
...col,
|
||||
list: handleListInsert(key, col.list, obj)
|
||||
}));
|
||||
}
|
||||
newList.push(item);
|
||||
}
|
||||
});
|
||||
if (type == 'row') {
|
||||
let lastRow: any = [];
|
||||
for (let j = 0; j < tdMax; j++) {
|
||||
lastRow.push({
|
||||
width: '',
|
||||
height: '',
|
||||
class: 'tableLayoutTd',
|
||||
children: [],
|
||||
position: [row.layout.length, j],
|
||||
});
|
||||
}
|
||||
row.layout.push({ list: lastRow });
|
||||
} else {
|
||||
row.layout.forEach((o, i) => {
|
||||
o.list.push({
|
||||
width: '',
|
||||
height: '',
|
||||
class: 'tableLayoutTd',
|
||||
children: [],
|
||||
position: [i, tdMax],
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
const handleCopyClick = (index: number, list: any[]) => {
|
||||
const key = buildUUID().replaceAll('-', '');
|
||||
const oldList = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
let copyData = {
|
||||
...list[index],
|
||||
key,
|
||||
model: `${list[index].type}_${key}`,
|
||||
rules: list[index].rules ?? [],
|
||||
bindField: '',
|
||||
};
|
||||
return newList;
|
||||
};
|
||||
|
||||
if (
|
||||
list[index].type === 'radio' ||
|
||||
list[index].type === 'checkbox' ||
|
||||
list[index].type === 'select'
|
||||
) {
|
||||
copyData = {
|
||||
...copyData,
|
||||
options: {
|
||||
...copyData.options,
|
||||
staticOptions: copyData.options.staticOptions.map((item: any) => ({ ...item })),
|
||||
const handleListDelete = (key: string, list: any[]) => {
|
||||
const newList: any[] = [];
|
||||
list.forEach((item) => {
|
||||
if (item.key !== key) {
|
||||
if (item.columns) {
|
||||
item.columns = item.columns.map((col: any) => ({
|
||||
...col,
|
||||
list: handleListDelete(key, col.list)
|
||||
}));
|
||||
}
|
||||
newList.push(item);
|
||||
}
|
||||
});
|
||||
return newList;
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AntdWidgetForm',
|
||||
components: {
|
||||
SvgIcon,
|
||||
Draggable,
|
||||
AntdWidgetFormItem
|
||||
},
|
||||
props: {
|
||||
widgetForm: {
|
||||
type: Object as PropType<WidgetForm>,
|
||||
required: true
|
||||
},
|
||||
};
|
||||
}
|
||||
copyLayoutData([copyData], mainTableName);
|
||||
|
||||
context.emit('update:widgetForm', {
|
||||
...props.widgetForm,
|
||||
list: handleListInsert(list[index].key, oldList, copyData),
|
||||
});
|
||||
inject('widgetFormSelect', copyData);
|
||||
context.emit('update:widgetFormSelect', copyData);
|
||||
};
|
||||
|
||||
const copyLayoutData = (data, tableName) => {
|
||||
data.map((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
item.bindTable = '';
|
||||
item.key = buildUUID().replaceAll('-', '');
|
||||
addBindTableAndField(item, tableName);
|
||||
for (const child of item.layout!) {
|
||||
copyLayoutData(child.list, tableName);
|
||||
widgetFormSelect: {
|
||||
type: Object
|
||||
}
|
||||
} else if (item.type === 'table-layout') {
|
||||
item.bindTable = '';
|
||||
item.key = buildUUID().replaceAll('-', '');
|
||||
addBindTableAndField(item, tableName);
|
||||
for (const child of item.layout!) {
|
||||
for (const list of child.list!) {
|
||||
copyLayoutData(list.children, tableName);
|
||||
}
|
||||
},
|
||||
emits: ['update:widgetForm', 'update:widgetFormSelect'],
|
||||
setup(props, context) {
|
||||
const state = inject('state') as any;
|
||||
const tableInfo = inject<Ref<TableInfo[]>>('tableInfo') as Ref<TableInfo[]>;
|
||||
const isFieldUpper = inject<Ref<boolean>>('isFieldUpper', ref(false));
|
||||
const designType = inject('designType') as string;
|
||||
const tablecell = inject<Ref<TableCell>>('tableCell');
|
||||
const tableth = inject<Ref<TableTh>>('tableTh');
|
||||
let mainTableName;
|
||||
if (designType !== 'data') {
|
||||
mainTableName = inject<string>('mainTableName');
|
||||
}
|
||||
} else if (['form', 'one-for-one'].includes(item.type)) {
|
||||
item.key = buildUUID().replaceAll('-', '');
|
||||
addBindTableAndField(item);
|
||||
copyLayoutData(item.children, item.bindTable);
|
||||
} else {
|
||||
item.bindField = '';
|
||||
item.bindTable = tableName;
|
||||
item.key = buildUUID().replaceAll('-', '');
|
||||
addBindTableAndField(item, tableName);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteClick = async (index: number, list: any[]) => {
|
||||
await deleteAdoptedCalc(index, list);
|
||||
const oldList = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
|
||||
if (list.length - 1 === index) {
|
||||
if (index === 0) {
|
||||
nextTick(() => context.emit('update:widgetFormSelect', null));
|
||||
} else {
|
||||
context.emit('update:widgetFormSelect', list[index - 1]);
|
||||
}
|
||||
} else {
|
||||
context.emit('update:widgetFormSelect', list[index + 1]);
|
||||
}
|
||||
|
||||
context.emit('update:widgetForm', {
|
||||
...props.widgetForm,
|
||||
list: handleListDelete(list[index].key, oldList),
|
||||
});
|
||||
};
|
||||
|
||||
const handleTabGridDeleteClick = (index: number, list: any[]) => {
|
||||
list.splice(index, 1);
|
||||
};
|
||||
|
||||
const handleMoveAdd = (event: any) => {
|
||||
const list = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
const { newIndex } = event;
|
||||
|
||||
//判断如果是单表 不支持子表单组件 (仅数据优先时)
|
||||
if (tableInfo.value.length < 2 && list[newIndex].type === 'form' && designType === 'data') {
|
||||
list.splice(newIndex, 2); //必须2
|
||||
context.emit('update:widgetForm', { ...props.widgetForm, list });
|
||||
error('单表不能使用子表单组件!');
|
||||
return;
|
||||
}
|
||||
const key = buildUUID().replaceAll('-', '');
|
||||
|
||||
list[newIndex] = {
|
||||
...toRaw(list[newIndex]),
|
||||
key,
|
||||
model: `${list[newIndex].type}_${key}`,
|
||||
rules: [],
|
||||
};
|
||||
|
||||
if (
|
||||
list[newIndex].type === 'radio' ||
|
||||
list[newIndex].type === 'checkbox' ||
|
||||
list[newIndex].type === 'select'
|
||||
) {
|
||||
list[newIndex] = {
|
||||
...list[newIndex],
|
||||
options: {
|
||||
...list[newIndex].options,
|
||||
staticOptions: list[newIndex].options.staticOptions.map((item: any) => ({
|
||||
...item,
|
||||
})),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (list[newIndex].type === 'grid') {
|
||||
list[newIndex].layout.map((item: any) => (item.list = []));
|
||||
}
|
||||
|
||||
if (list[newIndex].type === 'form') {
|
||||
list[newIndex].children.map((item: any) => (item.list = []));
|
||||
}
|
||||
|
||||
if (list[newIndex].type === 'tab') {
|
||||
list[newIndex].layout.map((item: any) => (item.list = []));
|
||||
}
|
||||
//从子表拖入主表时
|
||||
list[newIndex].isSubFormChild = false;
|
||||
list[newIndex].isSingleFormChild = false;
|
||||
|
||||
addBindTableAndField(list[newIndex]);
|
||||
|
||||
context.emit('update:widgetForm', { ...props.widgetForm, list });
|
||||
context.emit('update:widgetFormSelect', list[newIndex]);
|
||||
};
|
||||
|
||||
const handleColMoveAdd = (event: any, row: any, index: string | number | symbol) => {
|
||||
const { newIndex, oldIndex, item } = event;
|
||||
if (row.type === 'form') {
|
||||
const list = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
|
||||
if (item.className.includes('data-grid')) {
|
||||
item.tagName === 'DIV' && list.splice(oldIndex, 0, row.children[newIndex]);
|
||||
row.children[index].splice(newIndex, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
const key = buildUUID().replaceAll('-', '');
|
||||
|
||||
row.children[newIndex] = {
|
||||
...toRaw(row.children[index]),
|
||||
key,
|
||||
model: `${row.children[newIndex].type}_${key}`,
|
||||
rules: [],
|
||||
};
|
||||
|
||||
if (
|
||||
row.children[newIndex].type === 'radio' ||
|
||||
row.children[newIndex].type === 'checkbox' ||
|
||||
row.children[newIndex].type === 'select'
|
||||
) {
|
||||
row.children[newIndex] = {
|
||||
...row.children[newIndex],
|
||||
options: {
|
||||
...row.children[newIndex].options,
|
||||
staticOptions: row.children[newIndex].options.staticOptions.map((item: any) => ({
|
||||
...item,
|
||||
})),
|
||||
},
|
||||
const handleItemClick = (row: any) => {
|
||||
state.widgetFormSelect = row;
|
||||
if (row.type === 'table-layout') {
|
||||
if (tablecell) tablecell.value = {};
|
||||
if (tableth) tableth.value = {};
|
||||
}
|
||||
};
|
||||
}
|
||||
context.emit('update:widgetFormSelect', row.children[newIndex]);
|
||||
} else {
|
||||
const list = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
|
||||
if (item.className.includes('data-grid')) {
|
||||
item.tagName === 'DIV' && list.splice(oldIndex, 0, row.layout[index].list[newIndex]);
|
||||
row.layout[index].list.splice(newIndex, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
const key = buildUUID().replaceAll('-', '');
|
||||
|
||||
row.layout[index].list[newIndex] = {
|
||||
...toRaw(row.layout[index].list[newIndex]),
|
||||
key,
|
||||
model: `${row.layout[index].list[newIndex].type}_${key}`,
|
||||
rules: [],
|
||||
};
|
||||
|
||||
if (
|
||||
row.layout[index].list[newIndex].type === 'radio' ||
|
||||
row.layout[index].list[newIndex].type === 'checkbox' ||
|
||||
row.layout[index].list[newIndex].type === 'select'
|
||||
) {
|
||||
row.layout[index].list[newIndex] = {
|
||||
...row.layout[index].list[newIndex],
|
||||
options: {
|
||||
...row.layout[index].list[newIndex].options,
|
||||
staticOptions: row.layout[index].list[newIndex].options.staticOptions.map(
|
||||
(item: any) => ({
|
||||
...item,
|
||||
}),
|
||||
),
|
||||
},
|
||||
const handleAddClick = (row: any, type: string) => {
|
||||
let tdMax = 0;
|
||||
row.layout[0].list.forEach((o) => {
|
||||
if (o.colspan) {
|
||||
tdMax = tdMax + o.colspan;
|
||||
} else {
|
||||
tdMax += 1;
|
||||
}
|
||||
});
|
||||
if (type == 'row') {
|
||||
let lastRow: any = [];
|
||||
for (let j = 0; j < tdMax; j++) {
|
||||
lastRow.push({
|
||||
width: '',
|
||||
height: '',
|
||||
class: 'tableLayoutTd',
|
||||
children: [],
|
||||
position: [row.layout.length, j]
|
||||
});
|
||||
}
|
||||
row.layout.push({ list: lastRow });
|
||||
} else {
|
||||
row.layout.forEach((o, i) => {
|
||||
o.list.push({
|
||||
width: '',
|
||||
height: '',
|
||||
class: 'tableLayoutTd',
|
||||
children: [],
|
||||
position: [i, tdMax]
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
const handleCopyClick = (index: number, list: any[]) => {
|
||||
const key = buildUUID().replaceAll('-', '');
|
||||
const oldList = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
let copyData = {
|
||||
...list[index],
|
||||
key,
|
||||
model: `${list[index].type}_${key}`,
|
||||
rules: list[index].rules ?? [],
|
||||
bindField: ''
|
||||
};
|
||||
|
||||
context.emit('update:widgetFormSelect', row.layout[index].list[newIndex]);
|
||||
if (list[index].type === 'radio' || list[index].type === 'checkbox' || list[index].type === 'select') {
|
||||
copyData = {
|
||||
...copyData,
|
||||
options: {
|
||||
...copyData.options,
|
||||
staticOptions: copyData.options.staticOptions.map((item: any) => ({ ...item }))
|
||||
}
|
||||
};
|
||||
}
|
||||
copyLayoutData([copyData], mainTableName);
|
||||
|
||||
context.emit('update:widgetForm', {
|
||||
...props.widgetForm,
|
||||
list: handleListInsert(list[index].key, oldList, copyData)
|
||||
});
|
||||
inject('widgetFormSelect', copyData);
|
||||
context.emit('update:widgetFormSelect', copyData);
|
||||
};
|
||||
|
||||
const copyLayoutData = (data, tableName) => {
|
||||
data.map((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
item.bindTable = '';
|
||||
item.key = buildUUID().replaceAll('-', '');
|
||||
addBindTableAndField(item, tableName);
|
||||
for (const child of item.layout!) {
|
||||
copyLayoutData(child.list, tableName);
|
||||
}
|
||||
} else if (item.type === 'table-layout') {
|
||||
item.bindTable = '';
|
||||
item.key = buildUUID().replaceAll('-', '');
|
||||
addBindTableAndField(item, tableName);
|
||||
for (const child of item.layout!) {
|
||||
for (const list of child.list!) {
|
||||
copyLayoutData(list.children, tableName);
|
||||
}
|
||||
}
|
||||
} else if (['form', 'one-for-one'].includes(item.type)) {
|
||||
item.key = buildUUID().replaceAll('-', '');
|
||||
addBindTableAndField(item);
|
||||
copyLayoutData(item.children, item.bindTable);
|
||||
} else {
|
||||
item.bindField = '';
|
||||
item.bindTable = tableName;
|
||||
item.key = buildUUID().replaceAll('-', '');
|
||||
addBindTableAndField(item, tableName);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteClick = async (index: number, list: any[]) => {
|
||||
await deleteAdoptedCalc(index, list);
|
||||
const oldList = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
|
||||
if (list.length - 1 === index) {
|
||||
if (index === 0) {
|
||||
nextTick(() => context.emit('update:widgetFormSelect', null));
|
||||
} else {
|
||||
context.emit('update:widgetFormSelect', list[index - 1]);
|
||||
}
|
||||
} else {
|
||||
context.emit('update:widgetFormSelect', list[index + 1]);
|
||||
}
|
||||
|
||||
context.emit('update:widgetForm', {
|
||||
...props.widgetForm,
|
||||
list: handleListDelete(list[index].key, oldList)
|
||||
});
|
||||
};
|
||||
|
||||
const handleTabGridDeleteClick = (index: number, list: any[]) => {
|
||||
list.splice(index, 1);
|
||||
};
|
||||
|
||||
const handleMoveAdd = (event: any) => {
|
||||
const list = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
const { newIndex } = event;
|
||||
|
||||
//判断如果是单表 不支持子表单组件 (仅数据优先时)
|
||||
if (tableInfo.value.length < 2 && list[newIndex].type === 'form' && designType === 'data') {
|
||||
list.splice(newIndex, 2); //必须2
|
||||
context.emit('update:widgetForm', { ...props.widgetForm, list });
|
||||
error('单表不能使用子表单组件!');
|
||||
return;
|
||||
}
|
||||
const key = buildUUID().replaceAll('-', '');
|
||||
|
||||
list[newIndex] = {
|
||||
...toRaw(list[newIndex]),
|
||||
key,
|
||||
model: `${list[newIndex].type}_${key}`,
|
||||
rules: []
|
||||
};
|
||||
|
||||
if (list[newIndex].type === 'radio' || list[newIndex].type === 'checkbox' || list[newIndex].type === 'select') {
|
||||
list[newIndex] = {
|
||||
...list[newIndex],
|
||||
options: {
|
||||
...list[newIndex].options,
|
||||
staticOptions: list[newIndex].options.staticOptions.map((item: any) => ({
|
||||
...item
|
||||
}))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (list[newIndex].type === 'grid') {
|
||||
list[newIndex].layout.map((item: any) => (item.list = []));
|
||||
}
|
||||
|
||||
if (list[newIndex].type === 'form') {
|
||||
list[newIndex].children.map((item: any) => (item.list = []));
|
||||
}
|
||||
|
||||
if (list[newIndex].type === 'tab') {
|
||||
list[newIndex].layout.map((item: any) => (item.list = []));
|
||||
}
|
||||
//从子表拖入主表时
|
||||
list[newIndex].isSubFormChild = false;
|
||||
list[newIndex].isSingleFormChild = false;
|
||||
|
||||
addBindTableAndField(list[newIndex]);
|
||||
|
||||
context.emit('update:widgetForm', { ...props.widgetForm, list });
|
||||
context.emit('update:widgetFormSelect', list[newIndex]);
|
||||
};
|
||||
|
||||
const handleColMoveAdd = (event: any, row: any, index: string | number | symbol) => {
|
||||
const { newIndex, oldIndex, item } = event;
|
||||
if (row.type === 'form') {
|
||||
const list = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
|
||||
if (item.className.includes('data-grid')) {
|
||||
item.tagName === 'DIV' && list.splice(oldIndex, 0, row.children[newIndex]);
|
||||
row.children[index].splice(newIndex, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
const key = buildUUID().replaceAll('-', '');
|
||||
|
||||
row.children[newIndex] = {
|
||||
...toRaw(row.children[index]),
|
||||
key,
|
||||
model: `${row.children[newIndex].type}_${key}`,
|
||||
rules: []
|
||||
};
|
||||
|
||||
if (row.children[newIndex].type === 'radio' || row.children[newIndex].type === 'checkbox' || row.children[newIndex].type === 'select') {
|
||||
row.children[newIndex] = {
|
||||
...row.children[newIndex],
|
||||
options: {
|
||||
...row.children[newIndex].options,
|
||||
staticOptions: row.children[newIndex].options.staticOptions.map((item: any) => ({
|
||||
...item
|
||||
}))
|
||||
}
|
||||
};
|
||||
}
|
||||
context.emit('update:widgetFormSelect', row.children[newIndex]);
|
||||
} else {
|
||||
const list = JSON.parse(JSON.stringify(props.widgetForm.list));
|
||||
|
||||
if (item.className.includes('data-grid')) {
|
||||
item.tagName === 'DIV' && list.splice(oldIndex, 0, row.layout[index].list[newIndex]);
|
||||
row.layout[index].list.splice(newIndex, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
const key = buildUUID().replaceAll('-', '');
|
||||
|
||||
row.layout[index].list[newIndex] = {
|
||||
...toRaw(row.layout[index].list[newIndex]),
|
||||
key,
|
||||
model: `${row.layout[index].list[newIndex].type}_${key}`,
|
||||
rules: []
|
||||
};
|
||||
|
||||
if (row.layout[index].list[newIndex].type === 'radio' || row.layout[index].list[newIndex].type === 'checkbox' || row.layout[index].list[newIndex].type === 'select') {
|
||||
row.layout[index].list[newIndex] = {
|
||||
...row.layout[index].list[newIndex],
|
||||
options: {
|
||||
...row.layout[index].list[newIndex].options,
|
||||
staticOptions: row.layout[index].list[newIndex].options.staticOptions.map((item: any) => ({
|
||||
...item
|
||||
}))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
context.emit('update:widgetFormSelect', row.layout[index].list[newIndex]);
|
||||
}
|
||||
};
|
||||
const addBindTableAndField = (component: any, table?) => {
|
||||
//界面优先和简易模板
|
||||
if (designType !== 'data') {
|
||||
//需要绑定字段、组件没有绑定字段的情况下新增绑定字段
|
||||
const rangeComponents = ['time-range', 'date-range'];
|
||||
if (rangeComponents.includes(component.type)) {
|
||||
component.bindStartTime = changeToPinyin(component.label, isFieldUpper.value) + random(1000, 9999);
|
||||
component.bindEndTime = changeToPinyin(component.label, isFieldUpper.value) + random(1000, 9999);
|
||||
} else if (!noHaveField.includes(component.type) && !component.bindField) {
|
||||
component.bindField = changeToPinyin(component.label, isFieldUpper.value) + random(1000, 9999);
|
||||
}
|
||||
if (component.type === 'form' || component.type === 'one-for-one') {
|
||||
component.bindTable = isFieldUpper.value ? `${mainTableName.value}_CHILD_${random(1000, 9999)}` : `${mainTableName.value}_child_${random(1000, 9999)}`;
|
||||
} else if (!noHaveTableAndField.includes(component.type)) {
|
||||
component.bindTable = table || mainTableName.value;
|
||||
}
|
||||
}
|
||||
if (component.isGridChild) component.options.span = 7;
|
||||
};
|
||||
|
||||
//删除引用已删除的财务组件的计算式配置
|
||||
const deleteAdoptedCalc = (index: number, list: any[]) => {
|
||||
const component = list[index];
|
||||
if (['computational', 'money-chinese'].includes(component.type)) {
|
||||
component.options.beAdoptedComponent?.map((key) => {
|
||||
getLayoutComponent(list, key);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getLayoutComponent = (list, key) => {
|
||||
list?.map((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
getLayoutComponent(child.list, key);
|
||||
}
|
||||
} else if (item.type === 'table-layout') {
|
||||
for (const child of item.layout!) {
|
||||
for (const list of child.list) {
|
||||
getLayoutComponent(list.children, key);
|
||||
}
|
||||
}
|
||||
} else if (item.type === 'form') {
|
||||
item.children.map((child: any) => {
|
||||
if (['computational', 'money-chinese'].includes(child.type) && child.key === key) {
|
||||
child.options.computationalConfig = [];
|
||||
child.options.computationalConfigValue = '== 请填写计算式配置 ==';
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (['computational', 'money-chinese'].includes(item.type) && item.key === key) {
|
||||
item.options.computationalConfig = [];
|
||||
item.options.computationalConfigValue = '== 请填写计算式配置 ==';
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
handleItemClick,
|
||||
handleAddClick,
|
||||
handleCopyClick,
|
||||
handleDeleteClick,
|
||||
handleTabGridDeleteClick,
|
||||
handleMoveAdd,
|
||||
handleColMoveAdd,
|
||||
gridComponents,
|
||||
addBindTableAndField
|
||||
};
|
||||
}
|
||||
};
|
||||
const addBindTableAndField = (component: any, table?) => {
|
||||
//界面优先和简易模板
|
||||
if (designType !== 'data') {
|
||||
//需要绑定字段、组件没有绑定字段的情况下新增绑定字段
|
||||
const rangeComponents = ['time-range', 'date-range'];
|
||||
if (rangeComponents.includes(component.type)) {
|
||||
component.bindStartTime =
|
||||
changeToPinyin(component.label, isFieldUpper.value) + random(1000, 9999);
|
||||
component.bindEndTime =
|
||||
changeToPinyin(component.label, isFieldUpper.value) + random(1000, 9999);
|
||||
} else if (!noHaveField.includes(component.type) && !component.bindField) {
|
||||
component.bindField =
|
||||
changeToPinyin(component.label, isFieldUpper.value) + random(1000, 9999);
|
||||
}
|
||||
if (component.type === 'form' || component.type === 'one-for-one') {
|
||||
component.bindTable = isFieldUpper.value
|
||||
? `${mainTableName.value}_CHILD_${random(1000, 9999)}`
|
||||
: `${mainTableName.value}_child_${random(1000, 9999)}`;
|
||||
} else if (!noHaveTableAndField.includes(component.type)) {
|
||||
component.bindTable = table || mainTableName.value;
|
||||
}
|
||||
}
|
||||
if (component.isGridChild) component.options.span = 7;
|
||||
};
|
||||
|
||||
//删除引用已删除的财务组件的计算式配置
|
||||
const deleteAdoptedCalc = (index: number, list: any[]) => {
|
||||
const component = list[index];
|
||||
if (['computational', 'money-chinese'].includes(component.type)) {
|
||||
component.options.beAdoptedComponent?.map((key) => {
|
||||
getLayoutComponent(list, key);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getLayoutComponent = (list, key) => {
|
||||
list?.map((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
getLayoutComponent(child.list, key);
|
||||
}
|
||||
} else if (item.type === 'table-layout') {
|
||||
for (const child of item.layout!) {
|
||||
for (const list of child.list) {
|
||||
getLayoutComponent(list.children, key);
|
||||
}
|
||||
}
|
||||
} else if (item.type === 'form') {
|
||||
item.children.map((child: any) => {
|
||||
if (['computational', 'money-chinese'].includes(child.type) && child.key === key) {
|
||||
child.options.computationalConfig = [];
|
||||
child.options.computationalConfigValue = '== 请填写计算式配置 ==';
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (['computational', 'money-chinese'].includes(item.type) && item.key === key) {
|
||||
item.options.computationalConfig = [];
|
||||
item.options.computationalConfigValue = '== 请填写计算式配置 ==';
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
handleItemClick,
|
||||
handleAddClick,
|
||||
handleCopyClick,
|
||||
handleDeleteClick,
|
||||
handleTabGridDeleteClick,
|
||||
handleMoveAdd,
|
||||
handleColMoveAdd,
|
||||
gridComponents,
|
||||
addBindTableAndField,
|
||||
};
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
/* @import '/@/assets/style/designer/index.css'; */
|
||||
.awf-container-center {
|
||||
width: 100%;
|
||||
height: calc(100%);
|
||||
padding: 1px 10px 10px;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
}
|
||||
/* @import '/@/assets/style/designer/index.css'; */
|
||||
.awf-container-center {
|
||||
width: 100%;
|
||||
height: calc(100%);
|
||||
padding: 1px 10px 10px;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.widget-form-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
padding: 10px 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.widget-form-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
padding: 10px 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.widget-form-list {
|
||||
height: 100%;
|
||||
}
|
||||
.widget-form-list {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.fc-style .widget-form-container .widget-form-list {
|
||||
background: #fff;
|
||||
// border: 1px dashed #999;
|
||||
min-height: calc(100vh - 305px);
|
||||
}
|
||||
.fc-style .widget-form-container .widget-form-list {
|
||||
background: #fff;
|
||||
// border: 1px dashed #999;
|
||||
min-height: calc(100vh - 305px);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -821,8 +821,7 @@
|
||||
},
|
||||
labelCol: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
}
|
||||
default: () => {}
|
||||
},
|
||||
childIndex: {
|
||||
type: Number
|
||||
|
||||
@ -1,106 +1,92 @@
|
||||
<template>
|
||||
<Draggable
|
||||
tag="ul"
|
||||
item-key="type"
|
||||
ghostClass="ghost"
|
||||
:group="{ name: 'people', pull: 'clone', put: false }"
|
||||
:sort="false"
|
||||
:list="list"
|
||||
class="cg-list-container"
|
||||
:disabled="isDisabled"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<li
|
||||
v-if="fields.includes(element.type)"
|
||||
class="form-edit-widget-label cg-list"
|
||||
:class="{ 'no-put': element.type === 'divider' }"
|
||||
@click="handleClick(element)"
|
||||
>
|
||||
<a>
|
||||
<SvgIcon :name="element.type ?? element.icon" />
|
||||
<span>{{ element.label }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</Draggable>
|
||||
<div class="clear"></div>
|
||||
<Draggable tag="ul" item-key="type" ghostClass="ghost" :group="{ name: 'people', pull: 'clone', put: false }" :sort="false" :list="list" class="cg-list-container" :disabled="isDisabled">
|
||||
<template #item="{ element }">
|
||||
<li v-if="fields.includes(element.type)" class="form-edit-widget-label cg-list" :class="{ 'no-put': element.type === 'divider' }" @click="handleClick(element)">
|
||||
<a>
|
||||
<SvgIcon :name="element.type ?? element.icon" />
|
||||
<span>{{ element.label }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</Draggable>
|
||||
<div class="clear"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { PropType } from 'vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
fields: {
|
||||
type: Array as PropType<Array<string>>,
|
||||
required: true,
|
||||
},
|
||||
list: {
|
||||
type: Array as PropType<Array<any>>,
|
||||
required: true,
|
||||
},
|
||||
isDisabled: Boolean,
|
||||
});
|
||||
const emit = defineEmits(['copy']);
|
||||
const handleClick = (element: any) => {
|
||||
emit('copy', element);
|
||||
};
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String
|
||||
},
|
||||
fields: {
|
||||
type: Array as PropType<Array<string>>,
|
||||
required: true
|
||||
},
|
||||
list: {
|
||||
type: Array as PropType<Array<any>>,
|
||||
required: true
|
||||
},
|
||||
isDisabled: Boolean
|
||||
});
|
||||
const emit = defineEmits(['copy']);
|
||||
const handleClick = (element: any) => {
|
||||
emit('copy', element);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.left-title {
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
padding-left: 10px;
|
||||
box-sizing: border-box;
|
||||
margin: 15px 0;
|
||||
border-left: 6px solid #5e95ff;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
}
|
||||
.left-title {
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
padding-left: 10px;
|
||||
box-sizing: border-box;
|
||||
margin: 15px 0;
|
||||
border-left: 6px solid #5e95ff;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.cg-list-container {
|
||||
width: 100%;
|
||||
}
|
||||
.cg-list-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cg-list {
|
||||
float: left;
|
||||
width: 44%;
|
||||
margin-right: 6%;
|
||||
margin-bottom: 8px;
|
||||
padding: 8px 0;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
border: 1px solid #e4e4e4;
|
||||
}
|
||||
.cg-list {
|
||||
float: left;
|
||||
width: 44%;
|
||||
margin-right: 6%;
|
||||
margin-bottom: 8px;
|
||||
padding: 8px 0;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
border: 1px solid #e4e4e4;
|
||||
}
|
||||
|
||||
.cg-list:hover {
|
||||
border: 1px dashed #eef4ff;
|
||||
background-color: #eef4ff;
|
||||
cursor: v-bind("props.isDisabled ? 'not-allowed' : 'pointer'");
|
||||
}
|
||||
.cg-list:hover {
|
||||
border: 1px dashed #eef4ff;
|
||||
background-color: #eef4ff;
|
||||
cursor: v-bind("props.isDisabled ? 'not-allowed' : 'pointer'");
|
||||
}
|
||||
|
||||
.cg-list:hover a {
|
||||
color: #0960bd;
|
||||
cursor: v-bind("props.isDisabled ? 'not-allowed' : 'pointer'");
|
||||
}
|
||||
.cg-list:hover a {
|
||||
color: #0960bd;
|
||||
cursor: v-bind("props.isDisabled ? 'not-allowed' : 'pointer'");
|
||||
}
|
||||
|
||||
.cg-list a {
|
||||
color: #333;
|
||||
}
|
||||
.cg-list a {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.cg-list a svg {
|
||||
width: 14px !important;
|
||||
height: 14px !important;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.cg-list a svg {
|
||||
width: 14px !important;
|
||||
height: 14px !important;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
// @import '/@/assets/style/designer/index.css';
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
// @import '/@/assets/style/designer/index.css';
|
||||
</style>
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<div>
|
||||
<CodeEditor v-model:value="defaultValue" language="js" />
|
||||
</div>
|
||||
<div>
|
||||
<CodeEditor :value="tipContent" language="js" readonly />
|
||||
</div>
|
||||
</BasicModal>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<div>
|
||||
<CodeEditor v-model:value="defaultValue" language="js" />
|
||||
</div>
|
||||
<div>
|
||||
<CodeEditor :value="tipContent" language="js" readonly />
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { CodeEditor } from '/@/components/CodeEditor';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { CodeEditor } from '/@/components/CodeEditor';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const eventType = ref('');
|
||||
const eventType = ref('');
|
||||
|
||||
const tipContent = computed(() => {
|
||||
return `
|
||||
const tipContent = computed(() => {
|
||||
return `
|
||||
//事件方法参数 一共有3个
|
||||
{
|
||||
schema: FormSchema; //当前表单组件的schema
|
||||
@ -36,28 +36,28 @@
|
||||
}
|
||||
|
||||
`;
|
||||
});
|
||||
});
|
||||
|
||||
const defaultValue = ref(``);
|
||||
const defaultValue = ref(``);
|
||||
|
||||
const title = computed(() => {
|
||||
return `编辑${eventType.value}事件`;
|
||||
});
|
||||
const title = computed(() => {
|
||||
return `编辑${eventType.value}事件`;
|
||||
});
|
||||
|
||||
const [registerModal, { closeModal }] = useModalInner(async (data) => {
|
||||
eventType.value = data.type;
|
||||
//如果已经设置过当前事件代码 则显示已经设置的值 反之 显示默认值
|
||||
if (data.content) {
|
||||
defaultValue.value = data.content;
|
||||
} else {
|
||||
defaultValue.value = `
|
||||
const [registerModal, { closeModal }] = useModalInner(async (data) => {
|
||||
eventType.value = data.type;
|
||||
//如果已经设置过当前事件代码 则显示已经设置的值 反之 显示默认值
|
||||
if (data.content) {
|
||||
defaultValue.value = data.content;
|
||||
} else {
|
||||
defaultValue.value = `
|
||||
console.log(schema,formModel,formActionType);
|
||||
`;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
emit('success', unref(eventType), unref(defaultValue));
|
||||
closeModal();
|
||||
}
|
||||
async function handleSubmit() {
|
||||
emit('success', unref(eventType), unref(defaultValue));
|
||||
closeModal();
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,155 +1,138 @@
|
||||
<template>
|
||||
<div class="box-top">
|
||||
<div class="title">{{ t('隐藏组件列表') }}</div>
|
||||
<a-button type="primary" size="small" @click="addComponent">{{ t('添加组件') }}</a-button>
|
||||
</div>
|
||||
<a-form
|
||||
v-for="(item, index) in hiddenComponent"
|
||||
:key="item.key"
|
||||
:labelCol="{ span: 8 }"
|
||||
:wrapperCol="{ span: 16 }"
|
||||
style="margin-top: 20px; position: relative"
|
||||
@mouseenter="showDeleteIndex = index"
|
||||
@mouseleave="showDeleteIndex = -1"
|
||||
>
|
||||
<a-form-item :label="t('组件编码')" required>
|
||||
<a-input v-model:value="item.code" :placeholder="t('请输入组件编码')" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('组件名称')" required>
|
||||
<a-input
|
||||
v-model:value="item.label"
|
||||
:placeholder="t('请输入组件名称')"
|
||||
@change="handleChangeLabel(item)"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('组件值')" required>
|
||||
<a-input v-model:value="item.value" :placeholder="t('请输入组件值')" />
|
||||
</a-form-item>
|
||||
<template v-if="designType === 'data'">
|
||||
<a-form-item :label="t('绑定表')" required>
|
||||
<a-select
|
||||
v-model:value="item.bindTable"
|
||||
:placeholder="t('请选择数据表')"
|
||||
size="mini"
|
||||
@change="changeTable"
|
||||
>
|
||||
<a-select-option v-for="(table, idx) in mainTable" :value="table.name" :key="idx" />
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('绑定字段')" required>
|
||||
<a-select v-model:value="item.bindField" showSearch :placeholder="t('请选择表字段')" size="mini">
|
||||
<a-select-option v-for="(field, idx) in tableField" :value="field.name" :key="idx" />
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</template>
|
||||
<div class="icon-delete" v-show="index === showDeleteIndex">
|
||||
<SvgIcon name="delete" @click.stop="deleteHiddenComponent(index)" class="svg-delete" />
|
||||
<div class="box-top">
|
||||
<div class="title">{{ t('隐藏组件列表') }}</div>
|
||||
<a-button type="primary" size="small" @click="addComponent">{{ t('添加组件') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
<a-form v-for="(item, index) in hiddenComponent" :key="item.key" :labelCol="{ span: 8 }" :wrapperCol="{ span: 16 }" style="margin-top: 20px; position: relative" @mouseenter="showDeleteIndex = index" @mouseleave="showDeleteIndex = -1">
|
||||
<a-form-item :label="t('组件编码')" required>
|
||||
<a-input v-model:value="item.code" :placeholder="t('请输入组件编码')" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('组件名称')" required>
|
||||
<a-input v-model:value="item.label" :placeholder="t('请输入组件名称')" @change="handleChangeLabel(item)" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('组件值')" required>
|
||||
<a-input v-model:value="item.value" :placeholder="t('请输入组件值')" />
|
||||
</a-form-item>
|
||||
<template v-if="designType === 'data'">
|
||||
<a-form-item :label="t('绑定表')" required>
|
||||
<a-select v-model:value="item.bindTable" :placeholder="t('请选择数据表')" size="mini" @change="changeTable">
|
||||
<a-select-option v-for="(table, idx) in mainTable" :value="table.name" :key="idx" />
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('绑定字段')" required>
|
||||
<a-select v-model:value="item.bindField" showSearch :placeholder="t('请选择表字段')" size="mini">
|
||||
<a-select-option v-for="(field, idx) in tableField" :value="field.name" :key="idx" />
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</template>
|
||||
<div class="icon-delete" v-show="index === showDeleteIndex">
|
||||
<SvgIcon name="delete" @click.stop="deleteHiddenComponent(index)" class="svg-delete" />
|
||||
</div>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, inject, Ref } from 'vue';
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { TableInfo, FieldInfo, HiddenComponentInfo } from '../types';
|
||||
import { changeToPinyin } from '/@/utils/event/design';
|
||||
import { random } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
component: {
|
||||
type: Array as PropType<HiddenComponentInfo[]>,
|
||||
},
|
||||
});
|
||||
import { ref, watch, inject, Ref } from 'vue';
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { TableInfo, FieldInfo, HiddenComponentInfo } from '../types';
|
||||
import { changeToPinyin } from '/@/utils/event/design';
|
||||
import { random } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
component: {
|
||||
type: Array as PropType<HiddenComponentInfo[]>
|
||||
}
|
||||
});
|
||||
|
||||
const tableInfo = inject<Ref<TableInfo[]>>('tableInfo') as Ref<TableInfo[]>;
|
||||
const tableInfo = inject<Ref<TableInfo[]>>('tableInfo') as Ref<TableInfo[]>;
|
||||
|
||||
const designType = inject<string>('designType');
|
||||
const isFieldUpper = inject<Ref<boolean>>('isFieldUpper', ref(false));
|
||||
const designType = inject<string>('designType');
|
||||
const isFieldUpper = inject<Ref<boolean>>('isFieldUpper', ref(false));
|
||||
|
||||
const hiddenComponent = ref<HiddenComponentInfo[]>(props.component!);
|
||||
const mainTable = ref<TableInfo[]>([]);
|
||||
const tableField = ref<FieldInfo[]>([]);
|
||||
const showDeleteIndex = ref<number>(-1);
|
||||
let mainTableName;
|
||||
if (designType !== 'data') {
|
||||
mainTableName = inject<string>('mainTableName');
|
||||
}
|
||||
const hiddenComponent = ref<HiddenComponentInfo[]>(props.component!);
|
||||
const mainTable = ref<TableInfo[]>([]);
|
||||
const tableField = ref<FieldInfo[]>([]);
|
||||
const showDeleteIndex = ref<number>(-1);
|
||||
let mainTableName;
|
||||
if (designType !== 'data') {
|
||||
mainTableName = inject<string>('mainTableName');
|
||||
}
|
||||
|
||||
watch(
|
||||
() => tableInfo,
|
||||
() => {
|
||||
mainTable.value = tableInfo.value?.filter((item: any) => item.isMain); //隐藏组件只能选择主表的字段进行绑定
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
const addComponent = () => {
|
||||
const key = `hiddenComponent${Date.now()}`;
|
||||
const com: HiddenComponentInfo = {
|
||||
key,
|
||||
type: 'hiddenComponent',
|
||||
code: '',
|
||||
label: '',
|
||||
value: '',
|
||||
bindTable: '',
|
||||
bindField: '',
|
||||
watch(
|
||||
() => tableInfo,
|
||||
() => {
|
||||
mainTable.value = tableInfo.value?.filter((item: any) => item.isMain); //隐藏组件只能选择主表的字段进行绑定
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
const addComponent = () => {
|
||||
const key = `hiddenComponent${Date.now()}`;
|
||||
const com: HiddenComponentInfo = {
|
||||
key,
|
||||
type: 'hiddenComponent',
|
||||
code: '',
|
||||
label: '',
|
||||
value: '',
|
||||
bindTable: '',
|
||||
bindField: ''
|
||||
};
|
||||
if (designType !== 'data') {
|
||||
com.bindTable = mainTableName.value!;
|
||||
}
|
||||
hiddenComponent.value.push(com);
|
||||
};
|
||||
if (designType !== 'data') {
|
||||
com.bindTable = mainTableName.value!;
|
||||
}
|
||||
hiddenComponent.value.push(com);
|
||||
};
|
||||
|
||||
const handleChangeLabel = (info) => {
|
||||
if (designType !== 'data') {
|
||||
info.bindField = changeToPinyin(info.label, isFieldUpper.value) + random(1000, 9999);
|
||||
}
|
||||
};
|
||||
const deleteHiddenComponent = (index: number) => {
|
||||
hiddenComponent.value.splice(index, 1);
|
||||
};
|
||||
const changeTable = (val: string) => {
|
||||
const chooseTable = mainTable.value.find((table: any) => table.name === val)!;
|
||||
tableField.value = chooseTable?.fields;
|
||||
};
|
||||
const handleChangeLabel = (info) => {
|
||||
if (designType !== 'data') {
|
||||
info.bindField = changeToPinyin(info.label, isFieldUpper.value) + random(1000, 9999);
|
||||
}
|
||||
};
|
||||
const deleteHiddenComponent = (index: number) => {
|
||||
hiddenComponent.value.splice(index, 1);
|
||||
};
|
||||
const changeTable = (val: string) => {
|
||||
const chooseTable = mainTable.value.find((table: any) => table.name === val)!;
|
||||
tableField.value = chooseTable?.fields;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.box-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 5px 0 10px 10px;
|
||||
align-items: center;
|
||||
.box-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 5px 0 10px 10px;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
.title {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-delete {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
right: -5px;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
border: 1px solid #f64c4c;
|
||||
color: #f64c4c;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
.icon-delete {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
right: -5px;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
border: 1px solid #f64c4c;
|
||||
color: #f64c4c;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
|
||||
.svg-delete {
|
||||
width: 13px !important;
|
||||
height: 13px !important;
|
||||
.svg-delete {
|
||||
width: 13px !important;
|
||||
height: 13px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,59 +1,52 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
size="large"
|
||||
@register="registerDrawer"
|
||||
@close="handleCloser"
|
||||
:title="t('表单预览')"
|
||||
>
|
||||
<div>
|
||||
<SimpleForm ref="formRef" :formProps="state.formProps" :formModel="state.formModel">
|
||||
</SimpleForm>
|
||||
</div>
|
||||
</BasicDrawer>
|
||||
</div>
|
||||
<div>
|
||||
<BasicDrawer v-bind="$attrs" size="large" @register="registerDrawer" @close="handleCloser" :title="t('表单预览')">
|
||||
<div>
|
||||
<SimpleForm ref="formRef" :formProps="state.formProps" :formModel="state.formModel"> </SimpleForm>
|
||||
</div>
|
||||
</BasicDrawer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, inject } from 'vue';
|
||||
import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { buildOption } from '/@/utils/helper/designHelper';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const state = reactive({
|
||||
formProps: {} as any,
|
||||
formModel: {},
|
||||
});
|
||||
|
||||
const formRef = ref();
|
||||
|
||||
const isCustomForm = inject<boolean>('isCustomForm', false);
|
||||
|
||||
//使用表单钩子 注册表单 获取到 操作表单的方法
|
||||
|
||||
//使用抽屉内部钩子 获取到 操作抽屉的方法
|
||||
const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (option) => {
|
||||
//每次进来置空
|
||||
setDrawerProps({
|
||||
destroyOnClose: true,
|
||||
width: option?.config?.formWidth || 800,
|
||||
canFullscreen: true,
|
||||
import { reactive, ref, inject } from 'vue';
|
||||
import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { buildOption } from '/@/utils/helper/designHelper';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const state = reactive({
|
||||
formProps: {} as any,
|
||||
formModel: {}
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
formRef.value.setProps({
|
||||
...buildOption(option, !isCustomForm),
|
||||
showResetButton: true,
|
||||
showSubmitButton: true,
|
||||
});
|
||||
formRef.value.setDefaultValue();
|
||||
}, 50);
|
||||
});
|
||||
const formRef = ref();
|
||||
|
||||
//关闭方法
|
||||
const handleCloser = () => {
|
||||
formRef.value!.resetFields(); //重置表单
|
||||
state.formProps = {};
|
||||
};
|
||||
const isCustomForm = inject<boolean>('isCustomForm', false);
|
||||
|
||||
//使用表单钩子 注册表单 获取到 操作表单的方法
|
||||
|
||||
//使用抽屉内部钩子 获取到 操作抽屉的方法
|
||||
const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (option) => {
|
||||
//每次进来置空
|
||||
setDrawerProps({
|
||||
destroyOnClose: true,
|
||||
width: option?.config?.formWidth || 800,
|
||||
canFullscreen: true
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
formRef.value.setProps({
|
||||
...buildOption(option, !isCustomForm),
|
||||
showResetButton: true,
|
||||
showSubmitButton: true
|
||||
});
|
||||
formRef.value.setDefaultValue();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
//关闭方法
|
||||
const handleCloser = () => {
|
||||
formRef.value!.resetFields(); //重置表单
|
||||
state.formProps = {};
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -1,138 +1,125 @@
|
||||
<template>
|
||||
<div v-for="(item, index) in render" :key="item.type">
|
||||
<div :class="index == render.length - 1 ? 'mb-0' : 'event-box'" v-if="isShowEvent(item.name)">
|
||||
<div class="event-title">{{ item.name }}</div>
|
||||
<div>
|
||||
<a-row type="flex" align="middle">
|
||||
<a-col :offset="1" :span="6">
|
||||
<span>{{ t('配置脚本:') }}</span>
|
||||
</a-col>
|
||||
<a-col :span="17">
|
||||
<a-input
|
||||
:placeholder="t('点击配置脚本')"
|
||||
:value="configTxt(item.type)"
|
||||
@click="showConfigModal(item.type)"
|
||||
>
|
||||
<template #suffix>
|
||||
<Icon icon="ant-design:ellipsis-outlined" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div v-for="(item, index) in render" :key="item.type">
|
||||
<div :class="index == render.length - 1 ? 'mb-0' : 'event-box'" v-if="isShowEvent(item.name)">
|
||||
<div class="event-title">{{ item.name }}</div>
|
||||
<div>
|
||||
<a-row type="flex" align="middle">
|
||||
<a-col :offset="1" :span="6">
|
||||
<span>{{ t('配置脚本:') }}</span>
|
||||
</a-col>
|
||||
<a-col :span="17">
|
||||
<a-input :placeholder="t('点击配置脚本')" :value="configTxt(item.type)" @click="showConfigModal(item.type)">
|
||||
<template #suffix>
|
||||
<Icon icon="ant-design:ellipsis-outlined" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ScriptConfig @register="registerModal" @success="submitConfig" :disabled="disabled" />
|
||||
<ScriptConfig @register="registerModal" @success="submitConfig" :disabled="disabled" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import ScriptConfig from './settings/ScriptConfig.vue';
|
||||
import {
|
||||
noBlurComponentEvent,
|
||||
noChangeComponentEvent,
|
||||
noClickComponentEvent,
|
||||
noHaveTableAndField,
|
||||
} from '../../types';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
select: { type: Object, default: {} },
|
||||
widgetForm: { type: Object, default: {} },
|
||||
disabled: { type: Boolean, default: false },
|
||||
});
|
||||
const render = [
|
||||
{
|
||||
name: t('失焦事件'),
|
||||
type: 'blur',
|
||||
},
|
||||
{
|
||||
name: t('点击事件'),
|
||||
type: 'click',
|
||||
},
|
||||
{
|
||||
name: t('值改变事件'),
|
||||
type: 'change',
|
||||
},
|
||||
];
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
const getMainTableComponents = (list, mainTableComponent) => {
|
||||
const rangeComponents = ['time-range', 'date-range'];
|
||||
list.forEach((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
getMainTableComponents(child.list, mainTableComponent);
|
||||
import { ref } from 'vue';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import ScriptConfig from './settings/ScriptConfig.vue';
|
||||
import { noBlurComponentEvent, noChangeComponentEvent, noClickComponentEvent, noHaveTableAndField } from '../../types';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
select: { type: Object, default: {} },
|
||||
widgetForm: { type: Object, default: {} },
|
||||
disabled: { type: Boolean, default: false }
|
||||
});
|
||||
const render = [
|
||||
{
|
||||
name: t('失焦事件'),
|
||||
type: 'blur'
|
||||
},
|
||||
{
|
||||
name: t('点击事件'),
|
||||
type: 'click'
|
||||
},
|
||||
{
|
||||
name: t('值改变事件'),
|
||||
type: 'change'
|
||||
}
|
||||
} else if (rangeComponents.includes(item.type)) {
|
||||
//时间范围、日期范围需改为两个字段
|
||||
mainTableComponent.push({
|
||||
label: t(`{name}开始时间`, { name: item.label }),
|
||||
bindField: item.bindStartTime,
|
||||
];
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
const getMainTableComponents = (list, mainTableComponent) => {
|
||||
const rangeComponents = ['time-range', 'date-range'];
|
||||
list.forEach((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
getMainTableComponents(child.list, mainTableComponent);
|
||||
}
|
||||
} else if (rangeComponents.includes(item.type)) {
|
||||
//时间范围、日期范围需改为两个字段
|
||||
mainTableComponent.push({
|
||||
label: t(`{name}开始时间`, { name: item.label }),
|
||||
bindField: item.bindStartTime
|
||||
});
|
||||
mainTableComponent.push({
|
||||
label: t(`{name}结束时间`, { name: item.label }),
|
||||
bindField: item.bindEndTime
|
||||
});
|
||||
} else if (item.type !== 'form' && item.type !== 'one-for-one' && !noHaveTableAndField.includes(item.type)) {
|
||||
//除去不绑定表和字段的组件 以及表格组件
|
||||
mainTableComponent.push(item);
|
||||
}
|
||||
});
|
||||
mainTableComponent.push({
|
||||
label: t(`{name}结束时间`, { name: item.label }),
|
||||
bindField: item.bindEndTime,
|
||||
};
|
||||
|
||||
const isShowEvent = (name) => {
|
||||
const type = props.select?.type;
|
||||
switch (name) {
|
||||
case t('失焦事件'):
|
||||
return !noBlurComponentEvent.includes(type);
|
||||
case t('点击事件'):
|
||||
return !noClickComponentEvent.includes(type);
|
||||
case t('值改变事件'):
|
||||
return !noChangeComponentEvent.includes(type);
|
||||
}
|
||||
};
|
||||
const showConfigModal = (val) => {
|
||||
const mainTableComponent = ref<any[]>([]);
|
||||
|
||||
getMainTableComponents(props.widgetForm?.list, mainTableComponent.value);
|
||||
openModal(true, {
|
||||
type: val,
|
||||
content: props.select?.options.events[val] || '',
|
||||
list: mainTableComponent.value //这样传才能每次点击都更新
|
||||
});
|
||||
} else if (
|
||||
item.type !== 'form' &&
|
||||
item.type !== 'one-for-one' &&
|
||||
!noHaveTableAndField.includes(item.type)
|
||||
) {
|
||||
//除去不绑定表和字段的组件 以及表格组件
|
||||
mainTableComponent.push(item);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const isShowEvent = (name) => {
|
||||
const type = props.select?.type;
|
||||
switch (name) {
|
||||
case t('失焦事件'):
|
||||
return !noBlurComponentEvent.includes(type);
|
||||
case t('点击事件'):
|
||||
return !noClickComponentEvent.includes(type);
|
||||
case t('值改变事件'):
|
||||
return !noChangeComponentEvent.includes(type);
|
||||
}
|
||||
};
|
||||
const showConfigModal = (val) => {
|
||||
const mainTableComponent = ref<any[]>([]);
|
||||
|
||||
getMainTableComponents(props.widgetForm?.list, mainTableComponent.value);
|
||||
openModal(true, {
|
||||
type: val,
|
||||
content: props.select?.options.events[val] || '',
|
||||
list: mainTableComponent.value, //这样传才能每次点击都更新
|
||||
});
|
||||
};
|
||||
|
||||
const configTxt = (type) => {
|
||||
return props.select.options.events[type] ? t('已配置') : '';
|
||||
};
|
||||
const submitConfig = (type, value) => {
|
||||
if (props.select?.options.events) {
|
||||
props.select.options.events[type] = value;
|
||||
} else {
|
||||
props.select.options.events = {
|
||||
[type]: value,
|
||||
};
|
||||
}
|
||||
};
|
||||
const configTxt = (type) => {
|
||||
return props.select.options.events[type] ? t('已配置') : '';
|
||||
};
|
||||
const submitConfig = (type, value) => {
|
||||
if (props.select?.options.events) {
|
||||
props.select.options.events[type] = value;
|
||||
} else {
|
||||
props.select.options.events = {
|
||||
[type]: value
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.event-box {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.event-box {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.event-title {
|
||||
margin: 5px 0 10px 10px;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
.event-title {
|
||||
margin: 5px 0 10px 10px;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -468,10 +468,7 @@
|
||||
<a-input-number v-model:value="data.options.span" :max="24" :min="0" addonAfter="/ 24" @change="handleSpanChange" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="hasKey('mode')" label="模式选择">
|
||||
<a-select
|
||||
ref="select"
|
||||
v-model:value="data.options.mode"
|
||||
>
|
||||
<a-select ref="select" v-model:value="data.options.mode">
|
||||
<a-select-option value="">单选</a-select-option>
|
||||
<a-select-option value="multiple">多选</a-select-option>
|
||||
</a-select>
|
||||
@ -498,8 +495,8 @@
|
||||
<SvgIcon name="upload" style="margin-right: 10px" />
|
||||
{{ t('点击上传') }}
|
||||
</a-button>
|
||||
<div v-if="VITE_GLOB_UPLOAD_ALERT_TIP?.trim()" style="color: red; margin-top: 8px;">
|
||||
{{VITE_GLOB_UPLOAD_ALERT_TIP}}
|
||||
<div v-if="VITE_GLOB_UPLOAD_ALERT_TIP?.trim()" style="color: red; margin-top: 8px">
|
||||
{{ VITE_GLOB_UPLOAD_ALERT_TIP }}
|
||||
</div>
|
||||
</a-upload>
|
||||
</a-form-item>
|
||||
@ -790,7 +787,7 @@
|
||||
import StaticData from './settings/StaticData.vue';
|
||||
import { ApiConfig } from '/@/components/ApiConfig';
|
||||
import { DicItemSelect } from '/@/components/DicItemSelect';
|
||||
import { getAppEnvConfig } from '/@/utils/env';
|
||||
import { getAppEnvConfig } from '/@/utils/env';
|
||||
import { ColorPicker } from '/@/components/ColorPicker';
|
||||
import { TimePicker } from '/@/components/TimePicker';
|
||||
import SelectDepartmentV2 from '/@/components/Form/src/components/SelectDepartmentV2.vue';
|
||||
@ -1594,14 +1591,13 @@
|
||||
}
|
||||
|
||||
function findTableFields(obj) {
|
||||
|
||||
if (!props.widgetForm?.list) {
|
||||
return [];
|
||||
}
|
||||
const bTable = obj.bindTable;
|
||||
const pTable = props.widgetForm.list.find((item) => item.type === 'form' && item.bindTable === bTable);
|
||||
if (!pTable) {
|
||||
const tableFormList = props.widgetForm.list.filter(item => item.type !== 'form' && item.type !== 'associate-popup')
|
||||
const tableFormList = props.widgetForm.list.filter((item) => item.type !== 'form' && item.type !== 'associate-popup');
|
||||
return tableFormList;
|
||||
}
|
||||
return pTable.children;
|
||||
|
||||
@ -1,146 +1,134 @@
|
||||
<template>
|
||||
<div class="top-box">
|
||||
<div class="regular-title">{{ t('正则校验列表') }}</div>
|
||||
<a-button type="primary" size="small" @click="addRegular" class="add-btn">
|
||||
{{ t('添加正则') }}
|
||||
</a-button>
|
||||
</div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
v-for="(item, index) in data.options?.rules"
|
||||
:key="index"
|
||||
class="reg-item"
|
||||
@mouseenter="showDeleteIndex = index"
|
||||
@mouseleave="showDeleteIndex = -1"
|
||||
>
|
||||
<a-form-item :label="t('正则表达式')">
|
||||
<a-textarea
|
||||
:placeholder="t('请输入正则表达式')"
|
||||
v-model:value="item.pattern"
|
||||
size="small"
|
||||
@blur="checkPattern(item.pattern)"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('错误提示')">
|
||||
<a-textarea :placeholder="t('请输入错误提示')" v-model:value="item.message" size="small" />
|
||||
</a-form-item>
|
||||
<div class="delete-btn" v-show="index === showDeleteIndex">
|
||||
<SvgIcon name="delete" @click.stop="deleteRegList(index)" class="svg-delete" />
|
||||
<div class="top-box">
|
||||
<div class="regular-title">{{ t('正则校验列表') }}</div>
|
||||
<a-button type="primary" size="small" @click="addRegular" class="add-btn">
|
||||
{{ t('添加正则') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
<a-form layout="vertical" v-for="(item, index) in data.options?.rules" :key="index" class="reg-item" @mouseenter="showDeleteIndex = index" @mouseleave="showDeleteIndex = -1">
|
||||
<a-form-item :label="t('正则表达式')">
|
||||
<a-textarea :placeholder="t('请输入正则表达式')" v-model:value="item.pattern" size="small" @blur="checkPattern(item.pattern)" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('错误提示')">
|
||||
<a-textarea :placeholder="t('请输入错误提示')" v-model:value="item.message" size="small" />
|
||||
</a-form-item>
|
||||
<div class="delete-btn" v-show="index === showDeleteIndex">
|
||||
<SvgIcon name="delete" @click.stop="deleteRegList(index)" class="svg-delete" />
|
||||
</div>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { watch, ref } from 'vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
select: { type: Object },
|
||||
});
|
||||
const emit = defineEmits(['update:select']);
|
||||
const data = ref<any>();
|
||||
const showDeleteIndex = ref<number>(-1);
|
||||
watch(
|
||||
() => props.select,
|
||||
(val) => {
|
||||
data.value = val;
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
watch(
|
||||
data,
|
||||
(val) => {
|
||||
emit('update:select', val);
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
const addRegular = () => {
|
||||
data.value.options.rules.push({
|
||||
pattern: '',
|
||||
message: '',
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { watch, ref } from 'vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
select: { type: Object }
|
||||
});
|
||||
data.value.options.required = true;
|
||||
};
|
||||
const deleteRegList = (index) => {
|
||||
data.value.options.rules.splice(index, 1);
|
||||
};
|
||||
const checkPattern = (pattern) => {
|
||||
if (!pattern) return;
|
||||
const start = pattern.substr(0, 1);
|
||||
const end = pattern.substr(-1);
|
||||
if (start !== '/' || end !== '/') {
|
||||
message.error(t('正则表达式不合法,提醒:是否表达式前后带上了/'));
|
||||
return;
|
||||
}
|
||||
};
|
||||
const emit = defineEmits(['update:select']);
|
||||
const data = ref<any>();
|
||||
const showDeleteIndex = ref<number>(-1);
|
||||
watch(
|
||||
() => props.select,
|
||||
(val) => {
|
||||
data.value = val;
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
watch(
|
||||
data,
|
||||
(val) => {
|
||||
emit('update:select', val);
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
const addRegular = () => {
|
||||
data.value.options.rules.push({
|
||||
pattern: '',
|
||||
message: ''
|
||||
});
|
||||
data.value.options.required = true;
|
||||
};
|
||||
const deleteRegList = (index) => {
|
||||
data.value.options.rules.splice(index, 1);
|
||||
};
|
||||
const checkPattern = (pattern) => {
|
||||
if (!pattern) return;
|
||||
const start = pattern.substr(0, 1);
|
||||
const end = pattern.substr(-1);
|
||||
if (start !== '/' || end !== '/') {
|
||||
message.error(t('正则表达式不合法,提醒:是否表达式前后带上了/'));
|
||||
return;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.top-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 5px 0 10px 10px;
|
||||
.top-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 5px 0 10px 10px;
|
||||
|
||||
.regular-title {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
}
|
||||
|
||||
.reg-item {
|
||||
position: relative;
|
||||
padding: 5px 0 5px 15px;
|
||||
margin-bottom: 18px;
|
||||
|
||||
:deep(.ant-form-item-label) > label {
|
||||
font-size: 12px;
|
||||
.regular-title {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
top: -3px;
|
||||
right: -3px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border: 1px solid #f64c4c;
|
||||
color: #f64c4c;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
.reg-item {
|
||||
position: relative;
|
||||
padding: 5px 0 5px 15px;
|
||||
margin-bottom: 18px;
|
||||
|
||||
.svg-delete {
|
||||
width: 12px !important;
|
||||
height: 12px !important;
|
||||
}
|
||||
:deep(.ant-form-item-label) > label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
top: -3px;
|
||||
right: -3px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border: 1px solid #f64c4c;
|
||||
color: #f64c4c;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
|
||||
.svg-delete {
|
||||
width: 12px !important;
|
||||
height: 12px !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
:deep(.ant-form-item:last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
// .add-btn {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
|
||||
:deep(.ant-form-item:last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// .add-btn {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
|
||||
// /deep/.app-iconify {
|
||||
// display: block !important;
|
||||
// }
|
||||
// }
|
||||
// /deep/.app-iconify {
|
||||
// display: block !important;
|
||||
// }
|
||||
// }
|
||||
</style>
|
||||
|
||||
@ -1,165 +1,157 @@
|
||||
<template>
|
||||
<div class="awc-containter">
|
||||
<a-form
|
||||
v-bind="layout"
|
||||
v-if="tablecell && Object.keys(tablecell).length > 0"
|
||||
:key="1"
|
||||
size="small"
|
||||
>
|
||||
<a-form-item label="类型">
|
||||
<a-input v-model:value="tablecell.class" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item label="高度">
|
||||
<a-input-number v-model:value="tablecell.height" size="mini" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-form v-bind="layout" v-if="tableth && Object.keys(tableth).length > 0" :key="2" size="small">
|
||||
<a-form-item label="类型">
|
||||
<a-input v-model:value="tableth.class" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item label="宽度">
|
||||
<a-input-number v-model:value="tableth.width" size="mini" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-form v-bind="layout" v-if="showData" :key="3" size="small">
|
||||
<a-form-item :label="t('标题')">
|
||||
<a-input v-model:value="data.label" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item label="边框宽度">
|
||||
<a-input-number v-model:value="data.options.borderWidth" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item label="边框颜色">
|
||||
<ColorPicker v-model:value="data.options.borderColor" />
|
||||
</a-form-item>
|
||||
<a-form-item label="自定义类">
|
||||
<a-input v-model:value="data.options.class" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('是否显示')">
|
||||
<a-switch v-model:checked="data.options.isShow" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
<div class="awc-containter">
|
||||
<a-form v-bind="layout" v-if="tablecell && Object.keys(tablecell).length > 0" :key="1" size="small">
|
||||
<a-form-item label="类型">
|
||||
<a-input v-model:value="tablecell.class" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item label="高度">
|
||||
<a-input-number v-model:value="tablecell.height" size="mini" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-form v-bind="layout" v-if="tableth && Object.keys(tableth).length > 0" :key="2" size="small">
|
||||
<a-form-item label="类型">
|
||||
<a-input v-model:value="tableth.class" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item label="宽度">
|
||||
<a-input-number v-model:value="tableth.width" size="mini" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-form v-bind="layout" v-if="showData" :key="3" size="small">
|
||||
<a-form-item :label="t('标题')">
|
||||
<a-input v-model:value="data.label" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item label="边框宽度">
|
||||
<a-input-number v-model:value="data.options.borderWidth" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item label="边框颜色">
|
||||
<ColorPicker v-model:value="data.options.borderColor" />
|
||||
</a-form-item>
|
||||
<a-form-item label="自定义类">
|
||||
<a-input v-model:value="data.options.class" size="mini" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('是否显示')">
|
||||
<a-switch v-model:checked="data.options.isShow" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, inject, ref, Ref, watch } from 'vue';
|
||||
import { defineComponent, inject, ref, Ref, watch } from 'vue';
|
||||
|
||||
import Draggable from 'vuedraggable';
|
||||
import { SvgIcon, IconPicker, Icon } from '/@/components/Icon';
|
||||
import Draggable from 'vuedraggable';
|
||||
import { SvgIcon, IconPicker, Icon } from '/@/components/Icon';
|
||||
|
||||
import { ColorPicker } from '/@/components/ColorPicker';
|
||||
import { ColorPicker } from '/@/components/ColorPicker';
|
||||
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { TableCell, TableTh } from '../../types';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { TableCell, TableTh } from '../../types';
|
||||
|
||||
const { t } = useI18n();
|
||||
export default defineComponent({
|
||||
name: 'PropertyOption',
|
||||
components: {
|
||||
Draggable,
|
||||
SvgIcon,
|
||||
IconPicker,
|
||||
Icon,
|
||||
ColorPicker,
|
||||
},
|
||||
emits: ['update:select'],
|
||||
props: {
|
||||
//所选组件配置
|
||||
select: {
|
||||
type: Object,
|
||||
},
|
||||
widgetForm: {
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
setup(props, context) {
|
||||
const showData = ref(false);
|
||||
const data = ref<any>();
|
||||
const tablecell = inject<Ref<TableCell>>('tableCell');
|
||||
const tableth = inject<Ref<TableTh>>('tableTh');
|
||||
const layout = {
|
||||
labelCol: { span: 8 },
|
||||
wrapperCol: { span: 16 },
|
||||
};
|
||||
watch(
|
||||
() => props.select,
|
||||
(val) => {
|
||||
data.value = val;
|
||||
if (
|
||||
(tableth?.value && Object.keys(tableth.value).length > 0) ||
|
||||
(tablecell?.value && Object.keys(tablecell.value).length > 0)
|
||||
) {
|
||||
showData.value = false;
|
||||
} else {
|
||||
showData.value = true;
|
||||
}
|
||||
const { t } = useI18n();
|
||||
export default defineComponent({
|
||||
name: 'PropertyOption',
|
||||
components: {
|
||||
Draggable,
|
||||
SvgIcon,
|
||||
IconPicker,
|
||||
Icon,
|
||||
ColorPicker
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
emits: ['update:select'],
|
||||
props: {
|
||||
//所选组件配置
|
||||
select: {
|
||||
type: Object
|
||||
},
|
||||
widgetForm: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
);
|
||||
watch(
|
||||
() => tablecell?.value,
|
||||
(val) => {
|
||||
if (val && Object.keys(val).length > 0) {
|
||||
showData.value = false;
|
||||
} else if (tableth?.value && Object.keys(tableth.value).length <= 0) {
|
||||
showData.value = true;
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
watch(
|
||||
() => tableth?.value,
|
||||
(val) => {
|
||||
if (val && Object.keys(val).length > 0) {
|
||||
showData.value = false;
|
||||
} else if (tablecell?.value && Object.keys(tablecell.value).length <= 0) {
|
||||
showData.value = true;
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
watch(
|
||||
data,
|
||||
(val) => {
|
||||
context.emit('update:select', val);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
setup(props, context) {
|
||||
const showData = ref(false);
|
||||
const data = ref<any>();
|
||||
const tablecell = inject<Ref<TableCell>>('tableCell');
|
||||
const tableth = inject<Ref<TableTh>>('tableTh');
|
||||
const layout = {
|
||||
labelCol: { span: 8 },
|
||||
wrapperCol: { span: 16 }
|
||||
};
|
||||
watch(
|
||||
() => props.select,
|
||||
(val) => {
|
||||
data.value = val;
|
||||
if ((tableth?.value && Object.keys(tableth.value).length > 0) || (tablecell?.value && Object.keys(tablecell.value).length > 0)) {
|
||||
showData.value = false;
|
||||
} else {
|
||||
showData.value = true;
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => tablecell?.value,
|
||||
(val) => {
|
||||
if (val && Object.keys(val).length > 0) {
|
||||
showData.value = false;
|
||||
} else if (tableth?.value && Object.keys(tableth.value).length <= 0) {
|
||||
showData.value = true;
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => tableth?.value,
|
||||
(val) => {
|
||||
if (val && Object.keys(val).length > 0) {
|
||||
showData.value = false;
|
||||
} else if (tablecell?.value && Object.keys(tablecell.value).length <= 0) {
|
||||
showData.value = true;
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
watch(
|
||||
data,
|
||||
(val) => {
|
||||
context.emit('update:select', val);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
layout,
|
||||
tablecell,
|
||||
tableth,
|
||||
showData,
|
||||
data,
|
||||
t,
|
||||
};
|
||||
},
|
||||
});
|
||||
return {
|
||||
layout,
|
||||
tablecell,
|
||||
tableth,
|
||||
showData,
|
||||
data,
|
||||
t
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
*,
|
||||
:deep(.ant-input) {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
*,
|
||||
:deep(.ant-input) {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
:deep(.ant-row) {
|
||||
align-items: center;
|
||||
}
|
||||
:deep(.ant-row) {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,412 +1,382 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:width="1000"
|
||||
v-model:visible="visible"
|
||||
:title="title"
|
||||
:maskClosable="false"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleClose"
|
||||
:bodyStyle="{ padding: '0 10px 10px' }"
|
||||
>
|
||||
<div class="list-title">{{ t('字段列表') }}</div>
|
||||
<a-row type="flex" align="middle" :gutter="12" style="margin: 15px 0">
|
||||
<a-col flex="auto" class="text-right">{{ t('调用接口:') }}</a-col>
|
||||
<a-col flex="75%">
|
||||
<a-input v-model:value="apiConfigInfo.path" disabled />
|
||||
</a-col>
|
||||
<a-col flex="auto">
|
||||
<a-button key="submit" type="primary" @click="viewInterfaceInfo">{{
|
||||
t('查看接口信息')
|
||||
}}</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-table
|
||||
:dataSource="apiConfigInfo.outputParams"
|
||||
:columns="apiColumns"
|
||||
:pagination="false"
|
||||
:scroll="{ y: '400px' }"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'show'">
|
||||
{{ t('是否在弹层列表显示') }}
|
||||
<a-checkbox v-model:checked="checkedAll" @change="handleChecked" />
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'name'">
|
||||
<a-input
|
||||
v-model:value="record.name"
|
||||
:placeholder="t('请填写字段名')"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'component'">
|
||||
<a-select
|
||||
v-model:value="record.component"
|
||||
style="width: 100%"
|
||||
:placeholder="t('请选择填充组件')"
|
||||
@change="(value) => selectBindField(value, record)"
|
||||
allowClear
|
||||
:disabled="disabled"
|
||||
>
|
||||
<a-select-option :value="val.key" v-for="(val, idx) in selectedList" :key="idx">
|
||||
{{ val.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'tableTitle'">
|
||||
<a-input v-model:value="record.tableTitle" :placeholder="t('请填写表头名称')" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'show'">
|
||||
<a-checkbox v-model:checked="record.show" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'width'">
|
||||
<a-input
|
||||
v-model:value="record.width"
|
||||
:disabled="!record.show"
|
||||
:placeholder="t('请填写列表宽度')"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<DeleteTwoTone two-tone-color="#ff8080" @click="deleteParamas(index)" />
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-button type="dashed" block @click="addOutPutParamas" :disabled="disabled">
|
||||
<PlusOutlined />
|
||||
{{ t('新增') }}
|
||||
</a-button>
|
||||
</a-modal>
|
||||
<InterfaceInfoModal @register="registerModal" />
|
||||
<a-modal :width="1000" v-model:visible="visible" :title="title" :maskClosable="false" @ok="handleSubmit" @cancel="handleClose" :bodyStyle="{ padding: '0 10px 10px' }">
|
||||
<div class="list-title">{{ t('字段列表') }}</div>
|
||||
<a-row type="flex" align="middle" :gutter="12" style="margin: 15px 0">
|
||||
<a-col flex="auto" class="text-right">{{ t('调用接口:') }}</a-col>
|
||||
<a-col flex="75%">
|
||||
<a-input v-model:value="apiConfigInfo.path" disabled />
|
||||
</a-col>
|
||||
<a-col flex="auto">
|
||||
<a-button key="submit" type="primary" @click="viewInterfaceInfo">{{ t('查看接口信息') }}</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-table :dataSource="apiConfigInfo.outputParams" :columns="apiColumns" :pagination="false" :scroll="{ y: '400px' }">
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'show'">
|
||||
{{ t('是否在弹层列表显示') }}
|
||||
<a-checkbox v-model:checked="checkedAll" @change="handleChecked" />
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'name'">
|
||||
<a-input v-model:value="record.name" :placeholder="t('请填写字段名')" :disabled="disabled" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'component'">
|
||||
<a-select v-model:value="record.component" style="width: 100%" :placeholder="t('请选择填充组件')" @change="(value) => selectBindField(value, record)" allowClear :disabled="disabled">
|
||||
<a-select-option :value="val.key" v-for="(val, idx) in selectedList" :key="idx">
|
||||
{{ val.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'tableTitle'">
|
||||
<a-input v-model:value="record.tableTitle" :placeholder="t('请填写表头名称')" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'show'">
|
||||
<a-checkbox v-model:checked="record.show" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'width'">
|
||||
<a-input v-model:value="record.width" :disabled="!record.show" :placeholder="t('请填写列表宽度')" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<DeleteTwoTone two-tone-color="#ff8080" @click="deleteParamas(index)" />
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-button type="dashed" block @click="addOutPutParamas" :disabled="disabled">
|
||||
<PlusOutlined />
|
||||
{{ t('新增') }}
|
||||
</a-button>
|
||||
</a-modal>
|
||||
<InterfaceInfoModal @register="registerModal" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { watch, ref, reactive } from 'vue';
|
||||
import { ColumnProps } from 'ant-design-vue/lib/table/Column';
|
||||
import { PlusOutlined, DeleteTwoTone } from '@ant-design/icons-vue';
|
||||
import InterfaceInfoModal from './InterfaceInfoModal.vue';
|
||||
import { getInterfaceInfo } from '/@/api/system/interface/index';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { watch, ref, reactive } from 'vue';
|
||||
import { ColumnProps } from 'ant-design-vue/lib/table/Column';
|
||||
import { PlusOutlined, DeleteTwoTone } from '@ant-design/icons-vue';
|
||||
import InterfaceInfoModal from './InterfaceInfoModal.vue';
|
||||
import { getInterfaceInfo } from '/@/api/system/interface/index';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
apiAssoDia: { type: Boolean },
|
||||
apiConfig: {
|
||||
type: Object as PropType<any>,
|
||||
},
|
||||
selectedList: { type: Array as any },
|
||||
type: { type: String },
|
||||
disabled: { type: Boolean, default: () => false },
|
||||
});
|
||||
const emit = defineEmits(['update:apiAssoDia', 'update:apiConfig']);
|
||||
const visible = ref<boolean>(props.apiAssoDia);
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
apiAssoDia: { type: Boolean },
|
||||
apiConfig: {
|
||||
type: Object as PropType<any>
|
||||
},
|
||||
selectedList: { type: Array as any },
|
||||
type: { type: String },
|
||||
disabled: { type: Boolean, default: () => false }
|
||||
});
|
||||
const emit = defineEmits(['update:apiAssoDia', 'update:apiConfig']);
|
||||
const visible = ref<boolean>(props.apiAssoDia);
|
||||
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
const apiConfigInfo = ref();
|
||||
const apiColumns = ref<ColumnProps[]>([]);
|
||||
const title = ref<string>('');
|
||||
const checkedAll = ref<boolean>(false);
|
||||
const multiplePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
title: t('接口返回参数字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: t('是否在弹层中显示'),
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('列表宽度'),
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50,
|
||||
},
|
||||
]);
|
||||
|
||||
const associatePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
title: t('接口返回参数字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('填充组件'),
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('是否在弹层列表显示'),
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('列表宽度'),
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50,
|
||||
},
|
||||
]);
|
||||
|
||||
const associateSelectColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
title: t('接口返回参数字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('填充组件'),
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('填充组件绑定字段'),
|
||||
dataIndex: 'bindField',
|
||||
key: 'bindField',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50,
|
||||
},
|
||||
]);
|
||||
const preloadColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
title: t('接口返回参数字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50,
|
||||
},
|
||||
]);
|
||||
watch(
|
||||
() => props.type,
|
||||
(val) => {
|
||||
switch (val) {
|
||||
case 'button':
|
||||
case 'associate-popup':
|
||||
apiColumns.value = associatePopupColumns;
|
||||
title.value = t('联想数据配置-API');
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
apiColumns.value = multiplePopupColumns;
|
||||
title.value = t('多选数据配置-API');
|
||||
break;
|
||||
case 'associate-select':
|
||||
apiColumns.value = associateSelectColumns;
|
||||
title.value = t('联想数据配置-API');
|
||||
break;
|
||||
case 'preload-title':
|
||||
apiColumns.value = preloadColumns;
|
||||
title.value = t('表头配置-API');
|
||||
break;
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.apiConfig,
|
||||
(val) => {
|
||||
apiConfigInfo.value = cloneDeep(val);
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => apiConfigInfo.value,
|
||||
(val) => {
|
||||
checkedAll.value = val?.outputParams?.every((item: any) => {
|
||||
return item.show;
|
||||
});
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
function selectBindField(value, record) {
|
||||
if (!value || !isNaN(value)) {
|
||||
message.error(t('请先选择该组件的绑定表及绑定字段'));
|
||||
record.bindField = null;
|
||||
record.bindTable = undefined;
|
||||
} else {
|
||||
let obj = props.selectedList.find((o) => o.key == value);
|
||||
if (obj) {
|
||||
record.bindField = obj.bindField;
|
||||
if (obj.isSingleFormChild || obj.isSubFormChild) {
|
||||
record.bindTable = obj.bindTable;
|
||||
} else {
|
||||
record.bindTable = undefined;
|
||||
const apiConfigInfo = ref();
|
||||
const apiColumns = ref<ColumnProps[]>([]);
|
||||
const title = ref<string>('');
|
||||
const checkedAll = ref<boolean>(false);
|
||||
const multiplePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: t('接口返回参数字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: t('是否在弹层中显示'),
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('列表宽度'),
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function handleClose() {
|
||||
emit('update:apiAssoDia', false);
|
||||
}
|
||||
function handleChecked(e) {
|
||||
apiConfigInfo.value.outputParams.map((item: any) => (item.show = e.target.checked));
|
||||
}
|
||||
]);
|
||||
|
||||
function handleSubmit() {
|
||||
const bindFieldArr = <any>[];
|
||||
apiConfigInfo.value.outputParams?.map((item: any) => {
|
||||
if (item.bindField) {
|
||||
bindFieldArr.push(item.bindField);
|
||||
}
|
||||
});
|
||||
if (new Set(bindFieldArr).size !== bindFieldArr.length) {
|
||||
message.error(t('组件存在重复绑定,请更改'));
|
||||
return;
|
||||
}
|
||||
emit('update:apiConfig', apiConfigInfo.value);
|
||||
emit('update:apiAssoDia', false);
|
||||
}
|
||||
const associatePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: t('接口返回参数字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('填充组件'),
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('是否在弹层列表显示'),
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('列表宽度'),
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50
|
||||
}
|
||||
]);
|
||||
|
||||
const viewInterfaceInfo = async () => {
|
||||
//在弹窗内调接口会格式不对 所以在此处调接口传进去
|
||||
const info = await getInterfaceInfo({ id: props.apiConfig.apiId });
|
||||
openModal(true, {
|
||||
script: info?.script || '',
|
||||
});
|
||||
};
|
||||
const associateSelectColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: t('接口返回参数字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('填充组件'),
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('填充组件绑定字段'),
|
||||
dataIndex: 'bindField',
|
||||
key: 'bindField',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50
|
||||
}
|
||||
]);
|
||||
const preloadColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: t('接口返回参数字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50
|
||||
}
|
||||
]);
|
||||
watch(
|
||||
() => props.type,
|
||||
(val) => {
|
||||
switch (val) {
|
||||
case 'button':
|
||||
case 'associate-popup':
|
||||
apiColumns.value = associatePopupColumns;
|
||||
title.value = t('联想数据配置-API');
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
apiColumns.value = multiplePopupColumns;
|
||||
title.value = t('多选数据配置-API');
|
||||
break;
|
||||
case 'associate-select':
|
||||
apiColumns.value = associateSelectColumns;
|
||||
title.value = t('联想数据配置-API');
|
||||
break;
|
||||
case 'preload-title':
|
||||
apiColumns.value = preloadColumns;
|
||||
title.value = t('表头配置-API');
|
||||
break;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const addOutPutParamas = () => {
|
||||
if (!apiConfigInfo.value.outputParams) {
|
||||
apiConfigInfo.value.outputParams = [];
|
||||
watch(
|
||||
() => props.apiConfig,
|
||||
(val) => {
|
||||
apiConfigInfo.value = cloneDeep(val);
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => apiConfigInfo.value,
|
||||
(val) => {
|
||||
checkedAll.value = val?.outputParams?.every((item: any) => {
|
||||
return item.show;
|
||||
});
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
|
||||
function selectBindField(value, record) {
|
||||
if (!value || !isNaN(value)) {
|
||||
message.error(t('请先选择该组件的绑定表及绑定字段'));
|
||||
record.bindField = null;
|
||||
record.bindTable = undefined;
|
||||
} else {
|
||||
let obj = props.selectedList.find((o) => o.key == value);
|
||||
if (obj) {
|
||||
record.bindField = obj.bindField;
|
||||
if (obj.isSingleFormChild || obj.isSubFormChild) {
|
||||
record.bindTable = obj.bindTable;
|
||||
} else {
|
||||
record.bindTable = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let configObj = {};
|
||||
switch (props.type) {
|
||||
case 'button':
|
||||
case 'associate-popup':
|
||||
configObj = {
|
||||
name: '',
|
||||
tableTitle: '',
|
||||
bindField: '',
|
||||
show: true,
|
||||
width: 150,
|
||||
};
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
configObj = {
|
||||
name: '',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150,
|
||||
};
|
||||
break;
|
||||
case 'associate-select':
|
||||
configObj = {
|
||||
name: '',
|
||||
bindField: '',
|
||||
};
|
||||
break;
|
||||
function handleClose() {
|
||||
emit('update:apiAssoDia', false);
|
||||
}
|
||||
apiConfigInfo.value.outputParams.push(configObj);
|
||||
};
|
||||
const deleteParamas = (index) => {
|
||||
if (props.disabled) return;
|
||||
apiConfigInfo.value.outputParams.splice(index, 1);
|
||||
};
|
||||
function handleChecked(e) {
|
||||
apiConfigInfo.value.outputParams.map((item: any) => (item.show = e.target.checked));
|
||||
}
|
||||
|
||||
function handleSubmit() {
|
||||
const bindFieldArr = <any>[];
|
||||
apiConfigInfo.value.outputParams?.map((item: any) => {
|
||||
if (item.bindField) {
|
||||
bindFieldArr.push(item.bindField);
|
||||
}
|
||||
});
|
||||
if (new Set(bindFieldArr).size !== bindFieldArr.length) {
|
||||
message.error(t('组件存在重复绑定,请更改'));
|
||||
return;
|
||||
}
|
||||
emit('update:apiConfig', apiConfigInfo.value);
|
||||
emit('update:apiAssoDia', false);
|
||||
}
|
||||
|
||||
const viewInterfaceInfo = async () => {
|
||||
//在弹窗内调接口会格式不对 所以在此处调接口传进去
|
||||
const info = await getInterfaceInfo({ id: props.apiConfig.apiId });
|
||||
openModal(true, {
|
||||
script: info?.script || ''
|
||||
});
|
||||
};
|
||||
|
||||
const addOutPutParamas = () => {
|
||||
if (!apiConfigInfo.value.outputParams) {
|
||||
apiConfigInfo.value.outputParams = [];
|
||||
}
|
||||
let configObj = {};
|
||||
switch (props.type) {
|
||||
case 'button':
|
||||
case 'associate-popup':
|
||||
configObj = {
|
||||
name: '',
|
||||
tableTitle: '',
|
||||
bindField: '',
|
||||
show: true,
|
||||
width: 150
|
||||
};
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
configObj = {
|
||||
name: '',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150
|
||||
};
|
||||
break;
|
||||
case 'associate-select':
|
||||
configObj = {
|
||||
name: '',
|
||||
bindField: ''
|
||||
};
|
||||
break;
|
||||
}
|
||||
apiConfigInfo.value.outputParams.push(configObj);
|
||||
};
|
||||
const deleteParamas = (index) => {
|
||||
if (props.disabled) return;
|
||||
apiConfigInfo.value.outputParams.splice(index, 1);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.list-title {
|
||||
margin: 10px 0 5px;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
.list-title {
|
||||
margin: 10px 0 5px;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,461 +1,417 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:width="1000"
|
||||
:height="550"
|
||||
v-model:visible="dialog"
|
||||
:title="t('计算式配置')"
|
||||
:maskClosable="false"
|
||||
@ok="submitDialog"
|
||||
@cancel="closeDialog"
|
||||
style="overflow: auto"
|
||||
>
|
||||
<a-layout class="config-container" hasSider>
|
||||
<a-layout-sider width="300">
|
||||
<div class="component-list">
|
||||
<a-collapse v-model:activeKey="activeKey" expand-icon-position="right">
|
||||
<a-collapse-panel
|
||||
v-for="(item, index) in selectedComponents"
|
||||
:key="index"
|
||||
:header="item.label"
|
||||
>
|
||||
<draggable
|
||||
v-model="item.children"
|
||||
item-key="item.key"
|
||||
:group="{ name: 'computation', pull: 'clone', put: false }"
|
||||
:sort="false"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<a-tag
|
||||
:color="tagColor(item, element)"
|
||||
:class="{ 'disabled-tag': disabledCom(element.key) }"
|
||||
>
|
||||
{{ element.label }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</draggable>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</div>
|
||||
</a-layout-sider>
|
||||
<a-layout-content class="bgcWhite">
|
||||
<div class="title">{{ t('计算公式') }}</div>
|
||||
<div class="btn-list">
|
||||
<div>
|
||||
<draggable
|
||||
v-model="operatingBtnList"
|
||||
:group="{ name: 'computation', pull: 'clone', put: false }"
|
||||
item-key="item.label"
|
||||
:sort="false"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<a-tag>
|
||||
{{ element.label }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
<div class="input-number">
|
||||
<span>{{ t('数字:') }}</span>
|
||||
<a-input-number v-model:value="number" />
|
||||
<a-button type="primary" @click="addNumber">{{ t('确定') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="computational-box">
|
||||
<div v-if="!computationalList.length" class="computational-text">
|
||||
<p style="font-size: 24px; color: #606266">{{ t('拖拽左侧到此处进行添加') }}</p>
|
||||
<p>{{ t('变量之间可通过计算公式进行运算(例:销售单价 * 销售数量)') }}</p>
|
||||
</div>
|
||||
<draggable
|
||||
v-model="computationalList"
|
||||
group="computation"
|
||||
item-key="key"
|
||||
@add="addComputationalList"
|
||||
class="draggable"
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<div @mouseenter="mouseenter(index)" @mouseleave="isMouseenter = false">
|
||||
<a-select
|
||||
v-model:value="element.computationalMethod"
|
||||
style="width: 85px"
|
||||
v-if="element.computationalMethod"
|
||||
>
|
||||
<a-select-option value="sum">{{ t('总和') }}</a-select-option>
|
||||
<a-select-option value="mean">{{ t('平均数') }}</a-select-option>
|
||||
<a-select-option value="max">{{ t('最大值') }}</a-select-option>
|
||||
<a-select-option value="min">{{ t('最小值') }}</a-select-option>
|
||||
</a-select>
|
||||
<a-tag color="blue" closable style="padding: 5px" @close="delTag(index)">
|
||||
<span>{{ element.label }}</span>
|
||||
</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-modal>
|
||||
<a-modal :width="1000" :height="550" v-model:visible="dialog" :title="t('计算式配置')" :maskClosable="false" @ok="submitDialog" @cancel="closeDialog" style="overflow: auto">
|
||||
<a-layout class="config-container" hasSider>
|
||||
<a-layout-sider width="300">
|
||||
<div class="component-list">
|
||||
<a-collapse v-model:activeKey="activeKey" expand-icon-position="right">
|
||||
<a-collapse-panel v-for="(item, index) in selectedComponents" :key="index" :header="item.label">
|
||||
<draggable v-model="item.children" item-key="item.key" :group="{ name: 'computation', pull: 'clone', put: false }" :sort="false">
|
||||
<template #item="{ element }">
|
||||
<a-tag :color="tagColor(item, element)" :class="{ 'disabled-tag': disabledCom(element.key) }">
|
||||
{{ element.label }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</draggable>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</div>
|
||||
</a-layout-sider>
|
||||
<a-layout-content class="bgcWhite">
|
||||
<div class="title">{{ t('计算公式') }}</div>
|
||||
<div class="btn-list">
|
||||
<div>
|
||||
<draggable v-model="operatingBtnList" :group="{ name: 'computation', pull: 'clone', put: false }" item-key="item.label" :sort="false">
|
||||
<template #item="{ element }">
|
||||
<a-tag>
|
||||
{{ element.label }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
<div class="input-number">
|
||||
<span>{{ t('数字:') }}</span>
|
||||
<a-input-number v-model:value="number" />
|
||||
<a-button type="primary" @click="addNumber">{{ t('确定') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="computational-box">
|
||||
<div v-if="!computationalList.length" class="computational-text">
|
||||
<p style="font-size: 24px; color: #606266">{{ t('拖拽左侧到此处进行添加') }}</p>
|
||||
<p>{{ t('变量之间可通过计算公式进行运算(例:销售单价 * 销售数量)') }}</p>
|
||||
</div>
|
||||
<draggable v-model="computationalList" group="computation" item-key="key" @add="addComputationalList" class="draggable">
|
||||
<template #item="{ element, index }">
|
||||
<div @mouseenter="mouseenter(index)" @mouseleave="isMouseenter = false">
|
||||
<a-select v-model:value="element.computationalMethod" style="width: 85px" v-if="element.computationalMethod">
|
||||
<a-select-option value="sum">{{ t('总和') }}</a-select-option>
|
||||
<a-select-option value="mean">{{ t('平均数') }}</a-select-option>
|
||||
<a-select-option value="max">{{ t('最大值') }}</a-select-option>
|
||||
<a-select-option value="min">{{ t('最小值') }}</a-select-option>
|
||||
</a-select>
|
||||
<a-tag color="blue" closable style="padding: 5px" @close="delTag(index)">
|
||||
<span>{{ element.label }}</span>
|
||||
</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, inject, reactive, onMounted } from 'vue';
|
||||
import { ComputationalConfig } from '/@/components/Designer/src/types';
|
||||
import draggable from 'vuedraggable';
|
||||
import { cloneDeep, random } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
computationalDialog: { type: Boolean },
|
||||
computationalConfig: {
|
||||
type: Array as PropType<ComputationalConfig[]>,
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
const { widgetForm, widgetFormSelect } = inject('state') as any; //整个表单json配置
|
||||
const operatingBtnList = reactive([
|
||||
{
|
||||
key: 1,
|
||||
operation: '+',
|
||||
label: '+',
|
||||
type: 'operation',
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
operation: '-',
|
||||
label: '-',
|
||||
type: 'operation',
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
operation: '×',
|
||||
label: '*',
|
||||
type: 'operation',
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
operation: '÷',
|
||||
label: '/',
|
||||
type: 'operation',
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
operation: '(',
|
||||
label: '(',
|
||||
type: 'operation',
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
operation: ')',
|
||||
label: ')',
|
||||
type: 'operation',
|
||||
},
|
||||
{
|
||||
key: 7,
|
||||
operation: '.',
|
||||
label: '.',
|
||||
type: 'operation',
|
||||
},
|
||||
]);
|
||||
const number = ref<string>('');
|
||||
const isMouseenter = ref<Boolean>(false);
|
||||
const computationalList = ref<Array<any>>([]);
|
||||
const mouseenterIndex = ref<number>();
|
||||
const activeKey = ref([0]);
|
||||
const selectedComponents = ref<Array<any>>([]);
|
||||
const dialog = ref(props.computationalDialog);
|
||||
onMounted(() => {
|
||||
if (widgetForm.list.length) {
|
||||
getTableComponents(widgetForm.list, t('主表组件列表'));
|
||||
}
|
||||
if (props.computationalConfig.length) {
|
||||
computationalList.value = cloneDeep(props.computationalConfig);
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:computationalDialog',
|
||||
'setComputationalConfigValue',
|
||||
'update:computationalConfig',
|
||||
]);
|
||||
|
||||
const getTableComponents = (list, tableName, key?) => {
|
||||
list.forEach((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
getTableComponents(child.list, tableName);
|
||||
import { ref, inject, reactive, onMounted } from 'vue';
|
||||
import { ComputationalConfig } from '/@/components/Designer/src/types';
|
||||
import draggable from 'vuedraggable';
|
||||
import { cloneDeep, random } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
computationalDialog: { type: Boolean },
|
||||
computationalConfig: {
|
||||
type: Array as PropType<ComputationalConfig[]>,
|
||||
default: []
|
||||
}
|
||||
} else if (item.type === 'table-layout') {
|
||||
for (const child of item.layout!) {
|
||||
for (const list of child.list) {
|
||||
getTableComponents(list.children, key);
|
||||
}
|
||||
});
|
||||
const { widgetForm, widgetFormSelect } = inject('state') as any; //整个表单json配置
|
||||
const operatingBtnList = reactive([
|
||||
{
|
||||
key: 1,
|
||||
operation: '+',
|
||||
label: '+',
|
||||
type: 'operation'
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
operation: '-',
|
||||
label: '-',
|
||||
type: 'operation'
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
operation: '×',
|
||||
label: '*',
|
||||
type: 'operation'
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
operation: '÷',
|
||||
label: '/',
|
||||
type: 'operation'
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
operation: '(',
|
||||
label: '(',
|
||||
type: 'operation'
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
operation: ')',
|
||||
label: ')',
|
||||
type: 'operation'
|
||||
},
|
||||
{
|
||||
key: 7,
|
||||
operation: '.',
|
||||
label: '.',
|
||||
type: 'operation'
|
||||
}
|
||||
} else if (item.type === 'one-for-one') {
|
||||
getTableComponents(item.children, `${item.label}-${item.key}`, item.key);
|
||||
} else if (item.type === 'form') {
|
||||
const hasMethods = item.children.some((child) => {
|
||||
return child.key === widgetFormSelect.key;
|
||||
});
|
||||
const itemChildren = item.children.filter((child) => {
|
||||
child.computationalMethod = hasMethods ? undefined : 'sum';
|
||||
return child.type === 'computational' || child.type === 'money-chinese';
|
||||
});
|
||||
]);
|
||||
const number = ref<string>('');
|
||||
const isMouseenter = ref<Boolean>(false);
|
||||
const computationalList = ref<Array<any>>([]);
|
||||
const mouseenterIndex = ref<number>();
|
||||
const activeKey = ref([0]);
|
||||
const selectedComponents = ref<Array<any>>([]);
|
||||
const dialog = ref(props.computationalDialog);
|
||||
onMounted(() => {
|
||||
if (widgetForm.list.length) {
|
||||
getTableComponents(widgetForm.list, t('主表组件列表'));
|
||||
}
|
||||
if (props.computationalConfig.length) {
|
||||
computationalList.value = cloneDeep(props.computationalConfig);
|
||||
}
|
||||
});
|
||||
|
||||
selectedComponents.value.push({
|
||||
label: `${item.label}-${item.key}`,
|
||||
key: item.key,
|
||||
children: itemChildren,
|
||||
const emit = defineEmits(['update:computationalDialog', 'setComputationalConfigValue', 'update:computationalConfig']);
|
||||
|
||||
const getTableComponents = (list, tableName, key?) => {
|
||||
list.forEach((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
getTableComponents(child.list, tableName);
|
||||
}
|
||||
} else if (item.type === 'table-layout') {
|
||||
for (const child of item.layout!) {
|
||||
for (const list of child.list) {
|
||||
getTableComponents(list.children, key);
|
||||
}
|
||||
}
|
||||
} else if (item.type === 'one-for-one') {
|
||||
getTableComponents(item.children, `${item.label}-${item.key}`, item.key);
|
||||
} else if (item.type === 'form') {
|
||||
const hasMethods = item.children.some((child) => {
|
||||
return child.key === widgetFormSelect.key;
|
||||
});
|
||||
const itemChildren = item.children.filter((child) => {
|
||||
child.computationalMethod = hasMethods ? undefined : 'sum';
|
||||
return child.type === 'computational' || child.type === 'money-chinese';
|
||||
});
|
||||
|
||||
selectedComponents.value.push({
|
||||
label: `${item.label}-${item.key}`,
|
||||
key: item.key,
|
||||
children: itemChildren
|
||||
});
|
||||
} else if (item.type === 'computational' || item.type === 'money-chinese') {
|
||||
const index = selectedComponents.value.findIndex((x) => x.label === tableName);
|
||||
if (index !== -1) {
|
||||
selectedComponents.value[index].children.push(item);
|
||||
} else {
|
||||
const tableChildren = [item];
|
||||
if (tableName === t('主表组件列表')) {
|
||||
selectedComponents.value.unshift({
|
||||
label: tableName,
|
||||
key: '1',
|
||||
children: tableChildren
|
||||
});
|
||||
} else {
|
||||
selectedComponents.value.push({
|
||||
label: tableName,
|
||||
key: key,
|
||||
children: tableChildren
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (item.type === 'computational' || item.type === 'money-chinese') {
|
||||
const index = selectedComponents.value.findIndex((x) => x.label === tableName);
|
||||
if (index !== -1) {
|
||||
selectedComponents.value[index].children.push(item);
|
||||
} else {
|
||||
const tableChildren = [item];
|
||||
if (tableName === t('主表组件列表')) {
|
||||
selectedComponents.value.unshift({
|
||||
label: tableName,
|
||||
key: '1',
|
||||
children: tableChildren,
|
||||
};
|
||||
|
||||
const tagColor = (tableItem, componentItem) => {
|
||||
if (widgetFormSelect.key === componentItem.key) return '#f4f4f5';
|
||||
const currentItem = tableItem.children.some((item: any) => {
|
||||
return item.key === widgetFormSelect.key;
|
||||
});
|
||||
return currentItem ? 'green' : 'blue';
|
||||
};
|
||||
|
||||
const disabledCom = (currentKey) => {
|
||||
if (widgetFormSelect.key === currentKey) return true;
|
||||
const isDisabled = widgetFormSelect.options.beAdoptedComponent.some((key: string) => {
|
||||
return key === currentKey;
|
||||
});
|
||||
return isDisabled;
|
||||
};
|
||||
|
||||
const setBeAdoptedComponent = (list, key) => {
|
||||
list.forEach((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
setBeAdoptedComponent(child.list, key);
|
||||
}
|
||||
} else if (item.type === 'form') {
|
||||
setBeAdoptedComponent(item.children, key);
|
||||
} else if (item.key === key) {
|
||||
if (!item.options.beAdoptedComponent.includes(widgetFormSelect.key)) {
|
||||
if (!item.options.beAdoptedComponent) item.options.beAdoptedComponent = [];
|
||||
//被引用的组件不能引用当前组件
|
||||
item.options.beAdoptedComponent.push(widgetFormSelect.key);
|
||||
if (widgetFormSelect.options?.beAdoptedComponent.length) {
|
||||
item.options.beAdoptedComponent.push(...widgetFormSelect.options?.beAdoptedComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//编辑时 去掉已经删除的组件引用
|
||||
const deleteBeAdoptedComponent = (list, keys) => {
|
||||
keys.forEach((key) => {
|
||||
list.forEach((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
deleteBeAdoptedComponent(child.list, keys);
|
||||
}
|
||||
} else if (item.type === 'form') {
|
||||
deleteBeAdoptedComponent(item.children, keys);
|
||||
} else if (item.key === key) {
|
||||
//被引用的组件不能引用当前组件
|
||||
item.options.beAdoptedComponent = item.options.beAdoptedComponent.filter((x) => x !== widgetFormSelect.key);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
selectedComponents.value.push({
|
||||
label: tableName,
|
||||
key: key,
|
||||
children: tableChildren,
|
||||
});
|
||||
};
|
||||
const submitDialog = () => {
|
||||
let configValue = '';
|
||||
const computationalConfig: ComputationalConfig[] = [];
|
||||
computationalList.value.map((item: any) => {
|
||||
const text = item.computationalMethod ? `${item.computationalMethod}(${item.label})` : item.label;
|
||||
let isMainForm;
|
||||
if (item.hasOwnProperty('isMainForm')) {
|
||||
isMainForm = item.isMainForm;
|
||||
} else {
|
||||
if (item.type === 'computational' || item.type === 'money-chinese') {
|
||||
isMainForm = !(item?.isSubFormChild || item?.isSingleFormChild);
|
||||
} else {
|
||||
isMainForm = undefined;
|
||||
}
|
||||
}
|
||||
configValue = configValue.concat(text);
|
||||
computationalConfig.push({
|
||||
$index: item.$index,
|
||||
label: item.label,
|
||||
type: item.type,
|
||||
key: item.key,
|
||||
bindTable: item.bindTable,
|
||||
bindField: item.bindField,
|
||||
computationalMethod: item?.computationalMethod,
|
||||
isMainForm: isMainForm
|
||||
});
|
||||
}
|
||||
setBeAdoptedComponent(widgetForm.list, item.key);
|
||||
});
|
||||
const currentConfigKeys = computationalConfig.map((x) => x.bindTable && x.key);
|
||||
const oldConfigKeys = props.computationalConfig.map((x) => x.bindTable && x.key);
|
||||
|
||||
// 被删除的引用组件
|
||||
const needDeleteKeys = oldConfigKeys.filter((old) => {
|
||||
return old && currentConfigKeys.indexOf(old) === -1;
|
||||
});
|
||||
|
||||
deleteBeAdoptedComponent(widgetForm.list, needDeleteKeys);
|
||||
emit('setComputationalConfigValue', configValue);
|
||||
emit('update:computationalConfig', computationalConfig);
|
||||
emit('update:computationalDialog', false);
|
||||
};
|
||||
|
||||
const closeDialog = () => {
|
||||
emit('update:computationalDialog', false);
|
||||
};
|
||||
const addComputationalList = (e) => {
|
||||
computationalList.value[e.newIndex] = cloneDeep(computationalList.value[e.newIndex]);
|
||||
computationalList.value[e.newIndex].$index = random(100, 999);
|
||||
};
|
||||
const addNumber = () => {
|
||||
if (number.value) {
|
||||
computationalList.value.push({ label: number.value, type: 'operation' });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const tagColor = (tableItem, componentItem) => {
|
||||
if (widgetFormSelect.key === componentItem.key) return '#f4f4f5';
|
||||
const currentItem = tableItem.children.some((item: any) => {
|
||||
return item.key === widgetFormSelect.key;
|
||||
});
|
||||
return currentItem ? 'green' : 'blue';
|
||||
};
|
||||
|
||||
const disabledCom = (currentKey) => {
|
||||
if (widgetFormSelect.key === currentKey) return true;
|
||||
const isDisabled = widgetFormSelect.options.beAdoptedComponent.some((key: string) => {
|
||||
return key === currentKey;
|
||||
});
|
||||
return isDisabled;
|
||||
};
|
||||
|
||||
const setBeAdoptedComponent = (list, key) => {
|
||||
list.forEach((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
setBeAdoptedComponent(child.list, key);
|
||||
}
|
||||
} else if (item.type === 'form') {
|
||||
setBeAdoptedComponent(item.children, key);
|
||||
} else if (item.key === key) {
|
||||
if (!item.options.beAdoptedComponent.includes(widgetFormSelect.key)) {
|
||||
if (!item.options.beAdoptedComponent) item.options.beAdoptedComponent = [];
|
||||
//被引用的组件不能引用当前组件
|
||||
item.options.beAdoptedComponent.push(widgetFormSelect.key);
|
||||
if (widgetFormSelect.options?.beAdoptedComponent.length) {
|
||||
item.options.beAdoptedComponent.push(...widgetFormSelect.options?.beAdoptedComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//编辑时 去掉已经删除的组件引用
|
||||
const deleteBeAdoptedComponent = (list, keys) => {
|
||||
keys.forEach((key) => {
|
||||
list.forEach((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
deleteBeAdoptedComponent(child.list, keys);
|
||||
}
|
||||
} else if (item.type === 'form') {
|
||||
deleteBeAdoptedComponent(item.children, keys);
|
||||
} else if (item.key === key) {
|
||||
//被引用的组件不能引用当前组件
|
||||
item.options.beAdoptedComponent = item.options.beAdoptedComponent.filter(
|
||||
(x) => x !== widgetFormSelect.key,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
const submitDialog = () => {
|
||||
let configValue = '';
|
||||
const computationalConfig: ComputationalConfig[] = [];
|
||||
computationalList.value.map((item: any) => {
|
||||
const text = item.computationalMethod
|
||||
? `${item.computationalMethod}(${item.label})`
|
||||
: item.label;
|
||||
let isMainForm;
|
||||
if (item.hasOwnProperty('isMainForm')) {
|
||||
isMainForm = item.isMainForm;
|
||||
} else {
|
||||
if (item.type === 'computational' || item.type === 'money-chinese') {
|
||||
isMainForm = !(item?.isSubFormChild || item?.isSingleFormChild);
|
||||
} else {
|
||||
isMainForm = undefined;
|
||||
}
|
||||
}
|
||||
configValue = configValue.concat(text);
|
||||
computationalConfig.push({
|
||||
$index: item.$index,
|
||||
label: item.label,
|
||||
type: item.type,
|
||||
key: item.key,
|
||||
bindTable: item.bindTable,
|
||||
bindField: item.bindField,
|
||||
computationalMethod: item?.computationalMethod,
|
||||
isMainForm: isMainForm,
|
||||
});
|
||||
setBeAdoptedComponent(widgetForm.list, item.key);
|
||||
});
|
||||
const currentConfigKeys = computationalConfig.map((x) => x.bindTable && x.key);
|
||||
const oldConfigKeys = props.computationalConfig.map((x) => x.bindTable && x.key);
|
||||
|
||||
// 被删除的引用组件
|
||||
const needDeleteKeys = oldConfigKeys.filter((old) => {
|
||||
return old && currentConfigKeys.indexOf(old) === -1;
|
||||
});
|
||||
|
||||
deleteBeAdoptedComponent(widgetForm.list, needDeleteKeys);
|
||||
emit('setComputationalConfigValue', configValue);
|
||||
emit('update:computationalConfig', computationalConfig);
|
||||
emit('update:computationalDialog', false);
|
||||
};
|
||||
|
||||
const closeDialog = () => {
|
||||
emit('update:computationalDialog', false);
|
||||
};
|
||||
const addComputationalList = (e) => {
|
||||
computationalList.value[e.newIndex] = cloneDeep(computationalList.value[e.newIndex]);
|
||||
computationalList.value[e.newIndex].$index = random(100, 999);
|
||||
};
|
||||
const addNumber = () => {
|
||||
if (number.value) {
|
||||
computationalList.value.push({ label: number.value, type: 'operation' });
|
||||
}
|
||||
};
|
||||
const mouseenter = (index: number) => {
|
||||
mouseenterIndex.value = index;
|
||||
isMouseenter.value = true;
|
||||
};
|
||||
const delTag = (index) => {
|
||||
computationalList.value.splice(index, 1);
|
||||
};
|
||||
};
|
||||
const mouseenter = (index: number) => {
|
||||
mouseenterIndex.value = index;
|
||||
isMouseenter.value = true;
|
||||
};
|
||||
const delTag = (index) => {
|
||||
computationalList.value.splice(index, 1);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.bgcWhite {
|
||||
background: #fff;
|
||||
.bgcWhite {
|
||||
background: #fff;
|
||||
|
||||
.btn-list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
.btn-list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
|
||||
:deep(.ant-tag) {
|
||||
font-size: 18px !important;
|
||||
padding: 5px 15px !important;
|
||||
margin-bottom: 0;
|
||||
cursor: move;
|
||||
}
|
||||
:deep(.ant-tag) {
|
||||
font-size: 18px !important;
|
||||
padding: 5px 15px !important;
|
||||
margin-bottom: 0;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.input-number {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.input-number {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
:deep(.ant-input-number) {
|
||||
width: 100px;
|
||||
margin-right: 10px;
|
||||
:deep(.ant-input-number) {
|
||||
width: 100px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.computational-box {
|
||||
height: 100%;
|
||||
padding: 5px 10px;
|
||||
min-height: 300px;
|
||||
|
||||
.draggable {
|
||||
font-size: 13px;
|
||||
height: 100%;
|
||||
|
||||
> div {
|
||||
display: inline-block;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
> span:nth-of-type(1) {
|
||||
height: 30px;
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
p:nth-child(1) {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
p:nth-child(2) {
|
||||
color: #9e9d9d;
|
||||
}
|
||||
}
|
||||
|
||||
.computational-text {
|
||||
position: absolute;
|
||||
left: 45%;
|
||||
top: 300px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.computational-box {
|
||||
height: 100%;
|
||||
padding: 5px 10px;
|
||||
min-height: 300px;
|
||||
.config-container {
|
||||
margin: 10px;
|
||||
border: 1px solid #dcdfe6;
|
||||
|
||||
.draggable {
|
||||
.component-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
:deep(.ant-collapse) {
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-tag) {
|
||||
padding: 8px;
|
||||
font-size: 13px;
|
||||
height: 100%;
|
||||
|
||||
> div {
|
||||
display: inline-block;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
> span:nth-of-type(1) {
|
||||
height: 30px;
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
p:nth-child(1) {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
p:nth-child(2) {
|
||||
color: #9e9d9d;
|
||||
}
|
||||
}
|
||||
|
||||
.computational-text {
|
||||
position: absolute;
|
||||
left: 45%;
|
||||
top: 300px;
|
||||
text-align: center;
|
||||
}
|
||||
cursor: move;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.config-container {
|
||||
margin: 10px;
|
||||
border: 1px solid #dcdfe6;
|
||||
.title {
|
||||
padding: 15px 10px;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
.component-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
:deep(.ant-collapse) {
|
||||
width: 100%;
|
||||
.disabled-tag {
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
border: none;
|
||||
}
|
||||
color: #c3c5ca;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-tag) {
|
||||
padding: 8px;
|
||||
font-size: 13px;
|
||||
cursor: move;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
:deep(.ant-layout-sider) {
|
||||
background: #fff;
|
||||
border-right: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 15px 10px;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
.disabled-tag {
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
border: none;
|
||||
color: #c3c5ca;
|
||||
}
|
||||
|
||||
:deep(.ant-layout-sider) {
|
||||
background: #fff;
|
||||
border-right: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
:deep(.ant-collapse-header) {
|
||||
word-break: break-all;
|
||||
}
|
||||
:deep(.ant-collapse-header) {
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,260 +1,239 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:width="1000"
|
||||
v-model:visible="visible"
|
||||
:title="state.title"
|
||||
:maskClosable="false"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleClose"
|
||||
>
|
||||
<div class="list-title">字段列表</div>
|
||||
<a-table
|
||||
:dataSource="configDataSource"
|
||||
:columns="state.configColumns"
|
||||
:pagination="false"
|
||||
:scroll="{ y: '300px' }"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'show'">
|
||||
是否在弹层列表显示
|
||||
<a-checkbox v-model:checked="state.checkedAll" @change="handleChecked" />
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'component'">
|
||||
<a-select
|
||||
v-model:value="record.bindField"
|
||||
style="width: 100%"
|
||||
placeholder="请选择填充组件"
|
||||
allowClear
|
||||
>
|
||||
<a-select-option
|
||||
:value="val.bindField"
|
||||
v-for="(val, index) in selectedList"
|
||||
:key="index"
|
||||
>
|
||||
{{ val.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'tableTitle'">
|
||||
<a-input v-model:value="record.tableTitle" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'show'">
|
||||
<a-checkbox v-model:checked="record.show" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'width'">
|
||||
<a-input v-model:value="record.width" :disabled="!record.show" />
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-modal>
|
||||
<a-modal :width="1000" v-model:visible="visible" :title="state.title" :maskClosable="false" @ok="handleSubmit" @cancel="handleClose">
|
||||
<div class="list-title">字段列表</div>
|
||||
<a-table :dataSource="configDataSource" :columns="state.configColumns" :pagination="false" :scroll="{ y: '300px' }">
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'show'">
|
||||
是否在弹层列表显示
|
||||
<a-checkbox v-model:checked="state.checkedAll" @change="handleChecked" />
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'component'">
|
||||
<a-select v-model:value="record.bindField" style="width: 100%" placeholder="请选择填充组件" allowClear>
|
||||
<a-select-option :value="val.bindField" v-for="(val, index) in selectedList" :key="index">
|
||||
{{ val.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'tableTitle'">
|
||||
<a-input v-model:value="record.tableTitle" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'show'">
|
||||
<a-checkbox v-model:checked="record.show" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'width'">
|
||||
<a-input v-model:value="record.width" :disabled="!record.show" />
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { watch, reactive, ref } from 'vue';
|
||||
import { DataSourceConfig } from '../../../types';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { ColumnProps } from 'ant-design-vue/lib/table/Column';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { watch, reactive, ref } from 'vue';
|
||||
import { DataSourceConfig } from '../../../types';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { ColumnProps } from 'ant-design-vue/lib/table/Column';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
dataSourceAssoDia: { type: Boolean },
|
||||
type: { type: String },
|
||||
selectedList: { type: Array as any },
|
||||
dataSourceOptions: { type: Array as PropType<DataSourceConfig[]> },
|
||||
});
|
||||
const emit = defineEmits(['update:dataSourceAssoDia', 'update:dataSourceOptions']);
|
||||
const state = reactive({
|
||||
title: '',
|
||||
checkedAll: false as boolean,
|
||||
configColumns: [] as ColumnProps[],
|
||||
});
|
||||
const visible = ref<boolean>(props.dataSourceAssoDia);
|
||||
const configDataSource = ref<DataSourceConfig[]>([]);
|
||||
const multiplePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '字段名',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '表头名称',
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '是否在弹层列表显示',
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '列表宽度',
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
]);
|
||||
|
||||
const associatePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '字段名',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '填充组件',
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
width: 250,
|
||||
},
|
||||
{
|
||||
title: '表头名称',
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '是否在弹层列表显示',
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '列表宽度',
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
]);
|
||||
|
||||
const associateSelectColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '字段名',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '填充组件',
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '填充组件绑定字段',
|
||||
dataIndex: 'bindField',
|
||||
key: 'bindField',
|
||||
align: 'center',
|
||||
},
|
||||
]);
|
||||
|
||||
watch(
|
||||
() => props.type,
|
||||
(val) => {
|
||||
switch (val) {
|
||||
case 'associate-popup':
|
||||
state.configColumns = associatePopupColumns;
|
||||
state.title = '联想数据配置-数据源';
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
state.configColumns = multiplePopupColumns;
|
||||
state.title = '多选数据配置-数据源';
|
||||
break;
|
||||
case 'associate-select':
|
||||
state.configColumns = associateSelectColumns;
|
||||
state.title = '联想数据配置-数据源';
|
||||
break;
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.dataSourceOptions,
|
||||
(val) => {
|
||||
if (!val?.length) return;
|
||||
configDataSource.value = cloneDeep(val)!;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
configDataSource.value,
|
||||
(val) => {
|
||||
state.checkedAll = val!.every((item: any) => {
|
||||
return item.show;
|
||||
});
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
function handleClose() {
|
||||
emit('update:dataSourceAssoDia', false);
|
||||
}
|
||||
function handleChecked(e: any) {
|
||||
configDataSource.value.map((item: any) => (item.show = e.target.checked));
|
||||
}
|
||||
|
||||
function handleSubmit() {
|
||||
const bindFieldArr = [] as any;
|
||||
configDataSource.value?.map((item: any) => {
|
||||
if (item.bindField) {
|
||||
bindFieldArr.push(item.bindField);
|
||||
}
|
||||
const props = defineProps({
|
||||
dataSourceAssoDia: { type: Boolean },
|
||||
type: { type: String },
|
||||
selectedList: { type: Array as any },
|
||||
dataSourceOptions: { type: Array as PropType<DataSourceConfig[]> }
|
||||
});
|
||||
const emit = defineEmits(['update:dataSourceAssoDia', 'update:dataSourceOptions']);
|
||||
const state = reactive({
|
||||
title: '',
|
||||
checkedAll: false as boolean,
|
||||
configColumns: [] as ColumnProps[]
|
||||
});
|
||||
const visible = ref<boolean>(props.dataSourceAssoDia);
|
||||
const configDataSource = ref<DataSourceConfig[]>([]);
|
||||
const multiplePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: '字段名',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '表头名称',
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '是否在弹层列表显示',
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '列表宽度',
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 150
|
||||
}
|
||||
]);
|
||||
|
||||
if (new Set(bindFieldArr).size !== bindFieldArr.length) {
|
||||
message.error('组件存在重复绑定,请更改');
|
||||
return;
|
||||
const associatePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: '字段名',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '填充组件',
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: '表头名称',
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '是否在弹层列表显示',
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '列表宽度',
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 150
|
||||
}
|
||||
]);
|
||||
|
||||
const associateSelectColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: '字段名',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '填充组件',
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '填充组件绑定字段',
|
||||
dataIndex: 'bindField',
|
||||
key: 'bindField',
|
||||
align: 'center'
|
||||
}
|
||||
]);
|
||||
|
||||
watch(
|
||||
() => props.type,
|
||||
(val) => {
|
||||
switch (val) {
|
||||
case 'associate-popup':
|
||||
state.configColumns = associatePopupColumns;
|
||||
state.title = '联想数据配置-数据源';
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
state.configColumns = multiplePopupColumns;
|
||||
state.title = '多选数据配置-数据源';
|
||||
break;
|
||||
case 'associate-select':
|
||||
state.configColumns = associateSelectColumns;
|
||||
state.title = '联想数据配置-数据源';
|
||||
break;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.dataSourceOptions,
|
||||
(val) => {
|
||||
if (!val?.length) return;
|
||||
configDataSource.value = cloneDeep(val)!;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
configDataSource.value,
|
||||
(val) => {
|
||||
state.checkedAll = val!.every((item: any) => {
|
||||
return item.show;
|
||||
});
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
|
||||
function handleClose() {
|
||||
emit('update:dataSourceAssoDia', false);
|
||||
}
|
||||
function handleChecked(e: any) {
|
||||
configDataSource.value.map((item: any) => (item.show = e.target.checked));
|
||||
}
|
||||
|
||||
emit('update:dataSourceAssoDia', false);
|
||||
emit('update:dataSourceOptions', configDataSource.value);
|
||||
}
|
||||
function handleSubmit() {
|
||||
const bindFieldArr = [] as any;
|
||||
configDataSource.value?.map((item: any) => {
|
||||
if (item.bindField) {
|
||||
bindFieldArr.push(item.bindField);
|
||||
}
|
||||
});
|
||||
|
||||
if (new Set(bindFieldArr).size !== bindFieldArr.length) {
|
||||
message.error('组件存在重复绑定,请更改');
|
||||
return;
|
||||
}
|
||||
|
||||
emit('update:dataSourceAssoDia', false);
|
||||
emit('update:dataSourceOptions', configDataSource.value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.list-title {
|
||||
margin: 10px 0 5px 15px;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
.list-title {
|
||||
margin: 10px 0 5px 15px;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,328 +1,255 @@
|
||||
<template>
|
||||
<a-form-item :label="t('数据来源')">
|
||||
<a-radio-group
|
||||
button-style="solid"
|
||||
v-model:value="info.options.datasourceType"
|
||||
size="small"
|
||||
:disabled="disabled"
|
||||
@change="handleDatasourceChange"
|
||||
>
|
||||
<a-radio-button
|
||||
value="staticData"
|
||||
v-if="
|
||||
info.type === 'radio' ||
|
||||
info.type === 'checkbox' ||
|
||||
info.type === 'select' ||
|
||||
info.type === 'auto-complete'
|
||||
"
|
||||
>
|
||||
{{ t('静态数据') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="api">API</a-radio-button>
|
||||
<!-- <a-radio-button value="datasource">数据源</a-radio-button> -->
|
||||
<a-radio-button value="dic">{{ t('数据字典') }}</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<div v-if="info.options.datasourceType === 'staticData'">
|
||||
<StaticData
|
||||
:disabled="disabled"
|
||||
:options="info.options"
|
||||
@handleOptionsRemove="
|
||||
(index) => {
|
||||
emit('handleOptionsRemove', index);
|
||||
}
|
||||
"
|
||||
@handleInsertOption="handleInsertOption"
|
||||
@handleDefaultSelect="
|
||||
(val) => {
|
||||
info.options.defaultSelect = val;
|
||||
}
|
||||
"
|
||||
:type="info.type === 'checkbox' ? 'checkbox' : 'radio'"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="info.options.datasourceType === 'datasource'">
|
||||
<a-form-item :label="t('数据选项')">
|
||||
<DatasourceSelect v-model:value="info.options.datasourceId" @change="handleFieldChange" />
|
||||
<a-form-item :label="t('数据来源')">
|
||||
<a-radio-group button-style="solid" v-model:value="info.options.datasourceType" size="small" :disabled="disabled" @change="handleDatasourceChange">
|
||||
<a-radio-button value="staticData" v-if="info.type === 'radio' || info.type === 'checkbox' || info.type === 'select' || info.type === 'auto-complete'">
|
||||
{{ t('静态数据') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="api">API</a-radio-button>
|
||||
<!-- <a-radio-button value="datasource">数据源</a-radio-button> -->
|
||||
<a-radio-button value="dic">{{ t('数据字典') }}</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('显示字段')">
|
||||
<a-select v-model:value="info.options.labelField" :placeholder="t('请选择显示字段')">
|
||||
<a-select-option v-for="(item, idx) in fieldOptions" :value="item" :key="idx" />
|
||||
</a-select>
|
||||
<div v-if="info.options.datasourceType === 'staticData'">
|
||||
<StaticData
|
||||
:disabled="disabled"
|
||||
:options="info.options"
|
||||
@handleOptionsRemove="
|
||||
(index) => {
|
||||
emit('handleOptionsRemove', index);
|
||||
}
|
||||
"
|
||||
@handleInsertOption="handleInsertOption"
|
||||
@handleDefaultSelect="
|
||||
(val) => {
|
||||
info.options.defaultSelect = val;
|
||||
}
|
||||
"
|
||||
:type="info.type === 'checkbox' ? 'checkbox' : 'radio'"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="info.options.datasourceType === 'datasource'">
|
||||
<a-form-item :label="t('数据选项')">
|
||||
<DatasourceSelect v-model:value="info.options.datasourceId" @change="handleFieldChange" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('显示字段')">
|
||||
<a-select v-model:value="info.options.labelField" :placeholder="t('请选择显示字段')">
|
||||
<a-select-option v-for="(item, idx) in fieldOptions" :value="item" :key="idx" />
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('保存字段')">
|
||||
<a-select v-model:value="info.options.valueField" :placeholder="t('请选择保存字段')">
|
||||
<a-select-option v-for="(item, idx) in fieldOptions" :value="item" :key="idx" />
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-if="info.options.datasourceType === 'api'">
|
||||
<a-form-item :label="t('接口配置')">
|
||||
<a-input v-model:value="info.options.apiConfig.path" :placeholder="t('点击进行接口配置')" :disabled="disabled" @click="apiConfigDialog = true">
|
||||
<template #suffix>
|
||||
<Icon icon="ant-design:ellipsis-outlined" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-if="info.options.datasourceType === 'dic'">
|
||||
<a-form-item :label="t('数据选项')">
|
||||
<DicTreeSelect v-model:value="info.options.itemId" @change="handleDicChange" :disabled="disabled" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
<a-form-item :label="formLabel" v-if="info.type === 'associate-popup' || info.type === 'multiple-popup' || info.type === 'associate-select' || (info.type === 'button' && info.options.isSpecial && info.options.buttonType == 1)">
|
||||
<a-input :value="configText" :placeholder="t('点击进行配置')" @click="showConfigDialog">
|
||||
<template #suffix>
|
||||
<Icon icon="ant-design:ellipsis-outlined" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('保存字段')">
|
||||
<a-select v-model:value="info.options.valueField" :placeholder="t('请选择保存字段')">
|
||||
<a-select-option v-for="(item, idx) in fieldOptions" :value="item" :key="idx" />
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-if="info.options.datasourceType === 'api'">
|
||||
<a-form-item :label="t('接口配置')">
|
||||
<a-input
|
||||
v-model:value="info.options.apiConfig.path"
|
||||
:placeholder="t('点击进行接口配置')"
|
||||
:disabled="disabled"
|
||||
@click="apiConfigDialog = true"
|
||||
>
|
||||
<template #suffix>
|
||||
<Icon icon="ant-design:ellipsis-outlined" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-if="info.options.datasourceType === 'dic'">
|
||||
<a-form-item :label="t('数据选项')">
|
||||
<DicTreeSelect
|
||||
v-model:value="info.options.itemId"
|
||||
@change="handleDicChange"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<a-form-item
|
||||
:label="formLabel"
|
||||
v-if="
|
||||
info.type === 'associate-popup' ||
|
||||
info.type === 'multiple-popup' ||
|
||||
info.type === 'associate-select' ||
|
||||
(info.type === 'button' && info.options.isSpecial && info.options.buttonType == 1)
|
||||
"
|
||||
>
|
||||
<a-input :value="configText" :placeholder="t('点击进行配置')" @click="showConfigDialog">
|
||||
<template #suffix>
|
||||
<Icon icon="ant-design:ellipsis-outlined" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<DataSourceAssoConfig
|
||||
v-if="dataSourceAssoDia"
|
||||
v-model:dataSourceAssoDia="dataSourceAssoDia"
|
||||
v-model:dataSourceOptions="info.options.dataSourceOptions"
|
||||
:selectedList="list"
|
||||
:type="info.type"
|
||||
/>
|
||||
<ApiAssoConfig
|
||||
v-if="apiAssoDia"
|
||||
:disabled="disabled"
|
||||
v-model:apiAssoDia="apiAssoDia"
|
||||
v-model:apiConfig="info.options.apiConfig"
|
||||
:selectedList="list"
|
||||
:type="info.type"
|
||||
/>
|
||||
<DicAssoConfig
|
||||
v-if="dicAssoDia"
|
||||
v-model:dicAssoDia="dicAssoDia"
|
||||
v-model:dicOptions="info.options.dicOptions"
|
||||
:selectedList="list"
|
||||
:type="info.type"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
<ApiConfig
|
||||
v-if="apiConfigDialog"
|
||||
:isSubForm="info.isSubFormChild"
|
||||
v-model:apiConfigDialog="apiConfigDialog"
|
||||
v-model:apiConfig="info.options.apiConfig"
|
||||
:formItem="info"
|
||||
:title="t('API配置')"
|
||||
/>
|
||||
<DataSourceAssoConfig v-if="dataSourceAssoDia" v-model:dataSourceAssoDia="dataSourceAssoDia" v-model:dataSourceOptions="info.options.dataSourceOptions" :selectedList="list" :type="info.type" />
|
||||
<ApiAssoConfig v-if="apiAssoDia" :disabled="disabled" v-model:apiAssoDia="apiAssoDia" v-model:apiConfig="info.options.apiConfig" :selectedList="list" :type="info.type" />
|
||||
<DicAssoConfig v-if="dicAssoDia" v-model:dicAssoDia="dicAssoDia" v-model:dicOptions="info.options.dicOptions" :selectedList="list" :type="info.type" :disabled="disabled" />
|
||||
<ApiConfig v-if="apiConfigDialog" :isSubForm="info.isSubFormChild" v-model:apiConfigDialog="apiConfigDialog" v-model:apiConfig="info.options.apiConfig" :formItem="info" :title="t('API配置')" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { watch, ref, inject, computed } from 'vue';
|
||||
import DataSourceAssoConfig from './DataSourceAssoConfig.vue';
|
||||
import ApiAssoConfig from './ApiAssoConfig.vue';
|
||||
import DicAssoConfig from './DicAssoConfig.vue';
|
||||
import StaticData from './StaticData.vue';
|
||||
import { getDatasourceColumn } from '/@/api/system/datasource';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { DatasourceSelect } from '/@/components/DataSourceSelect';
|
||||
import { ApiConfig } from '/@/components/ApiConfig';
|
||||
import { DicTreeSelect } from '/@/components/DicTreeSelect';
|
||||
import { watch, ref, inject, computed } from 'vue';
|
||||
import DataSourceAssoConfig from './DataSourceAssoConfig.vue';
|
||||
import ApiAssoConfig from './ApiAssoConfig.vue';
|
||||
import DicAssoConfig from './DicAssoConfig.vue';
|
||||
import StaticData from './StaticData.vue';
|
||||
import { getDatasourceColumn } from '/@/api/system/datasource';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { DatasourceSelect } from '/@/components/DataSourceSelect';
|
||||
import { ApiConfig } from '/@/components/ApiConfig';
|
||||
import { DicTreeSelect } from '/@/components/DicTreeSelect';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
data: { type: Object },
|
||||
disabled: { type: Boolean, default: () => false },
|
||||
});
|
||||
const { widgetForm, widgetFormSelect } = inject('state') as any; //整个表单json配置
|
||||
|
||||
const emit = defineEmits(['update:data', 'handleOptionsRemove']);
|
||||
const info = ref<any>(props.data);
|
||||
const dataSourceAssoDia = ref<boolean>(false);
|
||||
const apiAssoDia = ref<boolean>(false);
|
||||
const dicAssoDia = ref<boolean>(false);
|
||||
const apiConfigDialog = ref<boolean>(false);
|
||||
const list = ref<any[]>([]);
|
||||
const selectedList = ref<any[]>([]);
|
||||
const selectedSingleList = ref<any[]>([]); //单表组件内部引用列表
|
||||
|
||||
const fieldOptions = ref<string[]>([]);
|
||||
const notBindFieldConfig = ['select', 'radio', 'checkbox', 'associate-select'];
|
||||
const noAssociateComponents = [
|
||||
'multiple-popup',
|
||||
'associate-popup',
|
||||
'associate-select',
|
||||
'form',
|
||||
'tab',
|
||||
'card',
|
||||
'grid',
|
||||
'one-for-one',
|
||||
'button',
|
||||
];
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(val) => {
|
||||
info.value = val;
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
watch(
|
||||
info.value,
|
||||
(val) => {
|
||||
emit('update:data', val);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
const getSelectedList = (list, isOneForOne = false) => {
|
||||
list?.map((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
getSelectedList(child.list, isOneForOne);
|
||||
}
|
||||
} else if (item.type == 'table-layout') {
|
||||
for (const child of item.layout!) {
|
||||
for (const item of child.list) {
|
||||
getSelectedList(item.children, isOneForOne);
|
||||
}
|
||||
}
|
||||
} else if (item.type === 'one-for-one') {
|
||||
getSelectedList(item.children, true);
|
||||
} else if (item.type === 'form') {
|
||||
if (item.bindTable === widgetFormSelect.bindTable) {
|
||||
selectedList.value = item.children.filter((child: any) => {
|
||||
return !noAssociateComponents.includes(child.type);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!noAssociateComponents.includes(item.type)) {
|
||||
if (isOneForOne) item.isSingleFormChild = true;
|
||||
selectedList.value.push(item);
|
||||
}
|
||||
}
|
||||
import { message } from 'ant-design-vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
data: { type: Object },
|
||||
disabled: { type: Boolean, default: () => false }
|
||||
});
|
||||
};
|
||||
const { widgetForm, widgetFormSelect } = inject('state') as any; //整个表单json配置
|
||||
|
||||
watch(
|
||||
() => widgetForm.list,
|
||||
() => {
|
||||
if (widgetForm.list.length) {
|
||||
selectedSingleList.value = [];
|
||||
selectedList.value = [];
|
||||
getSelectedList(widgetForm.list);
|
||||
list.value = selectedList.value;
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
const emit = defineEmits(['update:data', 'handleOptionsRemove']);
|
||||
const info = ref<any>(props.data);
|
||||
const dataSourceAssoDia = ref<boolean>(false);
|
||||
const apiAssoDia = ref<boolean>(false);
|
||||
const dicAssoDia = ref<boolean>(false);
|
||||
const apiConfigDialog = ref<boolean>(false);
|
||||
const list = ref<any[]>([]);
|
||||
const selectedList = ref<any[]>([]);
|
||||
const selectedSingleList = ref<any[]>([]); //单表组件内部引用列表
|
||||
|
||||
const configText = computed(() => {
|
||||
const datasourceType = info.value.options.datasourceType;
|
||||
const dicOptions = info.value.options.dicOptions;
|
||||
const outputParams = info.value.options.apiConfig?.outputParams;
|
||||
if (
|
||||
(datasourceType === 'dic' && dicOptions?.length) ||
|
||||
(datasourceType === 'api' && outputParams?.length)
|
||||
) {
|
||||
return t('已配置');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
const formLabel = computed(() => {
|
||||
return info.value?.type === 'multiple-popup' ? t('显示配置') : t('联想配置');
|
||||
});
|
||||
const fieldOptions = ref<string[]>([]);
|
||||
const notBindFieldConfig = ['select', 'radio', 'checkbox', 'associate-select'];
|
||||
const noAssociateComponents = ['multiple-popup', 'associate-popup', 'associate-select', 'form', 'tab', 'card', 'grid', 'one-for-one', 'button'];
|
||||
|
||||
const handleDatasourceChange = () => {
|
||||
info.value.options.params = null;
|
||||
info.value.options.labelField = 'label';
|
||||
info.value.options.valueField = 'value';
|
||||
watch(
|
||||
() => props.data,
|
||||
(val) => {
|
||||
info.value = val;
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
watch(
|
||||
info.value,
|
||||
(val) => {
|
||||
emit('update:data', val);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
|
||||
if (info.value.options.datasourceType === 'dic') {
|
||||
info.value.options.params = info.value.options.itemId
|
||||
? { itemId: info.value.options.itemId }
|
||||
: null;
|
||||
info.value.options.labelField = 'name';
|
||||
}
|
||||
if (info.value.options.datasourceType !== 'staticData') {
|
||||
if (info.value.type == 'multiple-popup' || info.value.type == 'checkbox') {
|
||||
info.value.options.defaultTempValue = [];
|
||||
}
|
||||
info.value.options.defaultSelect = null;
|
||||
}
|
||||
};
|
||||
const handleInsertOption = () => {
|
||||
const index = info.value.options.staticOptions.length + 1;
|
||||
info.value.options.staticOptions.push({
|
||||
key: index,
|
||||
label: `Option ${index}`,
|
||||
value: `Option ${index}`,
|
||||
});
|
||||
};
|
||||
const handleFieldChange = async (id: string) => {
|
||||
if (!id) return;
|
||||
info.value.options.labelField = undefined;
|
||||
info.value.options.valueField = undefined;
|
||||
info.value.options.dataSourceOptions = [];
|
||||
info.value.options.params = id;
|
||||
fieldOptions.value = await getDatasourceColumn(id);
|
||||
const getSelectedList = (list, isOneForOne = false) => {
|
||||
list?.map((item) => {
|
||||
if (['tab', 'grid', 'card'].includes(item.type)) {
|
||||
for (const child of item.layout!) {
|
||||
getSelectedList(child.list, isOneForOne);
|
||||
}
|
||||
} else if (item.type == 'table-layout') {
|
||||
for (const child of item.layout!) {
|
||||
for (const item of child.list) {
|
||||
getSelectedList(item.children, isOneForOne);
|
||||
}
|
||||
}
|
||||
} else if (item.type === 'one-for-one') {
|
||||
getSelectedList(item.children, true);
|
||||
} else if (item.type === 'form') {
|
||||
if (item.bindTable === widgetFormSelect.bindTable) {
|
||||
selectedList.value = item.children.filter((child: any) => {
|
||||
return !noAssociateComponents.includes(child.type);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!noAssociateComponents.includes(item.type)) {
|
||||
if (isOneForOne) item.isSingleFormChild = true;
|
||||
selectedList.value.push(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (fieldOptions.value.length) {
|
||||
fieldOptions.value.map((item, index) => {
|
||||
let options = {};
|
||||
if (notBindFieldConfig.includes(info.value.type)) {
|
||||
options = { key: index + 1, name: item };
|
||||
watch(
|
||||
() => widgetForm.list,
|
||||
() => {
|
||||
if (widgetForm.list.length) {
|
||||
selectedSingleList.value = [];
|
||||
selectedList.value = [];
|
||||
getSelectedList(widgetForm.list);
|
||||
list.value = selectedList.value;
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
|
||||
const configText = computed(() => {
|
||||
const datasourceType = info.value.options.datasourceType;
|
||||
const dicOptions = info.value.options.dicOptions;
|
||||
const outputParams = info.value.options.apiConfig?.outputParams;
|
||||
if ((datasourceType === 'dic' && dicOptions?.length) || (datasourceType === 'api' && outputParams?.length)) {
|
||||
return t('已配置');
|
||||
} else {
|
||||
options = {
|
||||
key: index + 1,
|
||||
name: item,
|
||||
tableTitle: item,
|
||||
bindField: '',
|
||||
show: true,
|
||||
width: '150',
|
||||
};
|
||||
return '';
|
||||
}
|
||||
info.value.options.dataSourceOptions.push(options);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
const formLabel = computed(() => {
|
||||
return info.value?.type === 'multiple-popup' ? t('显示配置') : t('联想配置');
|
||||
});
|
||||
|
||||
const handleDicChange = (val) => {
|
||||
info.value.options.params = { itemId: val };
|
||||
};
|
||||
const showConfigDialog = () => {
|
||||
if (info.value.options.datasourceType === 'datasource') {
|
||||
if (info.value.type === 'associate-popup' && !selectedList.value.length) {
|
||||
message.error(t('请保证存在一个或一个以上可联想绑定数据的组件'));
|
||||
} else {
|
||||
dataSourceAssoDia.value = true;
|
||||
}
|
||||
} else if (info.value.options.datasourceType === 'api') {
|
||||
apiAssoDia.value = true;
|
||||
} else if (info.value.options.datasourceType === 'dic') {
|
||||
dicAssoDia.value = true;
|
||||
}
|
||||
};
|
||||
const handleDatasourceChange = () => {
|
||||
info.value.options.params = null;
|
||||
info.value.options.labelField = 'label';
|
||||
info.value.options.valueField = 'value';
|
||||
|
||||
if (info.value.options.datasourceType === 'dic') {
|
||||
info.value.options.params = info.value.options.itemId ? { itemId: info.value.options.itemId } : null;
|
||||
info.value.options.labelField = 'name';
|
||||
}
|
||||
if (info.value.options.datasourceType !== 'staticData') {
|
||||
if (info.value.type == 'multiple-popup' || info.value.type == 'checkbox') {
|
||||
info.value.options.defaultTempValue = [];
|
||||
}
|
||||
info.value.options.defaultSelect = null;
|
||||
}
|
||||
};
|
||||
const handleInsertOption = () => {
|
||||
const index = info.value.options.staticOptions.length + 1;
|
||||
info.value.options.staticOptions.push({
|
||||
key: index,
|
||||
label: `Option ${index}`,
|
||||
value: `Option ${index}`
|
||||
});
|
||||
};
|
||||
const handleFieldChange = async (id: string) => {
|
||||
if (!id) return;
|
||||
info.value.options.labelField = undefined;
|
||||
info.value.options.valueField = undefined;
|
||||
info.value.options.dataSourceOptions = [];
|
||||
info.value.options.params = id;
|
||||
fieldOptions.value = await getDatasourceColumn(id);
|
||||
|
||||
if (fieldOptions.value.length) {
|
||||
fieldOptions.value.map((item, index) => {
|
||||
let options = {};
|
||||
if (notBindFieldConfig.includes(info.value.type)) {
|
||||
options = { key: index + 1, name: item };
|
||||
} else {
|
||||
options = {
|
||||
key: index + 1,
|
||||
name: item,
|
||||
tableTitle: item,
|
||||
bindField: '',
|
||||
show: true,
|
||||
width: '150'
|
||||
};
|
||||
}
|
||||
info.value.options.dataSourceOptions.push(options);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDicChange = (val) => {
|
||||
info.value.options.params = { itemId: val };
|
||||
};
|
||||
const showConfigDialog = () => {
|
||||
if (info.value.options.datasourceType === 'datasource') {
|
||||
if (info.value.type === 'associate-popup' && !selectedList.value.length) {
|
||||
message.error(t('请保证存在一个或一个以上可联想绑定数据的组件'));
|
||||
} else {
|
||||
dataSourceAssoDia.value = true;
|
||||
}
|
||||
} else if (info.value.options.datasourceType === 'api') {
|
||||
apiAssoDia.value = true;
|
||||
} else if (info.value.options.datasourceType === 'dic') {
|
||||
dicAssoDia.value = true;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -1,388 +1,364 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:width="1000"
|
||||
v-model:visible="visible"
|
||||
:title="title"
|
||||
:maskClosable="false"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleClose"
|
||||
:bodyStyle="{ padding: '0 10px 10px' }"
|
||||
>
|
||||
<div class="list-title">{{ t('字段列表') }}</div>
|
||||
<a-table
|
||||
:dataSource="dicInfo"
|
||||
:columns="dicColumns"
|
||||
:pagination="false"
|
||||
:scroll="{ y: '400px' }"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'show'">
|
||||
{{ t('是否在弹层列表显示') }}
|
||||
<a-checkbox v-model:checked="checkedAll" @change="handleChecked" />
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'component'">
|
||||
<a-select
|
||||
v-model:value="record.component"
|
||||
style="width: 100%"
|
||||
:placeholder="t('请选择填充组件')"
|
||||
@change="(value) => selectBindField(value, record)"
|
||||
allowClear
|
||||
:disabled="disabled"
|
||||
>
|
||||
<a-select-option :value="val.key" v-for="(val, idx) in selectedList" :key="idx">
|
||||
{{ val.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'tableTitle'">
|
||||
<a-input v-model:value="record.tableTitle" :placeholder="t('请填写表头名称')" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'show'">
|
||||
<a-checkbox v-model:checked="record.show" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'width'">
|
||||
<a-input
|
||||
v-model:value="record.width"
|
||||
:disabled="!record.show"
|
||||
:placeholder="t('请填写列表宽度')"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-modal>
|
||||
<a-modal :width="1000" v-model:visible="visible" :title="title" :maskClosable="false" @ok="handleSubmit" @cancel="handleClose" :bodyStyle="{ padding: '0 10px 10px' }">
|
||||
<div class="list-title">{{ t('字段列表') }}</div>
|
||||
<a-table :dataSource="dicInfo" :columns="dicColumns" :pagination="false" :scroll="{ y: '400px' }">
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'show'">
|
||||
{{ t('是否在弹层列表显示') }}
|
||||
<a-checkbox v-model:checked="checkedAll" @change="handleChecked" />
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'component'">
|
||||
<a-select v-model:value="record.component" style="width: 100%" :placeholder="t('请选择填充组件')" @change="(value) => selectBindField(value, record)" allowClear :disabled="disabled">
|
||||
<a-select-option :value="val.key" v-for="(val, idx) in selectedList" :key="idx">
|
||||
{{ val.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'tableTitle'">
|
||||
<a-input v-model:value="record.tableTitle" :placeholder="t('请填写表头名称')" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'show'">
|
||||
<a-checkbox v-model:checked="record.show" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'width'">
|
||||
<a-input v-model:value="record.width" :disabled="!record.show" :placeholder="t('请填写列表宽度')" />
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, onMounted } from 'vue';
|
||||
import { ColumnProps } from 'ant-design-vue/lib/table/Column';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
dicAssoDia: { type: Boolean },
|
||||
dicOptions: { type: Object as PropType<any> },
|
||||
selectedList: { type: Array as any },
|
||||
type: { type: String },
|
||||
disabled: { type: Boolean, default: () => false },
|
||||
});
|
||||
const emit = defineEmits(['update:dicAssoDia', 'update:dicOptions']);
|
||||
const dicInfo = ref<any[]>([]);
|
||||
const title = ref<string>('');
|
||||
const checkedAll = ref<boolean>(false);
|
||||
let dicColumns;
|
||||
const visible = ref<boolean>(props.dicAssoDia);
|
||||
|
||||
watch(
|
||||
() => props.dicOptions,
|
||||
(val) => {
|
||||
if (val && val.length) {
|
||||
dicInfo.value = cloneDeep(val);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => dicInfo.value,
|
||||
(val) => {
|
||||
checkedAll.value = val.every((item: any) => {
|
||||
return item.show;
|
||||
});
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
if (!dicInfo.value.length) {
|
||||
switch (props.type) {
|
||||
case 'button':
|
||||
case 'associate-popup':
|
||||
dicInfo.value = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: 'name',
|
||||
name: 'name',
|
||||
bindField: '',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
dataIndex: 'value',
|
||||
title: 'value',
|
||||
name: 'value',
|
||||
bindField: '',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150,
|
||||
},
|
||||
];
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
dicInfo.value = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: 'name',
|
||||
name: 'name',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
dataIndex: 'value',
|
||||
title: 'value',
|
||||
name: 'value',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150,
|
||||
},
|
||||
];
|
||||
break;
|
||||
case 'associate-select':
|
||||
dicInfo.value = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: 'name',
|
||||
name: 'name',
|
||||
bindField: '',
|
||||
},
|
||||
{
|
||||
dataIndex: 'value',
|
||||
title: 'value',
|
||||
name: 'value',
|
||||
bindField: '',
|
||||
},
|
||||
];
|
||||
break;
|
||||
case 'preload-title':
|
||||
dicInfo.value = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: 'name',
|
||||
name: 'name',
|
||||
tableTitle: 'name',
|
||||
},
|
||||
{
|
||||
dataIndex: 'value',
|
||||
title: 'value',
|
||||
name: 'value',
|
||||
tableTitle: 'value',
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
const multiplePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: t('字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('显示'),
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('列表宽度'),
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
]);
|
||||
|
||||
const associatePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: t('字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('填充组件'),
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
width: 250,
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('是否在弹层列表显示'),
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: t('列表宽度'),
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
]);
|
||||
|
||||
const associateSelectColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: t('字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('填充组件'),
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('填充组件绑定字段'),
|
||||
dataIndex: 'bindField',
|
||||
key: 'bindField',
|
||||
align: 'center',
|
||||
},
|
||||
]);
|
||||
|
||||
const preloadColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: t('字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
},
|
||||
]);
|
||||
watch(
|
||||
() => props.type,
|
||||
(val) => {
|
||||
console.log('props.type', val);
|
||||
switch (val) {
|
||||
case 'button':
|
||||
case 'associate-popup':
|
||||
dicColumns = associatePopupColumns;
|
||||
title.value = t('联想数据配置-数据字典');
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
dicColumns = multiplePopupColumns;
|
||||
title.value = t('多选数据配置-数据字典');
|
||||
break;
|
||||
case 'associate-select':
|
||||
dicColumns = associateSelectColumns;
|
||||
title.value = t('联想数据配置-数据字典');
|
||||
break;
|
||||
case 'preload-title':
|
||||
dicColumns = preloadColumns;
|
||||
title.value = t('表头配置-数据字典');
|
||||
break;
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
const selectBindField = (value, record) => {
|
||||
if (!value || !isNaN(value)) {
|
||||
message.error(t('请先选择该组件的绑定表及绑定字段'));
|
||||
record.bindField = null;
|
||||
record.bindTable = undefined;
|
||||
} else {
|
||||
let obj = props.selectedList.find((o) => o.key == value);
|
||||
if (obj) {
|
||||
record.bindField = obj.bindField;
|
||||
if (obj.isSingleFormChild || obj.isSubFormChild) {
|
||||
record.bindTable = obj.bindTable;
|
||||
} else {
|
||||
record.bindTable = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleChecked = (e: any) => {
|
||||
dicInfo.value.map((item: any) => (item.show = e.target.checked));
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
emit('update:dicAssoDia', false);
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
const bindFieldArr = [] as any;
|
||||
dicInfo.value?.map((item: any) => {
|
||||
if (item.bindField) {
|
||||
bindFieldArr.push(item.bindField);
|
||||
}
|
||||
import { ref, reactive, watch, onMounted } from 'vue';
|
||||
import { ColumnProps } from 'ant-design-vue/lib/table/Column';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
dicAssoDia: { type: Boolean },
|
||||
dicOptions: { type: Object as PropType<any> },
|
||||
selectedList: { type: Array as any },
|
||||
type: { type: String },
|
||||
disabled: { type: Boolean, default: () => false }
|
||||
});
|
||||
if (new Set(bindFieldArr).size !== bindFieldArr.length) {
|
||||
message.error(t('组件存在重复绑定,请更改'));
|
||||
return;
|
||||
}
|
||||
emit('update:dicAssoDia', false);
|
||||
emit('update:dicOptions', dicInfo.value);
|
||||
};
|
||||
const emit = defineEmits(['update:dicAssoDia', 'update:dicOptions']);
|
||||
const dicInfo = ref<any[]>([]);
|
||||
const title = ref<string>('');
|
||||
const checkedAll = ref<boolean>(false);
|
||||
let dicColumns;
|
||||
const visible = ref<boolean>(props.dicAssoDia);
|
||||
|
||||
watch(
|
||||
() => props.dicOptions,
|
||||
(val) => {
|
||||
if (val && val.length) {
|
||||
dicInfo.value = cloneDeep(val);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => dicInfo.value,
|
||||
(val) => {
|
||||
checkedAll.value = val.every((item: any) => {
|
||||
return item.show;
|
||||
});
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
if (!dicInfo.value.length) {
|
||||
switch (props.type) {
|
||||
case 'button':
|
||||
case 'associate-popup':
|
||||
dicInfo.value = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: 'name',
|
||||
name: 'name',
|
||||
bindField: '',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
dataIndex: 'value',
|
||||
title: 'value',
|
||||
name: 'value',
|
||||
bindField: '',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150
|
||||
}
|
||||
];
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
dicInfo.value = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: 'name',
|
||||
name: 'name',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
dataIndex: 'value',
|
||||
title: 'value',
|
||||
name: 'value',
|
||||
tableTitle: '',
|
||||
show: true,
|
||||
width: 150
|
||||
}
|
||||
];
|
||||
break;
|
||||
case 'associate-select':
|
||||
dicInfo.value = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: 'name',
|
||||
name: 'name',
|
||||
bindField: ''
|
||||
},
|
||||
{
|
||||
dataIndex: 'value',
|
||||
title: 'value',
|
||||
name: 'value',
|
||||
bindField: ''
|
||||
}
|
||||
];
|
||||
break;
|
||||
case 'preload-title':
|
||||
dicInfo.value = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: 'name',
|
||||
name: 'name',
|
||||
tableTitle: 'name'
|
||||
},
|
||||
{
|
||||
dataIndex: 'value',
|
||||
title: 'value',
|
||||
name: 'value',
|
||||
tableTitle: 'value'
|
||||
}
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
const multiplePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: t('字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('显示'),
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('列表宽度'),
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 150
|
||||
}
|
||||
]);
|
||||
|
||||
const associatePopupColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: t('字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('填充组件'),
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center',
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('是否在弹层列表显示'),
|
||||
dataIndex: 'show',
|
||||
key: 'show',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: t('列表宽度'),
|
||||
dataIndex: 'width',
|
||||
key: 'width',
|
||||
align: 'center',
|
||||
width: 150
|
||||
}
|
||||
]);
|
||||
|
||||
const associateSelectColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: t('字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('填充组件'),
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('填充组件绑定字段'),
|
||||
dataIndex: 'bindField',
|
||||
key: 'bindField',
|
||||
align: 'center'
|
||||
}
|
||||
]);
|
||||
|
||||
const preloadColumns = reactive<ColumnProps[]>([
|
||||
{
|
||||
title: '#',
|
||||
align: 'center',
|
||||
customRender: ({ index }) => `${index + 1}`, // 显示每一行的序号
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: t('字段名'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('表头名称'),
|
||||
dataIndex: 'tableTitle',
|
||||
key: 'tableTitle',
|
||||
align: 'center'
|
||||
}
|
||||
]);
|
||||
watch(
|
||||
() => props.type,
|
||||
(val) => {
|
||||
console.log('props.type', val);
|
||||
switch (val) {
|
||||
case 'button':
|
||||
case 'associate-popup':
|
||||
dicColumns = associatePopupColumns;
|
||||
title.value = t('联想数据配置-数据字典');
|
||||
break;
|
||||
case 'multiple-popup':
|
||||
dicColumns = multiplePopupColumns;
|
||||
title.value = t('多选数据配置-数据字典');
|
||||
break;
|
||||
case 'associate-select':
|
||||
dicColumns = associateSelectColumns;
|
||||
title.value = t('联想数据配置-数据字典');
|
||||
break;
|
||||
case 'preload-title':
|
||||
dicColumns = preloadColumns;
|
||||
title.value = t('表头配置-数据字典');
|
||||
break;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const selectBindField = (value, record) => {
|
||||
if (!value || !isNaN(value)) {
|
||||
message.error(t('请先选择该组件的绑定表及绑定字段'));
|
||||
record.bindField = null;
|
||||
record.bindTable = undefined;
|
||||
} else {
|
||||
let obj = props.selectedList.find((o) => o.key == value);
|
||||
if (obj) {
|
||||
record.bindField = obj.bindField;
|
||||
if (obj.isSingleFormChild || obj.isSubFormChild) {
|
||||
record.bindTable = obj.bindTable;
|
||||
} else {
|
||||
record.bindTable = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleChecked = (e: any) => {
|
||||
dicInfo.value.map((item: any) => (item.show = e.target.checked));
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
emit('update:dicAssoDia', false);
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
const bindFieldArr = [] as any;
|
||||
dicInfo.value?.map((item: any) => {
|
||||
if (item.bindField) {
|
||||
bindFieldArr.push(item.bindField);
|
||||
}
|
||||
});
|
||||
if (new Set(bindFieldArr).size !== bindFieldArr.length) {
|
||||
message.error(t('组件存在重复绑定,请更改'));
|
||||
return;
|
||||
}
|
||||
emit('update:dicAssoDia', false);
|
||||
emit('update:dicOptions', dicInfo.value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.list-title {
|
||||
margin: 10px 0 5px;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
.list-title {
|
||||
margin: 10px 0 5px;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,51 +1,51 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="t('查看接口信息')" @ok="closeModal">
|
||||
<a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane key="1" :tab="t('接口信息')">
|
||||
<CodeEditor :value="script" language="json" readonly />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" :tab="t('接口出参示例')">
|
||||
<CodeEditor :value="infoExample" language="json" readonly />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</BasicModal>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="t('查看接口信息')" @ok="closeModal">
|
||||
<a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane key="1" :tab="t('接口信息')">
|
||||
<CodeEditor :value="script" language="json" readonly />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" :tab="t('接口出参示例')">
|
||||
<CodeEditor :value="infoExample" language="json" readonly />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { CodeEditor } from '/@/components/CodeEditor';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const activeKey = ref<string>('1');
|
||||
const script = ref<string>('');
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
script.value = data.script;
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
draggable: false,
|
||||
showOkBtn: false,
|
||||
showCancelBtn: false,
|
||||
destroyOnClose: true,
|
||||
width: 800,
|
||||
import { ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { CodeEditor } from '/@/components/CodeEditor';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const activeKey = ref<string>('1');
|
||||
const script = ref<string>('');
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
script.value = data.script;
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
draggable: false,
|
||||
showOkBtn: false,
|
||||
showCancelBtn: false,
|
||||
destroyOnClose: true,
|
||||
width: 800
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const infoExample = JSON.stringify({
|
||||
code: 0,
|
||||
msg: t('提示信息'),
|
||||
data: [
|
||||
{
|
||||
label: t('选项一'),
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: t('选项二'),
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: t('选项三'),
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
const infoExample = JSON.stringify({
|
||||
code: 0,
|
||||
msg: t('提示信息'),
|
||||
data: [
|
||||
{
|
||||
label: t('选项一'),
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: t('选项二'),
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: t('选项三'),
|
||||
value: 1
|
||||
}
|
||||
]
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -1,132 +1,95 @@
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
@register="registerModal"
|
||||
:title="t('脚本配置')"
|
||||
@ok="handleSubmit"
|
||||
@visible-change="visibleChange"
|
||||
width="70%"
|
||||
>
|
||||
<div class="config-box">
|
||||
<div>
|
||||
<a-tabs
|
||||
v-model:activeKey="configTab"
|
||||
centered
|
||||
style="margin-bottom: 8px; background: #fff; height: 100%"
|
||||
>
|
||||
<a-tab-pane key="widget" :tab="t('脚本示例')">
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="t('脚本配置')" @ok="handleSubmit" @visible-change="visibleChange" width="70%">
|
||||
<div class="config-box">
|
||||
<div>
|
||||
<div
|
||||
v-for="(item, index) in example"
|
||||
:key="index"
|
||||
:class="['script-name', { 'active-name': activeIndex === index }]"
|
||||
@click="activeIndex = index"
|
||||
>
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="component" :tab="t('选择组件')">
|
||||
<div class="overflow-y-scroll">
|
||||
<Draggable
|
||||
v-model="widgetFormList"
|
||||
:group="{ name: 'script', pull: false, put: false }"
|
||||
item-key="key"
|
||||
@end="dragEnd"
|
||||
:sort="false"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<a-tag color="blue">{{ `${element.label}(${element.bindField})` }}</a-tag>
|
||||
</template>
|
||||
</Draggable>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
<!-- <div class="box-top">
|
||||
<a-tabs v-model:activeKey="configTab" centered style="margin-bottom: 8px; background: #fff; height: 100%">
|
||||
<a-tab-pane key="widget" :tab="t('脚本示例')">
|
||||
<div>
|
||||
<div v-for="(item, index) in example" :key="index" :class="['script-name', { 'active-name': activeIndex === index }]" @click="activeIndex = index">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="component" :tab="t('选择组件')">
|
||||
<div class="overflow-y-scroll">
|
||||
<Draggable v-model="widgetFormList" :group="{ name: 'script', pull: false, put: false }" item-key="key" @end="dragEnd" :sort="false">
|
||||
<template #item="{ element }">
|
||||
<a-tag color="blue">{{ `${element.label}(${element.bindField})` }}</a-tag>
|
||||
</template>
|
||||
</Draggable>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
<!-- <div class="box-top">
|
||||
<div class="title">{{ t('脚本示例') }}</div>
|
||||
<a-button type="primary" size="small" @click="componentVisible = true">{{
|
||||
t('选择组件')
|
||||
}}</a-button>
|
||||
</div> -->
|
||||
</div>
|
||||
<div style="max-width: 500px">
|
||||
<div class="box-top">
|
||||
<div class="title">{{ t('脚本示例代码') }}</div>
|
||||
</div>
|
||||
<div style="max-width: 500px">
|
||||
<div class="box-top">
|
||||
<div class="title">{{ t('脚本示例代码') }}</div>
|
||||
</div>
|
||||
<div style="height: calc(100% - 40px)">
|
||||
<CodeEditor :value="example[activeIndex].code" language="js" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="box-top">
|
||||
<div class="title">{{ t('自定义脚本') }}</div>
|
||||
</div>
|
||||
<div style="height: calc(100% - 40px)">
|
||||
<CodeEditor v-model:value="definedScript" language="js" :readonly="disabled" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: calc(100% - 40px)">
|
||||
<CodeEditor :value="example[activeIndex].code" language="js" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="box-top">
|
||||
<div class="title">{{ t('自定义脚本') }}</div>
|
||||
</div>
|
||||
<div style="height: calc(100% - 40px)">
|
||||
<CodeEditor v-model:value="definedScript" language="js" :readonly="disabled" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-drawer
|
||||
:title="t('组件列表(可将组件拖入自定义脚本当中)')"
|
||||
placement="left"
|
||||
:visible="componentVisible"
|
||||
:get-container="false"
|
||||
:style="{ position: 'absolute' }"
|
||||
:mask="false"
|
||||
width="50%"
|
||||
:closable="false"
|
||||
>
|
||||
<Draggable
|
||||
v-model="widgetFormList"
|
||||
:group="{ name: 'script', pull: false, put: false }"
|
||||
item-key="key"
|
||||
@end="dragEnd"
|
||||
:sort="false"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<a-tag color="blue">{{ `${element.label}(${element.bindField})` }}</a-tag>
|
||||
</template>
|
||||
</Draggable>
|
||||
<template #extra>
|
||||
<CloseOutlined @click="componentVisible = false" />
|
||||
</template>
|
||||
</a-drawer>
|
||||
</BasicModal>
|
||||
<a-drawer :title="t('组件列表(可将组件拖入自定义脚本当中)')" placement="left" :visible="componentVisible" :get-container="false" :style="{ position: 'absolute' }" :mask="false" width="50%" :closable="false">
|
||||
<Draggable v-model="widgetFormList" :group="{ name: 'script', pull: false, put: false }" item-key="key" @end="dragEnd" :sort="false">
|
||||
<template #item="{ element }">
|
||||
<a-tag color="blue">{{ `${element.label}(${element.bindField})` }}</a-tag>
|
||||
</template>
|
||||
</Draggable>
|
||||
<template #extra>
|
||||
<CloseOutlined @click="componentVisible = false" />
|
||||
</template>
|
||||
</a-drawer>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, inject } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { CodeEditor } from '/@/components/CodeEditor';
|
||||
import Draggable from 'vuedraggable';
|
||||
import { CloseOutlined } from '@ant-design/icons-vue';
|
||||
import { camelCaseString } from '/@/utils/event/design';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
defineProps({
|
||||
disabled: { type: Boolean, default: false },
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const eventType = ref('');
|
||||
const definedScript = ref(``);
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const activeIndex = ref(0);
|
||||
const componentVisible = ref<boolean>(false);
|
||||
const configIndex = ref();
|
||||
const configTab = ref('widget');
|
||||
import { ref, reactive, inject } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { CodeEditor } from '/@/components/CodeEditor';
|
||||
import Draggable from 'vuedraggable';
|
||||
import { CloseOutlined } from '@ant-design/icons-vue';
|
||||
import { camelCaseString } from '/@/utils/event/design';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
defineProps({
|
||||
disabled: { type: Boolean, default: false }
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const eventType = ref('');
|
||||
const definedScript = ref(``);
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const activeIndex = ref(0);
|
||||
const componentVisible = ref<boolean>(false);
|
||||
const configIndex = ref();
|
||||
const configTab = ref('widget');
|
||||
|
||||
const widgetFormList = ref([]); //整个表单json配置
|
||||
const isCustomForm = inject<boolean>('isCustomForm', false);
|
||||
const example = reactive([
|
||||
{
|
||||
title: t('读写组件值'),
|
||||
code: `const value = formModel.bindField //获取组件值
|
||||
const widgetFormList = ref([]); //整个表单json配置
|
||||
const isCustomForm = inject<boolean>('isCustomForm', false);
|
||||
const example = reactive([
|
||||
{
|
||||
title: t('读写组件值'),
|
||||
code: `const value = formModel.bindField //获取组件值
|
||||
formModel.bindField = 1 //修改组件值
|
||||
|
||||
// bindField: 组件的绑定字段`,
|
||||
},
|
||||
{
|
||||
title: t('ajax加载服务器数据'),
|
||||
code: `formActionType.httpRequest({
|
||||
// bindField: 组件的绑定字段`
|
||||
},
|
||||
{
|
||||
title: t('ajax加载服务器数据'),
|
||||
code: `formActionType.httpRequest({
|
||||
requestType: 'get', //请求方式有: get、post、put、delete
|
||||
requestUrl: '/system/dictionary-detail', //请求地址
|
||||
params: {
|
||||
@ -137,19 +100,19 @@
|
||||
// errorMessageMode='message' 错误提示为消息提示
|
||||
// errorMessageMode='modal' 显示modal错误弹窗,用于一些比较重要的错误
|
||||
// errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: t('修改组件样式'),
|
||||
code: `formActionType.changeStyle(schema, { border:'2px solid #5e95ff' },'bindField')
|
||||
`
|
||||
},
|
||||
{
|
||||
title: t('修改组件样式'),
|
||||
code: `formActionType.changeStyle(schema, { border:'2px solid #5e95ff' },'bindField')
|
||||
|
||||
// schema:必须要写
|
||||
// 中间对象为需要修改的样式
|
||||
// bindField:需要修改组件的绑定字段(字符串),如修改本组件 则不填`,
|
||||
},
|
||||
{
|
||||
title: t('弹出对话框'),
|
||||
code: `formActionType.showModal({
|
||||
// bindField:需要修改组件的绑定字段(字符串),如修改本组件 则不填`
|
||||
},
|
||||
{
|
||||
title: t('弹出对话框'),
|
||||
code: `formActionType.showModal({
|
||||
title: '我是标题', // 对话框标题
|
||||
content: '我是内容', // 对话框内容
|
||||
onOk() {
|
||||
@ -158,124 +121,122 @@
|
||||
onCancel() {
|
||||
console.log('onCancel') // 点击取消按钮的处理逻辑
|
||||
},
|
||||
});`,
|
||||
},
|
||||
{
|
||||
title: t('if判断'),
|
||||
code: `const value = 3
|
||||
});`
|
||||
},
|
||||
{
|
||||
title: t('if判断'),
|
||||
code: `const value = 3
|
||||
if(value === 3){ /* 括号内为判断条件 */
|
||||
console.log('value为3')
|
||||
/* 处理逻辑 */
|
||||
}`,
|
||||
},
|
||||
{
|
||||
title: t('循环'),
|
||||
code: `for(let i=0; i<3; i++){ /* 括号内为循环条件 */
|
||||
}`
|
||||
},
|
||||
{
|
||||
title: t('循环'),
|
||||
code: `for(let i=0; i<3; i++){ /* 括号内为循环条件 */
|
||||
console.log('i的值为', i)
|
||||
/* 处理逻辑 */
|
||||
}`,
|
||||
},
|
||||
{
|
||||
title: t('正则校验'),
|
||||
code: `formActionType.regTest({
|
||||
}`
|
||||
},
|
||||
{
|
||||
title: t('正则校验'),
|
||||
code: `formActionType.regTest({
|
||||
regExpression: /^[0-9]/,// 正则表达式
|
||||
testValue: 123,// 需要进行校验的值
|
||||
successMessage: '校验成功',// 校验成功的提示信息
|
||||
errorMessage: '校验失败'// 校验失败的提示信息
|
||||
})`,
|
||||
},
|
||||
{
|
||||
title: t('刷新API'),
|
||||
code: `formActionType.refreshAPI('bindField')
|
||||
})`
|
||||
},
|
||||
{
|
||||
title: t('刷新API'),
|
||||
code: `formActionType.refreshAPI('bindField')
|
||||
|
||||
// bindField:需要刷新API组件的绑定字段(字符串)`,
|
||||
},
|
||||
]);
|
||||
const [registerModal, { closeModal, setModalProps }] = useModalInner(async (data) => {
|
||||
widgetFormList.value = data.list;
|
||||
eventType.value = data.type;
|
||||
//如果已经设置过当前事件代码 则显示已经设置的值 反之 显示默认值
|
||||
definedScript.value = data.content;
|
||||
configIndex.value = data.index;
|
||||
setModalProps({
|
||||
fixedHeight: true,
|
||||
// bindField:需要刷新API组件的绑定字段(字符串)`
|
||||
}
|
||||
]);
|
||||
const [registerModal, { closeModal, setModalProps }] = useModalInner(async (data) => {
|
||||
widgetFormList.value = data.list;
|
||||
eventType.value = data.type;
|
||||
//如果已经设置过当前事件代码 则显示已经设置的值 反之 显示默认值
|
||||
definedScript.value = data.content;
|
||||
configIndex.value = data.index;
|
||||
setModalProps({
|
||||
fixedHeight: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const dragEnd = ({ item }) => {
|
||||
const component = item._underlying_vm_;
|
||||
const str = `${component.label}(${component.bindField})`;
|
||||
const replaceStr = isCustomForm
|
||||
? component.bindField
|
||||
: `${camelCaseString(component.bindField)}`;
|
||||
definedScript.value = definedScript.value.replace(str, replaceStr);
|
||||
};
|
||||
const handleSubmit = () => {
|
||||
emit('success', eventType.value, definedScript.value, configIndex.value);
|
||||
closeModal();
|
||||
};
|
||||
const dragEnd = ({ item }) => {
|
||||
const component = item._underlying_vm_;
|
||||
const str = `${component.label}(${component.bindField})`;
|
||||
const replaceStr = isCustomForm ? component.bindField : `${camelCaseString(component.bindField)}`;
|
||||
definedScript.value = definedScript.value.replace(str, replaceStr);
|
||||
};
|
||||
const handleSubmit = () => {
|
||||
emit('success', eventType.value, definedScript.value, configIndex.value);
|
||||
closeModal();
|
||||
};
|
||||
|
||||
const visibleChange = (visible: boolean) => {
|
||||
if (!visible) componentVisible.value = false;
|
||||
};
|
||||
const visibleChange = (visible: boolean) => {
|
||||
if (!visible) componentVisible.value = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.config-box {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
.config-box {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
div:nth-child(1) {
|
||||
flex: 1;
|
||||
div:nth-child(1) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
div {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.box-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin: 0 0 10px 10px;
|
||||
}
|
||||
|
||||
.script-name {
|
||||
cursor: pointer;
|
||||
padding: 10px 0 10px 15px;
|
||||
|
||||
&:hover {
|
||||
background: #eef4ff;
|
||||
}
|
||||
}
|
||||
|
||||
.active-name {
|
||||
background: #eef4ff;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
flex: 2;
|
||||
:deep(.ant-drawer-title),
|
||||
.title {
|
||||
font-size: 16px;
|
||||
height: 20px;
|
||||
line-height: 18px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
|
||||
.box-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin: 0 0 10px 10px;
|
||||
:deep(.ant-tag) {
|
||||
padding: 8px;
|
||||
font-size: 13px;
|
||||
margin-bottom: 7px;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.script-name {
|
||||
cursor: pointer;
|
||||
padding: 10px 0 10px 15px;
|
||||
|
||||
&:hover {
|
||||
background: #eef4ff;
|
||||
}
|
||||
:deep(.ant-tabs-tab) {
|
||||
padding: 0 0 8px;
|
||||
}
|
||||
|
||||
.active-name {
|
||||
background: #eef4ff;
|
||||
:deep(.ant-tabs-content) {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-drawer-title),
|
||||
.title {
|
||||
font-size: 16px;
|
||||
height: 20px;
|
||||
line-height: 18px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
|
||||
:deep(.ant-tag) {
|
||||
padding: 8px;
|
||||
font-size: 13px;
|
||||
margin-bottom: 7px;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
:deep(.ant-tabs-tab) {
|
||||
padding: 0 0 8px;
|
||||
}
|
||||
|
||||
:deep(.ant-tabs-content) {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,197 +1,175 @@
|
||||
<template>
|
||||
<div class="static-box">
|
||||
<div class="static-top">
|
||||
<div class="static-title">{{ t('静态数据列表') }}</div>
|
||||
<div>
|
||||
<a-button
|
||||
:disabled="disabled"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleReset"
|
||||
class="mr-0.5"
|
||||
<div class="static-box">
|
||||
<div class="static-top">
|
||||
<div class="static-title">{{ t('静态数据列表') }}</div>
|
||||
<div>
|
||||
<a-button :disabled="disabled" type="primary" size="small" @click="handleReset" class="mr-0.5"> 取消选中 </a-button>
|
||||
<a-button :disabled="disabled" type="primary" size="small" @click="emits('handleInsertOption')">
|
||||
{{ t('添加数据') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<a-table
|
||||
:dataSource="options?.staticOptions"
|
||||
:row-selection="{
|
||||
type: type,
|
||||
selectedRowKeys: selectedRowKey,
|
||||
onChange: onChange
|
||||
}"
|
||||
:pagination="false"
|
||||
:columns="columns"
|
||||
>
|
||||
取消选中
|
||||
</a-button>
|
||||
<a-button
|
||||
:disabled="disabled"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="emits('handleInsertOption')"
|
||||
>
|
||||
{{ t('添加数据') }}
|
||||
</a-button>
|
||||
</div>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'label'">
|
||||
<a-input v-model:value="record[column.key]" :disabled="disabled" :placeholder="t('请输入')" />
|
||||
</template>
|
||||
<template v-if="column.key === 'value'">
|
||||
<a-input v-model:value="record[column.key]" :disabled="disabled" :placeholder="t('请输入')" @change="(val) => changeValue(val, record.key)" />
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<DeleteTwoTone two-tone-color="#ff8080" @click="emits('handleOptionsRemove', index)" />
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<a-table
|
||||
:dataSource="options?.staticOptions"
|
||||
:row-selection="{
|
||||
type: type,
|
||||
selectedRowKeys: selectedRowKey,
|
||||
onChange: onChange,
|
||||
}"
|
||||
:pagination="false"
|
||||
:columns="columns"
|
||||
>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'label'">
|
||||
<a-input
|
||||
v-model:value="record[column.key]"
|
||||
:disabled="disabled"
|
||||
:placeholder="t('请输入')"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'value'">
|
||||
<a-input
|
||||
v-model:value="record[column.key]"
|
||||
:disabled="disabled"
|
||||
:placeholder="t('请输入')"
|
||||
@change="(val) => changeValue(val, record.key)"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<DeleteTwoTone two-tone-color="#ff8080" @click="emits('handleOptionsRemove', index)" />
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, onMounted } from 'vue';
|
||||
import { DeleteTwoTone } from '@ant-design/icons-vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
options: Object,
|
||||
type: String,
|
||||
disabled: { type: Boolean, default: () => false },
|
||||
});
|
||||
const emits = defineEmits(['handleOptionsRemove', 'handleInsertOption', 'handleDefaultSelect']);
|
||||
const selectedRowKey = ref<string[] | number[]>([1]);
|
||||
const selectedRow = ref<any[]>([]);
|
||||
|
||||
const columns = reactive([
|
||||
{
|
||||
title: t('显示值'),
|
||||
dataIndex: 'label',
|
||||
key: 'label',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('保存值'),
|
||||
dataIndex: 'value',
|
||||
key: 'value',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50,
|
||||
},
|
||||
]);
|
||||
|
||||
watch(
|
||||
() => props.options,
|
||||
(val) => {
|
||||
if (props.type === 'radio') {
|
||||
//单选组件、下拉选择
|
||||
if (!!val?.defaultSelect) {
|
||||
val.staticOptions.map((item: any, index: number) => {
|
||||
if (item.value === val?.defaultSelect) {
|
||||
selectedRowKey.value = [index + 1];
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
//多选组件
|
||||
if (val?.defaultSelect) {
|
||||
selectedRowKey.value = [];
|
||||
val.staticOptions.map((item: any, index: number) => {
|
||||
val?.defaultSelect.split(',').map((select: [string, number]) => {
|
||||
if (item.value === select) {
|
||||
(selectedRowKey.value as number[]).push(index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
selectedRowKey.value = [];
|
||||
}
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true },
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
selectedRowKey.value = [props.options?.staticOptions[0].key];
|
||||
selectedRow.value = [props.options?.staticOptions[0]];
|
||||
emits('handleDefaultSelect', props.options?.staticOptions[0].value);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => selectedRow.value,
|
||||
(val) => {
|
||||
const selected = val?.map((x) => x.value).join(',');
|
||||
emits('handleDefaultSelect', selected);
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
const onChange = (selectedRowKeys: string[] | number[], selectedRows: any[]) => {
|
||||
if (props.disabled) return;
|
||||
selectedRowKey.value = selectedRowKeys;
|
||||
selectedRow.value = selectedRows;
|
||||
let selectedValue;
|
||||
if (props.type === 'radio') {
|
||||
selectedValue = selectedRows[0].value;
|
||||
} else {
|
||||
selectedValue = selectedRows.map((item) => item.value).join(',');
|
||||
}
|
||||
emits('handleDefaultSelect', selectedValue);
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
selectedRowKey.value = [];
|
||||
selectedRow.value = [];
|
||||
emits('handleDefaultSelect', '');
|
||||
};
|
||||
|
||||
const changeValue = (e, key) => {
|
||||
selectedRow.value.map((row) => {
|
||||
if (row.key === key) {
|
||||
row.value = e.target.value;
|
||||
}
|
||||
import { ref, reactive, watch, onMounted } from 'vue';
|
||||
import { DeleteTwoTone } from '@ant-design/icons-vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
options: Object,
|
||||
type: String,
|
||||
disabled: { type: Boolean, default: () => false }
|
||||
});
|
||||
};
|
||||
const emits = defineEmits(['handleOptionsRemove', 'handleInsertOption', 'handleDefaultSelect']);
|
||||
const selectedRowKey = ref<string[] | number[]>([1]);
|
||||
const selectedRow = ref<any[]>([]);
|
||||
|
||||
const columns = reactive([
|
||||
{
|
||||
title: t('显示值'),
|
||||
dataIndex: 'label',
|
||||
key: 'label',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('保存值'),
|
||||
dataIndex: 'value',
|
||||
key: 'value',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 50
|
||||
}
|
||||
]);
|
||||
|
||||
watch(
|
||||
() => props.options,
|
||||
(val) => {
|
||||
if (props.type === 'radio') {
|
||||
//单选组件、下拉选择
|
||||
if (!!val?.defaultSelect) {
|
||||
val.staticOptions.map((item: any, index: number) => {
|
||||
if (item.value === val?.defaultSelect) {
|
||||
selectedRowKey.value = [index + 1];
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
//多选组件
|
||||
if (val?.defaultSelect) {
|
||||
selectedRowKey.value = [];
|
||||
val.staticOptions.map((item: any, index: number) => {
|
||||
val?.defaultSelect.split(',').map((select: [string, number]) => {
|
||||
if (item.value === select) {
|
||||
(selectedRowKey.value as number[]).push(index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
selectedRowKey.value = [];
|
||||
}
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
selectedRowKey.value = [props.options?.staticOptions[0].key];
|
||||
selectedRow.value = [props.options?.staticOptions[0]];
|
||||
emits('handleDefaultSelect', props.options?.staticOptions[0].value);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => selectedRow.value,
|
||||
(val) => {
|
||||
const selected = val?.map((x) => x.value).join(',');
|
||||
emits('handleDefaultSelect', selected);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const onChange = (selectedRowKeys: string[] | number[], selectedRows: any[]) => {
|
||||
if (props.disabled) return;
|
||||
selectedRowKey.value = selectedRowKeys;
|
||||
selectedRow.value = selectedRows;
|
||||
let selectedValue;
|
||||
if (props.type === 'radio') {
|
||||
selectedValue = selectedRows[0].value;
|
||||
} else {
|
||||
selectedValue = selectedRows.map((item) => item.value).join(',');
|
||||
}
|
||||
emits('handleDefaultSelect', selectedValue);
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
selectedRowKey.value = [];
|
||||
selectedRow.value = [];
|
||||
emits('handleDefaultSelect', '');
|
||||
};
|
||||
|
||||
const changeValue = (e, key) => {
|
||||
selectedRow.value.map((row) => {
|
||||
if (row.key === key) {
|
||||
row.value = e.target.value;
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.static-box {
|
||||
padding: 5px 0 10px 20px;
|
||||
.static-box {
|
||||
padding: 5px 0 10px 20px;
|
||||
|
||||
:deep(.ant-table) {
|
||||
font-size: 14px;
|
||||
:deep(.ant-table) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
:deep(.ant-table-tbody tr td) {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
:deep(.ant-table .ant-table-thead tr th) {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.static-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
margin-top: 5px;
|
||||
|
||||
.static-title {
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-table-tbody tr td) {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
:deep(.ant-table .ant-table-thead tr th) {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.static-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
margin-top: 5px;
|
||||
|
||||
.static-title {
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,158 +1,135 @@
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
@register="registerModal"
|
||||
title="批量设置权限所属人"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleClose"
|
||||
>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<div class="table-title">数据列表</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.componentType === 'switch'">
|
||||
<a-switch
|
||||
v-model:checked="record[column.dataIndex]"
|
||||
:unCheckedValue="0"
|
||||
:checkedValue="1"
|
||||
:disabled="true"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.componentType === 'picker-color'">
|
||||
<ColorPicker v-model:value="record[column.dataIndex]" :disabled="true" />
|
||||
</template>
|
||||
<template v-if="column.componentType === 'money-chinese'">
|
||||
{{
|
||||
!isNaN(record[column.dataIndex]) && record[column.dataIndex] !== null
|
||||
? nzhcn.encodeB(record[column.dataIndex]) + '元'
|
||||
: ''
|
||||
}}
|
||||
</template>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<SelectUser
|
||||
class="select-box"
|
||||
:selectedIds="state.userIds"
|
||||
:multiple="false"
|
||||
@change="getRuleUserIds"
|
||||
@changeNames="getRuleUserNames"
|
||||
>
|
||||
<a-button type="primary"> 设置权限所属人 </a-button>
|
||||
</SelectUser>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</BasicModal>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" title="批量设置权限所属人" @ok="handleSubmit" @cancel="handleClose">
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<div class="table-title">数据列表</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.componentType === 'switch'">
|
||||
<a-switch v-model:checked="record[column.dataIndex]" :unCheckedValue="0" :checkedValue="1" :disabled="true" />
|
||||
</template>
|
||||
<template v-if="column.componentType === 'picker-color'">
|
||||
<ColorPicker v-model:value="record[column.dataIndex]" :disabled="true" />
|
||||
</template>
|
||||
<template v-if="column.componentType === 'money-chinese'">
|
||||
{{ !isNaN(record[column.dataIndex]) && record[column.dataIndex] !== null ? nzhcn.encodeB(record[column.dataIndex]) + '元' : '' }}
|
||||
</template>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<SelectUser class="select-box" :selectedIds="state.userIds" :multiple="false" @change="getRuleUserIds" @changeNames="getRuleUserNames">
|
||||
<a-button type="primary"> 设置权限所属人 </a-button>
|
||||
</SelectUser>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { SelectUser } from '/@/components/SelectOrganizational/index';
|
||||
import { getAllUserList } from '/@/api/system/user';
|
||||
import { ColorPicker } from '/@/components/ColorPicker';
|
||||
import nzhcn from 'nzh/cn';
|
||||
import { reactive } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { SelectUser } from '/@/components/SelectOrganizational/index';
|
||||
import { getAllUserList } from '/@/api/system/user';
|
||||
import { ColorPicker } from '/@/components/ColorPicker';
|
||||
import nzhcn from 'nzh/cn';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const state = reactive({
|
||||
rowKey: '',
|
||||
dataSource: [] as any[],
|
||||
columns: [] as BasicColumn[],
|
||||
userIds: [],
|
||||
setDataAuthApi: null as any,
|
||||
apiParams: null,
|
||||
ruleUserIdName: 'ruleUserId',
|
||||
});
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
state.rowKey = data.rowKey;
|
||||
state.columns = cloneDeep(data.columns);
|
||||
state.dataSource = cloneDeep(data.dataSource);
|
||||
state.setDataAuthApi = data.setDataAuthApi;
|
||||
state.apiParams = data.params;
|
||||
state.ruleUserIdName = !!data.isCustomForm ? 'rule_user_id' : 'ruleUserId';
|
||||
|
||||
setModalProps({
|
||||
destroyOnClose: true,
|
||||
maskClosable: false,
|
||||
fixedHeight: true,
|
||||
width: 800,
|
||||
const state = reactive({
|
||||
rowKey: '',
|
||||
dataSource: [] as any[],
|
||||
columns: [] as BasicColumn[],
|
||||
userIds: [],
|
||||
setDataAuthApi: null as any,
|
||||
apiParams: null,
|
||||
ruleUserIdName: 'ruleUserId'
|
||||
});
|
||||
if (state.columns?.length && state.columns[0].dataIndex !== state.ruleUserIdName) {
|
||||
state.columns.unshift({
|
||||
dataIndex: state.ruleUserIdName,
|
||||
title: '当前权限人',
|
||||
});
|
||||
}
|
||||
|
||||
const userInfo = await getAllUserList();
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
state.rowKey = data.rowKey;
|
||||
state.columns = cloneDeep(data.columns);
|
||||
state.dataSource = cloneDeep(data.dataSource);
|
||||
state.setDataAuthApi = data.setDataAuthApi;
|
||||
state.apiParams = data.params;
|
||||
state.ruleUserIdName = !!data.isCustomForm ? 'rule_user_id' : 'ruleUserId';
|
||||
|
||||
state.dataSource.map((item) => {
|
||||
if (item[state.ruleUserIdName]) {
|
||||
const userIdsArr = item[state.ruleUserIdName].split(',');
|
||||
const userNamesArr = [] as string[];
|
||||
userInfo.map((user) => {
|
||||
if (userIdsArr.includes(user.id)) {
|
||||
userNamesArr.push(user.name);
|
||||
}
|
||||
setModalProps({
|
||||
destroyOnClose: true,
|
||||
maskClosable: false,
|
||||
fixedHeight: true,
|
||||
width: 800
|
||||
});
|
||||
item[state.ruleUserIdName] = userNamesArr.join(',');
|
||||
}
|
||||
if (state.columns?.length && state.columns[0].dataIndex !== state.ruleUserIdName) {
|
||||
state.columns.unshift({
|
||||
dataIndex: state.ruleUserIdName,
|
||||
title: '当前权限人'
|
||||
});
|
||||
}
|
||||
|
||||
const userInfo = await getAllUserList();
|
||||
|
||||
state.dataSource.map((item) => {
|
||||
if (item[state.ruleUserIdName]) {
|
||||
const userIdsArr = item[state.ruleUserIdName].split(',');
|
||||
const userNamesArr = [] as string[];
|
||||
userInfo.map((user) => {
|
||||
if (userIdsArr.includes(user.id)) {
|
||||
userNamesArr.push(user.name);
|
||||
}
|
||||
});
|
||||
item[state.ruleUserIdName] = userNamesArr.join(',');
|
||||
}
|
||||
});
|
||||
setTableData(state.dataSource);
|
||||
setColumns(state.columns);
|
||||
});
|
||||
setTableData(state.dataSource);
|
||||
setColumns(state.columns);
|
||||
});
|
||||
|
||||
const [registerTable, { setTableData, setColumns }] = useTable({
|
||||
rowKey: state.rowKey,
|
||||
columns: state.columns,
|
||||
dataSource: state.dataSource,
|
||||
pagination: false,
|
||||
});
|
||||
const [registerTable, { setTableData, setColumns }] = useTable({
|
||||
rowKey: state.rowKey,
|
||||
columns: state.columns,
|
||||
dataSource: state.dataSource,
|
||||
pagination: false
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
const params = {
|
||||
userIdList: state.userIds,
|
||||
dataIdList: state.dataSource.map((x) => x[state.rowKey]),
|
||||
};
|
||||
if (isFunction(state.setDataAuthApi)) {
|
||||
!!state.apiParams
|
||||
? await state.setDataAuthApi(state.apiParams, params)
|
||||
: await state.setDataAuthApi(params);
|
||||
async function handleSubmit() {
|
||||
const params = {
|
||||
userIdList: state.userIds,
|
||||
dataIdList: state.dataSource.map((x) => x[state.rowKey])
|
||||
};
|
||||
if (isFunction(state.setDataAuthApi)) {
|
||||
!!state.apiParams ? await state.setDataAuthApi(state.apiParams, params) : await state.setDataAuthApi(params);
|
||||
}
|
||||
closeModal();
|
||||
emit('success');
|
||||
state.userIds = [];
|
||||
}
|
||||
closeModal();
|
||||
emit('success');
|
||||
state.userIds = [];
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
state.userIds = [];
|
||||
}
|
||||
function handleClose() {
|
||||
state.userIds = [];
|
||||
}
|
||||
|
||||
function getRuleUserIds(ids) {
|
||||
state.userIds = ids;
|
||||
}
|
||||
function getRuleUserIds(ids) {
|
||||
state.userIds = ids;
|
||||
}
|
||||
|
||||
function getRuleUserNames(names) {
|
||||
state.dataSource.map((item) => {
|
||||
item[state.ruleUserIdName] = names;
|
||||
});
|
||||
setTableData(state.dataSource);
|
||||
}
|
||||
function getRuleUserNames(names) {
|
||||
state.dataSource.map((item) => {
|
||||
item[state.ruleUserIdName] = names;
|
||||
});
|
||||
setTableData(state.dataSource);
|
||||
}
|
||||
</script>
|
||||
<style lange="less" scoped>
|
||||
.select-box {
|
||||
text-align: right;
|
||||
width: auto !important;
|
||||
}
|
||||
.select-box {
|
||||
text-align: right;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.table-title {
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
.table-title {
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
padding-left: 6px;
|
||||
border-left: 6px solid #5e95ff;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user