17 changed files with 2650 additions and 0 deletions
@ -0,0 +1,219 @@ |
|||
<template> |
|||
<q-th :key="column.name" :rowspan="rowspan" :colspan="colspan" :style="styleComputed" :class="classComputed" style="font-weight: bold" :title="title"> |
|||
<span v-html="label"></span> |
|||
</q-th> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { Tools, $t } from '@/platform'; |
|||
import { computed, inject, reactive } from 'vue'; |
|||
import { Constant, GridTools } from './ts/index'; |
|||
|
|||
const tools = <GridTools>inject('tools'); |
|||
const props = defineProps({ |
|||
rowspan: { type: Number, default: undefined }, |
|||
colspan: { type: Number, default: undefined }, |
|||
title: { type: String, default: '' }, |
|||
label: { type: String, default: '' }, |
|||
style: { type: String, default: '' }, |
|||
class: { type: String, default: '' }, |
|||
column: { |
|||
type: Object, |
|||
default: () => { |
|||
return {}; |
|||
}, |
|||
}, |
|||
scope: { |
|||
// 顶部插槽属性 |
|||
type: Object, |
|||
default: () => { |
|||
return {}; |
|||
}, |
|||
}, |
|||
}); |
|||
|
|||
const thStickyLastNameComputed = computed(() => { |
|||
let result = <any>[]; |
|||
const stickyColumnArr = tools.titleFM.getStickyColumn(); |
|||
const lastColumn = tools.titleFM.getMultiTitleIndex(stickyColumnArr[stickyColumnArr.length - 1]['name']); |
|||
if (lastColumn.trIndex === 1) { |
|||
// 多表头锁定列的结尾列如果行下标为1直接取最后一列 |
|||
result = [stickyColumnArr[stickyColumnArr.length - 1]]; |
|||
} else { |
|||
const map = new Map(); |
|||
stickyColumnArr.forEach((item) => { |
|||
const trtdIndex = tools.titleFM.getMultiTitleIndex(item['name']); |
|||
if (map.has(trtdIndex.trIndex) && map.get(trtdIndex.trIndex)[0] < trtdIndex.tdIndex) { |
|||
map.set(trtdIndex.trIndex, [trtdIndex.tdIndex, item]); |
|||
} else if (!map.has(trtdIndex.trIndex)) { |
|||
map.set(trtdIndex.trIndex, [trtdIndex.tdIndex, item]); |
|||
} |
|||
}); |
|||
for (let key of map.keys()) { |
|||
result.push(map.get(key)[1]); |
|||
} |
|||
} |
|||
return result; |
|||
}); |
|||
|
|||
const classComputed = computed(() => { |
|||
const noBorder = noRightBorder(props.column.name); |
|||
if (props.class) { |
|||
return props.class + (noBorder ? ' no_border_right' : ''); |
|||
} else if (noBorder) { |
|||
return 'no_border_right'; |
|||
} |
|||
return ''; |
|||
}); |
|||
|
|||
const existYScroll = () => { |
|||
let existYScroll = false; |
|||
const clientHeight = tools.instance.getHtmlElement()?.getElementsByClassName('q-table__middle')[0]?.clientHeight; |
|||
const scrollHeight = tools.instance.getHtmlElement()?.getElementsByClassName('q-table__middle')[0]?.scrollHeight; |
|||
if (clientHeight && scrollHeight && scrollHeight > clientHeight) { |
|||
// 存在纵向滚动条 |
|||
existYScroll = true; |
|||
} |
|||
return existYScroll; |
|||
}; |
|||
|
|||
const noRightBorder = (name) => { |
|||
let lastColumn: any = tools.table.originalColumns[tools.table.originalColumns.length - 1]; |
|||
// for (let i = tools.table.originalColumns.length - 1; i > -1; i--) { |
|||
// const column = tools.table.originalColumns[i]; |
|||
// if (column.showIf) { |
|||
// lastColumn = column; |
|||
// break; |
|||
// } |
|||
// } |
|||
const flag = existYScroll(); |
|||
if (lastColumn['name'] === name && !flag) { |
|||
return true; |
|||
} else if (tools.table.store.multiHeaderLastNames[lastColumn['name']]?.includes(name) && !flag) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}; |
|||
|
|||
const styleComputed = computed(() => { |
|||
let style = ''; |
|||
if (!Tools.isEmpty(props.style)) { |
|||
if (!props.style.endsWith(';')) { |
|||
style = props.style + ';'; |
|||
} else { |
|||
style = props.style; |
|||
} |
|||
} |
|||
const stickyColumnArr = tools.titleFM.getStickyColumn(); |
|||
if ( |
|||
tools.table.configStore.stickyNum > 0 && |
|||
stickyColumnArr.findIndex((item: any) => { |
|||
return item.name === props.column.name; |
|||
}) > -1 |
|||
) { |
|||
const stickyThArr = <any>[]; |
|||
const trtdIndex = tools.titleFM.getMultiTitleIndex(props.column.name); |
|||
if (props.column.parents && props.column.parents.length > 0) { |
|||
// 存在父级节点,得到父级节点的列下标 |
|||
// 找到parent相同且tdIndex小于其的一共多少列 |
|||
for (let tr = 0; tr < trtdIndex.trIndex; tr++) { |
|||
const tdArr = tools.titleFM.multiTitles.value[tr]; |
|||
for (let td = 0; td < trtdIndex.tdIndex - 1; td++) { |
|||
if (tdArr[td] && tdArr[td].parents && tdArr[td].parents.length > 0) { |
|||
const result = |
|||
tdArr[td].parents.length === props.column.parents.length && |
|||
tdArr[td].parents.every((a) => props.column.parents.some((b) => a === b)) && |
|||
props.column.parents.every((_b) => tdArr[td].parents.some((_a) => _a === _b)); |
|||
if (result) { |
|||
if (tr === 0) { |
|||
stickyThArr.push({ trIndex: tr + 1, tdIndex: td + tools.cm.extColumnNum.value + 1 }); |
|||
} else { |
|||
stickyThArr.push({ trIndex: tr + 1, tdIndex: td + 1 }); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
props.column.parents.forEach((parent) => { |
|||
const parentTrtdIndex = tools.titleFM.getMultiTitleIndex(parent); |
|||
if (tools.titleFM.multiTitleMap.get(parent)!.parents && tools.titleFM.multiTitleMap.get(parent)!.parents.length > 0) { |
|||
const tdArr = tools.titleFM.multiTitles[parentTrtdIndex.trIndex - 1]; |
|||
for (let td = 0; td < parentTrtdIndex.tdIndex - 1; td++) { |
|||
const result = |
|||
tdArr[td].parents.length === tools.titleFM.multiTitleMap.get(parent)!.parents.length && |
|||
tdArr[td].parents.every((a) => tools.titleFM.multiTitleMap.get(parent)!.parents.some((b) => a === b)) && |
|||
tools.titleFM.multiTitleMap.get(parent)!.parents.every((_b) => tdArr[td].parents.some((_a) => _a === _b)); |
|||
if (result) { |
|||
stickyThArr.push({ trIndex: parentTrtdIndex.trIndex, tdIndex: td + 1 }); |
|||
} |
|||
} |
|||
} else { |
|||
const tdArr = tools.titleFM.multiTitles[parentTrtdIndex.trIndex - 1]; |
|||
for (let td = 0; td < parentTrtdIndex.tdIndex - 1; td++) { |
|||
if ( |
|||
tdArr[td].parents && |
|||
tdArr[td].parents.length > 0 && |
|||
tdArr[td].parents.findIndex((item) => { |
|||
return item === parent; |
|||
}) > -1 |
|||
) { |
|||
stickyThArr.push({ trIndex: parentTrtdIndex.trIndex, tdIndex: td + tools.cm.extColumnNum.value + 1 }); |
|||
} else { |
|||
stickyThArr.push({ trIndex: parentTrtdIndex.trIndex, tdIndex: td + tools.cm.extColumnNum.value + 1 }); |
|||
} |
|||
} |
|||
} |
|||
}); |
|||
if (trtdIndex.tdIndex === 1 && stickyThArr.length === 0) { |
|||
stickyThArr.push({ trIndex: 0, tdIndex: 0 }); |
|||
} |
|||
} else { |
|||
if (trtdIndex.tdIndex === 1) { |
|||
if (tools.cm.extColumnNum.value === 2) { |
|||
return thStickyLastNameComputed.value.findIndex((item) => { |
|||
return item.name === props.column.name; |
|||
}) > -1 |
|||
? (style += 'z-index: 3;position: sticky;left: calc(var(--columnWidth-1-1) + var(--columnWidth-1-2));') |
|||
: (style += 'z-index: 3;position: sticky;left: calc(var(--columnWidth-1-1) + var(--columnWidth-1-2));'); |
|||
} else if (tools.cm.extColumnNum.value === 1) { |
|||
return thStickyLastNameComputed.value.findIndex((item) => { |
|||
return item.name === props.column.name; |
|||
}) > -1 |
|||
? (style += 'z-index: 3;position: sticky;left: var(--columnWidth-1-1);') |
|||
: (style += 'z-index: 3;position: sticky;left: var(--columnWidth-1-1);'); |
|||
} else { |
|||
return thStickyLastNameComputed.value.findIndex((item) => { |
|||
return item.name === props.column.name; |
|||
}) > -1 |
|||
? (style += 'z-index: 3;position: sticky;left: 0px;') |
|||
: (style += 'z-index: 3;position: sticky;left: 0px;'); |
|||
} |
|||
} else { |
|||
for (let i = 1; i < trtdIndex.tdIndex; i++) { |
|||
stickyThArr.push({ trIndex: 1, tdIndex: i + tools.cm.extColumnNum.value }); |
|||
} |
|||
} |
|||
} |
|||
if (tools.cm.extColumnNum.value === 2) { |
|||
stickyThArr.push({ trIndex: 1, tdIndex: 1 }); |
|||
stickyThArr.push({ trIndex: 1, tdIndex: 2 }); |
|||
} else if (tools.cm.extColumnNum.value === 1) { |
|||
stickyThArr.push({ trIndex: 1, tdIndex: 1 }); |
|||
} |
|||
if (stickyThArr && stickyThArr.length > 0) { |
|||
let left = ''; |
|||
stickyThArr.forEach((item) => { |
|||
left += '+ var(--columnWidth-' + item.trIndex + '-' + item.tdIndex + ') '; |
|||
}); |
|||
if (left) { |
|||
style += 'z-index: 3;position: sticky;left: calc(' + left.substring(1) + ')' + ';'; |
|||
} |
|||
} |
|||
} |
|||
// if (c['name'] === tools.table.columns[tools.table.columns.length - 1]['name']) { |
|||
// style += 'border-right-width: 0px;'; |
|||
// } |
|||
return style; |
|||
}); |
|||
</script> |
|||
|
|||
<style lang="css"></style> |
@ -0,0 +1,200 @@ |
|||
<template> |
|||
<div v-show="fieldMethodsClass.getShow(props, modelValue)"> |
|||
<q-input |
|||
ref="textSelectRef" |
|||
v-model="displayValueComputed" |
|||
:hide-bottom-space="true" |
|||
:hide-hint="true" |
|||
:outlined="true" |
|||
:dense="true" |
|||
:autogrow="true" |
|||
v-bind="attrs" |
|||
type="text" |
|||
:rules="fieldMethodsClass.getRules(props, { value: modelValue, displayValue: displayValueComputed }, textSelectRef, undefined)" |
|||
:readonly="fieldMethodsClass.getReadOnly(props, { value: modelValue, displayValue: displayValueComputed })" |
|||
:disable="fieldMethodsClass.getDisable(props, { value: modelValue, displayValue: displayValueComputed })" |
|||
:clearable="false" |
|||
> |
|||
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> |
|||
<template v-if="!props['form'] || (props['form'] && props['form'].getStatus() !== 'view')" #append> |
|||
<q-btn v-if="!Tools.isEmpty(displayValueComputed)" flat square unelevated dense icon="cancel" @click="fieldMethodsClass.clearValue"></q-btn> |
|||
<q-btn flat square unelevated dense icon="pageview"> |
|||
<q-popup-proxy v-model:model-value="isShow" anchor="bottom right" self="top right" :offset="[0, 10]"> |
|||
<div style="width: 700px; height: 400px"> |
|||
<w-grid |
|||
ref="dictionaryGridRef" |
|||
title="数据字典列表" |
|||
:checkbox-selection="false" |
|||
:pageable="false" |
|||
:dense="true" |
|||
:fetch-data-url="dictionaryGridFetchDataUrl" |
|||
:config-button="false" |
|||
:query-form-cols-num="2" |
|||
:toolbar-actions="['query', 'reset']" |
|||
:query-form-fields="[{ name: 'code', label: $t('code'), type: 'w-text' }]" |
|||
:columns="[ |
|||
{ name: 'code', label: $t('code') }, |
|||
{ |
|||
name: 'name', |
|||
label: $t('name'), |
|||
format: (value, row) => { |
|||
return $t(row.code); |
|||
}, |
|||
}, |
|||
]" |
|||
:ticked-record="{ |
|||
columnName: valueUseColumnName, |
|||
data: typeof modelValue === 'string' ? [modelValue] : modelValue, |
|||
}" |
|||
db-click-operation="none" |
|||
@row-click="rowClick" |
|||
> |
|||
</w-grid> |
|||
</div> |
|||
</q-popup-proxy> |
|||
</q-btn> |
|||
</template> |
|||
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]> |
|||
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot> |
|||
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot> |
|||
</template> |
|||
</q-input> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { $t, axios, Environment, Tools } from '@/platform'; |
|||
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; |
|||
import { computed, onMounted, ref, useAttrs, useSlots, watch } from 'vue'; |
|||
import FormElementSlot from '../form/FormElementSlot.vue'; |
|||
import { FormFieldMethods } from '../form/FormField'; |
|||
|
|||
const textSelectRef = ref(); |
|||
const attrs = useAttrs(); |
|||
const slots = useSlots(); |
|||
const modelValue = defineModel<string>(); |
|||
const modelObjectValue = ref({}); // 模型值包含实际值与显示值的对象集合。 |
|||
const dictionaryGridRef = ref(); |
|||
|
|||
const dictionaryGridFetchDataUrl = Environment.apiContextPath('/api/template/config/dictionaryList'); |
|||
const isShow = ref(false); |
|||
|
|||
interface FieldProps extends FormFieldProps {} |
|||
const props = withDefaults(defineProps<FieldProps>(), { |
|||
showIf: true, |
|||
}); |
|||
class FieldMethods extends FormFieldMethods { |
|||
isTemplateSlot = this.getSlotType(slots); |
|||
slotNames = this.getSlotNames(slots, props); |
|||
updateValue = (value_) => { |
|||
if (props['onUpdateValue']) { |
|||
props['onUpdateValue']({ |
|||
value: value_, |
|||
displayValue: displayValueComputed.value, |
|||
form: props['form'], |
|||
}); |
|||
} |
|||
}; |
|||
validate = () => { |
|||
return textSelectRef.value.validate(); |
|||
}; |
|||
|
|||
setValue = (value) => { |
|||
modelValue.value = value; |
|||
setObjectValueByValue(value); |
|||
}; |
|||
getValue = () => { |
|||
return modelValue.value; |
|||
}; |
|||
getObjectValue = () => { |
|||
return modelObjectValue.value; |
|||
}; |
|||
// 组件清空值 |
|||
clearValue = () => { |
|||
modelValue.value = undefined; |
|||
fieldMethodsClass.clearObjectValue(); |
|||
}; |
|||
// 清空显示值 |
|||
clearObjectValue = () => { |
|||
modelObjectValue.value = {}; |
|||
}; |
|||
} |
|||
const fieldMethodsClass = new FieldMethods(); |
|||
const valueUseColumnName = 'code'; |
|||
|
|||
const displayValueComputed = computed(() => { |
|||
if (modelObjectValue.value) { |
|||
return modelObjectValue.value['displayValue']; |
|||
} |
|||
return ''; |
|||
}); |
|||
|
|||
const getActualDisplayValue = (row) => { |
|||
return row['code'] + '(' + $t(row.code) + ')'; |
|||
}; |
|||
|
|||
const rowClick = (args) => { |
|||
const modelValue_ = args.row[valueUseColumnName]; |
|||
fieldMethodsClass.clearValue(); |
|||
modelValue.value = modelValue_; |
|||
modelObjectValue.value = { value: modelValue_, displayValue: getActualDisplayValue(args.row) }; |
|||
isShow.value = false; |
|||
}; |
|||
|
|||
watch( |
|||
() => modelValue.value, |
|||
(newVal, oldVal) => { |
|||
if (newVal !== oldVal) { |
|||
fieldMethodsClass.updateValue(newVal); |
|||
} |
|||
if (Tools.isEmpty(newVal) || (Array.isArray(modelValue.value) && modelValue.value.length === 0)) { |
|||
fieldMethodsClass.clearObjectValue(); |
|||
} else if (newVal !== oldVal) { |
|||
setObjectValueByValue(newVal); |
|||
} |
|||
}, |
|||
); |
|||
|
|||
// 根据实际值设置显示值 |
|||
const setObjectValueByValue = async (value) => { |
|||
if ((Array.isArray(value) && value.length > 0) || (typeof value === 'string' && !Tools.isEmpty(value))) { |
|||
fieldMethodsClass.clearObjectValue(); |
|||
const urlSearchParams = new URLSearchParams(); |
|||
urlSearchParams.append( |
|||
'criteria', |
|||
JSON.stringify({ |
|||
fieldName: valueUseColumnName, |
|||
operator: 'inSet', |
|||
value: Array.isArray(value) ? value : [value], |
|||
}), |
|||
); |
|||
const resp = await axios.get(dictionaryGridFetchDataUrl, { params: urlSearchParams }).catch((error) => { |
|||
console.info('error-------------', error); |
|||
}); |
|||
if (resp && resp.data) { |
|||
const responseData = resp.data; |
|||
if (Array.isArray(responseData) && responseData.length > 0) { |
|||
responseData.forEach((item) => { |
|||
modelObjectValue.value = { value: item[valueUseColumnName], displayValue: getActualDisplayValue(item) }; |
|||
}); |
|||
} else if (typeof responseData === 'object' && responseData.content?.length > 0) { |
|||
responseData.content.forEach((item) => { |
|||
modelObjectValue.value = { value: item[valueUseColumnName], displayValue: getActualDisplayValue(item) }; |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
onMounted(() => { |
|||
setObjectValueByValue(modelValue.value); |
|||
}); |
|||
|
|||
defineExpose({ |
|||
validate: fieldMethodsClass.validate, |
|||
setValue: fieldMethodsClass.setValue, |
|||
getValue: fieldMethodsClass.getValue, |
|||
getObjectValue: fieldMethodsClass.getObjectValue, |
|||
clearValue: fieldMethodsClass.clearValue, |
|||
}); |
|||
</script> |
@ -0,0 +1,29 @@ |
|||
<template> |
|||
<w-dialog ref="dialogRef" title="预览" width="90%" height="90%" body-padding="0px 0px 0px 0px"> |
|||
<w-grid ref="gridRef" v-bind="config"></w-grid> |
|||
</w-dialog> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { ref } from 'vue'; |
|||
import { Page } from './page'; |
|||
|
|||
const dialogRef = ref(); |
|||
const gridRef = ref(); |
|||
const config = ref({}); |
|||
|
|||
const show = async (data_) => { |
|||
const { templateConfig, templateGrid, templateGridFields } = data_; |
|||
const page = new Page(templateConfig, templateGrid, templateGridFields); |
|||
config.value = await page.buildGridConfig(); |
|||
dialogRef.value.show(); |
|||
}; |
|||
const hide = () => { |
|||
dialogRef.value.hide(); |
|||
}; |
|||
|
|||
defineExpose({ |
|||
show, |
|||
hide, |
|||
}); |
|||
</script> |
@ -0,0 +1,44 @@ |
|||
export class GridToolbar { |
|||
static type = { |
|||
separator: { label: '分割符', value: 'separator' }, |
|||
query: { label: '查询', value: 'query' }, |
|||
reset: { label: '重置', value: 'reset' }, |
|||
refresh: { label: '刷新', value: 'refresh' }, |
|||
add: { label: '新增', value: 'add' }, |
|||
edit: { label: '编辑', value: 'edit' }, |
|||
clone: { label: '复制', value: 'clone' }, |
|||
remove: { label: '删除', value: 'remove' }, |
|||
view: { label: '查看', value: 'view' }, |
|||
export: { label: '导出', value: 'export' }, |
|||
addTop: { label: '新增顶级节点', value: 'addTop' }, |
|||
addChild: { label: '新增子节点', value: 'addChild' }, |
|||
expand: { label: '展开/收起所有', value: 'expand' }, |
|||
config: { label: '表格设置', value: 'config' }, |
|||
}; |
|||
|
|||
/** |
|||
* 所有按钮集合 |
|||
*/ |
|||
static options: Array<any> = Object.values(this.type); |
|||
/** |
|||
* 排除分割符后的操作型按钮集合 |
|||
*/ |
|||
static operatorOptions: Array<any> = Object.values(this.type).filter((item) => item.value !== this.type.separator.value); |
|||
/** |
|||
* 字段来源为数据库表的默认按钮集合 |
|||
*/ |
|||
static tableDefaultOptions: Array<any> = [ |
|||
this.type.query.value, |
|||
this.type.reset.value, |
|||
this.type.separator.value, |
|||
this.type.add.value, |
|||
this.type.edit.value, |
|||
this.type.clone.value, |
|||
this.type.remove.value, |
|||
this.type.config.value, |
|||
]; |
|||
/** |
|||
* 字段来源为SQL的默认按钮集合 |
|||
*/ |
|||
static sqlDefaultOptions: Array<any> = [this.type.query.value, this.type.reset.value, this.type.config.value]; |
|||
} |
@ -0,0 +1,256 @@ |
|||
<template> |
|||
<div v-show="fieldMethodsClass.getShow(props, modelValue)"> |
|||
<q-input |
|||
ref="textSelectRef" |
|||
v-model="displayValueComputed" |
|||
:hide-bottom-space="true" |
|||
:hide-hint="true" |
|||
:outlined="true" |
|||
:dense="true" |
|||
:autogrow="true" |
|||
v-bind="attrs" |
|||
type="text" |
|||
:rules="fieldMethodsClass.getRules(props, { value: modelValue, displayValue: displayValueComputed }, textSelectRef, undefined)" |
|||
:readonly="fieldMethodsClass.getReadOnly(props, { value: modelValue, displayValue: displayValueComputed })" |
|||
:disable="fieldMethodsClass.getDisable(props, { value: modelValue, displayValue: displayValueComputed })" |
|||
:clearable="false" |
|||
> |
|||
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> |
|||
<template v-if="!props['form'] || props['form']?.getStatus() !== 'view'" #append> |
|||
<q-btn v-if="!Tools.isEmpty(displayValueComputed)" flat square unelevated dense icon="cancel" @click="fieldMethodsClass.clearValue"></q-btn> |
|||
<q-btn |
|||
flat |
|||
square |
|||
unelevated |
|||
dense |
|||
icon="settings_applications" |
|||
@click=" |
|||
() => { |
|||
dialogRef.show(); |
|||
nextTick(() => { |
|||
if (modelValue && modelValue.length > 0) { |
|||
const rows = <any>[]; |
|||
modelValue.forEach((item) => { |
|||
rows.push(GridToolbar.type[item]); |
|||
}); |
|||
gridRef.setLocalData(rows); |
|||
} |
|||
}); |
|||
} |
|||
" |
|||
></q-btn> |
|||
<w-dialog |
|||
ref="dialogRef" |
|||
title="按钮配置" |
|||
width="40%" |
|||
height="70%" |
|||
:can-maximize="false" |
|||
body-padding="5px 5px 5px 5px" |
|||
:buttons="[ |
|||
{ |
|||
label: '确定', |
|||
icon: 'beenhere', |
|||
click: () => { |
|||
const currRows = gridRef.getRows(); |
|||
const result = <any>[]; |
|||
currRows.forEach((row) => { |
|||
result.push(row.value); |
|||
}); |
|||
modelValue = result; |
|||
dialogRef.hide(); |
|||
}, |
|||
}, |
|||
]" |
|||
> |
|||
<w-grid |
|||
ref="gridRef" |
|||
title="按钮列表(拖拽可进行排序)" |
|||
:local-mode="true" |
|||
:dense="true" |
|||
dnd-mode="local" |
|||
:config-button="false" |
|||
:toolbar-actions="[ |
|||
[ |
|||
{ |
|||
extend: 'add', |
|||
label: '引入', |
|||
click: () => { |
|||
selectDialogRef.show(); |
|||
nextTick(() => { |
|||
const rows = <any>[]; |
|||
GridToolbar.options.forEach((button) => { |
|||
rows.push({ label: button.label, value: button.value }); |
|||
}); |
|||
selectGridRef.setLocalData(rows); |
|||
}); |
|||
}, |
|||
}, |
|||
{ |
|||
extend: 'add', |
|||
name: 'addAll', |
|||
label: '全部引入', |
|||
click: () => { |
|||
const rows = <any>[]; |
|||
GridToolbar.operatorOptions.forEach((button) => { |
|||
rows.push({ label: button.label, value: button.value }); |
|||
}); |
|||
gridRef.setLocalData(rows); |
|||
}, |
|||
}, |
|||
], |
|||
[ |
|||
{ |
|||
extend: 'remove', |
|||
click: (args: any) => { |
|||
args.grid.removeLocalData(args.grid.getTickedRows()); |
|||
}, |
|||
}, |
|||
{ |
|||
extend: 'remove', |
|||
name: 'removeAll', |
|||
enableIf: (args: any) => { |
|||
const rows = args.grid.getRows(); |
|||
if (rows.length > 0) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
label: '全部删除', |
|||
click: (args: any) => { |
|||
args.grid.removeLocalData(args.grid.getRows()); |
|||
}, |
|||
}, |
|||
], |
|||
]" |
|||
:columns="[ |
|||
{ |
|||
name: 'label', |
|||
label: '按钮', |
|||
sortable: false, |
|||
}, |
|||
]" |
|||
> |
|||
</w-grid> |
|||
<w-dialog |
|||
ref="selectDialogRef" |
|||
title="引入按钮" |
|||
width="30%" |
|||
height="65%" |
|||
:can-maximize="false" |
|||
body-padding="5px 5px 5px 5px" |
|||
:buttons="[ |
|||
{ |
|||
label: '确定', |
|||
icon: 'beenhere', |
|||
click: () => { |
|||
const rows = selectGridRef.getTickedRows(); |
|||
const currRows = gridRef.getRows(); |
|||
rows.forEach((row) => { |
|||
if ( |
|||
row.value === GridToolbar.type.separator.value || |
|||
(row.value !== GridToolbar.type.separator.value && currRows.findIndex((item) => item.value === row.value) < 0) |
|||
) { |
|||
gridRef.addLocalData({ label: row.label, value: row.value }); |
|||
} |
|||
}); |
|||
selectDialogRef.hide(); |
|||
}, |
|||
}, |
|||
]" |
|||
> |
|||
<w-grid |
|||
ref="selectGridRef" |
|||
:local-mode="true" |
|||
:dense="true" |
|||
:config-button="false" |
|||
:columns="[ |
|||
{ |
|||
name: 'label', |
|||
label: '按钮', |
|||
sortable: false, |
|||
}, |
|||
]" |
|||
> |
|||
</w-grid> |
|||
</w-dialog> |
|||
</w-dialog> |
|||
</template> |
|||
</q-input> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { ref, computed, useAttrs, watch, nextTick } from 'vue'; |
|||
import { Tools, FormFieldProps, FormFieldMethods } from 'platform-core'; |
|||
import { GridToolbar } from './GridToolbar'; |
|||
|
|||
const dialogRef = ref(); |
|||
const gridRef = ref(); |
|||
const selectDialogRef = ref(); |
|||
const selectGridRef = ref(); |
|||
const textSelectRef = ref(); |
|||
const attrs = useAttrs(); |
|||
const modelValue = defineModel<Array<string>>(); |
|||
|
|||
interface FieldProps extends FormFieldProps { |
|||
multiple?: boolean; |
|||
} |
|||
const props = withDefaults(defineProps<FieldProps>(), { |
|||
showIf: true, |
|||
multiple: false, // 是否允许多选,多选模式下模型绑定值必须为数组 |
|||
}); |
|||
class FieldMethods extends FormFieldMethods { |
|||
updateValue = (value_) => { |
|||
if (props['onUpdateValue']) { |
|||
props['onUpdateValue']({ |
|||
value: value_, |
|||
displayValue: displayValueComputed.value, |
|||
form: props['form'], |
|||
}); |
|||
} |
|||
}; |
|||
validate = () => { |
|||
return textSelectRef.value.validate(); |
|||
}; |
|||
|
|||
setValue = (value) => { |
|||
modelValue.value = value; |
|||
}; |
|||
getValue = () => { |
|||
return modelValue.value; |
|||
}; |
|||
clearValue = () => { |
|||
modelValue.value = []; |
|||
}; |
|||
} |
|||
const fieldMethodsClass = new FieldMethods(); |
|||
|
|||
const displayValueComputed = computed(() => { |
|||
let result = ''; |
|||
if (modelValue.value && modelValue.value.length > 0) { |
|||
result = '['; |
|||
modelValue.value.forEach((item) => { |
|||
result = result + GridToolbar.type[item].label + ','; |
|||
}); |
|||
result = result.substring(0, result.length - 1); |
|||
result += ']'; |
|||
} |
|||
return result; |
|||
}); |
|||
|
|||
watch( |
|||
() => modelValue.value, |
|||
(newVal, oldVal) => { |
|||
if (newVal !== oldVal) { |
|||
fieldMethodsClass.updateValue(newVal); |
|||
} |
|||
}, |
|||
); |
|||
|
|||
defineExpose({ |
|||
validate: fieldMethodsClass.validate, |
|||
setValue: fieldMethodsClass.setValue, |
|||
getValue: fieldMethodsClass.getValue, |
|||
clearValue: fieldMethodsClass.clearValue, |
|||
}); |
|||
</script> |
@ -0,0 +1,427 @@ |
|||
<template> |
|||
<div v-show="fieldMethodsClass.getShow(props, modelValue)"> |
|||
<q-input |
|||
ref="textSelectRef" |
|||
v-model="displayValueComputed" |
|||
:hide-bottom-space="true" |
|||
:hide-hint="true" |
|||
:outlined="true" |
|||
:dense="true" |
|||
:autogrow="true" |
|||
v-bind="attrs" |
|||
type="text" |
|||
:rules="fieldMethodsClass.getRules(props, { value: modelValue, displayValue: displayValueComputed }, textSelectRef, undefined)" |
|||
:readonly="fieldMethodsClass.getReadOnly(props, { value: modelValue, displayValue: displayValueComputed })" |
|||
:disable="fieldMethodsClass.getDisable(props, { value: modelValue, displayValue: displayValueComputed })" |
|||
:clearable="false" |
|||
> |
|||
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> |
|||
<template v-if="!props['form'] || props['form']?.getStatus() !== 'view'" #append> |
|||
<q-btn v-if="!Tools.isEmpty(displayValueComputed)" flat square unelevated dense icon="cancel" @click="fieldMethodsClass.clearValue"></q-btn> |
|||
<q-btn |
|||
flat |
|||
square |
|||
unelevated |
|||
dense |
|||
icon="settings_applications" |
|||
@click=" |
|||
() => { |
|||
const fields = getFields(); |
|||
if (fields.length > 0) { |
|||
dialogRef.show(); |
|||
nextTick(() => { |
|||
if (modelValue && modelValue.length > 0) { |
|||
const rows = <any>[]; |
|||
modelValue.forEach((item) => { |
|||
rows.push({ name: item['name'], label: item['label'], children: toRaw(item['columns']), isGroup: item['isGroup'] }); |
|||
}); |
|||
gridRef.setLocalData(rows); |
|||
} |
|||
}); |
|||
} else { |
|||
NotifyManager.warn('字段列表为空,无法进行多表头配置'); |
|||
} |
|||
} |
|||
" |
|||
></q-btn> |
|||
<w-dialog |
|||
ref="dialogRef" |
|||
title="多表头配置" |
|||
width="80%" |
|||
height="80%" |
|||
:can-maximize="false" |
|||
body-padding="5px 5px 5px 5px" |
|||
:buttons="[ |
|||
{ |
|||
label: '确定', |
|||
icon: 'beenhere', |
|||
click: () => { |
|||
const currRows = gridRef.getRows(); |
|||
const result = <any>[]; |
|||
currRows.forEach((row) => { |
|||
let children = []; |
|||
if (row['children']) { |
|||
children = toRaw(row['children']); |
|||
removeExtraField(children); |
|||
} |
|||
const tmp = { name: row['name'], label: row['label'], isGroup: row['isGroup'] }; |
|||
if (children.length > 0) { |
|||
tmp['columns'] = children; |
|||
} |
|||
result.push(tmp); |
|||
}); |
|||
modelValue = result; |
|||
dialogRef.hide(); |
|||
}, |
|||
}, |
|||
]" |
|||
> |
|||
<w-grid |
|||
ref="gridRef" |
|||
title="表头列表(拖拽可移动)" |
|||
:local-mode="true" |
|||
:dense="true" |
|||
:tree="true" |
|||
primary-key="name" |
|||
:tree-icon=" |
|||
(row) => { |
|||
if (row.isGroup) { |
|||
return { |
|||
name: 'bi-folder-fill', |
|||
color: 'amber', |
|||
}; |
|||
} |
|||
return { |
|||
name: 'note', |
|||
}; |
|||
} |
|||
" |
|||
dnd-mode="local" |
|||
:config-button="false" |
|||
:toolbar-actions="[ |
|||
{ |
|||
extend: 'add', |
|||
label: '新增', |
|||
}, |
|||
[ |
|||
{ |
|||
extend: 'remove', |
|||
click: (args: any) => { |
|||
const tickedRows = args.grid.getTickedRows(); |
|||
const selectedRows = args.grid.getSelectedRow(); |
|||
if (tickedRows.length > 0) { |
|||
args.grid.removeLocalData(tickedRows); |
|||
} else { |
|||
args.grid.removeLocalData(selectedRows); |
|||
} |
|||
}, |
|||
}, |
|||
{ |
|||
extend: 'remove', |
|||
name: 'removeAll', |
|||
enableIf: (args: any) => { |
|||
const rows = args.grid.getRows(); |
|||
if (rows.length > 0) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
label: '全部删除', |
|||
click: (args: any) => { |
|||
args.grid.removeLocalData(args.grid.getRows()); |
|||
}, |
|||
}, |
|||
], |
|||
'separator', |
|||
[ |
|||
{ |
|||
extend: 'add', |
|||
name: 'importColumn', |
|||
label: '引入', |
|||
click: () => { |
|||
selectDialogRef.show(); |
|||
nextTick(() => { |
|||
const result = getFields(); |
|||
selectGridRef.setLocalData(result); |
|||
}); |
|||
}, |
|||
}, |
|||
{ |
|||
extend: 'add', |
|||
name: 'importColumnAll', |
|||
label: '全部引入', |
|||
click: () => { |
|||
const result = getFields(); |
|||
importColumn(result); |
|||
}, |
|||
}, |
|||
], |
|||
'separator', |
|||
'expand', |
|||
]" |
|||
:columns="[ |
|||
{ |
|||
name: 'name', |
|||
label: '表头名称', |
|||
sortable: false, |
|||
}, |
|||
{ |
|||
name: 'label', |
|||
label: '页面显示名称', |
|||
sortable: false, |
|||
}, |
|||
{ |
|||
name: 'isGroup', |
|||
label: '是否分组表头', |
|||
showIf: false, |
|||
}, |
|||
]" |
|||
:editor="{ |
|||
dialog: { |
|||
title: '新增表头', |
|||
width: '30%', |
|||
height: '30%', |
|||
}, |
|||
form: { |
|||
colsNum: 1, |
|||
fields: [ |
|||
{ label: '字段名称', name: 'name', requiredIf: true, type: 'w-text' }, |
|||
{ label: '页面显示名称', name: 'label', requiredIf: true, type: 'w-text' }, |
|||
{ label: '是否分组表头', name: 'isGroup', showIf: false, defaultValue: true, type: 'w-checkbox' }, |
|||
], |
|||
}, |
|||
}" |
|||
@after-editor-open=" |
|||
(args) => { |
|||
const row = args.grid.getSelectedRow(); |
|||
if (row && row['isGroup']) { |
|||
// 将表单状态改为新增子节点 |
|||
args.grid.getEditorForm().setStatus('addChild'); |
|||
} |
|||
} |
|||
" |
|||
> |
|||
</w-grid> |
|||
<w-dialog |
|||
ref="selectDialogRef" |
|||
title="引入字段" |
|||
width="70%" |
|||
height="70%" |
|||
:can-maximize="false" |
|||
body-padding="5px 5px 5px 5px" |
|||
:buttons="[ |
|||
{ |
|||
label: '确定', |
|||
icon: 'beenhere', |
|||
click: () => { |
|||
const rows = selectGridRef.getTickedRows(); |
|||
importColumn(rows); |
|||
selectDialogRef.hide(); |
|||
}, |
|||
}, |
|||
]" |
|||
> |
|||
<w-grid |
|||
ref="selectGridRef" |
|||
:local-mode="true" |
|||
:dense="true" |
|||
:config-button="false" |
|||
:columns="[ |
|||
{ |
|||
name: 'fieldName', |
|||
label: '字段名称', |
|||
sortable: false, |
|||
}, |
|||
{ |
|||
name: 'fieldLabel', |
|||
label: '页面显示名称', |
|||
sortable: false, |
|||
}, |
|||
]" |
|||
> |
|||
</w-grid> |
|||
</w-dialog> |
|||
</w-dialog> |
|||
</template> |
|||
</q-input> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { ref, computed, useAttrs, watch, nextTick, inject, toRaw } from 'vue'; |
|||
import { Tools, FormFieldProps, FormFieldMethods, NotifyManager } from 'platform-core'; |
|||
import { FormConfig } from './ts/FormConfig'; |
|||
|
|||
const dialogRef = ref(); |
|||
const gridRef = ref(); |
|||
const selectDialogRef = ref(); |
|||
const selectGridRef = ref(); |
|||
const textSelectRef = ref(); |
|||
const attrs = useAttrs(); |
|||
const modelValue = defineModel<Array<any>>(); |
|||
const formConfig = <FormConfig>inject('formConfig'); |
|||
|
|||
interface FieldProps extends FormFieldProps { |
|||
multiple?: boolean; |
|||
} |
|||
const props = withDefaults(defineProps<FieldProps>(), { |
|||
showIf: true, |
|||
multiple: false, // 是否允许多选,多选模式下模型绑定值必须为数组 |
|||
}); |
|||
class FieldMethods extends FormFieldMethods { |
|||
updateValue = (value_) => { |
|||
if (props['onUpdateValue']) { |
|||
props['onUpdateValue']({ |
|||
value: value_, |
|||
displayValue: displayValueComputed.value, |
|||
form: props['form'], |
|||
}); |
|||
} |
|||
}; |
|||
validate = () => { |
|||
return textSelectRef.value.validate(); |
|||
}; |
|||
|
|||
setValue = (value) => { |
|||
modelValue.value = value; |
|||
}; |
|||
getValue = () => { |
|||
return modelValue.value; |
|||
}; |
|||
clearValue = () => { |
|||
modelValue.value = []; |
|||
}; |
|||
} |
|||
const fieldMethodsClass = new FieldMethods(); |
|||
|
|||
const displayValueComputed = computed(() => { |
|||
let result = ''; |
|||
if (modelValue.value && modelValue.value.length > 0) { |
|||
result = `已配置${modelValue.value.length}列`; |
|||
} |
|||
return result; |
|||
}); |
|||
|
|||
watch( |
|||
() => modelValue.value, |
|||
(newVal, oldVal) => { |
|||
if (newVal !== oldVal) { |
|||
fieldMethodsClass.updateValue(newVal); |
|||
} |
|||
}, |
|||
); |
|||
|
|||
const removeExtraField = (arr: Array<any>) => { |
|||
if (arr && arr.length > 0) { |
|||
arr.forEach((item: any) => { |
|||
if (item.children && item.children.length > 0) { |
|||
removeExtraField(item.children); |
|||
} else { |
|||
removeFields(item); |
|||
} |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
const removeFields = (target: any) => { |
|||
if (Tools.hasOwnProperty(target, '_rowKey_')) { |
|||
delete target['_rowKey_']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, 'expand')) { |
|||
delete target['expand']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, '_tickedCount')) { |
|||
delete target['_tickedCount']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, '_childrenTickedCount')) { |
|||
delete target['_childrenTickedCount']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, '_rowOldValue')) { |
|||
delete target['_rowOldValue']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, '_rowIndex')) { |
|||
delete target['_rowIndex']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, '_lazyloadNoChildren')) { |
|||
delete target['_lazyloadNoChildren']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, '_selectable')) { |
|||
delete target['_selectable']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, '_treeTickable')) { |
|||
delete target['_treeTickable']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, 'ticked')) { |
|||
delete target['ticked']; |
|||
} |
|||
if (Tools.hasOwnProperty(target, 'selected')) { |
|||
delete target['selected']; |
|||
} |
|||
}; |
|||
|
|||
// 获取字段列表中的数据 |
|||
const getFields = () => { |
|||
const rows = formConfig.cf.getFieldGridRef().getRows(); |
|||
const result = <any>[]; |
|||
rows.forEach((row) => { |
|||
result.push({ fieldName: row['fieldName'], fieldLabel: row['fieldLabel'] }); |
|||
}); |
|||
return result; |
|||
}; |
|||
|
|||
const importColumn = (rows: Array<any>) => { |
|||
const row = gridRef.value.getSelectedRow(); |
|||
const result = <any>[]; |
|||
if (rows.length > 0) { |
|||
const currRows = gridRef.value.getRows(); |
|||
const columns = getColumn(currRows); |
|||
rows.forEach((item) => { |
|||
if (columns.findIndex((tmp) => tmp['name'] === item['fieldName']) < 0) { |
|||
const tmp = { name: item['fieldName'], label: item['fieldLabel'] }; |
|||
if (row && row['isGroup']) { |
|||
tmp['parent'] = row['name']; |
|||
} |
|||
result.push(tmp); |
|||
} |
|||
}); |
|||
} |
|||
if (result.length > 0) { |
|||
gridRef.value.addLocalData(result); |
|||
} else { |
|||
NotifyManager.info('列表中已经存在的字段已被忽略'); |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* 获取将父子列全部平铺后的表格列数据 |
|||
* @param columns |
|||
*/ |
|||
const getColumn = (columns: Array<any>) => { |
|||
const gridColumns = <any>[]; |
|||
if (columns && columns.length > 0) { |
|||
columns.forEach((item: any) => { |
|||
childrenHandler(item, gridColumns); |
|||
}); |
|||
return gridColumns; |
|||
} |
|||
return []; |
|||
}; |
|||
|
|||
// 孩子列处理 |
|||
const childrenHandler = (item: any, gridColumns: any) => { |
|||
if (item.children && item.children.length > 0) { |
|||
item.children.forEach((column) => { |
|||
childrenHandler(column, gridColumns); |
|||
}); |
|||
} else { |
|||
gridColumns.push({ name: item.name, label: item.label }); |
|||
} |
|||
}; |
|||
|
|||
defineExpose({ |
|||
validate: fieldMethodsClass.validate, |
|||
setValue: fieldMethodsClass.setValue, |
|||
getValue: fieldMethodsClass.getValue, |
|||
clearValue: fieldMethodsClass.clearValue, |
|||
}); |
|||
</script> |
@ -0,0 +1,120 @@ |
|||
<template> |
|||
<w-dialog ref="dialogRef" :title="title" :maximized="true" :can-maximize="false" body-padding="5px 5px 0px 5px" :buttons="buttonsComputed"> |
|||
<w-splitter :model-value="20"> |
|||
<template #before> |
|||
<Form></Form> |
|||
</template> |
|||
<template #after> |
|||
<FieldGrid class="pl-1"> </FieldGrid> |
|||
</template> |
|||
</w-splitter> |
|||
<ViewDialog ref="viewDialogRef"></ViewDialog> |
|||
</w-dialog> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref, provide, getCurrentInstance, nextTick, computed } from 'vue'; |
|||
import { Tools, NotifyManager, VueTools } from 'platform-core'; |
|||
import { FormConfig } from './ts/FormConfig'; |
|||
import Form from './Form.vue'; |
|||
import FieldGrid from './FieldGrid.vue'; |
|||
import ViewDialog from '../ViewDialog.vue'; |
|||
|
|||
const dialogRef = ref(); |
|||
const viewDialogRef = ref(); |
|||
const emit = defineEmits(['refresh-grid']); |
|||
const formConfig = new FormConfig(); |
|||
const title = ref('新增'); |
|||
const editFlag = ref(false); |
|||
|
|||
const saveButton = { |
|||
icon: 'save', |
|||
label: '保存', |
|||
loading: false, |
|||
click: () => { |
|||
formConfig.api.save(); |
|||
}, |
|||
}; |
|||
const viewButton = { |
|||
icon: 'visibility', |
|||
label: '预览', |
|||
click: () => { |
|||
view(); |
|||
}, |
|||
}; |
|||
|
|||
const buttonsComputed = computed(() => { |
|||
if (!editFlag.value) { |
|||
return [saveButton]; |
|||
} else { |
|||
return [saveButton, viewButton]; |
|||
} |
|||
}); |
|||
|
|||
const view = () => { |
|||
const rows = formConfig.cf.getFieldGridRef().getRows(); |
|||
if (!rows || rows.length === 0) { |
|||
NotifyManager.warn('字段列表为空'); |
|||
return; |
|||
} |
|||
if (Tools.isEmpty(formConfig.editId) || Tools.isEmpty(formConfig.editGridId)) { |
|||
NotifyManager.warn('保存后才可预览'); |
|||
return; |
|||
} |
|||
const data = formConfig.api.buildSaveData(); |
|||
viewDialogRef.value.show(data); |
|||
}; |
|||
|
|||
const show = async (selected: any) => { |
|||
dialogRef.value.show(); |
|||
if (selected) { |
|||
editFlag.value = true; |
|||
title.value = '编辑'; |
|||
formConfig.editId = selected.id; |
|||
const data = await formConfig.api.fetchFormConfigData(); |
|||
formConfig.editGridId = data['templateGrid'].id; |
|||
nextTick(() => { |
|||
const gridConfigData = data['templateGrid']; |
|||
const fields = data['templateGridFields']; |
|||
formConfig.cf.getTemplateConfigFormRef().setData({ ...data['templateConfig'], ...gridConfigData }); |
|||
if (gridConfigData.columnTitles) { |
|||
const titles = JSON.parse(gridConfigData.columnTitles); |
|||
if (Tools.hasOwnProperty(titles, 'value')) { |
|||
gridConfigData.columnTitles = titles.value; |
|||
} else { |
|||
gridConfigData.columnTitles = []; |
|||
} |
|||
} else { |
|||
gridConfigData.columnTitles = []; |
|||
} |
|||
formConfig.cf.getMainConfigFormRef().setData(gridConfigData); |
|||
formConfig.cf.getPageSortConfigFormRef().setData(gridConfigData); |
|||
formConfig.cf.getQueryConfigFormRef().setData(gridConfigData); |
|||
formConfig.cf.getEditConfigFormRef().setData(gridConfigData); |
|||
console.info('222fields=========', fields); |
|||
formConfig.cf.getFieldGridRef().setLocalData(fields); |
|||
const names = fields.map((item) => item.fieldName); |
|||
formConfig.cf.setPrimaryKeyOptions(names); |
|||
}); |
|||
} |
|||
}; |
|||
const hide = () => { |
|||
dialogRef.value.hide(); |
|||
}; |
|||
|
|||
defineExpose({ |
|||
show, |
|||
hide, |
|||
}); |
|||
|
|||
// 获得自身实例 |
|||
const instance = getCurrentInstance(); |
|||
// 将对外暴露API添加至自身实例中 |
|||
VueTools.expose2Instance(instance); |
|||
|
|||
const getDialogRef = () => { |
|||
return instance; |
|||
}; |
|||
formConfig.cf.getDialogRef = getDialogRef; |
|||
|
|||
provide('formConfig', formConfig); |
|||
</script> |
@ -0,0 +1,318 @@ |
|||
<template> |
|||
<w-dialog |
|||
ref="dialogRef" |
|||
title="字段属性编辑" |
|||
width="80%" |
|||
height="80%" |
|||
body-padding="5px 5px 5px 5px" |
|||
:buttons="[ |
|||
{ |
|||
label: '确定', |
|||
icon: 'beenhere', |
|||
click: () => { |
|||
save(); |
|||
}, |
|||
}, |
|||
]" |
|||
> |
|||
<w-form |
|||
ref="formRef" |
|||
:cols-num="3" |
|||
:fields="[ |
|||
{ |
|||
type: 'w-form-group', |
|||
mode: 'card', |
|||
layout: 'form', |
|||
headerBgColor: 'green', |
|||
colsNum: 2, |
|||
colSpan: 'full', |
|||
label: '基础属性', |
|||
fields: [ |
|||
{ name: 'fieldName', label: '字段名称', type: 'w-text', readOnlyIf: true }, |
|||
{ |
|||
name: 'sqlType', |
|||
label: '数据库类型', |
|||
type: 'w-text', |
|||
readOnlyIf: true, |
|||
showIf: () => { |
|||
if (formConfig.cm.fieldComeFromValueComputed.value === 'table') { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ name: 'fieldLabel', label: '页面显示名称', type: 'w-text' }, |
|||
{ name: 'editorFormType', label: '前端组件', type: 'w-select', options: ComponentType.options }, |
|||
{ name: 'fieldType', label: 'Java类型', type: 'w-select', options: JavaType.options }, |
|||
{ |
|||
name: 'fieldLength', |
|||
label: '字段长度', |
|||
type: 'w-integer', |
|||
showIf: (args: any) => { |
|||
if (args.form?.getFieldValue('fieldType') === JavaType.type.String.value && formConfig.cm.fieldComeFromValueComputed.value === 'table') { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'fieldPrecision', |
|||
label: '字段精度', |
|||
type: 'w-integer', |
|||
showIf: (args: any) => { |
|||
if (args.form?.getFieldValue('fieldType') === JavaType.type.BigDecimal.value && formConfig.cm.fieldComeFromValueComputed.value === 'table') { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ name: 'optionComeFrom', label: '码值类型', type: 'w-select', options: DictionaryType.options }, |
|||
{ |
|||
label: '码值', |
|||
name: 'dictionaryOptionValue', |
|||
type: 'w-select', |
|||
options: [ |
|||
{ label: 'XX状态', value: 'xx' }, |
|||
{ label: 'AA类型', value: 'aa' }, |
|||
], |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('optionComeFrom') === DictionaryType.type.dictionary.value) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '码值', |
|||
name: 'otherOptionValue', |
|||
type: 'w-text', |
|||
hideHint: true, |
|||
showIf: (args) => { |
|||
if ( |
|||
args.form?.getFieldValue('optionComeFrom') === DictionaryType.type.array.value || |
|||
args.form?.getFieldValue('optionComeFrom') === DictionaryType.type.sql.value |
|||
) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
], |
|||
}, |
|||
{ |
|||
type: 'q-space', |
|||
colSpan: 'full', |
|||
}, |
|||
{ |
|||
type: 'q-space', |
|||
colSpan: 'full', |
|||
}, |
|||
{ |
|||
type: 'q-space', |
|||
colSpan: 'full', |
|||
}, |
|||
{ |
|||
type: 'w-form-group', |
|||
mode: 'card', |
|||
headerBgColor: 'red', |
|||
layout: 'form', |
|||
colsNum: 1, |
|||
label: '查询面板', |
|||
fields: [ |
|||
{ |
|||
label: '查询面板中显示', |
|||
name: 'queryShow', |
|||
type: 'w-checkbox', |
|||
}, |
|||
{ |
|||
label: '默认值', |
|||
name: 'queryDefaultValue', |
|||
type: 'w-text', |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('queryShow') === true) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '是否为必填项', |
|||
name: 'queryIsRequired', |
|||
type: 'w-select', |
|||
defaultValue: false, |
|||
options: [ |
|||
{ label: '是', value: true }, |
|||
{ label: '否', value: false }, |
|||
], |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('queryShow') === true) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '匹配模式', |
|||
name: 'queryOperator', |
|||
type: 'w-select', |
|||
defaultValue: 'contains', |
|||
options: [ |
|||
{ label: '模糊匹配', value: 'contains' }, |
|||
{ label: '完全匹配', value: 'equals' }, |
|||
], |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('queryShow') === true) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
], |
|||
}, |
|||
{ |
|||
type: 'w-form-group', |
|||
mode: 'card', |
|||
headerBgColor: 'orange', |
|||
layout: 'form', |
|||
colsNum: 1, |
|||
label: '列表', |
|||
fields: [ |
|||
{ |
|||
label: '列表中显示', |
|||
name: 'tableShow', |
|||
type: 'w-checkbox', |
|||
}, |
|||
{ |
|||
label: '是否支持排序', |
|||
name: 'tableSort', |
|||
defaultValue: true, |
|||
type: 'w-select', |
|||
options: [ |
|||
{ label: '是', value: true }, |
|||
{ label: '否', value: false }, |
|||
], |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('tableShow') === true) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '列对齐方式', |
|||
name: 'tableColumnAlign', |
|||
defaultValue: 'left', |
|||
type: 'w-select', |
|||
options: [ |
|||
{ label: '居左', value: 'left' }, |
|||
{ label: '居中', value: 'center' }, |
|||
{ label: '居右', value: 'right' }, |
|||
], |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('tableShow') === true) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '列宽', |
|||
name: 'tableColumnWidth', |
|||
type: 'w-integer', |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('tableShow') === true) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
], |
|||
}, |
|||
{ |
|||
type: 'w-form-group', |
|||
mode: 'card', |
|||
headerBgColor: 'teal', |
|||
layout: 'form', |
|||
colsNum: 1, |
|||
label: '编辑页面', |
|||
fields: [ |
|||
{ |
|||
label: '编辑页面中显示', |
|||
name: 'editorShow', |
|||
type: 'w-checkbox', |
|||
disableIf: () => { |
|||
return formConfig.cm.fieldComeFromValueComputed.value === 'sql'; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '默认值', |
|||
name: 'editorDefaultValue', |
|||
type: 'w-text', |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('editorShow') === true) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '是否为必填项', |
|||
name: 'editorIsRequired', |
|||
type: 'w-select', |
|||
options: [ |
|||
{ label: '是', value: true }, |
|||
{ label: '否', value: false }, |
|||
], |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('editorShow') === true) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
], |
|||
}, |
|||
]" |
|||
> |
|||
</w-form> |
|||
</w-dialog> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { ref, inject, nextTick } from 'vue'; |
|||
import { FormConfig } from './ts/FormConfig'; |
|||
import { JavaType } from './ts/JavaType'; |
|||
import { DictionaryType } from './ts/DictionaryType'; |
|||
import { ComponentType } from './ts/ComponentType'; |
|||
|
|||
const dialogRef = ref(); |
|||
const formRef = ref(); |
|||
const formConfig = <FormConfig>inject('formConfig'); |
|||
const data = ref({}); |
|||
|
|||
const save = async () => { |
|||
const validate = await formRef.value.validate(); |
|||
if (validate) { |
|||
const formData = formRef.value.getData(); |
|||
data.value = { ...data.value, ...formData }; |
|||
formConfig.cf.getFieldGridRef().updateLocalData(data.value); |
|||
dialogRef.value.hide(); |
|||
} |
|||
}; |
|||
|
|||
const show = (data_) => { |
|||
data.value = data_; |
|||
dialogRef.value.show(); |
|||
nextTick(() => { |
|||
formRef.value.setData(data_); |
|||
}); |
|||
}; |
|||
const hide = () => { |
|||
dialogRef.value.hide(); |
|||
}; |
|||
|
|||
defineExpose({ |
|||
show, |
|||
hide, |
|||
}); |
|||
</script> |
@ -0,0 +1,508 @@ |
|||
<template> |
|||
<div class="pr-1"> |
|||
<q-list bordered class="rounded-borders"> |
|||
<q-expansion-item default-opened expand-separator icon="settings" label="模板配置" header-class="text-green"> |
|||
<div class="p-1"> |
|||
<w-form |
|||
ref="templateRef" |
|||
:cols-num="1" |
|||
:fields="[ |
|||
{ |
|||
label: '模板名称', |
|||
name: 'templateName', |
|||
type: 'w-text', |
|||
requiredIf: true, |
|||
}, |
|||
{ |
|||
label: '模板类型', |
|||
name: 'templateType', |
|||
type: 'w-select', |
|||
requiredIf: true, |
|||
showIf: false, |
|||
defaultValue: 'GRID', |
|||
options: [{ label: '表格页面模板', value: 'GRID' }], |
|||
}, |
|||
{ |
|||
label: '页面加载类型', |
|||
name: 'pageLoadType', |
|||
type: 'w-select', |
|||
requiredIf: true, |
|||
showIf: false, |
|||
defaultValue: 'CONFIG', |
|||
options: [ |
|||
{ label: '配置加载', value: 'CONFIG' }, |
|||
{ label: 'JSON字符串加载', value: 'JSON' }, |
|||
], |
|||
}, |
|||
{ |
|||
label: '字段来源', |
|||
name: 'fieldComeFrom', |
|||
type: 'w-select', |
|||
requiredIf: true, |
|||
defaultValue: 'table', |
|||
options: [ |
|||
{ label: '数据库单表', value: 'table' }, |
|||
{ label: 'SQL语句', value: 'sql' }, |
|||
], |
|||
onUpdateValue: (args) => { |
|||
if (args.value === 'table') { |
|||
formConfig.cf.getMainConfigFormRef().getFieldComponent('buttons').setValue(GridToolbar.tableDefaultOptions); |
|||
} else if (args.value === 'sql') { |
|||
formConfig.cf.getMainConfigFormRef().getFieldComponent('buttons').setValue(GridToolbar.sqlDefaultOptions); |
|||
} |
|||
}, |
|||
}, |
|||
{ |
|||
label: '数据库表', |
|||
name: 'databaseTable', |
|||
type: 'w-db-table-select', |
|||
requiredIf: true, |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('fieldComeFrom') === 'sql') { |
|||
return false; |
|||
} |
|||
return true; |
|||
}, |
|||
onUpdateValue: (args) => { |
|||
const fields = args.form.getFieldComponent('databaseTable').getFields(); |
|||
if (fields && fields.length > 0) { |
|||
formConfig.fm.setFieldGridData(fields); |
|||
const names = fields.map((item) => item.name); |
|||
formConfig.cf.setPrimaryKeyOptions(names); |
|||
} |
|||
}, |
|||
}, |
|||
{ |
|||
label: 'SQL', |
|||
name: 'sql', |
|||
type: 'w-code-mirror', |
|||
lang: 'sql', |
|||
toolbar: false, |
|||
requiredIf: true, |
|||
hint: `当查询面板配置了字段时,需要把查询条件通过占位符放到sql中,在页面中真正查询数据时才能带上用户输入的查询条件,示例:select u.loginname_,r.name_ from sys_user_role ur join sys_user u on ur.user_id_=u.id_ join sys_role r on ur.role_id_=r.id_ where u.loginname_='#{loginname_}' and r.name_ like '%#{name_}%'`, |
|||
hideHint: true, |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('fieldComeFrom') === 'sql') { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
slot: { |
|||
append: { |
|||
componentType: 'q-btn', |
|||
attrs: { |
|||
dense: true, |
|||
label: '查询', |
|||
icon: 'search', |
|||
color: 'primary', |
|||
onClick: () => { |
|||
const sql = templateRef.getFieldValue('sql'); |
|||
formConfig.api.loadFields(sql); |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
]" |
|||
> |
|||
</w-form> |
|||
</div> |
|||
</q-expansion-item> |
|||
|
|||
<q-expansion-item default-opened expand-separator icon="grid_on" label="表格配置" header-class="text-light-blue"> |
|||
<div class="p-1"> |
|||
<div class="flex justify-end p-2"> |
|||
<q-toggle v-model="mainConfigToggleModelValue" dense label="全部配置" /> |
|||
</div> |
|||
<w-form |
|||
ref="mainConfigFormRef" |
|||
:cols-num="1" |
|||
:fields="[ |
|||
{ label: '表格标题', name: 'title', type: 'w-text' }, |
|||
{ |
|||
label: '数据主键', |
|||
name: 'primaryKey', |
|||
type: 'w-select', |
|||
options: primaryKeyOptions, |
|||
}, |
|||
{ |
|||
label: '表格按钮', |
|||
name: 'buttons', |
|||
defaultValue: GridToolbar.tableDefaultOptions, |
|||
type: markRawGridToolbarSelect, |
|||
}, |
|||
{ |
|||
type: 'w-form-group', |
|||
layout: 'form', |
|||
colsNum: 2, |
|||
fields: [ |
|||
{ |
|||
label: '显示序号', |
|||
name: 'sortNo', |
|||
type: 'w-checkbox', |
|||
defaultValue: true, |
|||
}, |
|||
{ |
|||
label: '显示复选框', |
|||
name: 'checkboxSelection', |
|||
type: 'w-checkbox', |
|||
defaultValue: true, |
|||
}, |
|||
], |
|||
}, |
|||
{ |
|||
label: '多表头', |
|||
name: 'moreColumnTitle', |
|||
type: 'w-select', |
|||
defaultValue: false, |
|||
options: [ |
|||
{ label: '启用', value: true }, |
|||
{ label: '禁用', value: false }, |
|||
], |
|||
}, |
|||
{ |
|||
label: '多表头配置', |
|||
name: 'columnTitles', |
|||
requiredIf: true, |
|||
type: markRawColumnTitleConfig, |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('moreColumnTitle')) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '紧凑模式', |
|||
name: 'dense', |
|||
type: 'w-checkbox-group', |
|||
defaultValue: ['denseToolbar'], |
|||
simple: false, |
|||
showIf: () => { |
|||
if (mainConfigToggleModelValue) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
options: [ |
|||
{ label: '整体紧凑', value: 'dense' }, |
|||
{ label: '按钮栏紧凑', value: 'denseToolbar' }, |
|||
{ label: '标题紧凑', value: 'denseHeader' }, |
|||
{ label: '内容紧凑', value: 'denseBody' }, |
|||
{ label: '分页栏紧凑', value: 'denseBottom' }, |
|||
], |
|||
}, |
|||
{ |
|||
label: '冻结列数', |
|||
name: 'stickyNum', |
|||
type: 'w-select', |
|||
defaultValue: 0, |
|||
showIf: () => { |
|||
if (mainConfigToggleModelValue) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
options: [ |
|||
{ label: '不冻结', value: 0 }, |
|||
{ label: '冻结1列', value: 1 }, |
|||
{ label: '冻结2列', value: 2 }, |
|||
{ label: '冻结3列', value: 3 }, |
|||
{ label: '冻结4列', value: 4 }, |
|||
{ label: '冻结5列', value: 5 }, |
|||
{ label: '冻结6列', value: 6 }, |
|||
{ label: '冻结7列', value: 7 }, |
|||
{ label: '冻结8列', value: 8 }, |
|||
{ label: '冻结8列', value: 9 }, |
|||
{ label: '冻结10列', value: 10 }, |
|||
], |
|||
}, |
|||
{ |
|||
label: '表格模式', |
|||
name: 'tree', |
|||
type: 'w-select', |
|||
defaultValue: false, |
|||
showIf: () => { |
|||
if (mainConfigToggleModelValue) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
options: [ |
|||
{ label: '普通表格', value: false }, |
|||
{ label: '树形表格', value: true }, |
|||
], |
|||
}, |
|||
{ |
|||
label: '数据外键', |
|||
name: 'foreignKey', |
|||
type: 'w-text', |
|||
showIf: (args) => { |
|||
if (mainConfigToggleModelValue && args.form?.getFieldValue('tree')) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
defaultValue: 'parent', |
|||
hint: `树形表格模式时,该字段为构建树数据的关系字段`, |
|||
}, |
|||
{ |
|||
label: '树形表格数据关系', |
|||
name: 'treeRelationship', |
|||
type: 'w-select', |
|||
defaultValue: 'parent', |
|||
showIf: (args) => { |
|||
if (mainConfigToggleModelValue && args.form?.getFieldValue('tree')) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
options: [ |
|||
{ label: 'parent', value: 'parent' }, |
|||
{ label: 'children', value: 'children' }, |
|||
], |
|||
}, |
|||
{ |
|||
label: '树形表格默认全部展开', |
|||
name: 'treeDefaultExpandAll', |
|||
type: 'w-checkbox', |
|||
showIf: (args) => { |
|||
if (mainConfigToggleModelValue && args.form?.getFieldValue('tree')) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '数据操作URL前缀', |
|||
name: 'dataUrl', |
|||
type: 'w-text', |
|||
showIf: false, |
|||
defaultValue: '', |
|||
}, |
|||
{ |
|||
label: '查询URL', |
|||
name: 'fetchDataUrl', |
|||
type: 'w-text', |
|||
showIf: false, |
|||
defaultValue: 'api/jdbc/list', |
|||
}, |
|||
{ |
|||
label: '新增URL', |
|||
name: 'addDataUrl', |
|||
type: 'w-text', |
|||
showIf: false, |
|||
defaultValue: 'api/jdbc/add', |
|||
}, |
|||
{ |
|||
label: '编辑URL', |
|||
name: 'editDataUrl', |
|||
type: 'w-text', |
|||
showIf: false, |
|||
defaultValue: 'api/jdbc/edit', |
|||
}, |
|||
{ |
|||
label: '删除URL', |
|||
name: 'removeDataUrl', |
|||
type: 'w-text', |
|||
showIf: false, |
|||
defaultValue: 'api/jdbc/delete', |
|||
}, |
|||
{ |
|||
label: '自动加载数据', |
|||
name: 'autoFetchData', |
|||
type: 'w-checkbox', |
|||
showIf: false, |
|||
defaultValue: true, |
|||
}, |
|||
]" |
|||
> |
|||
</w-form> |
|||
</div> |
|||
</q-expansion-item> |
|||
|
|||
<q-expansion-item expand-separator icon="auto_stories" label="分页排序" header-class="text-purple"> |
|||
<div class="p-1"> |
|||
<w-form |
|||
ref="pageSortConfigFormRef" |
|||
:cols-num="1" |
|||
:fields="[ |
|||
{ |
|||
label: '默认排序字段', |
|||
name: 'defaultSortBy', |
|||
type: 'w-text', |
|||
hint: `示例:单字段默认排序:['username'],多字段默认排序:['username', '-date'],其中'-date'的中'-'代表倒序`, |
|||
}, |
|||
{ |
|||
label: '排序方式', |
|||
name: 'descending', |
|||
type: 'w-select', |
|||
defaultValue: false, |
|||
options: [ |
|||
{ label: '正序', value: false }, |
|||
{ label: '倒序', value: true }, |
|||
], |
|||
}, |
|||
{ |
|||
label: '是否分页', |
|||
name: 'pageable', |
|||
type: 'w-select', |
|||
defaultValue: true, |
|||
options: [ |
|||
{ label: '是', value: true }, |
|||
{ label: '否', value: false }, |
|||
], |
|||
}, |
|||
{ |
|||
label: '每页显示行数', |
|||
name: 'rowsPerPage', |
|||
type: 'w-number', |
|||
defaultValue: 10, |
|||
showIf: (args) => { |
|||
if (args.form?.getFieldValue('pageable')) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
}, |
|||
{ |
|||
label: '后端使用的初始页码', |
|||
name: 'reqPageStart', |
|||
type: 'w-select', |
|||
defaultValue: 1, |
|||
options: [ |
|||
{ label: '从1开始', value: 1 }, |
|||
{ label: '从0开始', value: 0 }, |
|||
], |
|||
showIf: (args) => { |
|||
// if ( |
|||
// args.form?.getFieldValue('pageable') |
|||
// ) { |
|||
// return true; |
|||
// } |
|||
return false; |
|||
}, |
|||
}, |
|||
]" |
|||
> |
|||
</w-form> |
|||
</div> |
|||
</q-expansion-item> |
|||
|
|||
<q-expansion-item expand-separator icon="find_in_page" label="查询面板" header-class="text-teal"> |
|||
<div class="p-1"> |
|||
<w-form |
|||
ref="queryConfigFormRef" |
|||
:cols-num="1" |
|||
:fields="[ |
|||
{ |
|||
label: '一行显示条件个数', |
|||
name: 'queryFormColsNum', |
|||
type: 'w-select', |
|||
defaultValue: 0, |
|||
options: [ |
|||
{ label: '自适应', value: 0 }, |
|||
{ label: '1个', value: 1 }, |
|||
{ label: '2个', value: 2 }, |
|||
{ label: '3个', value: 3 }, |
|||
{ label: '4个', value: 4 }, |
|||
{ label: '5个', value: 5 }, |
|||
{ label: '6个', value: 6 }, |
|||
], |
|||
}, |
|||
{ |
|||
label: '查询条件默认行数', |
|||
name: 'queryFormRowNum', |
|||
type: 'w-number', |
|||
defaultValue: 1, |
|||
}, |
|||
]" |
|||
> |
|||
</w-form> |
|||
</div> |
|||
</q-expansion-item> |
|||
|
|||
<q-expansion-item expand-separator icon="edit_document" label="编辑页面" header-class="text-orange"> |
|||
<div class="p-1"> |
|||
<w-form |
|||
ref="editConfigFormRef" |
|||
:cols-num="1" |
|||
:fields="[ |
|||
{ |
|||
label: '窗口宽度', |
|||
name: 'editorWidth', |
|||
type: 'w-text', |
|||
hint: '不设置根据内容自动撑;支持设置百分比,示例:80%;也支持设置像素点,示例:500px', |
|||
}, |
|||
{ |
|||
label: '窗口高度', |
|||
name: 'editorHeight', |
|||
type: 'w-text', |
|||
hint: '不设置根据内容自动撑;支持设置百分比,示例:80%;也支持设置像素点,示例:500px', |
|||
}, |
|||
{ |
|||
label: '一行显示元素个数', |
|||
name: 'editorFormColsNum', |
|||
type: 'w-select', |
|||
defaultValue: 1, |
|||
options: [ |
|||
{ label: '自适应', value: 0 }, |
|||
{ label: '1个', value: 1 }, |
|||
{ label: '2个', value: 2 }, |
|||
{ label: '3个', value: 3 }, |
|||
{ label: '4个', value: 4 }, |
|||
{ label: '5个', value: 5 }, |
|||
{ label: '6个', value: 6 }, |
|||
], |
|||
}, |
|||
]" |
|||
> |
|||
</w-form> |
|||
</div> |
|||
</q-expansion-item> |
|||
</q-list> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { inject, ref, computed, markRaw } from 'vue'; |
|||
import { Options } from 'platform-core'; |
|||
import { FormConfig } from './ts/FormConfig'; |
|||
import GridToolbarSelect from '../components/GridToolbarSelect.vue'; |
|||
import { GridToolbar } from '@/views/form/components/GridToolbar'; |
|||
import ColumnTitleConfig from './ColumnTitleConfig.vue'; |
|||
|
|||
const markRawGridToolbarSelect = markRaw(GridToolbarSelect); |
|||
const markRawColumnTitleConfig = markRaw(ColumnTitleConfig); |
|||
const templateRef = ref(); |
|||
const mainConfigFormRef = ref(); |
|||
const pageSortConfigFormRef = ref(); |
|||
const queryConfigFormRef = ref(); |
|||
const editConfigFormRef = ref(); |
|||
const mainConfigToggleModelValue = ref(false); |
|||
const primaryKeyOptions = ref(<any>[]); |
|||
const formConfig = <FormConfig>inject('formConfig'); |
|||
const getTemplateConfigFormRef = () => { |
|||
return templateRef.value; |
|||
}; |
|||
const getMainConfigFormRef = () => { |
|||
return mainConfigFormRef.value; |
|||
}; |
|||
const getPageSortConfigFormRef = () => { |
|||
return pageSortConfigFormRef.value; |
|||
}; |
|||
const getQueryConfigFormRef = () => { |
|||
return queryConfigFormRef.value; |
|||
}; |
|||
const getEditConfigFormRef = () => { |
|||
return editConfigFormRef.value; |
|||
}; |
|||
const setPrimaryKeyOptions = (options: Array<any>) => { |
|||
primaryKeyOptions.value = options; |
|||
}; |
|||
formConfig.cf.getTemplateConfigFormRef = getTemplateConfigFormRef; |
|||
formConfig.cf.getMainConfigFormRef = getMainConfigFormRef; |
|||
formConfig.cf.getPageSortConfigFormRef = getPageSortConfigFormRef; |
|||
formConfig.cf.getQueryConfigFormRef = getQueryConfigFormRef; |
|||
formConfig.cf.getEditConfigFormRef = getEditConfigFormRef; |
|||
formConfig.cf.setPrimaryKeyOptions = setPrimaryKeyOptions; |
|||
</script> |
@ -0,0 +1,52 @@ |
|||
export class ComponentType { |
|||
static type = { |
|||
text: { label: '文本框', value: 'text', component: 'w-text' }, |
|||
textarea: { label: '文本域', value: 'textarea', component: 'w-textarea' }, |
|||
checkbox: { label: '复选框', value: 'checkbox', component: 'w-checkbox' }, |
|||
codeMirror: { label: '代码编辑器', value: 'codeMirror', component: 'w-code-mirror' }, |
|||
date: { label: '日期', value: 'date', component: 'w-date' }, |
|||
dateRange: { label: '日期范围', value: 'dateRange', component: 'w-date-range' }, |
|||
icon: { label: '图标选择', value: 'icon', component: 'w-icon' }, |
|||
number: { label: '数字框', value: 'number', component: 'w-number' }, |
|||
integer: { label: '整数框', value: 'integer', component: 'w-integer' }, |
|||
radio: { label: '单选按钮', value: 'radio', component: 'w-radio' }, |
|||
select: { label: '下拉框', value: 'select', component: 'w-select' }, |
|||
multipleSelect: { label: '多选下拉框', value: 'multipleSelect', component: 'w-select' }, |
|||
userSelect: { label: '用户选择', value: 'userSelect', component: 'w-user-select' }, |
|||
mulitpleUserSelect: { label: '用户选择(多选)', value: 'mulitpleUserSelect', component: 'w-user-select' }, |
|||
orgSelect: { label: '机构选择', value: 'orgSelect', component: 'w-org-select' }, |
|||
mulitpleOrgSelect: { label: '机构选择(多选)', value: 'mulitpleOrgSelect', component: 'w-org-select' }, |
|||
roleSelect: { label: '角色选择', value: 'roleSelect', component: 'w-role-select' }, |
|||
mulitpleRoleSelect: { label: '角色选择(多选)', value: 'mulitpleRoleSelect', type: 'w-role-select' }, |
|||
dbTableSelect: { label: '数据表选择', value: 'dbTableSelect', component: 'w-db-table-select' }, |
|||
mulitpleDbTableSelect: { label: '数据表选择(多选)', value: 'mulitpleDbTableSelect', component: 'w-db-table-select' }, |
|||
}; |
|||
|
|||
/** |
|||
* 所有组件集合 |
|||
*/ |
|||
static options: Array<any> = Object.values(this.type); |
|||
|
|||
/** |
|||
* 多选类型的组件集合 |
|||
*/ |
|||
static multipleSelectTypes: Array<any> = [ |
|||
this.type.multipleSelect, |
|||
this.type.mulitpleUserSelect, |
|||
this.type.mulitpleOrgSelect, |
|||
this.type.mulitpleRoleSelect, |
|||
this.type.mulitpleDbTableSelect, |
|||
]; |
|||
|
|||
/** |
|||
* 所有选项类型的组件集合 |
|||
*/ |
|||
static selectTypes: Array<any> = [ |
|||
this.type.select, |
|||
this.type.userSelect, |
|||
this.type.orgSelect, |
|||
this.type.roleSelect, |
|||
this.type.dbTableSelect, |
|||
...this.multipleSelectTypes, |
|||
]; |
|||
} |
@ -0,0 +1,21 @@ |
|||
import { computed } from 'vue'; |
|||
import { Tools } from 'platform-core'; |
|||
import { FormConfig } from './FormConfig'; |
|||
|
|||
export class ComputedManager { |
|||
form: FormConfig; |
|||
|
|||
constructor(form_: FormConfig) { |
|||
this.form = form_; |
|||
} |
|||
|
|||
fieldComeFromValueComputed = computed(() => { |
|||
if (this.form.cf.getTemplateConfigFormRef) { |
|||
const ref = this.form.cf.getTemplateConfigFormRef(); |
|||
if (ref && !Tools.isEmpty(ref.getFieldValue('fieldComeFrom'))) { |
|||
return ref.getFieldValue('fieldComeFrom'); |
|||
} |
|||
} |
|||
return undefined; |
|||
}); |
|||
} |
@ -0,0 +1,10 @@ |
|||
export class DictionaryType { |
|||
static type = { |
|||
none: { label: '无', value: 'none' }, |
|||
dictionary: { label: '数据字典', value: 'dictionary' }, |
|||
array: { label: '自定义数组', value: 'array' }, |
|||
sql: { label: 'Sql', value: 'sql' }, |
|||
}; |
|||
|
|||
static options: Array<any> = Object.values(this.type); |
|||
} |
@ -0,0 +1,51 @@ |
|||
import type { ComponentFunctionsType } from './type/ComponentFunctionsType'; |
|||
import { RequestApi } from './RequestApi'; |
|||
import { ComputedManager } from './ComputedManager'; |
|||
import { FunctionManager } from './FunctionManager'; |
|||
|
|||
export class FormConfig { |
|||
/** |
|||
* 编辑时模板ID |
|||
*/ |
|||
editId: string = ''; |
|||
/** |
|||
* 编辑时表格类型的表单,主表ID |
|||
*/ |
|||
editGridId: string = ''; |
|||
/** |
|||
* 方案集合 |
|||
*/ |
|||
schemas: Array<any> = []; |
|||
/** |
|||
* 计算属性管理器 |
|||
*/ |
|||
cm: ComputedManager; |
|||
/** |
|||
* 函数管理器 |
|||
*/ |
|||
fm: FunctionManager; |
|||
/** |
|||
* 请求API管理器 |
|||
*/ |
|||
api: RequestApi; |
|||
/** |
|||
* vue文件中定义的函数管理器 |
|||
*/ |
|||
cf: ComponentFunctionsType = { |
|||
getDialogRef: () => {}, |
|||
getFieldGridRef: () => {}, |
|||
getTemplateConfigFormRef: () => {}, |
|||
getMainConfigFormRef: () => {}, |
|||
getPageSortConfigFormRef: () => {}, |
|||
getQueryConfigFormRef: () => {}, |
|||
getEditConfigFormRef: () => {}, |
|||
setPrimaryKeyOptions: () => {}, |
|||
}; |
|||
|
|||
constructor() { |
|||
this.api = new RequestApi(this); |
|||
this.cm = new ComputedManager(this); |
|||
this.fm = new FunctionManager(this); |
|||
this.api.getSchemas(); |
|||
} |
|||
} |
@ -0,0 +1,204 @@ |
|||
import { Tools } from 'platform-core'; |
|||
import { FormConfig } from './FormConfig'; |
|||
import { ComponentType } from './ComponentType'; |
|||
import { JavaType } from './JavaType'; |
|||
|
|||
export class FunctionManager { |
|||
form: FormConfig; |
|||
|
|||
constructor(form_: FormConfig) { |
|||
this.form = form_; |
|||
} |
|||
|
|||
/** |
|||
* 设置字段列表数据 |
|||
* @param fields 字段集合 |
|||
*/ |
|||
setFieldGridData(fields: Array<any>) { |
|||
if (this.form.cf.getFieldGridRef) { |
|||
if (this.form.cm.fieldComeFromValueComputed.value === 'table') { |
|||
const data = this.buildTableTypeFields(fields); |
|||
this.form.cf.getFieldGridRef().setLocalData(data); |
|||
} else if (this.form.cm.fieldComeFromValueComputed.value === 'sql') { |
|||
const data = this.buildSqlTypeFields(fields); |
|||
this.form.cf.getFieldGridRef().setLocalData(data); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private buildSqlTypeFields(fields: Array<any>) { |
|||
const result = <any>[]; |
|||
fields.forEach((item: any) => { |
|||
const javaType = this.getFieldType(item['javaType']); |
|||
const autoData = this.buildAutoData(item['name']); |
|||
const componentType = this.getComponentType(item['javaType']); |
|||
const field = { |
|||
tableName: undefined, |
|||
fieldName: item['name'], |
|||
fieldLabel: undefined, |
|||
fieldType: javaType, // 字段类型
|
|||
fieldLength: javaType === 'String' ? item['size'] : undefined, // 字段长度
|
|||
fieldPrecision: undefined, // 字段精度
|
|||
fieldIsSelect: false, // 字段为选项值
|
|||
optionComeFrom: 'none', // 选项值来源
|
|||
dictionaryOptionValue: '', // 数据字典选项值
|
|||
otherOptionValue: '', // 其他类型选项值
|
|||
addValueType: 'NONE', // 新增时系统自动填充类型
|
|||
editOverride: undefined, // 修改时覆盖系统自动填充值
|
|||
// 查询面板
|
|||
queryShow: false, // 查询面板中显示
|
|||
queryFormType: componentType, // 使用的表单类型
|
|||
queryDefaultValue: '', // 默认值
|
|||
queryIsrequiredIf: false, // 必填项
|
|||
queryOperator: '', // 匹配模式
|
|||
// 列表
|
|||
tableShow: true, // 列表中显示
|
|||
tableSort: false, // 支持排序
|
|||
tableColumnAlign: '', // 列对齐方式
|
|||
tableColumnWidth: undefined, // 列宽
|
|||
// 新增页面
|
|||
editorShow: false, // 新增编辑页面中显示
|
|||
editorFormType: componentType, // 使用的表单类型
|
|||
editorDefaultValue: '', // 默认值
|
|||
editorIsRequired: false, // 必填项
|
|||
}; |
|||
result.push({ ...field, ...autoData }); |
|||
}); |
|||
return result; |
|||
} |
|||
|
|||
private buildTableTypeFields(fields: Array<any>) { |
|||
const result = <any>[]; |
|||
fields.forEach((item: any) => { |
|||
// 设置主键
|
|||
if (item['partOfPrimaryKey'] && this.form.cf.getMainConfigFormRef) { |
|||
this.form.cf.getMainConfigFormRef().setFieldValue('primaryKey', item['name']); |
|||
} |
|||
const javaType = this.getFieldType(item['javaType']); |
|||
const autoData = this.buildAutoData(item['name']); |
|||
const componentType = this.getComponentType(item['javaType']); |
|||
const field = { |
|||
tableName: this.form.cf.getTemplateConfigFormRef ? this.form.cf.getTemplateConfigFormRef().getFieldValue('databaseTable') : undefined, |
|||
fieldName: item['name'], |
|||
fieldLabel: item['remarks'], |
|||
sqlType: item['sqlType'], |
|||
width: item['width'], |
|||
fieldType: javaType, // 字段类型
|
|||
fieldLength: javaType === 'String' ? item['size'] : undefined, // 字段长度
|
|||
fieldPrecision: undefined, // 字段精度
|
|||
fieldIsSelect: false, // 字段为选项值
|
|||
optionComeFrom: 'none', // 选项值来源
|
|||
dictionaryOptionValue: '', // 数据字典选项值
|
|||
otherOptionValue: '', // 其他类型选项值
|
|||
addValueType: 'NONE', // 新增时系统自动填充类型
|
|||
editOverride: undefined, // 修改时覆盖系统自动填充值
|
|||
// 查询面板
|
|||
queryShow: false, // 查询面板中显示
|
|||
queryFormType: componentType, // 使用的表单类型
|
|||
queryDefaultValue: '', // 默认值
|
|||
queryIsrequiredIf: false, // 必填项
|
|||
queryOperator: '', // 匹配模式
|
|||
// 列表
|
|||
tableShow: true, // 列表中显示
|
|||
tableSort: false, // 支持排序
|
|||
tableColumnAlign: '', // 列对齐方式
|
|||
tableColumnWidth: undefined, // 列宽
|
|||
// 新增页面
|
|||
editorShow: true, // 新增编辑页面中显示
|
|||
editorFormType: componentType, // 使用的表单类型
|
|||
editorDefaultValue: '', // 默认值
|
|||
editorIsRequired: false, // 必填项
|
|||
}; |
|||
result.push({ ...field, ...autoData }); |
|||
}); |
|||
return result; |
|||
} |
|||
|
|||
private buildAutoData(name: string) { |
|||
if (name.toUpperCase() === 'ID' || name.toUpperCase() === 'ID_') { |
|||
return { |
|||
addValueType: 'UUID', |
|||
editOverride: false, |
|||
tableShow: false, |
|||
editorShow: false, |
|||
}; |
|||
} else if (name.toUpperCase() === 'JPA_VERSION' || name.toUpperCase() === 'JPA_VERSION_') { |
|||
return { |
|||
editOverride: false, |
|||
tableShow: false, |
|||
editorShow: false, |
|||
}; |
|||
} else if (name.toUpperCase() === 'DATA_COME_FROM' || name.toUpperCase() === 'DATA_COME_FROM_') { |
|||
return { |
|||
addValueType: 'DCF_INPUT', |
|||
editOverride: false, |
|||
tableShow: false, |
|||
editorShow: false, |
|||
}; |
|||
} else if (name.toUpperCase() === 'CREATOR' || name.toUpperCase() === 'CREATOR_') { |
|||
return { |
|||
addValueType: 'CURR_USER', |
|||
editOverride: false, |
|||
tableShow: false, |
|||
editorShow: false, |
|||
}; |
|||
} else if (name.toUpperCase() === 'CREATE_DATE' || name.toUpperCase() === 'CREATE_DATE_') { |
|||
return { |
|||
addValueType: 'CURR_DATE', |
|||
editOverride: false, |
|||
tableShow: false, |
|||
editorShow: false, |
|||
}; |
|||
} else if (name.toUpperCase() === 'LAST_MODIFIER' || name.toUpperCase() === 'LAST_MODIFIER_') { |
|||
return { |
|||
addValueType: 'CURR_USER', |
|||
editOverride: true, |
|||
tableShow: false, |
|||
editorShow: false, |
|||
}; |
|||
} else if (name.toUpperCase() === 'LAST_MODIFYDATE' || name.toUpperCase() === 'LAST_MODIFYDATE_') { |
|||
return { |
|||
addValueType: 'CURR_DATE', |
|||
editOverride: true, |
|||
tableShow: false, |
|||
editorShow: false, |
|||
}; |
|||
} else if (name.toUpperCase() === 'CORP_CODE' || name.toUpperCase() === 'CORP_CODE_') { |
|||
return { |
|||
addValueType: 'CURR_CORP', |
|||
editOverride: true, |
|||
tableShow: false, |
|||
editorShow: false, |
|||
}; |
|||
} |
|||
return {}; |
|||
} |
|||
|
|||
private getFieldType(javaType: string) { |
|||
if (javaType === 'java.lang.Integer' || javaType === 'java.lang.Long') { |
|||
return JavaType.type.Integer.value; |
|||
} else if (javaType === 'java.sql.Timestamp') { |
|||
return JavaType.type.Date.value; |
|||
} else if (javaType === 'java.lang.Boolean') { |
|||
return JavaType.type.Boolean.value; |
|||
} else if (javaType === 'java.math.BigDecimal') { |
|||
return JavaType.type.BigDecimal.value; |
|||
} else { |
|||
return JavaType.type.String.value; |
|||
} |
|||
} |
|||
|
|||
private getComponentType(javaType: string) { |
|||
if (javaType === 'java.lang.Integer' || javaType === 'java.lang.Long') { |
|||
return ComponentType.type.integer.value; |
|||
} else if (javaType === 'java.sql.Timestamp') { |
|||
return ComponentType.type.date.value; |
|||
} else if (javaType === 'java.lang.Boolean') { |
|||
return ComponentType.type.select.value; |
|||
} else if (javaType === 'java.math.BigDecimal') { |
|||
return ComponentType.type.number.value; |
|||
} else { |
|||
return ComponentType.type.text.value; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
export class JavaType { |
|||
static type = { |
|||
String: { label: '字符串', value: 'String' }, |
|||
Integer: { label: '整数', value: 'Integer' }, |
|||
BigDecimal: { label: '小数', value: 'BigDecimal' }, |
|||
Date: { label: '日期', value: 'Date' }, |
|||
Boolean: { label: '布尔', value: 'Boolean' }, |
|||
}; |
|||
|
|||
static options: Array<any> = Object.values(this.type); |
|||
} |
@ -0,0 +1,170 @@ |
|||
import { toRaw } from 'vue'; |
|||
import { axios, Environment, NotifyManager } from 'platform-core'; |
|||
import { FormConfig } from './FormConfig'; |
|||
import { ComponentType } from './ComponentType'; |
|||
|
|||
export class RequestApi { |
|||
form: FormConfig; |
|||
|
|||
constructor(form_: FormConfig) { |
|||
this.form = form_; |
|||
} |
|||
|
|||
getSchemas() { |
|||
axios({ |
|||
method: 'GET', |
|||
url: Environment.apiContextPath('api/template/config/schemas'), |
|||
}).then((resp) => { |
|||
this.form.schemas = []; |
|||
resp.data.forEach((item: any) => { |
|||
this.form.schemas.push({ label: item.name, value: item.name }); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
loadFields(sql: string) { |
|||
const requestParams = { |
|||
method: 'POST', |
|||
headers: { 'content-type': 'text/plain;charset=utf-8;' }, |
|||
data: sql, |
|||
url: Environment.apiContextPath('api/jdbc/fetchMetaDataBySql'), |
|||
}; |
|||
axios(requestParams) |
|||
.then((resp: any) => { |
|||
const columns = <any>[]; |
|||
const gridRef = this.form.cf.getFieldGridRef(); |
|||
const oldColumns = gridRef.getRows(); |
|||
// if (oldColumns.length > 0) {
|
|||
// resp.data.forEach((item) => {
|
|||
// const column = oldColumns.find((oldColumn) => {
|
|||
// return oldColumn.fieldName === item.columnName;
|
|||
// });
|
|||
// if (!Tools.isEmpty(column)) {
|
|||
// columns.push({
|
|||
// id: item.id,
|
|||
// parent: item.parent,
|
|||
// name: item.columnName,
|
|||
// fieldName: item.columnName,
|
|||
// queryShow: item.queryShow || false,
|
|||
// tableShow: item.tableShow || false,
|
|||
// ...column,
|
|||
// });
|
|||
// } else {
|
|||
// columns.push({
|
|||
// id: item.id,
|
|||
// parent: item.parent,
|
|||
// name: item.columnName,
|
|||
// fieldName: item.columnName,
|
|||
// queryShow: item.queryShow || false,
|
|||
// tableShow: item.tableShow || false,
|
|||
// });
|
|||
// }
|
|||
// });
|
|||
// gridRef.setLocalData(columns, 'sql');
|
|||
// } else {
|
|||
resp.data.forEach((item) => { |
|||
columns.push({ |
|||
id: item.id, |
|||
parent: item.parent, |
|||
name: item.columnName, |
|||
fieldName: item.columnName, |
|||
queryShow: item.parent === 'where_field' || false, |
|||
optionComeFrom: 'none', // 选项值来源
|
|||
addValueType: 'NONE', // 新增时系统自动填充类型
|
|||
// 查询表单
|
|||
queryFormtype: ComponentType.type.text.value, // 使用的表单类型
|
|||
queryDefaultValue: '', // 默认值
|
|||
queryIsrequiredIf: false, // 必填项
|
|||
queryOperator: '', // 匹配模式
|
|||
// 列表
|
|||
tableShow: true, // 列表中显示
|
|||
tableSort: false, // 支持排序
|
|||
tableColumnAlign: '', // 列对齐方式
|
|||
tableColumnWidth: undefined, // 列宽
|
|||
// 新增页面
|
|||
editorShow: false, // 新增编辑页面中显示
|
|||
editorFormType: ComponentType.type.text.value, // 使用的表单类型
|
|||
editorDefaultValue: '', // 默认值
|
|||
editorIsRequired: false, // 必填项
|
|||
}); |
|||
}); |
|||
gridRef.setLocalData(columns); |
|||
const names = columns.map((item) => item.fieldName); |
|||
this.form.cf.setPrimaryKeyOptions(names); |
|||
// }
|
|||
}) |
|||
.catch((error: any) => { |
|||
NotifyManager.error('SQL执行报错'); |
|||
}); |
|||
} |
|||
|
|||
async fetchFormConfigData() { |
|||
const resp = await axios.get(Environment.apiContextPath('api/template/config/fetch/') + this.form.editId); |
|||
if (resp && resp.data) { |
|||
return resp.data; |
|||
} |
|||
return undefined; |
|||
} |
|||
|
|||
buildSaveData() { |
|||
const templateFormData = this.form.cf.getTemplateConfigFormRef().getData(); |
|||
const mainFormData = this.form.cf.getMainConfigFormRef().getData(); |
|||
const pageSortFormData = this.form.cf.getPageSortConfigFormRef().getData(); |
|||
const queryFormData = this.form.cf.getQueryConfigFormRef().getData(); |
|||
const editFormData = this.form.cf.getEditConfigFormRef().getData(); |
|||
const rows = this.form.cf.getFieldGridRef().getRows(); |
|||
rows.forEach((item: any, index: number) => { |
|||
item['sortNo'] = index + 1; |
|||
if (item['editorFormType'] === ComponentType.type.date.value) { |
|||
// 当前端组件为日期类型时,查询面板的组件替换为日期范围
|
|||
item['queryFormType'] = ComponentType.type.dateRange.value; |
|||
} else { |
|||
// 其他组件通用
|
|||
item['queryFormType'] = item['editorFormType']; |
|||
} |
|||
}); |
|||
const requestData = { |
|||
templateConfig: { ...templateFormData, ...{ id: this.form.editId } }, |
|||
templateGrid: { ...templateFormData, ...mainFormData, ...pageSortFormData, ...queryFormData, ...editFormData, id: this.form.editGridId }, |
|||
templateGridFields: toRaw(rows), |
|||
}; |
|||
requestData.templateGrid['columnTitles'] = JSON.stringify({ value: mainFormData['columnTitles'] }); |
|||
return requestData; |
|||
} |
|||
|
|||
async save() { |
|||
const rows = this.form.cf.getFieldGridRef().getRows(); |
|||
if (!rows || rows.length === 0) { |
|||
NotifyManager.warn('字段列表为空'); |
|||
return; |
|||
} |
|||
if (!(await this.formValidate())) { |
|||
return; |
|||
} |
|||
const requestData = this.buildSaveData(); |
|||
axios({ |
|||
method: 'POST', |
|||
url: Environment.apiContextPath('api/template/config') + (this.form.editId ? '/edit' : '/add'), |
|||
data: requestData, |
|||
}) |
|||
.then((resp) => { |
|||
// 关闭窗口,刷新表格
|
|||
this.form.cf.getDialogRef().hide(); |
|||
this.form.cf.getDialogRef().emit('refresh-grid'); |
|||
NotifyManager.info('保存成功'); |
|||
}) |
|||
.catch((error) => { |
|||
console.info('error====', error); |
|||
NotifyManager.error('保存失败'); |
|||
}); |
|||
} |
|||
|
|||
private async formValidate() { |
|||
const templateConfigFormValidate = await this.form.cf.getTemplateConfigFormRef().validate(); |
|||
const mainConfigFormValidate = await this.form.cf.getMainConfigFormRef().validate(); |
|||
const pageSortFormValidate = await this.form.cf.getPageSortConfigFormRef().validate(); |
|||
const queryFormValidate = await this.form.cf.getQueryConfigFormRef().validate(); |
|||
const editFormValidate = await this.form.cf.getEditConfigFormRef().validate(); |
|||
return templateConfigFormValidate && mainConfigFormValidate && pageSortFormValidate && queryFormValidate && editFormValidate; |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
export type ComponentFunctionsType = { |
|||
getDialogRef: Function; |
|||
getFieldGridRef: Function; |
|||
getTemplateConfigFormRef: Function; |
|||
getMainConfigFormRef: Function; |
|||
getPageSortConfigFormRef: Function; |
|||
getQueryConfigFormRef: Function; |
|||
getEditConfigFormRef: Function; |
|||
setPrimaryKeyOptions: Function; |
|||
} |
Loading…
Reference in new issue