Browse Source
1、dbClickOperation修改为配置按钮的name,触发事件为按钮的click。 2、表格第一列选择框全选只有勾选未选中与勾选单条行为不一致。 3、提供表格编辑模式,双击或者点击按钮直接在表格上编辑。main
43 changed files with 3763 additions and 3737 deletions
@ -0,0 +1,351 @@ |
|||||
|
<template> |
||||
|
<template v-if="props.grid.props.tree"> |
||||
|
<TreeGridRow |
||||
|
:ref="(el) => setTreeRowComponentRef(el, scope.row)" |
||||
|
:grid="props.grid" |
||||
|
:columns-map="props.tableColumnsMap" |
||||
|
:row="props.scope.row" |
||||
|
:cols="props.scope.cols" |
||||
|
:row-key="props.rowKeyName" |
||||
|
:grid-row-click="props.rowClick" |
||||
|
:grid-row-db-click="props.rowDbClick" |
||||
|
:after-row-draggable="props.afterRowDraggable" |
||||
|
:get-row="props.getRow" |
||||
|
:url="props.url" |
||||
|
:get-row-component-refs="getRowComponentRefs" |
||||
|
:set-old-value="setOldValue" |
||||
|
:no-data-tr-colspan="noDataTrColspan" |
||||
|
></TreeGridRow> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<q-tr |
||||
|
ref="trRef" |
||||
|
:class="props.scope.row[table.selectedField] ? 'selected' : ''" |
||||
|
:props="props.scope" |
||||
|
:draggable=" |
||||
|
((typeof props.grid.props.draggable === 'boolean' && props.grid.props.draggable) || |
||||
|
(typeof props.grid.props.draggable === 'string' && props.grid.props.draggable === 'local')) && |
||||
|
table.bodyEditStatus === 'none' |
||||
|
? true |
||||
|
: false |
||||
|
" |
||||
|
@click.stop="rowClick($event, scope.row, scope.rowIndex)" |
||||
|
@dblclick.stop="rowDbClick($event, scope.row, scope.rowIndex)" |
||||
|
@dragenter="onDragEnter($event, scope)" |
||||
|
@dragleave="onDragLeave" |
||||
|
@dragover="onDragOver($event, scope)" |
||||
|
@drop="onDrop($event, scope)" |
||||
|
@dragstart="onDragStart($event, scope)" |
||||
|
> |
||||
|
<q-td v-if="table.checkboxSelection" class="text-center" style="padding: 0; width: 50px"> |
||||
|
<q-checkbox |
||||
|
v-model="props.getRow(table.rows, scope.row[props.rowKeyName], false)[table.tickedField]" |
||||
|
flat |
||||
|
:dense="props.denseBody" |
||||
|
@update:model-value="updateTicked($event, scope.row)" |
||||
|
/> |
||||
|
</q-td> |
||||
|
<template v-for="(col, index) in scope.cols" :key="index"> |
||||
|
<GridTd |
||||
|
:ref="(el) => setComponentRef(el, scope.row, col)" |
||||
|
:grid="props.grid" |
||||
|
:get-row="props.getRow" |
||||
|
:row-key-name="props.rowKeyName" |
||||
|
:scope="scope" |
||||
|
:col="col" |
||||
|
:value="col.value" |
||||
|
:is-selected-row="isSelectedRowComputed" |
||||
|
></GridTd> |
||||
|
</template> |
||||
|
</q-tr> |
||||
|
<GridEditToolbar |
||||
|
:grid="props.grid" |
||||
|
:url="props.url" |
||||
|
:row="props.scope.row" |
||||
|
:row-key-name="props.rowKeyName" |
||||
|
:get-row="props.getRow" |
||||
|
:get-row-component-refs="getRowComponentRefs" |
||||
|
:set-old-value="setOldValue" |
||||
|
:no-data-tr-colspan="noDataTrColspan" |
||||
|
></GridEditToolbar> |
||||
|
</template> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { computed, inject, ref, toRaw } from 'vue'; |
||||
|
import { Tools } from '@/platform'; |
||||
|
import TreeGridRow from './TreeGridRow.vue'; |
||||
|
import GridTd from './GridTd.vue'; |
||||
|
import GridEditToolbar from './GridEditToolbar.vue'; |
||||
|
|
||||
|
const trRef = ref(); |
||||
|
const props = defineProps({ |
||||
|
grid: { |
||||
|
// 表格实例 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
url: { |
||||
|
// 表格所有的url |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
scope: { |
||||
|
// 顶部插槽属性 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
tableColumnsMap: { |
||||
|
type: Map, |
||||
|
default: () => { |
||||
|
return new Map(); |
||||
|
}, |
||||
|
}, |
||||
|
rowKeyName: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
rowClick: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
rowDbClick: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
afterRowDraggable: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
denseBody: { |
||||
|
type: Boolean, |
||||
|
default: () => { |
||||
|
return false; |
||||
|
}, |
||||
|
}, |
||||
|
getRow: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
setOldValue: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
noDataTrColspan: { |
||||
|
type: Number, |
||||
|
default: () => { |
||||
|
return 0; |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
const table = inject('table'); |
||||
|
|
||||
|
const componentRef = ref({}); |
||||
|
const getRowComponentRefs = (rowKey: string | Array<string>) => { |
||||
|
const refs = <any>[]; |
||||
|
if (!Tools.isEmpty(componentRef.value)) { |
||||
|
const filterResult = Object.keys(componentRef.value).filter((item) => { |
||||
|
if (typeof rowKey === 'string') { |
||||
|
return item.startsWith(rowKey + '_'); |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
}); |
||||
|
if (filterResult.length > 0) { |
||||
|
filterResult.forEach((key) => { |
||||
|
refs.push(componentRef.value[key]); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
return refs; |
||||
|
}; |
||||
|
|
||||
|
const setComponentRef = (el, row, col) => { |
||||
|
if (el && !Tools.isEmpty(col.type)) { |
||||
|
componentRef.value[row[props.rowKeyName] + '_' + col.name] = el; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const setTreeRowComponentRef = (el, row) => { |
||||
|
if (el && !Tools.isEmpty(row)) { |
||||
|
componentRef.value[row[props.rowKeyName] + '_'] = el; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const isSelectedRowComputed = computed(() => { |
||||
|
const selected = props.grid.getSelectedRow(); |
||||
|
if (!Tools.isEmpty(selected)) { |
||||
|
return props.scope.row[props.rowKeyName] === props.grid.getSelectedRow()[props.rowKeyName]; |
||||
|
} |
||||
|
return false; |
||||
|
}); |
||||
|
|
||||
|
// 得到表格数据行的中间高度 |
||||
|
const gridTrMiddleHeightComputed = computed(() => { |
||||
|
if (trRef?.value) { |
||||
|
return trRef.value.$el.offsetHeight / 2; |
||||
|
} else { |
||||
|
return (table.dense || table.denseBody ? 24 : 48) / 2; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 拖拽开始 |
||||
|
const onDragStart = (e, scope) => { |
||||
|
const currPageIndex = table.rows.findIndex((item) => { |
||||
|
return item[props.rowKeyName] === scope.row[props.rowKeyName]; |
||||
|
}); |
||||
|
const currPageStartIndex = scope.rowIndex - currPageIndex; |
||||
|
if (props.grid.props.pageable) { |
||||
|
table.dragRow = { row: { ...scope.row }, rowIndex: scope.rowIndex, currPageIndex: currPageIndex, currPageStartIndex }; |
||||
|
} else { |
||||
|
table.dragRow = { row: { ...scope.row }, rowIndex: scope.rowIndex, currPageIndex: scope.rowIndex, currPageStartIndex }; |
||||
|
} |
||||
|
e.dataTransfer.dropEffect = 'move'; |
||||
|
}; |
||||
|
const addDragTopStyle = (e) => { |
||||
|
if (e.target?.parentNode?.children) { |
||||
|
for (let i = 0; i < e.target.parentNode.children.length; i++) { |
||||
|
e.target.parentNode.children[i].style.borderTopWidth = '2px'; |
||||
|
e.target.parentNode.children[i].style.borderTopStyle = 'dashed'; |
||||
|
e.target.parentNode.children[i].style.borderTopColor = 'orange'; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const removeDragTopStyle = (e) => { |
||||
|
if (e.target?.parentNode?.children) { |
||||
|
for (let i = 0; i < e.target.parentNode.children.length; i++) { |
||||
|
e.target.parentNode.children[i].style.borderTopWidth = ''; |
||||
|
e.target.parentNode.children[i].style.borderTopStyle = ''; |
||||
|
e.target.parentNode.children[i].style.borderTopColor = ''; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
const addDragBottomStyle = (e) => { |
||||
|
if (e.target?.parentNode?.children) { |
||||
|
for (let i = 0; i < e.target.parentNode.children.length; i++) { |
||||
|
e.target.parentNode.children[i].style.borderBottomWidth = '2px'; |
||||
|
e.target.parentNode.children[i].style.borderBottomStyle = 'dashed'; |
||||
|
e.target.parentNode.children[i].style.borderBottomColor = 'orange'; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
const removeDragBottomStyle = (e) => { |
||||
|
if (e.target?.parentNode?.children) { |
||||
|
for (let i = 0; i < e.target.parentNode.children.length; i++) { |
||||
|
e.target.parentNode.children[i].style.borderBottomWidth = ''; |
||||
|
e.target.parentNode.children[i].style.borderBottomStyle = ''; |
||||
|
e.target.parentNode.children[i].style.borderBottomColor = ''; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
// 拖拽至可放置区域触发 |
||||
|
const onDragEnter = (e, scope) => { |
||||
|
if (table.dragRow.rowIndex !== scope.rowIndex && table.dragRow.currPageStartIndex + e.target.parentNode.parentNode.children.length === scope.rowIndex + 1) { |
||||
|
// 最后一行 |
||||
|
addDragBottomStyle(e); |
||||
|
} else if (table.dragRow.rowIndex !== scope.rowIndex) { |
||||
|
addDragTopStyle(e); |
||||
|
} |
||||
|
}; |
||||
|
// 拖拽至不可放置区域触发 |
||||
|
const onDragLeave = (e) => { |
||||
|
removeDragTopStyle(e); |
||||
|
removeDragBottomStyle(e); |
||||
|
}; |
||||
|
// 拖拽过程触发 |
||||
|
const onDragOver = (e, scope) => { |
||||
|
if ( |
||||
|
e.offsetY >= gridTrMiddleHeightComputed.value && |
||||
|
table.dragRow.rowIndex !== scope.rowIndex && |
||||
|
table.dragRow.currPageStartIndex + e.target.parentNode.parentNode.children.length === scope.rowIndex + 1 |
||||
|
) { |
||||
|
removeDragTopStyle(e); |
||||
|
addDragBottomStyle(e); |
||||
|
} else if ( |
||||
|
e.offsetY < gridTrMiddleHeightComputed.value && |
||||
|
table.dragRow.rowIndex !== scope.rowIndex && |
||||
|
table.dragRow.currPageStartIndex + e.target.parentNode.parentNode.children.length === scope.rowIndex + 1 |
||||
|
) { |
||||
|
removeDragBottomStyle(e); |
||||
|
addDragTopStyle(e); |
||||
|
} |
||||
|
e.preventDefault(); |
||||
|
}; |
||||
|
// 拖拽放置时触发 |
||||
|
const onDrop = (e, scope) => { |
||||
|
e.preventDefault(); |
||||
|
if (table.dragRow.rowIndex === scope.rowIndex) { |
||||
|
return; |
||||
|
} |
||||
|
const dragRow = table.dragRow.row; |
||||
|
const currPageStartIndex = table.dragRow.currPageStartIndex; |
||||
|
table.rows.splice(table.dragRow.currPageIndex, 1); |
||||
|
if (e.offsetY < gridTrMiddleHeightComputed.value && table.dragRow.rowIndex < scope.rowIndex) { |
||||
|
table.rows.splice(scope.rowIndex - currPageStartIndex - 1, 0, dragRow); |
||||
|
} else { |
||||
|
table.rows.splice(scope.rowIndex - currPageStartIndex, 0, dragRow); |
||||
|
} |
||||
|
removeDragTopStyle(e); |
||||
|
removeDragBottomStyle(e); |
||||
|
|
||||
|
const updateData = <any>[]; |
||||
|
|
||||
|
table.rows.forEach((item, index) => { |
||||
|
if (!Tools.isEmpty(item)) { |
||||
|
item[props.grid.props.orderBy] = currPageStartIndex + index + 1; |
||||
|
updateData.push(toRaw(item)); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
if (typeof props.grid.props.draggable === 'boolean' && props.grid.props.draggable) { |
||||
|
// 访问后端更新排序 |
||||
|
props.grid.updates(updateData); |
||||
|
} |
||||
|
|
||||
|
props.afterRowDraggable(updateData); |
||||
|
}; |
||||
|
|
||||
|
// 处理当前页所有数据勾选状态 |
||||
|
const allTickedStatus = () => { |
||||
|
// 存在一条勾选的记录设置为 null |
||||
|
// 一条勾选的记录都没有设置为 false |
||||
|
// 全部勾选设置为 true |
||||
|
const ticked_ = <any>[]; |
||||
|
table.rows.forEach((item) => { |
||||
|
if (item[table.tickedField]) { |
||||
|
ticked_.push(item); |
||||
|
} |
||||
|
}); |
||||
|
if (ticked_.length === table.rows.length) { |
||||
|
table.allTicked = true; |
||||
|
} else if (ticked_.length > 0) { |
||||
|
table.allTicked = null; |
||||
|
} else { |
||||
|
table.allTicked = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const updateTicked = (evt: Event, row: any) => { |
||||
|
if (table.bodyEditStatus === 'none') { |
||||
|
props.getRow(table.rows, row[props.rowKeyName], false)[table.selectedField] = row[table.tickedField]; |
||||
|
allTickedStatus(); |
||||
|
if (props.grid.props.onUpdateTicked) { |
||||
|
props.grid.emit('updateTicked', evt, row); |
||||
|
} |
||||
|
} else { |
||||
|
props.getRow(table.rows, row[props.rowKeyName], false)[table.tickedField] = !props.getRow(table.rows, row[props.rowKeyName], false)[table.tickedField]; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
allTickedStatus, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="css"></style> |
@ -0,0 +1,324 @@ |
|||||
|
<template> |
||||
|
<q-tr v-if="showRowEditButtonComputed"> |
||||
|
<q-td :colspan="props.noDataTrColspan"> |
||||
|
<div class="editButton text-center"> |
||||
|
<w-toolbar |
||||
|
:dense="true" |
||||
|
align="center" |
||||
|
:grid="props.grid" |
||||
|
:buttons="[ |
||||
|
{ |
||||
|
label: '保存', |
||||
|
name: 'save', |
||||
|
icon: 'save', |
||||
|
color: 'primary', |
||||
|
outline: false, |
||||
|
click: async (args) => { |
||||
|
save(args); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: '取消', |
||||
|
name: 'cancel', |
||||
|
icon: 'close', |
||||
|
color: 'blue-grey', |
||||
|
outline: false, |
||||
|
click: (args) => { |
||||
|
if (table.bodyEditStatus === 'rowEdit') { |
||||
|
props.setOldValue(args.selected); |
||||
|
} else if (table.bodyEditStatus === 'rowsEdit') { |
||||
|
props.grid.getRows().forEach((item) => { |
||||
|
props.setOldValue(item); |
||||
|
}); |
||||
|
} |
||||
|
table.bodyEditStatus = 'none'; |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
></w-toolbar> |
||||
|
</div> |
||||
|
</q-td> |
||||
|
</q-tr> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { computed, inject, ref, toRaw } from 'vue'; |
||||
|
import { Tools, NotifyManager, noErrorAxios, t } from '@/platform'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
grid: { |
||||
|
// 表格实例 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
url: { |
||||
|
// 表格所有的url |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
rowKeyName: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
row: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
getRow: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
getRowComponentRefs: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
setOldValue: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
noDataTrColspan: { |
||||
|
type: Number, |
||||
|
default: () => { |
||||
|
return 0; |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
const table = inject('table'); |
||||
|
|
||||
|
const validate = async (refs) => { |
||||
|
let result = true; |
||||
|
for (let i = 0; i < refs.length; i++) { |
||||
|
const component = refs[i].getComponentRef(); |
||||
|
if (!Tools.isEmpty(refs[i].getComponentOneRef)) { |
||||
|
const componentOne = refs[i].getComponentOneRef(); |
||||
|
if (!Tools.isEmpty(componentOne) && !Tools.isEmpty(componentOne.validate)) { |
||||
|
const componentOneValidateResult = await componentOne.validate(); |
||||
|
if (!componentOneValidateResult) { |
||||
|
result = false; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (props.grid.props.tree && !Tools.isEmpty(component)) { |
||||
|
const keys = Object.keys(component); |
||||
|
for (let k = 0; k < keys.length; k++) { |
||||
|
if (!Tools.isEmpty(component[keys[k]]?.validate)) { |
||||
|
const treeComponentValidateResult = await component[keys[k]].validate(); |
||||
|
if (!treeComponentValidateResult) { |
||||
|
result = false; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} else if (!Tools.isEmpty(component.validate)) { |
||||
|
const componentValidateResult = await component.validate(); |
||||
|
if (!componentValidateResult) { |
||||
|
result = false; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return result; |
||||
|
}; |
||||
|
|
||||
|
const rowSave = (args) => { |
||||
|
let data = args.selected['_rowOldValue']; |
||||
|
let submitFlag = true; |
||||
|
let localeUpdateFlag = false; |
||||
|
let url = ''; |
||||
|
// 执行保存 |
||||
|
props.grid.emit('beforeEditorDataSubmit', data, (handlerRequestParams: any | boolean, localeUpdate: boolean = false) => { |
||||
|
if (typeof handlerRequestParams === 'boolean' && handlerRequestParams === false) { |
||||
|
submitFlag = false; |
||||
|
} else { |
||||
|
data = handlerRequestParams; |
||||
|
} |
||||
|
localeUpdateFlag = localeUpdate; |
||||
|
}); |
||||
|
if (localeUpdateFlag && submitFlag) { |
||||
|
// 只进行本地修改,不访问服务器 |
||||
|
props.grid.replaceRow(data); |
||||
|
table.bodyEditStatus = 'none'; |
||||
|
} else { |
||||
|
if (submitFlag) { |
||||
|
data = { ...args.selected, ...data }; |
||||
|
if (!Tools.isEmpty(props.url.editDataUrl)) { |
||||
|
url = props.url.editDataUrl + '/' + args.selected[props.grid.props.primaryKey]; |
||||
|
} else { |
||||
|
url = props.url.dataUrl + '/' + args.selected[props.grid.props.primaryKey]; |
||||
|
} |
||||
|
const requestParams = { |
||||
|
method: 'PUT', |
||||
|
headers: { 'content-type': 'application/json;charset=utf-8;' }, |
||||
|
data: data, |
||||
|
url: url, |
||||
|
}; |
||||
|
noErrorAxios(requestParams) |
||||
|
.then((resp) => { |
||||
|
props.grid.emit('afterEditorDataSubmit', resp.data); |
||||
|
NotifyManager.info(t('tip.operationSuccess')); |
||||
|
if (props.grid.props.refreshData || !props.grid.props.tree) { |
||||
|
props.grid.refresh(); |
||||
|
} else if (resp.data) { |
||||
|
props.grid.replaceRow(data); |
||||
|
} |
||||
|
// 保存成功后退出编辑状态 |
||||
|
table.bodyEditStatus = 'none'; |
||||
|
}) |
||||
|
.catch((error) => { |
||||
|
const response = error?.response; |
||||
|
const status = response?.status; |
||||
|
const data = response?.data; |
||||
|
if (data?.code === 1001) { |
||||
|
NotifyManager.error('服务器验证未通过'); |
||||
|
} else { |
||||
|
//其他错误 |
||||
|
if (status === 500) { |
||||
|
NotifyManager.error(t(data?.errorMessageI18nKey)); |
||||
|
} else { |
||||
|
NotifyManager.error(t(status)); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 检查数据是否修改过 |
||||
|
const checkDataModified = (row) => { |
||||
|
const keys = Object.keys(row['_rowOldValue']); |
||||
|
return keys.some((key) => row[key] !== row['_rowOldValue'][key]); |
||||
|
}; |
||||
|
|
||||
|
const treeDataPush = (arr) => { |
||||
|
const data = <any>[]; |
||||
|
if (arr && arr.length > 0) { |
||||
|
arr.forEach((item) => { |
||||
|
if (checkDataModified(item)) { |
||||
|
data.push(item['_rowOldValue']); |
||||
|
} |
||||
|
const childrenData = treeDataPush(item.children); |
||||
|
if (childrenData.length > 0) { |
||||
|
data.push(...childrenData); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
return data; |
||||
|
}; |
||||
|
|
||||
|
const rowsSave = (args) => { |
||||
|
let data = <any>[]; |
||||
|
const rows = args.grid.getRows(); |
||||
|
const isTree = props.grid.props.tree; |
||||
|
rows.forEach((item) => { |
||||
|
if (checkDataModified(item)) { |
||||
|
data.push(item['_rowOldValue']); |
||||
|
} |
||||
|
if (isTree && item.children) { |
||||
|
const childrenData = treeDataPush(item.children); |
||||
|
if (childrenData.length > 0) { |
||||
|
data.push(...childrenData); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
let submitFlag = true; |
||||
|
let localeUpdateFlag = false; |
||||
|
// 执行保存 |
||||
|
props.grid.emit('beforeEditorDataSubmit', data, (handlerRequestParams: any | boolean, localeUpdate: boolean = false) => { |
||||
|
if (typeof handlerRequestParams === 'boolean' && handlerRequestParams === false) { |
||||
|
submitFlag = false; |
||||
|
} else { |
||||
|
data = handlerRequestParams; |
||||
|
} |
||||
|
localeUpdateFlag = localeUpdate; |
||||
|
}); |
||||
|
if (localeUpdateFlag && submitFlag) { |
||||
|
// 只进行本地修改,不访问服务器 |
||||
|
data.forEach((item) => { |
||||
|
props.grid.replaceRow(item); |
||||
|
}); |
||||
|
table.bodyEditStatus = 'none'; |
||||
|
} else { |
||||
|
if (submitFlag) { |
||||
|
props.grid.updates(data, (callbackData) => { |
||||
|
NotifyManager.info(t('tip.operationSuccess')); |
||||
|
if (props.grid.props.refreshData || !props.grid.props.tree) { |
||||
|
props.grid.refresh(); |
||||
|
} else if (!Tools.isEmpty(callbackData)) { |
||||
|
callbackData.forEach((item) => { |
||||
|
props.grid.replaceRow(item); |
||||
|
}); |
||||
|
} |
||||
|
// 保存成功后退出编辑状态 |
||||
|
table.bodyEditStatus = 'none'; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const save = async (args) => { |
||||
|
const refs = props.getRowComponentRefs(table.bodyEditStatus === 'rowEdit' ? args.selected[props.rowKeyName] : []); |
||||
|
const result = await validate(refs); |
||||
|
if (!result) { |
||||
|
NotifyManager.error('验证未通过'); |
||||
|
} else { |
||||
|
if (table.bodyEditStatus === 'rowEdit') { |
||||
|
rowSave(args); |
||||
|
} else if (table.bodyEditStatus === 'rowsEdit') { |
||||
|
rowsSave(args); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const showRowEditButtonComputed = computed(() => { |
||||
|
if (table.bodyEditStatus === 'rowEdit' && isSelectedRowComputed.value) { |
||||
|
return true; |
||||
|
} else if (table.bodyEditStatus === 'rowsEdit' && table.rows.length > 0 && isLastRowComputed.value) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
const checkLastRow = (row) => { |
||||
|
if (props.grid.props.tree && row['expand'] && !Tools.isEmpty(row.children) && row.children.length > 0) { |
||||
|
const childrenLastRow = row.children[row.children.length - 1]; |
||||
|
if (childrenLastRow['expand'] && !Tools.isEmpty(childrenLastRow.children) && childrenLastRow.children.length > 0) { |
||||
|
return checkLastRow(childrenLastRow); |
||||
|
} else { |
||||
|
return childrenLastRow[props.rowKeyName] === props.row[props.rowKeyName]; |
||||
|
} |
||||
|
} else { |
||||
|
return row[props.rowKeyName] === props.row[props.rowKeyName]; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const isLastRowComputed = computed(() => { |
||||
|
const lastRow = table.rows[table.rows.length - 1]; |
||||
|
return checkLastRow(lastRow); |
||||
|
}); |
||||
|
|
||||
|
const isSelectedRowComputed = computed(() => { |
||||
|
const selected = props.grid.getSelectedRow(); |
||||
|
if (!Tools.isEmpty(selected)) { |
||||
|
return props.row[props.rowKeyName] === props.grid.getSelectedRow()[props.rowKeyName]; |
||||
|
} |
||||
|
return false; |
||||
|
}); |
||||
|
|
||||
|
defineExpose({}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="css"> |
||||
|
.editButton { |
||||
|
position: sticky; |
||||
|
background-color: white; |
||||
|
left: 45%; |
||||
|
width: 150px; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,227 @@ |
|||||
|
<template> |
||||
|
<w-dialog ref="dialogRef" :title="dialog.dialogTitle" v-bind="props.grid.props.editor.dialog" :buttons="dialogButtonsComputed"> |
||||
|
<w-form ref="dialogFormRef" v-bind="props.grid.props.editor.form" class="pt-1.5 px-1.5"></w-form> |
||||
|
</w-dialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, reactive, inject, computed } from 'vue'; |
||||
|
import { t, Tools, noErrorAxios, NotifyManager } from '@/platform'; |
||||
|
|
||||
|
const dialogRef = ref(); |
||||
|
const dialogFormRef = ref(); |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
grid: { |
||||
|
// 表格实例 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
url: { |
||||
|
// 表格所有的url |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
request: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
setRowDataExtraProperty: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
getRow: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
}); |
||||
|
const table = inject('table'); |
||||
|
|
||||
|
const dialogButtonsComputed = computed(() => { |
||||
|
if (props.grid.props.editor?.dialog?.buttons) { |
||||
|
return [...props.grid.props.editor.dialog.buttons, ...dialog.dialogButtons]; |
||||
|
} |
||||
|
return dialog.dialogButtons; |
||||
|
}); |
||||
|
|
||||
|
const save = async () => { |
||||
|
dialog.dialogButtons[0].loading = true; |
||||
|
const formStatus = dialogFormRef.value.getStatus(); |
||||
|
const validate = await dialogFormRef.value.validate(); |
||||
|
if (validate) { |
||||
|
let dialogFormData = dialogFormRef.value.getData(); |
||||
|
const selected = props.grid.getSelectedRow(); |
||||
|
const primaryKey = selected[props.grid.props.primaryKey]; |
||||
|
if (formStatus === 'edit' && selected) { |
||||
|
dialogFormData[props.grid.props.primaryKey] = primaryKey; |
||||
|
} |
||||
|
let submitFlag = true; |
||||
|
let closeDialog = true; |
||||
|
props.grid.emit('beforeEditorDataSubmit', dialogFormData, (handlerRequestParams: any | boolean, closeFlag: boolean = true) => { |
||||
|
if (typeof handlerRequestParams === 'boolean' && handlerRequestParams === false) { |
||||
|
submitFlag = false; |
||||
|
} else { |
||||
|
dialogFormData = handlerRequestParams; |
||||
|
} |
||||
|
closeDialog = closeFlag; |
||||
|
}); |
||||
|
if (submitFlag) { |
||||
|
if (formStatus === 'addTop') { |
||||
|
dialogFormData[props.grid.props.foreignKey] = null; |
||||
|
} else if (formStatus === 'addChild') { |
||||
|
dialogFormData[props.grid.props.foreignKey] = primaryKey; |
||||
|
} else if (formStatus === 'edit' && primaryKey) { |
||||
|
dialogFormData[props.grid.props.foreignKey] = primaryKey; |
||||
|
} else if (formStatus === 'clone' && primaryKey) { |
||||
|
dialogFormData[props.grid.props.foreignKey] = selected[props.grid.props.foreignKey]; |
||||
|
} |
||||
|
if (formStatus === 'edit') { |
||||
|
// 将行数据默认添加到传递给后端的数据中 |
||||
|
dialogFormData = { ...selected, ...dialogFormData }; |
||||
|
} |
||||
|
let requestParams = { |
||||
|
method: getMethod(formStatus), |
||||
|
headers: { 'content-type': 'application/json;charset=utf-8;' }, |
||||
|
data: dialogFormData, |
||||
|
url: getUrl(formStatus, selected), |
||||
|
}; |
||||
|
dialog.dialogButtons[0].loading = false; |
||||
|
noErrorAxios(requestParams) |
||||
|
.then((resp) => { |
||||
|
dialog.dialogButtons[0].loading = false; |
||||
|
props.grid.emit('afterEditorDataSubmit', resp.data); |
||||
|
NotifyManager.info(t('tip.operationSuccess')); |
||||
|
if (closeDialog) { |
||||
|
dialogRef.value.hide(); |
||||
|
} |
||||
|
if (props.grid.props.refreshData || !props.grid.props.tree) { |
||||
|
props.grid.refresh(); |
||||
|
} else if (resp.data && (formStatus === 'add' || formStatus === 'clone' || formStatus === 'addTop' || formStatus === 'addChild')) { |
||||
|
addData(resp.data); |
||||
|
} else if (resp.data) { |
||||
|
updateData(resp.data); |
||||
|
} |
||||
|
}) |
||||
|
.catch((error) => { |
||||
|
const response = error?.response; |
||||
|
const status = response?.status; |
||||
|
const data = response?.data; |
||||
|
if (data?.code === 1001) { |
||||
|
// 验证错误 |
||||
|
if (error.response.data.data) { |
||||
|
dialogFormRef.value.setValidationErrors(error.response.data.data); |
||||
|
} |
||||
|
} else { |
||||
|
//其他错误 |
||||
|
if (status === 500) { |
||||
|
NotifyManager.error(t(data?.errorMessageI18nKey)); |
||||
|
} else { |
||||
|
NotifyManager.error(t(status)); |
||||
|
} |
||||
|
} |
||||
|
dialog.dialogButtons[0].loading = false; |
||||
|
}); |
||||
|
} else { |
||||
|
dialog.dialogButtons[0].loading = false; |
||||
|
if (closeDialog) { |
||||
|
dialogRef.value.hide(); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
dialog.dialogButtons[0].loading = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const dialog = reactive({ |
||||
|
dialogTitle: t('action.addNew'), |
||||
|
dialogButtons: [ |
||||
|
{ |
||||
|
icon: 'beenhere', |
||||
|
labelI18nKey: 'action.submit', |
||||
|
label: t('action.submit'), |
||||
|
loading: false, |
||||
|
click: () => { |
||||
|
save(); |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}); |
||||
|
|
||||
|
// 新增树表格中的数据 |
||||
|
const addTreeRow = (row) => { |
||||
|
if (Tools.isEmpty(row[props.grid.props.foreignKey])) { |
||||
|
table.rows.push(row); |
||||
|
} else { |
||||
|
const parent = props.getRow(table.rows, row[props.grid.props.foreignKey], true); |
||||
|
if (parent) { |
||||
|
if (parent['children'] && Array.isArray(parent['children'])) { |
||||
|
parent['children'].push(row); |
||||
|
} else { |
||||
|
parent['children'] = [row]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const addData = (rowData) => { |
||||
|
if (props.grid.props.tree) { |
||||
|
addTreeRow(rowData); |
||||
|
props.setRowDataExtraProperty(table.rows); |
||||
|
} else { |
||||
|
props.grid.addRow(rowData, false); |
||||
|
} |
||||
|
}; |
||||
|
const updateData = (rowData) => { |
||||
|
const selected = props.grid.getSelectedRow(); |
||||
|
rowData[props.grid.props.primaryKey] = selected[props.grid.props.primaryKey]; |
||||
|
rowData[props.grid.props.selectedField] = true; |
||||
|
if (selected['children']) { |
||||
|
rowData['children'] = selected['children']; |
||||
|
} |
||||
|
props.grid.replaceRow(rowData); |
||||
|
}; |
||||
|
|
||||
|
const getMethod = (formStatus: string) => { |
||||
|
if (formStatus === 'add' || formStatus === 'clone' || formStatus === 'addTop' || formStatus === 'addChild') { |
||||
|
return 'POST'; |
||||
|
} else { |
||||
|
return 'PUT'; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const getUrl = (formStatus: string, selected: any) => { |
||||
|
if (formStatus === 'add' || formStatus === 'clone' || formStatus === 'addTop' || formStatus === 'addChild') { |
||||
|
if (!Tools.isEmpty(props.url.addDataUrl)) { |
||||
|
return props.url.addDataUrl; |
||||
|
} else { |
||||
|
return props.url.dataUrl; |
||||
|
} |
||||
|
} else { |
||||
|
if (!Tools.isEmpty(props.url.editDataUrl)) { |
||||
|
return props.url.editDataUrl + '/' + selected[props.grid.props.primaryKey]; |
||||
|
} else { |
||||
|
return props.url.dataUrl + '/' + selected[props.grid.props.primaryKey]; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const resetButtonLabel = () => { |
||||
|
dialog.dialogButtons[0].label = t(dialog.dialogButtons[0].labelI18nKey); |
||||
|
}; |
||||
|
const getDialog = () => { |
||||
|
return dialogRef.value; |
||||
|
}; |
||||
|
const getForm = () => { |
||||
|
return dialogFormRef.value; |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
resetButtonLabel, |
||||
|
getDialog, |
||||
|
getForm, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="css"></style> |
@ -0,0 +1,539 @@ |
|||||
|
<template> |
||||
|
<template v-if="columnTitleState.columnTitleRowNum > 1"> |
||||
|
<q-tr v-for="(r, rIndex) in columnTitleState.columnTitleArr" :key="rIndex"> |
||||
|
<q-th |
||||
|
v-if="rIndex === 0 && props.selection === 'multiple' && table.checkboxSelection && !props.grid.props.tree" |
||||
|
:rowspan="columnTitleState.columnTitleRowNum" |
||||
|
:style="moreColumnTitleTableSelectionStyle" |
||||
|
> |
||||
|
<q-checkbox v-model="table.allTicked" flat :dense="props.denseHeader" @update:model-value="allTickedUpdateFun" /> |
||||
|
</q-th> |
||||
|
<q-th |
||||
|
v-else-if="rIndex === 0 && table.checkboxSelection && !props.grid.props.tree" |
||||
|
:rowspan="columnTitleState.columnTitleRowNum" |
||||
|
:style="moreColumnTitleTableSelectionStyle" |
||||
|
></q-th> |
||||
|
<q-th |
||||
|
v-if="rIndex === 0 && table.sortNo && !props.grid.props.tree" |
||||
|
:rowspan="columnTitleState.columnTitleRowNum" |
||||
|
:style="moreColumnTitleTableSortNoStyle" |
||||
|
> |
||||
|
{{ $t('rownum') }} |
||||
|
</q-th> |
||||
|
<q-th |
||||
|
v-for="c in r" |
||||
|
:key="c.name" |
||||
|
:rowspan="c.rowspan" |
||||
|
:colspan="c.colspan" |
||||
|
:style="thStyleHandler(c, props.scope)" |
||||
|
:class="c.classes" |
||||
|
:props="titleScopeHandler(c, props.scope)" |
||||
|
style="font-weight: bold" |
||||
|
:title="c.title" |
||||
|
> |
||||
|
<span v-dompurify-html="Tools.isUndefinedOrNull(c.label) ? '' : c.label"></span> |
||||
|
</q-th> |
||||
|
</q-tr> |
||||
|
<q-tr v-if="table.rows.length === 0" :style="props.noDataTrHeightStyle" class="noDataTr"> |
||||
|
<q-td :colspan="props.noDataTrColspan" align="center" valian="middle"><q-icon size="2em" name="info" />{{ $t('tip.noData') }}</q-td> |
||||
|
</q-tr> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<q-tr :props="scope"> |
||||
|
<q-th |
||||
|
v-if="props.selection === 'multiple' && table.checkboxSelection && !props.grid.props.tree" |
||||
|
:style="props.grid.props.tree ? '' : 'padding: 0; min-width: 50px;width: 50px;max-width:50px'" |
||||
|
> |
||||
|
<q-checkbox v-model="table.allTicked" flat :dense="props.denseHeader" @update:model-value="allTickedUpdateFun" |
||||
|
/></q-th> |
||||
|
<q-th |
||||
|
v-else-if="table.checkboxSelection && !props.grid.props.tree" |
||||
|
:style="props.grid.props.tree ? '' : 'padding: 0; min-width: 50px;width: 50px;max-width:50px'" |
||||
|
></q-th> |
||||
|
<template v-for="col in scope.cols" :key="col.name"> |
||||
|
<q-th |
||||
|
:props="scope" |
||||
|
:style="col.style + (col.name === '_sortNo_' ? 'padding: 0; min-width: 50px;width: 50px;max-width:50px' : '')" |
||||
|
:class="col.classes" |
||||
|
style="font-weight: bold" |
||||
|
:title="col.title" |
||||
|
> |
||||
|
<span v-dompurify-html="Tools.isUndefinedOrNull(col.label) ? '' : col.label"></span> |
||||
|
</q-th> |
||||
|
</template> |
||||
|
</q-tr> |
||||
|
<q-tr v-if="table.rows.length === 0" :style="props.noDataTrHeightStyle" class="noDataTr"> |
||||
|
<q-td :colspan="props.noDataTrColspan" align="center" valian="middle"><q-icon size="2em" name="info" />{{ $t('tip.noData') }}</q-td> |
||||
|
</q-tr> |
||||
|
</template> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { Tools } from '@/platform'; |
||||
|
import { computed, inject, reactive } from 'vue'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
grid: { |
||||
|
// 表格实例 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
scope: { |
||||
|
// 顶部插槽属性 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
selection: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
denseHeader: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
rawColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
tableColumns: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
excludeColumnNum: { |
||||
|
type: Number, |
||||
|
default: () => { |
||||
|
return 0; |
||||
|
}, |
||||
|
}, |
||||
|
noDataTrHeightStyle: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
noDataTrColspan: { |
||||
|
type: Number, |
||||
|
default: () => { |
||||
|
return 0; |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
const table = inject('table'); |
||||
|
|
||||
|
// 多行列标题相关变量 |
||||
|
const columnTitleState = reactive({ |
||||
|
columnTitleRowNum: 1, // 多行列标题总行数 |
||||
|
columnTitleArr: <any>[], // 多行列标题集合 |
||||
|
}); |
||||
|
// 多行列标题的处理类型 |
||||
|
type MoreColumnTitleType = { |
||||
|
name: string; // 列模型的name |
||||
|
title: string; // 列模型的title(鼠标移动上去显示内容) |
||||
|
label: string; // 列模型的label |
||||
|
parentLevel: number; // 父层级数 |
||||
|
childrenLevel: number; // 子层级数 |
||||
|
rowspan: number; // 跨行数 |
||||
|
colspan: number; // 跨列数 |
||||
|
rowIndex: number; // 列模型所处的行下标 |
||||
|
style: any; // 列模型配置的内嵌样式 |
||||
|
classes: any; // 列模型配置的 classes |
||||
|
parents: any; // 列模型的父name集合 |
||||
|
}; |
||||
|
// 多行列标题的记录 map |
||||
|
let moreColumnTitleMap = new Map<string, MoreColumnTitleType>(); |
||||
|
let allColumnMap = new Map(); |
||||
|
|
||||
|
const moreColumnTitleTableSelectionStyle = computed(() => { |
||||
|
if (table.stickyNum > 0) { |
||||
|
if (props.grid.props.tree) { |
||||
|
return 'z-index: 3;position: sticky;left: 0px;'; |
||||
|
} else { |
||||
|
return 'z-index: 3;position: sticky;left: 0px;padding: 0; width: 50px;min-width:50px;max-width:50px;'; |
||||
|
} |
||||
|
} |
||||
|
return 'padding: 0; width: 50px;min-width:50px;max-width:50px;'; |
||||
|
}); |
||||
|
|
||||
|
const moreColumnTitleTableSortNoStyle = computed(() => { |
||||
|
if (table.checkboxSelection && table.sortNo && table.stickyNum > 0) { |
||||
|
return 'z-index: 3;position: sticky;left: var(--columnWidth-1-1);width: 50px;min-width:50px;max-width:50px;'; |
||||
|
} else if (table.sortNo && table.stickyNum > 0) { |
||||
|
return 'z-index: 3;position: sticky;left: 0px;width: 50px;min-width:50px;max-width:50px;'; |
||||
|
} |
||||
|
return 'width: 50px;min-width:50px;max-width:50px;'; |
||||
|
}); |
||||
|
|
||||
|
const allTickedUpdateFun = (value, evt) => { |
||||
|
if (table.bodyEditStatus === 'none') { |
||||
|
if (value) { |
||||
|
table.rows.forEach((item) => { |
||||
|
item[table.tickedField] = true; |
||||
|
item[table.selectedField] = true; |
||||
|
}); |
||||
|
} else { |
||||
|
table.rows.forEach((item) => { |
||||
|
item[table.tickedField] = false; |
||||
|
item[table.selectedField] = false; |
||||
|
}); |
||||
|
} |
||||
|
} else if (table.bodyEditStatus === 'rowEdit') { |
||||
|
table.allTicked = null; |
||||
|
} else if (table.bodyEditStatus === 'rowsEdit') { |
||||
|
table.allTicked = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const handlerStickyChildrenColumn = (item, columns) => { |
||||
|
columns.push(item); |
||||
|
if (item.columns && item.columns.length > 0) { |
||||
|
item.columns.forEach((children) => { |
||||
|
handlerStickyChildrenColumn(children, columns); |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const getStickyColumn = () => { |
||||
|
const columns = props.rawColumns.filter((item, index) => { |
||||
|
return index < table.stickyNum; |
||||
|
}); |
||||
|
const arr = []; |
||||
|
columns.forEach((item) => { |
||||
|
handlerStickyChildrenColumn(item, arr); |
||||
|
}); |
||||
|
return arr; |
||||
|
}; |
||||
|
|
||||
|
// 获取多行的列标题下标 |
||||
|
const getMoreRowColumnTitleIndex = (name: any) => { |
||||
|
let trIndex = -1; |
||||
|
let tdIndex = -1; |
||||
|
for (let tr = 0; tr < columnTitleState.columnTitleArr.length; tr++) { |
||||
|
const tdArr = columnTitleState.columnTitleArr[tr]; |
||||
|
let flag = false; |
||||
|
for (let td = 0; td < tdArr.length; td++) { |
||||
|
if (name === tdArr[td].name) { |
||||
|
trIndex = tr + 1; |
||||
|
tdIndex = td + 1; |
||||
|
flag = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (flag) { |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return { trIndex: trIndex, tdIndex: tdIndex }; |
||||
|
}; |
||||
|
|
||||
|
const thStickyLastNameComputed = computed(() => { |
||||
|
let result = <any>[]; |
||||
|
const stickyColumnArr = getStickyColumn(); |
||||
|
const lastColumn = getMoreRowColumnTitleIndex(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 = getMoreRowColumnTitleIndex(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 thStyleHandler = (c: any, scope: any) => { |
||||
|
let style = ''; |
||||
|
if (!Tools.isEmpty(c.style)) { |
||||
|
if (c.style.substr(-1) !== ';') { |
||||
|
style = c.style + ';'; |
||||
|
} |
||||
|
style = c.style; |
||||
|
} |
||||
|
const stickyColumnArr = getStickyColumn(); |
||||
|
if ( |
||||
|
table.stickyNum > 0 && |
||||
|
stickyColumnArr.findIndex((item: any) => { |
||||
|
return item.name === c.name; |
||||
|
}) > -1 |
||||
|
) { |
||||
|
const stickyThArr = <any>[]; |
||||
|
const trtdIndex = getMoreRowColumnTitleIndex(c.name); |
||||
|
if (c.parents && c.parents.length > 0) { |
||||
|
// 存在父级节点,得到父级节点的列下标 |
||||
|
// 找到parent相同且tdIndex小于其的一共多少列 |
||||
|
for (let tr = 0; tr < trtdIndex.trIndex; tr++) { |
||||
|
const tdArr = columnTitleState.columnTitleArr[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 === c.parents.length && |
||||
|
tdArr[td].parents.every((a) => c.parents.some((b) => a === b)) && |
||||
|
c.parents.every((_b) => tdArr[td].parents.some((_a) => _a === _b)); |
||||
|
if (result) { |
||||
|
if (tr === 0) { |
||||
|
stickyThArr.push({ trIndex: tr + 1, tdIndex: td + props.excludeColumnNum + 1 }); |
||||
|
} else { |
||||
|
stickyThArr.push({ trIndex: tr + 1, tdIndex: td + 1 }); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
c.parents.forEach((parent) => { |
||||
|
const parentTrtdIndex = getMoreRowColumnTitleIndex(parent); |
||||
|
if (moreColumnTitleMap.get(parent)!.parents && moreColumnTitleMap.get(parent)!.parents.length > 0) { |
||||
|
const tdArr = columnTitleState.columnTitleArr[parentTrtdIndex.trIndex - 1]; |
||||
|
for (let td = 0; td < parentTrtdIndex.tdIndex - 1; td++) { |
||||
|
const result = |
||||
|
tdArr[td].parents.length === moreColumnTitleMap.get(parent)!.parents.length && |
||||
|
tdArr[td].parents.every((a) => moreColumnTitleMap.get(parent)!.parents.some((b) => a === b)) && |
||||
|
moreColumnTitleMap.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 = columnTitleState.columnTitleArr[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 + props.excludeColumnNum + 1 }); |
||||
|
} else { |
||||
|
stickyThArr.push({ trIndex: parentTrtdIndex.trIndex, tdIndex: td + props.excludeColumnNum + 1 }); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
if (trtdIndex.tdIndex === 1 && stickyThArr.length === 0) { |
||||
|
stickyThArr.push({ trIndex: 0, tdIndex: 0 }); |
||||
|
} |
||||
|
} else { |
||||
|
if (trtdIndex.tdIndex === 1) { |
||||
|
if (props.excludeColumnNum === 2) { |
||||
|
return thStickyLastNameComputed.value.findIndex((item) => { |
||||
|
return item.name === c.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 (props.excludeColumnNum === 1) { |
||||
|
return thStickyLastNameComputed.value.findIndex((item) => { |
||||
|
return item.name === c.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 === c.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 + props.excludeColumnNum }); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (props.excludeColumnNum === 2) { |
||||
|
stickyThArr.push({ trIndex: 1, tdIndex: 1 }); |
||||
|
stickyThArr.push({ trIndex: 1, tdIndex: 2 }); |
||||
|
} else if (props.excludeColumnNum === 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) + ')' + ';'; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return style; |
||||
|
}; |
||||
|
|
||||
|
const titleScopeHandler = (column: any, scope: any) => { |
||||
|
if (props.tableColumns?.length > 0) { |
||||
|
const i = props.tableColumns.findIndex((item: any) => item['name'] === column.name); |
||||
|
if (i > -1) { |
||||
|
return scope; |
||||
|
} |
||||
|
} |
||||
|
return undefined; |
||||
|
}; |
||||
|
|
||||
|
// 将所有列转换到 map 中 |
||||
|
const columnToMap = (column: any) => { |
||||
|
if (Tools.isEmpty(column.name)) { |
||||
|
column.name = Tools.uuid(); |
||||
|
} |
||||
|
if (Tools.isEmpty(column.label)) { |
||||
|
column.label = column.name; |
||||
|
} |
||||
|
if (column && column.columns && column.columns.length > 0) { |
||||
|
allColumnMap.set(column.name, column); |
||||
|
moreColumnTitleMap.set(column.name, { |
||||
|
name: column.name, |
||||
|
label: column.label, |
||||
|
title: column.title, |
||||
|
parentLevel: 0, |
||||
|
childrenLevel: 0, |
||||
|
rowspan: 0, |
||||
|
colspan: 0, |
||||
|
rowIndex: 0, |
||||
|
style: column.style, |
||||
|
classes: column.classes, |
||||
|
parents: [], |
||||
|
}); |
||||
|
column.columns.forEach((item) => { |
||||
|
columnToMap(item); |
||||
|
}); |
||||
|
} else { |
||||
|
allColumnMap.set(column.name, column); |
||||
|
moreColumnTitleMap.set(column.name, { |
||||
|
name: column.name, |
||||
|
label: column.label, |
||||
|
title: column.title, |
||||
|
parentLevel: 0, |
||||
|
childrenLevel: 0, |
||||
|
rowspan: 0, |
||||
|
colspan: 0, |
||||
|
rowIndex: 0, |
||||
|
style: column.style, |
||||
|
classes: column.classes, |
||||
|
parents: [], |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
let tmpColspan = 0; |
||||
|
const deepArr = []; |
||||
|
const getChildrenLevel = (column, deep, deepArr) => { |
||||
|
if (column && column.columns && column.columns.length > 0) { |
||||
|
deep++; |
||||
|
column.columns.forEach((item) => { |
||||
|
getChildrenLevel(item, deep, deepArr); |
||||
|
}); |
||||
|
} else if (column) { |
||||
|
// deep++; |
||||
|
deepArr.push(deep); |
||||
|
tmpColspan += 1; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 根据子找所有父,返回值不包含查找的对象 |
||||
|
function findParents(arrData: any, name: any) { |
||||
|
if (arrData.length == 0) return; |
||||
|
for (let i = 0; i < arrData.length; i++) { |
||||
|
if (arrData[i].name == name) { |
||||
|
return []; |
||||
|
} else { |
||||
|
if (arrData[i].columns) { |
||||
|
const res = findParents(arrData[i].columns, name); |
||||
|
if (res !== undefined) { |
||||
|
return res.concat(arrData[i].name).reverse(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const handlerMoreRowColumnTitle = () => { |
||||
|
moreColumnTitleMap = new Map<string, MoreColumnTitleType>(); |
||||
|
allColumnMap = new Map(); |
||||
|
props.rawColumns.forEach((tableColumn: any) => { |
||||
|
columnToMap(tableColumn); |
||||
|
}); |
||||
|
let maxColumnChildrenLevel = 0; |
||||
|
for (let key of allColumnMap.keys()) { |
||||
|
// 处理列的 childrenLevel |
||||
|
let tmpChildrenLevel = 0; |
||||
|
getChildrenLevel(allColumnMap.get(key), 0, deepArr); |
||||
|
tmpChildrenLevel = Math.max(...deepArr); |
||||
|
if (tmpChildrenLevel > maxColumnChildrenLevel) { |
||||
|
maxColumnChildrenLevel = tmpChildrenLevel; |
||||
|
} |
||||
|
deepArr.splice(0, deepArr.length); |
||||
|
moreColumnTitleMap.get(key)!.childrenLevel = tmpChildrenLevel; |
||||
|
|
||||
|
// 处理列的 colspan |
||||
|
moreColumnTitleMap.get(key)!.colspan = tmpColspan; |
||||
|
tmpColspan = 0; |
||||
|
|
||||
|
// 处理列的 parent |
||||
|
const parent = findParents(props.rawColumns, key); |
||||
|
moreColumnTitleMap.get(key)!.parents = parent; |
||||
|
|
||||
|
// 处理列的 parentLevel |
||||
|
moreColumnTitleMap.get(key)!.parentLevel = parent.length; |
||||
|
|
||||
|
// 处理列的 rowIndex |
||||
|
moreColumnTitleMap.get(key)!.rowIndex = parent.length; |
||||
|
} |
||||
|
if (maxColumnChildrenLevel > 0) { |
||||
|
// 更改列头总行数 = 最大子层级数 + 1 |
||||
|
columnTitleState.columnTitleRowNum = maxColumnChildrenLevel + 1; |
||||
|
} |
||||
|
|
||||
|
const map = new Map<number, [any]>(); |
||||
|
for (let key of moreColumnTitleMap.keys()) { |
||||
|
const value: any = moreColumnTitleMap.get(key); |
||||
|
// 得到列头总行数后处理列的 rowspan |
||||
|
if (value.parentLevel === 0 && value.childrenLevel === 0) { |
||||
|
value.rowspan = columnTitleState.columnTitleRowNum; |
||||
|
} else if (value.parentLevel === 0) { |
||||
|
value.rowspan = 1; |
||||
|
} else { |
||||
|
// 总行数 - 父层级数 - 子层级数 |
||||
|
value.rowspan = columnTitleState.columnTitleRowNum - value.parentLevel - value.childrenLevel; |
||||
|
} |
||||
|
if (map.has(value.rowIndex)) { |
||||
|
(map.get(value.rowIndex) as any).push(value); |
||||
|
} else { |
||||
|
map.set(value.rowIndex, [value]); |
||||
|
} |
||||
|
} |
||||
|
const arr = Array.from(map); |
||||
|
|
||||
|
columnTitleState.columnTitleArr = []; |
||||
|
arr.sort((a, b) => a[0] - b[0]); |
||||
|
arr.forEach((item) => { |
||||
|
columnTitleState.columnTitleArr.push(item[1]); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const getColumnTitleState = () => { |
||||
|
return columnTitleState; |
||||
|
}; |
||||
|
const getMoreColumnTitleMap = () => { |
||||
|
return moreColumnTitleMap; |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
handlerMoreRowColumnTitle, |
||||
|
getColumnTitleState, |
||||
|
getMoreColumnTitleMap, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="css"></style> |
@ -0,0 +1,73 @@ |
|||||
|
<template> |
||||
|
<template v-if="props.grid.props.pageable && !props.grid.props.tree"> |
||||
|
<template v-if="props.state.refHeightWidth.middleWidth > 600"> |
||||
|
<q-pagination |
||||
|
v-model="page" |
||||
|
:boundary-links="props.state.pagination.config.boundaryLinks" |
||||
|
:boundary-numbers="props.state.pagination.config.boundaryNumbers" |
||||
|
:direction-links="props.state.pagination.config.directionLinks" |
||||
|
:ellipses="props.state.pagination.config.ellipses" |
||||
|
:max-pages="props.state.pagination.config.maxPages" |
||||
|
:min="1" |
||||
|
:max="props.scope.pagesNumber" |
||||
|
:size="props.denseBottom ? '10px' : ''" |
||||
|
@update:model-value="pageChange" |
||||
|
/> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<q-pagination |
||||
|
v-model="page" |
||||
|
:boundary-links="props.state.pagination.config.boundaryLinks" |
||||
|
:boundary-numbers="props.state.pagination.config.boundaryNumbers" |
||||
|
:direction-links="props.state.pagination.config.directionLinks" |
||||
|
:ellipses="props.state.pagination.config.ellipses" |
||||
|
:max-pages="3" |
||||
|
:min="1" |
||||
|
:max="props.scope.pagesNumber" |
||||
|
:size="props.denseBottom ? '10px' : ''" |
||||
|
@update:model-value="pageChange" |
||||
|
/> |
||||
|
</template> |
||||
|
<span>{{ $t('tip.pagenation.totalRecord', { count: props.state.pagination.rowsNumber }) }}</span> |
||||
|
</template> |
||||
|
<template v-else> {{ $t('tip.pagenation.totalRecord', { count: props.state.pagination.rowsNumber }) }} </template> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
const page = defineModel({ type: Number, default: 1 }); |
||||
|
const props = defineProps({ |
||||
|
grid: { |
||||
|
// 表格实例 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
scope: { |
||||
|
// 顶部插槽属性 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
state: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
denseBottom: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
request: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const pageChange = (value) => { |
||||
|
page.value = value; |
||||
|
props.request(props.state); |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="css"></style> |
@ -0,0 +1,77 @@ |
|||||
|
<template> |
||||
|
<q-td :key="col.name" :props="scope" :title="col.classes?.indexOf('truncate') > -1 && !Tools.isEmpty(value) && typeof value !== 'object' ? value : ''"> |
||||
|
<template v-if="col.name === '_sortNo_'"> |
||||
|
{{ scope.rowIndex + 1 }} |
||||
|
</template> |
||||
|
<template v-if="!Tools.isEmpty(col.type) && ((props.isSelectedRow && table.bodyEditStatus === 'rowEdit') || table.bodyEditStatus === 'rowsEdit')"> |
||||
|
<component |
||||
|
:is="col.type" |
||||
|
ref="componentRef" |
||||
|
v-bind="col.attrs" |
||||
|
v-model="props.getRow(table.rows, scope.row[props.rowKeyName], false)['_rowOldValue'][col.name]" |
||||
|
bg-color="light-green-1" |
||||
|
></component> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<template v-if="!Tools.isEmpty(value) && typeof value === 'object' && value.componentType && value.bindModelValue"> |
||||
|
<component :is="value.componentType" v-bind="value.attrs" v-model="props.getRow(table.rows, scope.row[props.rowKeyName], false)[col.name]"></component> |
||||
|
</template> |
||||
|
<template v-else-if="!Tools.isEmpty(value) && typeof value === 'object' && value.componentType"> |
||||
|
<component :is="value.componentType" v-bind="value.attrs"></component> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<span v-dompurify-html="Tools.isUndefinedOrNull(value) ? '' : value"></span> |
||||
|
</template> |
||||
|
</template> |
||||
|
</q-td> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { inject, computed, ref } from 'vue'; |
||||
|
import { Tools } from '@/platform'; |
||||
|
|
||||
|
const componentRef = ref(); |
||||
|
const props = defineProps({ |
||||
|
grid: { |
||||
|
type: Object, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
getRow: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
rowKeyName: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
scope: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
col: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
value: { |
||||
|
type: [Object, String, Number, Boolean], |
||||
|
default: '', |
||||
|
}, |
||||
|
isSelectedRow: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
}); |
||||
|
const table = inject('table'); |
||||
|
|
||||
|
const getComponentRef = () => { |
||||
|
return componentRef.value; |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
getComponentRef, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="css"></style> |
@ -0,0 +1,654 @@ |
|||||
|
<template> |
||||
|
<div class="col"> |
||||
|
<w-form ref="formRef" v-bind="props.grid.props.queryFormAttrs" :fields="queryFormFieldsComputed" :cols-num="props.grid.props.queryFormColsNum"></w-form> |
||||
|
<div |
||||
|
v-if="props.grid.props.title || buttons_.length > 0 || props.grid.props.configButton || fields.length > 0" |
||||
|
class="flex flex-nowrap items-end" |
||||
|
:class="fields.length > 0 ? 'pt-2.5' : ''" |
||||
|
> |
||||
|
<div class="flex-none">{{ $t(props.grid.props.title ? props.grid.props.title : '') }}</div> |
||||
|
<div class="flex-1"> |
||||
|
<w-toolbar |
||||
|
ref="toolbarRef" |
||||
|
:dense="denseToolbarComputed" |
||||
|
v-bind="props.grid.props.toolbarConfigure" |
||||
|
:buttons="toolbarButtonsComputed" |
||||
|
:grid="props.grid" |
||||
|
></w-toolbar> |
||||
|
</div> |
||||
|
<div v-if="props.grid.props.configButton" class="flex-none pl-1"> |
||||
|
<q-btn round dense :size="denseToolbarComputed ? '13px' : undefined" icon="manage_accounts" unelevated outline> |
||||
|
<q-popup-proxy v-model="table.gridConfig"> |
||||
|
<GridConfig :scope="props.scope" :more-column-title-array="props.moreColumnTitleArray" :grid="props.grid"></GridConfig> |
||||
|
</q-popup-proxy> |
||||
|
</q-btn> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { computed, inject, ref, reactive, nextTick, onBeforeMount, toRaw } from 'vue'; |
||||
|
import { useQuasar, exportFile } from 'quasar'; |
||||
|
import { axios, Tools, t, NotifyManager } from '@/platform'; |
||||
|
import GridConfig from './GridConfig.vue'; |
||||
|
|
||||
|
const $q = useQuasar(); |
||||
|
|
||||
|
const formRef = ref(); |
||||
|
const toolbarRef = ref(); |
||||
|
const localeFlag = ref(false); |
||||
|
const fields = ref(<any>[]); |
||||
|
const buttons_ = ref(<any>[]); |
||||
|
const moreQueryStatus = ref(false); // 当前更多查询状态是否激活 |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
grid: { |
||||
|
// 表格实例 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
scope: { |
||||
|
// 顶部插槽属性 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
moreColumnTitleArray: { |
||||
|
// 多表头数组 |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
buildQueryCriterias: { |
||||
|
// 构建查询 |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
columns: { |
||||
|
// 表格列集合 |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
url: { |
||||
|
// 表格所有的url |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
const table = inject('table'); |
||||
|
|
||||
|
const queryFormFieldsComputed = computed(() => { |
||||
|
localeFlag.value; |
||||
|
return fields.value; |
||||
|
}); |
||||
|
const toolbarButtonsComputed = computed(() => { |
||||
|
localeFlag.value; |
||||
|
return buttons_.value; |
||||
|
}); |
||||
|
const denseToolbarComputed = computed(() => { |
||||
|
if (table.denseToolbar) { |
||||
|
return true; |
||||
|
} else if (table.dense !== false) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
const screenCols = { xs: 1, sm: 2, md: 3, lg: 4, xl: 6 }; |
||||
|
const queryFormColsNumComputed = computed(() => { |
||||
|
if (typeof props.grid.props.queryFormColsNum === 'number' && props.grid.props.queryFormColsNum > 0) { |
||||
|
return props.grid.props.queryFormColsNum; |
||||
|
} else if (typeof props.grid.props.queryFormColsNum === 'object') { |
||||
|
const screen = { ...screenCols, ...props.grid.props.queryFormColsNum }; |
||||
|
return screen[$q.screen.name]; |
||||
|
} |
||||
|
return screenCols[$q.screen.name]; |
||||
|
}); |
||||
|
|
||||
|
// 处理查询form显示的字段 |
||||
|
const handlerQueryFormShowField = () => { |
||||
|
fields.value = []; |
||||
|
if (moreQueryStatus.value) { |
||||
|
props.grid.props.queryFormFields.forEach((item: any) => { |
||||
|
fields.value.push(item); |
||||
|
item.showIf = () => { |
||||
|
return true; |
||||
|
}; |
||||
|
}); |
||||
|
} else { |
||||
|
// 一行应该显示的字段个数 |
||||
|
const rowColsNum = queryFormColsNumComputed.value * (props.grid.props.queryFormRowNum || 1); |
||||
|
let currRowColsNum = 0; |
||||
|
props.grid.props.queryFormFields.forEach((item: any) => { |
||||
|
if (Tools.hasOwnProperty(item, 'colSpan')) { |
||||
|
currRowColsNum += item.colSpan; |
||||
|
} else { |
||||
|
currRowColsNum += 1; |
||||
|
} |
||||
|
if (currRowColsNum <= rowColsNum) { |
||||
|
fields.value.push(item); |
||||
|
item.showIf = (form) => { |
||||
|
return true; |
||||
|
}; |
||||
|
} else { |
||||
|
item.showIf = (form) => { |
||||
|
return false; |
||||
|
}; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const edit = (selected) => { |
||||
|
if (!selected) { |
||||
|
NotifyManager.warn(t('action.edit.tip')); |
||||
|
} else { |
||||
|
props.grid.getEditorDialog().show(); |
||||
|
nextTick(() => { |
||||
|
props.grid.getEditorDialog().setTitle(t('action.edit')); |
||||
|
props.grid.getEditorForm().setStatus('edit'); |
||||
|
props.grid.getEditorForm().setData(selected); |
||||
|
props.grid.emit('afterEditorOpen', selected); |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const clone = (selected) => { |
||||
|
if (!selected) { |
||||
|
NotifyManager.warn(t('action.copy.tip')); |
||||
|
} else { |
||||
|
selected[props.grid.props.primaryKey] = undefined; |
||||
|
props.grid.getEditorDialog().show(); |
||||
|
nextTick(() => { |
||||
|
props.grid.getEditorDialog().setTitle(t('action.copy')); |
||||
|
props.grid.getEditorForm().setStatus('clone'); |
||||
|
props.grid.getEditorForm().setData(selected); |
||||
|
props.grid.emit('afterEditorOpen', selected); |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const remove = () => { |
||||
|
const ids = <any>[]; |
||||
|
const tickedRows = props.grid.getTickedRows(); |
||||
|
const selectedRows = props.grid.getSelectedRows(); |
||||
|
if (tickedRows?.length > 0) { |
||||
|
tickedRows.forEach((item) => { |
||||
|
ids.push(item[props.grid.props.primaryKey]); |
||||
|
}); |
||||
|
} else if (selectedRows?.length > 0) { |
||||
|
selectedRows.forEach((item) => { |
||||
|
ids.push(item[props.grid.props.primaryKey]); |
||||
|
}); |
||||
|
} |
||||
|
let requestParams: any = { |
||||
|
method: 'DELETE', |
||||
|
url: props.url.removeDataUrl || props.url.dataUrl, |
||||
|
data: ids, |
||||
|
}; |
||||
|
axios(requestParams) |
||||
|
.then((resp) => { |
||||
|
props.grid.emit('afterRemove', resp?.data); |
||||
|
NotifyManager.info(t('tip.operationSuccess')); |
||||
|
if (props.grid.props.refreshData || !props.grid.props.tree) { |
||||
|
props.grid.refresh(); |
||||
|
} else { |
||||
|
props.grid.removeRows(resp?.data); |
||||
|
} |
||||
|
}) |
||||
|
.catch((error) => { |
||||
|
console.error(error); |
||||
|
console.info('==========error==========', error); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const getExportData = async () => { |
||||
|
let resultData = <any>[]; |
||||
|
const reqParams: any = { pageable: false }; |
||||
|
let urlSearchParams = props.buildQueryCriterias(reqParams); |
||||
|
const resp = await axios.get(props.url.fetchDataUrl || props.url.dataUrl, { params: urlSearchParams }); |
||||
|
if (resp && resp.data) { |
||||
|
const responseData = resp.data; |
||||
|
if (Array.isArray(responseData)) { |
||||
|
resultData = responseData; |
||||
|
} else if (typeof responseData === 'object' && responseData.content) { |
||||
|
resultData = responseData.content; |
||||
|
} |
||||
|
} |
||||
|
return resultData; |
||||
|
}; |
||||
|
|
||||
|
const wrapCsvValue = (val, formatFn, row) => { |
||||
|
let formatted = formatFn !== void 0 ? formatFn(val, row) : val; |
||||
|
formatted = formatted === void 0 || formatted === null ? '' : String(formatted); |
||||
|
formatted = formatted.split('"').join('""'); |
||||
|
/** |
||||
|
* Excel accepts \n and \r in strings, but some other CSV parsers do not |
||||
|
* Uncomment the next two lines to escape new lines |
||||
|
*/ |
||||
|
// .split('\n').join('\\n') |
||||
|
// .split('\r').join('\\r') |
||||
|
return `"${formatted}"`; |
||||
|
}; |
||||
|
|
||||
|
const resetDefaultValues = () => { |
||||
|
let requestParams: any = { |
||||
|
method: 'POST', |
||||
|
url: props.url.dataUrl + '/resetDefaultValues', |
||||
|
}; |
||||
|
axios(requestParams) |
||||
|
.then((resp) => { |
||||
|
NotifyManager.info(t('tip.operationSuccess')); |
||||
|
props.grid.refresh(); |
||||
|
}) |
||||
|
.catch((error) => { |
||||
|
console.error(error); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const showLoading = (msg: string = '正在处理,请稍等...') => { |
||||
|
$q.loading.show({ |
||||
|
message: msg, |
||||
|
boxClass: 'bg-grey-2 text-grey-9', |
||||
|
spinnerColor: 'primary', |
||||
|
}); |
||||
|
}; |
||||
|
const hideLoading = () => { |
||||
|
$q.loading.hide(); |
||||
|
}; |
||||
|
|
||||
|
const buttonObj = reactive({ |
||||
|
separator: 'separator', |
||||
|
query: { |
||||
|
name: 'query', |
||||
|
icon: 'search', |
||||
|
labelI18nKey: 'action.query', |
||||
|
label: t('action.query'), |
||||
|
click: () => { |
||||
|
props.grid.refresh(); |
||||
|
}, |
||||
|
}, |
||||
|
moreQuery: { |
||||
|
name: 'moreQuery', |
||||
|
icon: 'zoom_in', |
||||
|
labelI18nKey: 'action.moreQueryConditions', |
||||
|
label: t('action.moreQueryConditions'), |
||||
|
enableIf: () => { |
||||
|
if (props.grid.props.queryFormFields.length <= fields.value.length && !moreQueryStatus.value) { |
||||
|
return false; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
}, |
||||
|
click: () => { |
||||
|
moreQueryStatus.value = !moreQueryStatus.value; |
||||
|
handlerQueryFormShowField(); |
||||
|
}, |
||||
|
}, |
||||
|
reset: { |
||||
|
name: 'reset', |
||||
|
icon: 'restart_alt', |
||||
|
labelI18nKey: 'action.reset', |
||||
|
label: t('action.reset'), |
||||
|
click: () => { |
||||
|
formRef.value.reset(); |
||||
|
}, |
||||
|
}, |
||||
|
refresh: { |
||||
|
name: 'refresh', |
||||
|
icon: 'loop', |
||||
|
labelI18nKey: 'action.refresh', |
||||
|
label: t('action.refresh'), |
||||
|
click: () => { |
||||
|
props.grid.refresh(); |
||||
|
}, |
||||
|
}, |
||||
|
add: { |
||||
|
name: 'add', |
||||
|
icon: 'add', |
||||
|
labelI18nKey: 'action.addNew', |
||||
|
label: t('action.addNew'), |
||||
|
click: () => { |
||||
|
props.grid.getEditorDialog().show(); |
||||
|
nextTick(() => { |
||||
|
props.grid.getEditorDialog().setTitle(t('action.addNew')); |
||||
|
props.grid.getEditorForm().setStatus('add'); |
||||
|
props.grid.emit('afterEditorOpen'); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
edit: { |
||||
|
name: 'edit', |
||||
|
icon: 'edit', |
||||
|
labelI18nKey: 'action.edit', |
||||
|
label: t('action.edit'), |
||||
|
enableIf: (args) => { |
||||
|
if (args.selected) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: (args) => { |
||||
|
edit(args.selected); |
||||
|
}, |
||||
|
}, |
||||
|
rowEdit: { |
||||
|
name: 'rowEdit', |
||||
|
icon: 'border_color', |
||||
|
labelI18nKey: 'action.edit', |
||||
|
label: t('action.edit'), |
||||
|
enableIf: (args) => { |
||||
|
if (args.selected) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: (args) => { |
||||
|
table.bodyEditStatus = 'rowEdit'; |
||||
|
}, |
||||
|
}, |
||||
|
rowsEdit: { |
||||
|
name: 'rowsEdit', |
||||
|
icon: 'app_registration', |
||||
|
labelI18nKey: 'action.edit', |
||||
|
label: t('action.edit'), |
||||
|
click: (args) => { |
||||
|
table.bodyEditStatus = 'rowsEdit'; |
||||
|
// 清空勾选与选中 |
||||
|
props.grid.cleanSelected(); |
||||
|
props.grid.cleanTicked(); |
||||
|
table.allTicked = false; |
||||
|
}, |
||||
|
}, |
||||
|
clone: { |
||||
|
name: 'clone', |
||||
|
icon: 'content_copy', |
||||
|
labelI18nKey: 'action.copy', |
||||
|
label: t('action.copy'), |
||||
|
enableIf: (args) => { |
||||
|
if (args.selected) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: (args) => { |
||||
|
clone(args.selected); |
||||
|
}, |
||||
|
}, |
||||
|
remove: { |
||||
|
name: 'remove', |
||||
|
icon: 'delete', |
||||
|
labelI18nKey: 'action.remove', |
||||
|
label: t('action.remove'), |
||||
|
enableIf: (args) => { |
||||
|
if (args.ticked) { |
||||
|
return true; |
||||
|
} else if (args.selected) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: (tips: boolean = true) => { |
||||
|
if (!tips) { |
||||
|
remove(); |
||||
|
} else { |
||||
|
$q.dialog({ |
||||
|
title: t('confirm'), |
||||
|
message: t('action.remove.tip'), |
||||
|
cancel: { noCaps: true }, |
||||
|
ok: { noCaps: true }, |
||||
|
persistent: true, |
||||
|
}).onOk(() => { |
||||
|
remove(); |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
view: { |
||||
|
name: 'view', |
||||
|
icon: 'visibility', |
||||
|
labelI18nKey: 'action.view', |
||||
|
label: t('action.view'), |
||||
|
enableIf: (args) => { |
||||
|
if (args.selected) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: () => { |
||||
|
props.grid.view(); |
||||
|
}, |
||||
|
}, |
||||
|
export: { |
||||
|
name: 'export', |
||||
|
icon: 'file_download', |
||||
|
labelI18nKey: 'action.export', |
||||
|
label: t('action.export'), |
||||
|
click: async () => { |
||||
|
showLoading(); |
||||
|
let exportData = props.grid.getRows(); |
||||
|
// 判断是否配置了 url, 以不分页形式请求后端获取全部数据一把导出。 |
||||
|
if (!Tools.isEmpty(props.grid.props.fetchDataUrl) || !Tools.isEmpty(props.grid.props.dataUrl)) { |
||||
|
const fetchResult = await getExportData(); |
||||
|
if (fetchResult && fetchResult.length > 0) { |
||||
|
exportData = fetchResult; |
||||
|
} |
||||
|
} |
||||
|
const content = [props.columns.map((col) => wrapCsvValue(col.label))] |
||||
|
.concat( |
||||
|
exportData.map((row) => |
||||
|
props.columns |
||||
|
.map((col) => wrapCsvValue(typeof col.field === 'function' ? col.field(row) : row[col.field === void 0 ? col.name : col.field], col.format, row)) |
||||
|
.join(','), |
||||
|
), |
||||
|
) |
||||
|
.join('\r\n'); |
||||
|
|
||||
|
const status = exportFile('table-export.csv', content, { |
||||
|
encoding: 'utf-8', |
||||
|
mimeType: 'text/csv', |
||||
|
byteOrderMark: '\uFEFF', // 解决乱码问题 |
||||
|
}); |
||||
|
|
||||
|
if (status !== true) { |
||||
|
NotifyManager.error(t('action.export.failed')); |
||||
|
} |
||||
|
hideLoading(); |
||||
|
}, |
||||
|
}, |
||||
|
addTop: { |
||||
|
name: 'addTop', |
||||
|
icon: 'add', |
||||
|
labelI18nKey: 'action.addTop', |
||||
|
label: t('action.addTop'), |
||||
|
click: () => { |
||||
|
props.grid.getEditorDialog().show(); |
||||
|
nextTick(() => { |
||||
|
props.grid.getEditorDialog().setTitle(t('action.addTop')); |
||||
|
props.grid.getEditorForm().setStatus('addTop'); |
||||
|
props.grid.emit('afterEditorOpen'); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
addChild: { |
||||
|
name: 'addChild', |
||||
|
icon: 'playlist_add', |
||||
|
labelI18nKey: 'action.addChild', |
||||
|
label: t('action.addChild'), |
||||
|
enableIf: (args) => { |
||||
|
if (args.selected) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: () => { |
||||
|
props.grid.getEditorDialog().show(); |
||||
|
nextTick(() => { |
||||
|
props.grid.getEditorDialog().setTitle(t('action.addChild')); |
||||
|
props.grid.getEditorForm().setStatus('addChild'); |
||||
|
props.grid.emit('afterEditorOpen'); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
expand: { |
||||
|
name: 'expand', |
||||
|
icon: (args) => { |
||||
|
return table.treeExpand ? 'expand_less' : 'expand_more'; |
||||
|
}, |
||||
|
label: (args) => { |
||||
|
return table.treeExpand ? t('action.collapseAll') : t('action.expandAll'); |
||||
|
}, |
||||
|
click: () => { |
||||
|
props.grid.expandFun(table.rows, table.treeExpand); |
||||
|
table.treeExpand = !table.treeExpand; |
||||
|
}, |
||||
|
}, |
||||
|
resetDefaultValues: { |
||||
|
name: 'resetDefaultValues', |
||||
|
icon: 'bi-copy', |
||||
|
labelI18nKey: 'action.resetDefaultValues', |
||||
|
label: t('action.resetDefaultValues'), |
||||
|
click: (tips: boolean = true) => { |
||||
|
if (!tips) { |
||||
|
resetDefaultValues(); |
||||
|
} else { |
||||
|
$q.dialog({ |
||||
|
title: t('confirm'), |
||||
|
message: t('action.resetDefaultValues.tip'), |
||||
|
cancel: { noCaps: true }, |
||||
|
ok: { noCaps: true }, |
||||
|
persistent: true, |
||||
|
}).onOk(() => { |
||||
|
resetDefaultValues(); |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
// 处理toobar |
||||
|
const handleChildrenBtn = (arr, moreQueryShow) => { |
||||
|
const tempArr = <any>[]; |
||||
|
for (let i = 0; i < arr.length; i++) { |
||||
|
const btn = arr[i]; |
||||
|
if (Array.isArray(btn) && btn.length > 0) { |
||||
|
const handleResult = handleChildrenBtn(btn, moreQueryShow); |
||||
|
if (handleResult && handleResult.length > 0) { |
||||
|
tempArr.push(handleResult); |
||||
|
} |
||||
|
} else if (typeof btn === 'string' && buttonObj[btn]) { |
||||
|
if (btn === buttonObj.query.name && i === 0) { |
||||
|
// 查询按钮为第一个时,追加更多查询时直接追加到查询按钮当前所在下标的后面一个,不能追加为数组,否则按钮组取第一个为 QBtnDropdown 左边按钮时取到的是一个数组,会报错。 |
||||
|
// ['query', 'reset'] |
||||
|
tempArr.push(buttonObj[btn]); |
||||
|
tempArr.push(buttonObj[buttonObj.moreQuery.name]); |
||||
|
} else if (btn === buttonObj.query.name) { |
||||
|
tempArr.push([buttonObj[btn], buttonObj[buttonObj.moreQuery.name]]); |
||||
|
} else { |
||||
|
tempArr.push(buttonObj[btn]); |
||||
|
} |
||||
|
} else if (typeof btn === 'object' && btn.extend && buttonObj[btn.extend]) { |
||||
|
tempArr.push({ ...buttonObj[btn.extend], ...btn, _click: buttonObj[btn.extend].click }); |
||||
|
} else { |
||||
|
tempArr.push(btn); |
||||
|
} |
||||
|
} |
||||
|
return tempArr; |
||||
|
}; |
||||
|
const handleToolbarActions = () => { |
||||
|
buttons_.value.splice(0, buttons_.value.length); |
||||
|
// 处理查询按钮,符合条件时给其追加更多查询按钮 |
||||
|
let moreQueryShow = false; |
||||
|
const rowColsNum = queryFormColsNumComputed.value * (props.grid.props.queryFormRowNum || 1); |
||||
|
let currRowColsNum = 0; |
||||
|
let showQueryFormFieldNum = 0; |
||||
|
props.grid.props.queryFormFields.forEach((item: any) => { |
||||
|
if (Tools.hasOwnProperty(item, 'colSpan')) { |
||||
|
currRowColsNum += item.colSpan; |
||||
|
} else { |
||||
|
currRowColsNum += 1; |
||||
|
} |
||||
|
if (currRowColsNum <= rowColsNum) { |
||||
|
showQueryFormFieldNum += 1; |
||||
|
} |
||||
|
}); |
||||
|
if (showQueryFormFieldNum < props.grid.props.queryFormFields.length) { |
||||
|
moreQueryShow = true; |
||||
|
} |
||||
|
props.grid.props.toolbarActions.forEach((btn: any, index) => { |
||||
|
if (typeof btn === 'string' && buttonObj[btn]) { |
||||
|
if (btn === buttonObj.query.name && moreQueryShow) { |
||||
|
buttons_.value.push([buttonObj[btn], buttonObj[buttonObj.moreQuery.name]]); |
||||
|
} else { |
||||
|
buttons_.value.push(buttonObj[btn]); |
||||
|
} |
||||
|
} else if (Array.isArray(btn) && btn.length > 0) { |
||||
|
buttons_.value.push(handleChildrenBtn(btn, moreQueryShow)); |
||||
|
} else if (typeof btn === 'object' && btn.extend && buttonObj[btn.extend]) { |
||||
|
// 继承内置按钮 |
||||
|
buttons_.value.push({ ...buttonObj[btn.extend], ...btn, _click: buttonObj[btn.extend].click }); |
||||
|
} else { |
||||
|
buttons_.value.push(btn); |
||||
|
} |
||||
|
}); |
||||
|
if (buttons_.value.length > 0 && buttons_.value[buttons_.value.length - 1] !== 'separator' && props.grid.props.configButton) { |
||||
|
buttons_.value.push(buttonObj.separator); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const setLocaleFlag = () => { |
||||
|
localeFlag.value = !localeFlag.value; |
||||
|
}; |
||||
|
const resetLabel = () => { |
||||
|
Object.keys(buttonObj).forEach((btn) => { |
||||
|
if (typeof buttonObj[btn] === 'object' && buttonObj[btn].labelI18nKey) { |
||||
|
buttonObj[btn].label = t(buttonObj[btn].labelI18nKey); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const buttonClick = (arr) => { |
||||
|
arr.forEach((button) => { |
||||
|
if (typeof button === 'object' && !Tools.isEmpty(button.click) && props.grid.props.dbClickOperation === button.name) { |
||||
|
toolbarRef.value.buttonClick(button); |
||||
|
} else if (Array.isArray(button) && button.length > 0) { |
||||
|
buttonClick(button); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
const dbClickOperation = (row) => { |
||||
|
if (!Tools.isEmpty(row) && props.grid.props.dbClickOperation === buttonObj.expand.name) { |
||||
|
row['expand'] = Tools.isEmpty(row['expand']) ? true : !row['expand']; |
||||
|
} else { |
||||
|
buttonClick(buttons_.value); |
||||
|
} |
||||
|
}; |
||||
|
const getQueryForm = () => { |
||||
|
return formRef.value; |
||||
|
}; |
||||
|
|
||||
|
onBeforeMount(() => { |
||||
|
handleToolbarActions(); |
||||
|
}); |
||||
|
|
||||
|
defineExpose({ |
||||
|
setLocaleFlag, |
||||
|
edit, |
||||
|
handlerQueryFormShowField, |
||||
|
handleToolbarActions, |
||||
|
resetLabel, |
||||
|
dbClickOperation, |
||||
|
getQueryForm, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="css"></style> |
@ -0,0 +1,100 @@ |
|||||
|
<template> |
||||
|
<w-drawer ref="drawerRef" :title="$t('action.view')" v-bind="props.grid.props.viewer.drawer"> |
||||
|
<div class="p-2.5"> |
||||
|
<w-info-panel ref="infoRef" v-bind="props.grid.props.viewer.panel" :info="infoArray"></w-info-panel> |
||||
|
</div> |
||||
|
</w-drawer> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { t, Tools, NotifyManager } from '@/platform'; |
||||
|
|
||||
|
const drawerRef = ref(); |
||||
|
const infoRef = ref(); |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
grid: { |
||||
|
// 表格实例 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
tableColumnsMap: { |
||||
|
type: Map, |
||||
|
default: () => { |
||||
|
return new Map(); |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const infoArray = ref(<any>[]); |
||||
|
|
||||
|
const view = () => { |
||||
|
const selected = props.grid.getSelectedRow(); |
||||
|
if (!selected) { |
||||
|
NotifyManager.warn(t('action.view.tip')); |
||||
|
} else { |
||||
|
infoArray.value = []; |
||||
|
if (props.grid.props.viewer.panel.fields && props.grid.props.viewer.panel.fields.length > 0) { |
||||
|
for (let item of props.grid.props.viewer.panel.fields) { |
||||
|
if (item.format) { |
||||
|
let value = selected[item.name]; |
||||
|
try { |
||||
|
value = item.format(selected[item.name], selected[0]); |
||||
|
} catch (error) { |
||||
|
console.error('format error!'); |
||||
|
} |
||||
|
infoArray.value.push({ label: item.label, value: value, originalValue: selected[item.name] }); |
||||
|
} else { |
||||
|
let value = null; |
||||
|
if (props.tableColumnsMap.get(item.name) && !Tools.isEmpty(props.tableColumnsMap.get(item.name).format)) { |
||||
|
value = selected[item.name]; |
||||
|
try { |
||||
|
value = props.tableColumnsMap.get(item.name).format(selected[item.name], selected); |
||||
|
} catch (error) { |
||||
|
console.error('format error!'); |
||||
|
} |
||||
|
} else { |
||||
|
value = selected[item.name]; |
||||
|
} |
||||
|
infoArray.value.push({ label: item.label, value: value, originalValue: selected[item.name] }); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
for (let item of props.tableColumnsMap) { |
||||
|
if (item[1].format) { |
||||
|
let value = selected[item[0]]; |
||||
|
try { |
||||
|
value = item[1].format(selected[item[0]], selected); |
||||
|
} catch (error) { |
||||
|
console.error('format error!'); |
||||
|
} |
||||
|
infoArray.value.push({ label: item[1].label, value: value, originalValue: selected[item.name] }); |
||||
|
} else { |
||||
|
infoArray.value.push({ |
||||
|
label: item[1].label, |
||||
|
value: selected[item[0]], |
||||
|
originalValue: selected[item.name], |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
drawerRef.value.show(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const getViewerDrawer = () => { |
||||
|
return drawerRef.value; |
||||
|
}; |
||||
|
const getInfoPanel = () => { |
||||
|
return infoRef.value; |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
getViewerDrawer, |
||||
|
getInfoPanel, |
||||
|
view, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="css"></style> |
File diff suppressed because it is too large
@ -1,39 +0,0 @@ |
|||||
<template> |
|
||||
<q-table :binary-state-sort="true" column-sort-order="ad" :v-bind="attrs"> |
|
||||
<template #top> |
|
||||
<div class="row"> |
|
||||
<div class="col">{{ attrs.title }}</div> |
|
||||
<div class="col items-end"> |
|
||||
<q-btn label="dksfj"></q-btn> |
|
||||
</div> |
|
||||
</div> |
|
||||
</template> |
|
||||
</q-table> |
|
||||
</template> |
|
||||
|
|
||||
<script setup lang="ts"> |
|
||||
import { useAttrs } from 'vue'; |
|
||||
import { useI18n } from 'vue-i18n'; |
|
||||
import { Tools } from '@/platform/utils/Tools'; |
|
||||
|
|
||||
const attrs = useAttrs(); |
|
||||
const { t } = useI18n(); |
|
||||
|
|
||||
for (const column of attrs.columns) { |
|
||||
if (Tools.isUndefinedOrNull(column.label)) { |
|
||||
column.label = t(column.name); |
|
||||
} |
|
||||
if (Tools.isUndefinedOrNull(column.field)) { |
|
||||
column.field = column.name; |
|
||||
} |
|
||||
if (Tools.isUndefinedOrNull(column.align)) { |
|
||||
column.align = 'left'; |
|
||||
} |
|
||||
if (Tools.isUndefinedOrNull(column.sortable)) { |
|
||||
column.sortable = true; |
|
||||
} |
|
||||
if (Tools.isUndefinedOrNull(column.sortOrder)) { |
|
||||
column.sortOrder = 'da'; |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
@ -0,0 +1,645 @@ |
|||||
|
.w-grid .q-table__top { |
||||
|
padding: var(--tableTopPadding) var(--tableTopPadding); |
||||
|
} |
||||
|
.w-grid .q-table__middle .q-table th { |
||||
|
padding: var(--tableHeaderPadding) 8px; |
||||
|
border-left-width: 0px; |
||||
|
border-right-width: 1px; |
||||
|
border-top-width: 0px; |
||||
|
border-bottom-width: 1px; |
||||
|
} |
||||
|
.w-grid .q-table__middle .q-table th:last-child { |
||||
|
border-right-width: 0px; |
||||
|
} |
||||
|
.w-grid .q-table__middle .q-table td { |
||||
|
height: var(--tableBodyHeight); |
||||
|
padding: var(--tableBodyPadding) 8px; |
||||
|
border-left-width: 0px; |
||||
|
border-right-width: 1px; |
||||
|
border-top-width: 0px; |
||||
|
border-bottom-width: 1px; |
||||
|
} |
||||
|
.w-grid .q-table__middle .q-table td:last-child { |
||||
|
border-right-width: 0px; |
||||
|
} |
||||
|
.w-grid .q-table__bottom { |
||||
|
min-height: var(--tableBottomHeight); |
||||
|
border-color: rgba(0, 0, 0, 0.12); |
||||
|
border-style: solid; |
||||
|
border-top-width: 0px; |
||||
|
border-left-width: 1px; |
||||
|
border-right-width: 1px; |
||||
|
border-bottom-width: 1px; |
||||
|
} |
||||
|
.w-grid .q-table__control .q-field__control { |
||||
|
min-height: var(--tableBottomButtonHeight) !important; |
||||
|
} |
||||
|
.w-grid .q-table__control .q-field__control q-field__append { |
||||
|
height: var(--tableBottomButtonHeight) !important; |
||||
|
} |
||||
|
.w-grid .q-table__control .q-field__control-container .q-field__native { |
||||
|
min-height: var(--tableBottomButtonHeight) !important; |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
.w-grid .q-table__control .q-field__control .q-field__marginal { |
||||
|
height: var(--tableBottomButtonHeight) !important; |
||||
|
} |
||||
|
.w-grid .q-table__card .q-table__middle { |
||||
|
border-color: rgba(0, 0, 0, 0.12); |
||||
|
border-style: solid; |
||||
|
border-left-width: 1px; |
||||
|
border-right-width: 1px; |
||||
|
border-bottom-width: 1px; |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table thead tr:not(.noDataTr) { |
||||
|
height: var(--tableColumnTitleHeight) !important; |
||||
|
} |
||||
|
|
||||
|
/** 表格所有th固定、设置默认index、背景设置 */ |
||||
|
.sticky-header-column-table tr th { |
||||
|
position: sticky; |
||||
|
z-index: 2; |
||||
|
background: var(--tableHeadBgColor); |
||||
|
} |
||||
|
|
||||
|
/** 固定表头后,修改top距离 */ |
||||
|
.sticky-header-column-table thead { |
||||
|
position: sticky; |
||||
|
z-index: 2; |
||||
|
top: 0; |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-1-1 tr:first-child th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-2 tr:first-child th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-2-rb tr:first-child th:nth-child(2) { |
||||
|
border-right-width: 1px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-3 tr:first-child th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-4 tr:first-child th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-5 tr:first-child th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-6 tr:first-child th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-7 tr:first-child th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-8 tr:first-child th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-9 tr:first-child th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-1-10 tr:first-child th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-2-1 tr:nth-child(2) th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-2-2 tr:nth-child(2) th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-2-3 tr:nth-child(2) th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-2-4 tr:nth-child(2) th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-2-5 tr:nth-child(2) th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-2-6 tr:nth-child(2) th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-2-7 tr:nth-child(2) th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-2-8 tr:nth-child(2) th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-2-9 tr:nth-child(2) th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-2-10 tr:nth-child(2) th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-3-1 tr:nth-child(3) th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-3-2 tr:nth-child(3) th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-3-3 tr:nth-child(3) th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-3-4 tr:nth-child(3) th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-3-5 tr:nth-child(3) th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-3-6 tr:nth-child(3) th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-3-7 tr:nth-child(3) th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-3-8 tr:nth-child(3) th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-3-9 tr:nth-child(3) th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-3-10 tr:nth-child(3) th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-4-1 tr:nth-child(4) th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-4-2 tr:nth-child(4) th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-4-3 tr:nth-child(4) th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-4-4 tr:nth-child(4) th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-4-5 tr:nth-child(4) th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-4-6 tr:nth-child(4) th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-4-7 tr:nth-child(4) th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-4-8 tr:nth-child(4) th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-4-9 tr:nth-child(4) th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-4-10 tr:nth-child(4) th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-5-1 tr:nth-child(5) th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-5-2 tr:nth-child(5) th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-5-3 tr:nth-child(5) th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-5-4 tr:nth-child(5) th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-5-5 tr:nth-child(5) th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-5-6 tr:nth-child(5) th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-5-7 tr:nth-child(5) th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-5-8 tr:nth-child(5) th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-5-9 tr:nth-child(5) th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-5-10 tr:nth-child(5) th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-6-1 tr:nth-child(6) th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-6-2 tr:nth-child(6) th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-6-3 tr:nth-child(6) th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-6-4 tr:nth-child(6) th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-6-5 tr:nth-child(6) th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-6-6 tr:nth-child(6) th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-6-7 tr:nth-child(6) th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-6-8 tr:nth-child(6) th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-6-9 tr:nth-child(6) th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-6-10 tr:nth-child(6) th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-7-1 tr:nth-child(7) th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-7-2 tr:nth-child(7) th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-7-3 tr:nth-child(7) th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-7-4 tr:nth-child(7) th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-7-5 tr:nth-child(7) th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-7-6 tr:nth-child(7) th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-7-7 tr:nth-child(7) th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-7-8 tr:nth-child(7) th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-7-9 tr:nth-child(7) th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-7-10 tr:nth-child(7) th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-8-1 tr:nth-child(8) th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-8-2 tr:nth-child(8) th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-8-3 tr:nth-child(8) th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-8-4 tr:nth-child(8) th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-8-5 tr:nth-child(8) th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-8-6 tr:nth-child(8) th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-8-7 tr:nth-child(8) th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-8-8 tr:nth-child(8) th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-8-9 tr:nth-child(8) th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-8-10 tr:nth-child(8) th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-9-1 tr:nth-child(9) th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-9-2 tr:nth-child(9) th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-9-3 tr:nth-child(9) th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-9-4 tr:nth-child(9) th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-9-5 tr:nth-child(9) th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-9-6 tr:nth-child(9) th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-9-7 tr:nth-child(9) th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-9-8 tr:nth-child(9) th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-9-9 tr:nth-child(9) th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-9-10 tr:nth-child(9) th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-tr-10-1 tr:nth-child(10) th:first-child { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-tr-10-2 tr:nth-child(10) th:nth-child(2) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-10-3 tr:nth-child(10) th:nth-child(3) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-10-4 tr:nth-child(10) th:nth-child(4) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-10-5 tr:nth-child(10) th:nth-child(5) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-10-6 tr:nth-child(10) th:nth-child(6) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-10-7 tr:nth-child(10) th:nth-child(7) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-10-8 tr:nth-child(10) th:nth-child(8) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-10-9 tr:nth-child(10) th:nth-child(9) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-tr-10-10 tr:nth-child(10) th:nth-child(10) { |
||||
|
z-index: 3; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
||||
|
|
||||
|
.sticky-header-column-table-td-1 td:first-child { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: 0px; |
||||
|
} |
||||
|
.sticky-header-column-table-td-2 td:nth-child(2) { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: var(--column1Width); |
||||
|
} |
||||
|
.sticky-header-column-table-td-3 td:nth-child(3) { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: var(--column2Width); |
||||
|
} |
||||
|
.sticky-header-column-table-td-4 td:nth-child(4) { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: var(--column3Width); |
||||
|
} |
||||
|
.sticky-header-column-table-td-5 td:nth-child(5) { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: var(--column4Width); |
||||
|
} |
||||
|
.sticky-header-column-table-td-6 td:nth-child(6) { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: var(--column5Width); |
||||
|
} |
||||
|
.sticky-header-column-table-td-7 td:nth-child(7) { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: var(--column6Width); |
||||
|
} |
||||
|
.sticky-header-column-table-td-8 td:nth-child(8) { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: var(--column7Width); |
||||
|
} |
||||
|
.sticky-header-column-table-td-9 td:nth-child(9) { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: var(--column8Width); |
||||
|
} |
||||
|
.sticky-header-column-table-td-10 td:nth-child(10) { |
||||
|
background-color: var(--stickyBgColor); |
||||
|
z-index: 1; |
||||
|
position: sticky; |
||||
|
left: var(--column9Width); |
||||
|
} |
@ -0,0 +1,59 @@ |
|||||
|
import { Tools, t, componentRegistryName } from '@/platform'; |
||||
|
|
||||
|
// 列样式处理
|
||||
|
const columnStyle = (item: any) => { |
||||
|
let style = ''; |
||||
|
if (Tools.hasOwnProperty(item, 'style')) { |
||||
|
style = item.style; |
||||
|
} |
||||
|
if (Tools.hasOwnProperty(item, 'width')) { |
||||
|
if (typeof item.width === 'number') { |
||||
|
item.style = `min-width: ` + item.width + `px; width: ` + item.width + `px;max-width: ` + item.width + `px;` + style; |
||||
|
} else { |
||||
|
item.style = `min-width: ` + item.width + `; width: ` + item.width + `;max-width: ` + item.width + `;` + style; |
||||
|
} |
||||
|
delete item.width; |
||||
|
|
||||
|
if (Tools.hasOwnProperty(item, 'classes')) { |
||||
|
item.classes = item.classes + ' truncate'; |
||||
|
} else { |
||||
|
item.classes = 'truncate'; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 孩子列处理
|
||||
|
const childrenHandler = (item: any, gridColumns: any) => { |
||||
|
if (item.columns && item.columns.length > 0) { |
||||
|
item.columns.forEach((column) => { |
||||
|
childrenHandler(column, gridColumns); |
||||
|
}); |
||||
|
} else { |
||||
|
columnStyle(item); |
||||
|
// 替换行编辑类型为注册名
|
||||
|
if (!Tools.isEmpty(item.type)) { |
||||
|
item.type = componentRegistryName(item.type); |
||||
|
} |
||||
|
const col = { |
||||
|
...{ align: 'left', label: item.name, field: item.name, name: item.name, sortable: true, hidden: false }, |
||||
|
...item, |
||||
|
}; |
||||
|
if (Tools.isEmpty(col.name)) { |
||||
|
col.name = Tools.uuid(); |
||||
|
} |
||||
|
gridColumns.push(col); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 列的默认属性
|
||||
|
export const columnDefaultProps = (columns: any, sortNo: boolean = true) => { |
||||
|
const gridColumns = <any>[]; |
||||
|
if (columns && columns.length > 0) { |
||||
|
gridColumns.push({ name: '_sortNo_', align: 'center', label: t('rownum'), field: '_sortNo_', hidden: sortNo }); |
||||
|
columns.forEach((item: any) => { |
||||
|
childrenHandler(item, gridColumns); |
||||
|
}); |
||||
|
return gridColumns; |
||||
|
} |
||||
|
return []; |
||||
|
}; |
@ -1,334 +0,0 @@ |
|||||
import { Tools } from '@/platform/utils'; |
|
||||
/** |
|
||||
* 抽取窗口组件属性 |
|
||||
* @param {Object} props 属性对象 |
|
||||
* @returns 窗口组件属性 |
|
||||
*/ |
|
||||
export function extractDialogProps(props: any) { |
|
||||
if (props) { |
|
||||
const result: any = {}; |
|
||||
result.persistent = props.persistent; // 设置后,用户在对话框外单击或按 ESC 键时不再关闭对话框;此外,应用程序路由更改也不会关闭它
|
|
||||
result.noEscDismiss = props.noEscDismiss; // 用户不能按 ESC 键关闭对话框;如果还设置了 'persistent' 属性,则无需设置它
|
|
||||
result.noBackdropDismiss = props.noBackdropDismiss; // 用户不能通过单击对话框外部来关闭对话框;如果还设置了 'persistent' 属性,则无需设置它
|
|
||||
result.noRouteDismiss = props.noRouteDismiss; // 更改路由应用程序不会关闭对话框;如果还设置了 'persistent' 属性,则无需设置它
|
|
||||
result.autoClose = props.autoClose; // 对话框内的任何单击/点击都将关闭它
|
|
||||
result.noShake = props.noShake; // 不要晃动对话框来引起用户的注意。
|
|
||||
result.allowFocusOutside = props.allowFocusOutside; // 允许对话框外的元素可聚焦;出于辅助功能的原因,默认情况下 QDialog 不允许外部聚焦.
|
|
||||
result.seamless = props.seamless; // 使对话框进入无缝模式;不使用背景,因此用户也可以与页面的其他部分进行交互
|
|
||||
result.position = props.position; // 将对话框附着到一侧(默认:standard、top、right、bottom、left)
|
|
||||
result.square = props.square; // 强制内容具有方形边框
|
|
||||
return Tools.pickNotNil(result); |
|
||||
} |
|
||||
return {}; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 抽取form表单组件属性 |
|
||||
* @param {Object} props 属性对象 |
|
||||
* @returns 表单组件属性 |
|
||||
*/ |
|
||||
export function extractFormProps(props: any) { |
|
||||
if (props) { |
|
||||
const result: any = {}; |
|
||||
result.autofocus = props.autofocus; // 在初始组件渲染时将第一个可聚焦元素聚焦
|
|
||||
result.greedy = props.greedy; // 验证表单中的所有字段(默认情况下,它在通过同步的验证找到第一个无效字段后停止)
|
|
||||
return Tools.pickNotNil(result); |
|
||||
} |
|
||||
return {}; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 抽取表单项组件属性 |
|
||||
* @param {String} type 组件类型 |
|
||||
* @param {Object} props 属性对象 |
|
||||
* @returns 表单项组件属性 |
|
||||
*/ |
|
||||
export function extractFormItemComponentProps(type: string, props: any) { |
|
||||
if ('dateRange' === type) { |
|
||||
return dateRange(props); |
|
||||
} else if ('date' === type) { |
|
||||
return date(props); |
|
||||
} else if ('select' === type) { |
|
||||
return select(props); |
|
||||
} else if ('checkbox' === type) { |
|
||||
return checkbox(props); |
|
||||
} else if ('optionGroup' === type) { |
|
||||
return optionGroup(props); |
|
||||
} else { |
|
||||
return input(props); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* input组件 |
|
||||
* @param props |
|
||||
* @returns |
|
||||
*/ |
|
||||
function input(props: any) { |
|
||||
if (props) { |
|
||||
const result: any = {}; |
|
||||
result.hint = props.hint; // 辅助(提示)文本,放在组件下面
|
|
||||
result.hideBottomSpace = props.hideBottomSpace ?? true; |
|
||||
result.hideHint = props.hideHint ?? true; // 当字段没有焦点时隐藏辅助(提示)文本
|
|
||||
result.stackLabel = props.stackLabel; // 标签将始终显示在字段上方,而不考虑字段内容(如果有)
|
|
||||
result.prefix = props.prefix; // 前缀
|
|
||||
result.suffix = props.suffix; // 后缀
|
|
||||
result.clearable = props.clearable; // 设置值(非 undefined 或 null )时附加可清除图标;单击时,模型将变为空
|
|
||||
result.counter = props.counter; // 在右下角显示自动计数器(字符数)
|
|
||||
result.autogrow = props.autogrow; // 使字段及其内容自动增长(内容过长时组件变高,内容换行)
|
|
||||
result.maxlength = props.maxlength; // 指定模型的最大长度
|
|
||||
result.disable = props.disable; // 将组件置于禁用模式
|
|
||||
result.labelColor = props.labelColor; // 组件 label 的文字颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.color = props.color; // 组件颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.bgColor = props.bgColor; // 组件背景颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.filled = props.filled; // 对字段使用“填充”设计
|
|
||||
result.outlined = props.outlined ?? true; // 对字段使用“轮廓线”设计
|
|
||||
result.borderless = props.borderless; // 对字段采用“无边界”设计,与 outlined 冲突
|
|
||||
result.rounded = props.rounded; // 为组件应用较小标准的边框圆角,也就是边框为椭圆
|
|
||||
result.dense = props.dense ?? true; // 紧凑模式,占用更少的空间
|
|
||||
result.type = props.type; // 组件类型
|
|
||||
return Tools.pickNotNil(result); |
|
||||
} |
|
||||
return {}; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 日期范围组件 |
|
||||
* @param props |
|
||||
* @returns |
|
||||
*/ |
|
||||
function dateRange(props: any) { |
|
||||
if (props) { |
|
||||
const result: any = {}; |
|
||||
result.hint = props.hint; // 辅助(提示)文本,放在组件下面
|
|
||||
result.hideHint = props.hideHint ?? true; // 当字段没有焦点时隐藏辅助(提示)文本
|
|
||||
result.hideBottomSpace = props.hideBottomSpace ?? true; |
|
||||
result.stackLabel = props.stackLabel; // 标签将始终显示在字段上方,而不考虑字段内容(如果有)
|
|
||||
result.clearable = props.clearable; // 设置值(非 undefined 或 null )时附加可清除图标;单击时,模型将变为空
|
|
||||
result.disable = props.disable; // 将组件置于禁用模式
|
|
||||
result.labelColor = props.labelColor; // 组件 label 的文字颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.color = props.color; // 组件颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.bgColor = props.bgColor; // 组件背景颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.filled = props.filled; // 对字段使用“填充”设计
|
|
||||
result.outlined = props.outlined ?? true; // 对字段使用“轮廓线”设计
|
|
||||
result.borderless = props.borderless; // 对字段采用“无边界”设计,与 outlined 冲突
|
|
||||
result.rounded = props.rounded; // 为组件应用较小标准的边框圆角,也就是边框为椭圆
|
|
||||
result.dense = props.dense ?? true; // 紧凑模式,占用更少的空间
|
|
||||
return Tools.pickNotNil(result); |
|
||||
} |
|
||||
return {}; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 日期组件 |
|
||||
* @param props |
|
||||
* @returns |
|
||||
*/ |
|
||||
function date(props: any) { |
|
||||
if (props) { |
|
||||
const result: any = {}; |
|
||||
result.hint = props.hint; // 辅助(提示)文本,放在组件下面
|
|
||||
result.hideHint = props.hideHint ?? true; // 当字段没有焦点时隐藏辅助(提示)文本
|
|
||||
result.hideBottomSpace = props.hideBottomSpace ?? true; |
|
||||
result.stackLabel = props.stackLabel; // 标签将始终显示在字段上方,而不考虑字段内容(如果有)
|
|
||||
result.clearable = props.clearable; // 设置值(非 undefined 或 null )时附加可清除图标;单击时,模型将变为空
|
|
||||
result.disable = props.disable; // 将组件置于禁用模式
|
|
||||
result.labelColor = props.labelColor; // 组件 label 的文字颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.color = props.color; // 组件颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.bgColor = props.bgColor; // 组件背景颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.filled = props.filled; // 对字段使用“填充”设计
|
|
||||
result.outlined = props.outlined ?? true; // 对字段使用“轮廓线”设计
|
|
||||
result.borderless = props.borderless; // 对字段采用“无边界”设计,与 outlined 冲突
|
|
||||
result.rounded = props.rounded; // 为组件应用较小标准的边框圆角,也就是边框为椭圆
|
|
||||
result.dense = props.dense ?? true; // 紧凑模式,占用更少的空间
|
|
||||
return Tools.pickNotNil(result); |
|
||||
} |
|
||||
return {}; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 下拉框组件 |
|
||||
* @param props |
|
||||
* @returns |
|
||||
*/ |
|
||||
function select(props: any) { |
|
||||
if (props) { |
|
||||
const result: any = {}; |
|
||||
result.hint = props.hint; // 辅助(提示)文本,放在组件下面
|
|
||||
result.hideHint = props.hideHint ?? true; // 当字段没有焦点时隐藏辅助(提示)文本
|
|
||||
result.hideBottomSpace = props.hideBottomSpace ?? true; |
|
||||
result.stackLabel = props.stackLabel; // 标签将始终显示在字段上方,而不考虑字段内容(如果有)
|
|
||||
result.prefix = props.prefix; // 前缀
|
|
||||
result.suffix = props.suffix; // 后缀
|
|
||||
result.clearable = props.clearable; // 设置值(非 undefined 或 null )时附加可清除图标;单击时,模型将变为空
|
|
||||
result.counter = props.counter; // 在右下角显示自动计数器(字符数)
|
|
||||
result.useInput = props.useInput; // 使用一个输入标签,用户可以在其中输入
|
|
||||
result.autogrow = props.autogrow; // 使字段及其内容自动增长(内容过长时组件变高,内容换行)
|
|
||||
result.disable = props.disable; // 将组件置于禁用模式
|
|
||||
result.labelColor = props.labelColor; // 组件 label 的文字颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.color = props.color; // 组件颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.bgColor = props.bgColor; // 组件背景颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.filled = props.filled; // 对字段使用“填充”设计
|
|
||||
result.outlined = props.outlined ?? true; // 对字段使用“轮廓线”设计
|
|
||||
result.borderless = props.borderless; // 对字段采用“无边界”设计,与 outlined 冲突
|
|
||||
result.rounded = props.rounded; // 为组件应用较小标准的边框圆角,也就是边框为椭圆
|
|
||||
result.dense = props.dense ?? true; // 紧凑模式,占用更少的空间
|
|
||||
result.multiple = props.multiple; // 支持多选
|
|
||||
result.options = props.options; // 下拉选项集合
|
|
||||
result.maxValues = props.maxValues; // 允许用户可以进行的最大选择数
|
|
||||
result.useChips = props.useChips; // 使用QChip显示当前选择的内容
|
|
||||
return Tools.pickNotNil(result); |
|
||||
} |
|
||||
return {}; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 复选框组件 |
|
||||
* @param props |
|
||||
* @returns |
|
||||
*/ |
|
||||
function checkbox(props: any) { |
|
||||
if (props) { |
|
||||
const result: any = {}; |
|
||||
result.keepColor = props.keepColor; // 当组件未勾选/关闭时,是否应保留颜色?
|
|
||||
result.checkedIcon = props.checkedIcon; // 此图标将会在 model 值为 true 时被使用(代替默认的设计)
|
|
||||
result.uncheckedIcon = props.uncheckedIcon; // 此图标将会在 model 值为 false 时被使用(代替默认的设计)
|
|
||||
result.toggleIndeterminate = props.toggleIndeterminate ?? false; // 当用户点击组件时,除 true 和 false 外,是否还添加一个不确定(indeterminate)的状态?
|
|
||||
result.leftLabel = props.leftLabel; // 如有标签,应显示在组件的左侧
|
|
||||
result.trueValue = props.trueValue; // model 为何值时被视为选中/勾选/启用?
|
|
||||
result.falseValue = props.falseValue; // model 为何值时被视为未选中/未勾选/关闭?
|
|
||||
result.disable = props.disable; // 将组件置于禁用模式
|
|
||||
result.size = props.size; // 带有 CSS 单位的尺寸大小,包括单位的名称或标准大小名称(xs | sm | md | lg | xl)
|
|
||||
result.color = props.color; // 组件的颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.dense = props.dense; // 紧凑模式,占用更少的空间
|
|
||||
return Tools.pickNotNil(result); |
|
||||
} |
|
||||
return {}; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 选项组组件 |
|
||||
* @param props |
|
||||
* @returns |
|
||||
*/ |
|
||||
function optionGroup(props: any) { |
|
||||
if (props) { |
|
||||
const result: any = {}; |
|
||||
result.name = props.name; // 用于指定控件的名称;如果处理直接提交到 URL 的表单时很有用
|
|
||||
result.keepColor = props.keepColor; // 当组件未勾选/关闭时,是否应保留颜色?
|
|
||||
result.type = props.optionGroupType; // 要使用的输入组件类型,默认radio,可选:radio、checkbox、toggle
|
|
||||
result.leftLabel = props.leftLabel; // 如有标签,应显示在组件的左侧
|
|
||||
result.inline = props.inline ?? true; // 将输入组件显示为内联块,而不是每个组件都有自己的行
|
|
||||
result.options = props.options; //具有值、标签和禁用(可选)属性的对象数组,包含的属性:label、value、disable等
|
|
||||
result.disable = props.disable; // 将组件置于禁用模式下
|
|
||||
result.size = props.size; // 带有 CSS 单位的尺寸大小,包括单位的名称或标准大小名称(xs | sm | md | lg | xl)
|
|
||||
result.color = props.color; // 组件的颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.dense = props.dense; // 紧凑模式,占用更少的空间
|
|
||||
return Tools.pickNotNil(result); |
|
||||
} |
|
||||
return {}; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 抽取表格组件属性 |
|
||||
* @param {Object} props 属性对象 |
|
||||
* @returns 表格组件属性 |
|
||||
*/ |
|
||||
export function extractTableProps(props: any) { |
|
||||
if (props) { |
|
||||
const result: any = {}; |
|
||||
result.color = props.color; // 组件的颜色,来自 Quasar 调色板的颜色名称
|
|
||||
result.dense = props.dense; // 密恐模式;
|
|
||||
result.dark = props.dark; // 设置组件背景为深色
|
|
||||
result.flat = props.flat; // 应用“平面”设计(无默认阴影)
|
|
||||
result.bordered = props.bordered; // 将默认边框应用于组件
|
|
||||
result.square = props.square; // 删除边框圆角(border-radius),使边框为正方形
|
|
||||
return Tools.pickNotNil(result); |
|
||||
} |
|
||||
return {}; |
|
||||
} |
|
||||
|
|
||||
function columnStyle(item: any) { |
|
||||
let style = ''; |
|
||||
if (Tools.hasOwnProperty(item, 'style')) { |
|
||||
style = item.style; |
|
||||
} |
|
||||
if (Tools.hasOwnProperty(item, 'width')) { |
|
||||
if (typeof item.width === 'number') { |
|
||||
item.style = `min-width: ` + item.width + `px; width: ` + item.width + `px;max-width: ` + item.width + `px;` + style; |
|
||||
} else { |
|
||||
item.style = `min-width: ` + item.width + `; width: ` + item.width + `;max-width: ` + item.width + `;` + style; |
|
||||
} |
|
||||
delete item.width; |
|
||||
|
|
||||
if (Tools.hasOwnProperty(item, 'classes')) { |
|
||||
item.classes = item.classes + ' truncate'; |
|
||||
} else { |
|
||||
item.classes = 'truncate'; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
function columnChildrenHandler(item: any, gridColumns: any) { |
|
||||
if (item.columns && item.columns.length > 0) { |
|
||||
item.columns.forEach((column) => { |
|
||||
columnChildrenHandler(column, gridColumns); |
|
||||
}); |
|
||||
} else { |
|
||||
columnStyle(item); |
|
||||
gridColumns.push({ |
|
||||
...{ align: 'left', label: item.name, field: item.name, sortable: true, hidden: false }, |
|
||||
...item, |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
/** |
|
||||
* 处理表格列属性 |
|
||||
*/ |
|
||||
export function extractTableColumnsProps(props: any) { |
|
||||
const gridColumns = <any>[]; |
|
||||
if (props.columns && props.columns.length > 0) { |
|
||||
gridColumns.push({ name: '_sortNo_', align: 'center', label: '序号', field: '_sortNo_', hidden: props.sortNo ? false : true }); |
|
||||
props.columns.forEach((item: any) => { |
|
||||
columnChildrenHandler(item, gridColumns); |
|
||||
}); |
|
||||
return gridColumns; |
|
||||
} |
|
||||
return []; |
|
||||
} |
|
||||
|
|
||||
const formColsScreenMap = new Map(); |
|
||||
formColsScreenMap.set(1, { xs: 1, sm: 1, md: 2, lg: 3, xl: 4 }); |
|
||||
formColsScreenMap.set(2, { xs: 1, sm: 2, md: 2, lg: 3, xl: 4 }); |
|
||||
formColsScreenMap.set(3, { xs: 1, sm: 2, md: 3, lg: 4, xl: 6 }); |
|
||||
formColsScreenMap.set(4, { xs: 1, sm: 2, md: 4, lg: 4, xl: 6 }); |
|
||||
formColsScreenMap.set(5, { xs: 1, sm: 2, md: 5, lg: 6, xl: 6 }); |
|
||||
formColsScreenMap.set(6, { xs: 1, sm: 3, md: 6, lg: 6, xl: 6 }); |
|
||||
formColsScreenMap.set(7, { xs: 1, sm: 4, md: 7, lg: 7, xl: 7 }); |
|
||||
formColsScreenMap.set(8, { xs: 1, sm: 4, md: 8, lg: 8, xl: 8 }); |
|
||||
formColsScreenMap.set(9, { xs: 1, sm: 4, md: 9, lg: 9, xl: 9 }); |
|
||||
formColsScreenMap.set(10, { xs: 1, sm: 4, md: 10, lg: 10, xl: 10 }); |
|
||||
formColsScreenMap.set(11, { xs: 1, sm: 4, md: 11, lg: 11, xl: 11 }); |
|
||||
formColsScreenMap.set(12, { xs: 1, sm: 4, md: 12, lg: 12, xl: 12 }); |
|
||||
/** |
|
||||
* 根据设置的每列显示数、屏幕断点获取当前查询表单每行显示多少个字段 |
|
||||
* @param configColsNumber |
|
||||
* @param screen |
|
||||
*/ |
|
||||
export function getQueryFormColsNumberByScreen(configColsNumber: number, screen: any) { |
|
||||
return formColsScreenMap.get(configColsNumber)[screen]; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 集合根据传入的key转map |
|
||||
* @param key |
|
||||
* @param array |
|
||||
*/ |
|
||||
export function arrayToMap(key, array) { |
|
||||
const map = new Map(); |
|
||||
array.forEach((item) => { |
|
||||
if (item.name !== '_sortNo_') { |
|
||||
map.set(item[key], item); |
|
||||
} |
|
||||
}); |
|
||||
return map; |
|
||||
} |
|
@ -0,0 +1,18 @@ |
|||||
|
<template> |
||||
|
<template v-if="props.value && typeof props.value === 'object' && props.value.componentType"> |
||||
|
<component :is="props.value.componentType" v-bind="props.value.attrs"></component> |
||||
|
</template> |
||||
|
<template v-else-if="props.value"> |
||||
|
{{ props.value }} |
||||
|
{{ props.value }} |
||||
|
</template> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
const props = defineProps({ |
||||
|
value: { |
||||
|
type: [Object, String, Number, Boolean], |
||||
|
default: '', |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="css"></style> |
@ -1,752 +1,69 @@ |
|||||
<!-- <template> |
|
||||
<q-splitter :model-value="65" class="w-full h-full"> |
|
||||
<template #before> |
|
||||
<div class="px-1"> |
|
||||
<w-grid |
|
||||
ref="userGridRef" |
|
||||
:title="$t('system.user.grid.title')" |
|
||||
selection="multiple" |
|
||||
:query-form-fields="[ |
|
||||
{ name: 'loginName', label: $t('loginName'), type: 'text' }, |
|
||||
{ name: 'userName', label: $t('userName'), type: 'text' }, |
|
||||
{ name: 'enable', label: $t('isEnable'), type: 'select', options: Options.yesNo() }, |
|
||||
{ name: 'dataComeFrom', label: $t('dataComeFrom'), type: 'select', options: Options.enum(DataComeFromEnum) }, |
|
||||
]" |
|
||||
:toolbar-configure="{ noIcon: false }" |
|
||||
:toolbar-actions="[ |
|
||||
'query', |
|
||||
'refresh', |
|
||||
'separator', |
|
||||
'add', |
|
||||
'clone', |
|
||||
'edit', |
|
||||
'remove', |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'setPassword', |
|
||||
label: t('system.user.action.setPassword'), |
|
||||
icon: 'bi-shield-check', |
|
||||
enableIf: function (selecteds) { |
|
||||
return selecteds.length > 0; |
|
||||
}, |
|
||||
click: function (selecteds) { |
|
||||
setPasswordDialogRef.open('setPassword', selecteds); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'setAllPassword', |
|
||||
label: t('system.user.action.setAllPassword'), |
|
||||
icon: 'bi-shield', |
|
||||
enableIf: function (selecteds) { |
|
||||
return true; |
|
||||
}, |
|
||||
click: function () { |
|
||||
setPasswordDialogRef.open('setAllPassword'); |
|
||||
}, |
|
||||
}, |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'resetPassword', |
|
||||
label: t('system.user.action.resetPassword'), |
|
||||
icon: 'bi-shield-fill-check', |
|
||||
enableIf: function (selecteds) { |
|
||||
return selecteds.length > 0; |
|
||||
}, |
|
||||
click: function (selecteds) { |
|
||||
DialogManager.confirm(t('system.user.confirm.resetPassword'), () => { |
|
||||
const userIds = Tools.extractProperties(selecteds, 'id'); |
|
||||
axios.post(Environment.apiContextPath('/api/system/user/resetPassword'), userIds).then(() => { |
|
||||
NotifyManager.info(t('operationSuccess')); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'resetAllPassword', |
|
||||
label: t('system.user.action.resetAllPassword'), |
|
||||
icon: 'bi-shield-fill', |
|
||||
enableIf: function (selecteds) { |
|
||||
return true; |
|
||||
}, |
|
||||
click: function () { |
|
||||
DialogManager.confirm(t('system.user.confirm.resetAllPassword'), () => { |
|
||||
axios.post(Environment.apiContextPath('/api/system/user/resetAllPassword')).then(() => { |
|
||||
setPasswordDialogRef.value.hide(); |
|
||||
NotifyManager.info(t('operationSuccess')); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
'separator', |
|
||||
'view', |
|
||||
'export', |
|
||||
]" |
|
||||
:data-url="Environment.apiContextPath('/api/system/user')" |
|
||||
row-key="id" |
|
||||
:columns="[ |
|
||||
{ name: 'loginName', label: t('loginName') }, |
|
||||
{ name: 'userName', label: t('userName') }, |
|
||||
{ |
|
||||
name: 'status', |
|
||||
label: t('status'), |
|
||||
format: (value, row) => { |
|
||||
return { |
|
||||
componentType: UserStatusTag, |
|
||||
attrs: row, |
|
||||
}; |
|
||||
}, |
|
||||
}, |
|
||||
{ name: 'dataComeFrom', label: t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
|
||||
{ name: 'lastModifier', label: t('lastModifier') }, |
|
||||
{ name: 'lastModifyDate', label: t('lastModifyDate'), format: Formater.dateOnly() }, |
|
||||
]" |
|
||||
:editor="{ |
|
||||
dialog: { |
|
||||
width: '600px', |
|
||||
height: '610px', |
|
||||
}, |
|
||||
form: { |
|
||||
colsNum: 4, |
|
||||
fields: [ |
|
||||
{ name: 'loginName', label: t('loginName'), type: 'text', required: true, colspan: 4 }, |
|
||||
{ name: 'userName', label: t('userName'), type: 'text', required: true, colspan: 4 }, |
|
||||
{ name: 'description', label: t('description'), type: 'textarea', rows: 1, colspan: 4 }, |
|
||||
{ name: 'password', label: t('password'), type: 'password', colspan: 4 }, |
|
||||
{ |
|
||||
name: 'confirmPassword', |
|
||||
label: t('confirmPassword'), |
|
||||
type: 'password', |
|
||||
colspan: 4, |
|
||||
rules: [ |
|
||||
(value) => { |
|
||||
return Tools.stringEquals(userGridRef.getAddEditFormRef().value.getData().password, value) |
|
||||
? true |
|
||||
: t('passwordAndConfirmPasswordMustEqual'); |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
{ name: 'mobile', label: t('mobile'), type: 'text', colsFirst: true, colspan: 4 }, |
|
||||
{ name: 'phone', label: t('phone'), type: 'text', colsFirst: true, colspan: 4 }, |
|
||||
{ name: 'email', label: t('email'), type: 'text', colsFirst: true, colspan: 4 }, |
|
||||
{ name: 'weixin', label: t('weixin'), type: 'text', colsFirst: true, colspan: 4 }, |
|
||||
{ name: 'qq', label: t('qq'), type: 'text', colsFirst: true, colspan: 4 }, |
|
||||
|
|
||||
{ name: 'enable', label: t('enable'), type: 'checkbox', defaultValue: true }, |
|
||||
{ name: 'accountExpired', label: t('accountExpired'), type: 'checkbox', defaultValue: false }, |
|
||||
{ name: 'accountLocked', label: t('accountLocked'), type: 'checkbox', defaultValue: false }, |
|
||||
{ name: 'credentialsExpired', label: t('credentialsExpired'), type: 'checkbox', defaultValue: false }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
:viewer="{ |
|
||||
panel: { |
|
||||
columnNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'id', label: t('id') }, |
|
||||
{ name: 'loginName', label: t('loginName') }, |
|
||||
{ name: 'userName', label: t('userName') }, |
|
||||
{ name: 'description', label: t('description') }, |
|
||||
{ name: 'enable', label: t('enable'), format: Formater.yesNo() }, |
|
||||
{ name: 'accountExpired', label: t('accountExpired'), format: Formater.yesNo() }, |
|
||||
{ name: 'accountLocked', label: t('accountLocked'), format: Formater.yesNo() }, |
|
||||
{ name: 'credentialsExpired', label: t('credentialsExpired'), format: Formater.yesNo() }, |
|
||||
{ name: 'email', label: t('email') }, |
|
||||
{ name: 'phone', label: t('phone') }, |
|
||||
{ name: 'mobile', label: t('mobile') }, |
|
||||
{ name: 'weixin', label: t('weixin') }, |
|
||||
{ name: 'qq', label: t('qq') }, |
|
||||
{ name: 'dataComeFrom', label: t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
|
||||
{ name: 'creator', label: t('creator') }, |
|
||||
{ name: 'createDate', label: t('createDate') }, |
|
||||
{ name: 'lastModifier', label: t('lastModifier') }, |
|
||||
{ name: 'lastModifyDate', label: t('lastModifyDate') }, |
|
||||
{ name: 'corporationCode', label: t('corporationCode') }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
@row-click=" |
|
||||
(evt, row, index) => { |
|
||||
currentSelectedUserId = row.id; |
|
||||
roleQueryUrl = Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + currentSelectedUserId; |
|
||||
orgQueryUrl = Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByUser?userId=') + currentSelectedUserId; |
|
||||
roleGridRef?.refresh(); |
|
||||
orgTreeGridRef?.refresh(); |
|
||||
// if (roleGridRef) { |
|
||||
// roleGridRef.setFetchDataUrl(Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + row.id); |
|
||||
// } |
|
||||
// if (orgTreeGridRef) { |
|
||||
// orgTreeGridRef.setFetchDataUrl(Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByUser?userId=') + row.id); |
|
||||
// orgTreeGridRef.refresh(); |
|
||||
// } |
|
||||
} |
|
||||
" |
|
||||
></w-grid> |
|
||||
</div> |
|
||||
</template> |
|
||||
<template #after> |
|
||||
<div class="px-1"> |
|
||||
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0"> |
|
||||
<q-tab name="role" icon="bi-people" :label="$t('role')" /> |
|
||||
<q-tab name="org" icon="bi-diagram-3" :label="$t('org')" /> |
|
||||
</q-tabs> |
|
||||
|
|
||||
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive class=""> |
|
||||
<q-tab-panel name="role" class="p-0"> |
|
||||
<w-grid |
|
||||
ref="roleGridRef" |
|
||||
:title="$t('system.role.grid.title')" |
|
||||
:data-url="roleQueryUrl" |
|
||||
:auto-fetch-data="false" |
|
||||
selection="multiple" |
|
||||
:full-screen-button="false" |
|
||||
:toolbar-configure="{ noIcon: true }" |
|
||||
:toolbar-actions="[ |
|
||||
'refresh', |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'addRole', |
|
||||
label: $t('system.role.action.addRole'), |
|
||||
enableIf: () => { |
|
||||
if (userGridRef) { |
|
||||
return userGridRef.getSelectedRows().length > 0; |
|
||||
} |
|
||||
return false; |
|
||||
}, |
|
||||
click: () => { |
|
||||
selectRoleDialog.open({ userId: userGridRef.getSelectedRows()[0].id, userGrid: userGridRef, roleGrid: roleGridRef }); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'addAllRole', |
|
||||
label: t('system.role.action.addAllRole'), |
|
||||
enableIf: () => { |
|
||||
if (userGridRef) { |
|
||||
return userGridRef.getSelectedRows().length > 0; |
|
||||
} |
|
||||
return false; |
|
||||
}, |
|
||||
click: () => { |
|
||||
const selectedUser = userGridRef.getSelectedRows()[0]; |
|
||||
DialogManager.confirm( |
|
||||
t('system.role.action.addAllRole.confirm', { userLoginName: selectedUser.loginName, userName: selectedUser.userName }), |
|
||||
() => { |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/user/addAllRoles'), { |
|
||||
one: selectedUser.id, |
|
||||
many: [], |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + selectedUser.id).then((response) => { |
|
||||
roleGridRef.replaceRows(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
); |
|
||||
}, |
|
||||
}, |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'removeRole', |
|
||||
label: t('system.role.action.removeRole'), |
|
||||
enableIf: () => { |
|
||||
if (userGridRef && roleGridRef) { |
|
||||
return userGridRef.getSelectedRows().length > 0 && roleGridRef.getSelectedRows().length > 0; |
|
||||
} |
|
||||
return false; |
|
||||
}, |
|
||||
click: (selecteds) => { |
|
||||
const selectedUser = userGridRef.getSelectedRows()[0]; |
|
||||
const roleIds = Tools.extractProperties(selecteds, 'id'); |
|
||||
const messageKey = roleIds.length > 1 ? 'system.role.action.removeRole.confirms' : 'system.role.action.removeRole.confirm'; |
|
||||
DialogManager.confirm( |
|
||||
t(messageKey, { |
|
||||
userLoginName: selectedUser.loginName, |
|
||||
userName: selectedUser.userName, |
|
||||
roleCode: selecteds[0].code, |
|
||||
roleName: selecteds[0].name, |
|
||||
counter: selecteds.length, |
|
||||
}), |
|
||||
() => { |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/user/removeRoles'), { |
|
||||
one: selectedUser.id, |
|
||||
many: roleIds, |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + selectedUser.id).then((response) => { |
|
||||
roleGridRef.replaceRows(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'removeAllRole', |
|
||||
label: $t('system.role.action.removeAllRole'), |
|
||||
enableIf: () => { |
|
||||
if (userGridRef && roleGridRef) { |
|
||||
return userGridRef.getSelectedRows().length > 0 && roleGridRef.getRows().length > 0; |
|
||||
} |
|
||||
return false; |
|
||||
}, |
|
||||
click: () => { |
|
||||
const selectedUser = userGridRef.getSelectedRows()[0]; |
|
||||
DialogManager.confirm( |
|
||||
t('system.role.action.removeAllRole.confirm', { userLoginName: selectedUser.loginName, userName: selectedUser.userName }), |
|
||||
() => { |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/user/removeAllRoles'), { |
|
||||
one: selectedUser.id, |
|
||||
many: [], |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + selectedUser.id).then((response) => { |
|
||||
roleGridRef.replaceRows(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
); |
|
||||
}, |
|
||||
}, |
|
||||
'separator', |
|
||||
'view', |
|
||||
]" |
|
||||
:columns="[ |
|
||||
{ width: 100, name: 'code', label: $t('code') }, |
|
||||
{ width: 100, name: 'name', label: $t('name') }, |
|
||||
{ |
|
||||
width: 60, |
|
||||
name: 'status', |
|
||||
label: t('status'), |
|
||||
format: (value, row) => { |
|
||||
return { |
|
||||
componentType: RoleStatusTag, |
|
||||
attrs: row, |
|
||||
}; |
|
||||
}, |
|
||||
}, |
|
||||
]" |
|
||||
:viewer="{ |
|
||||
panel: { |
|
||||
columnNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'id', label: t('id') }, |
|
||||
{ name: 'code', label: t('code') }, |
|
||||
{ name: 'name', label: t('name') }, |
|
||||
{ name: 'description', label: t('description') }, |
|
||||
{ name: 'enable', label: t('enable'), format: Formater.yesNo() }, |
|
||||
{ name: 'dataComeFrom', label: t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
|
||||
{ name: 'creator', label: t('creator') }, |
|
||||
{ name: 'createDate', label: t('createDate') }, |
|
||||
{ name: 'lastModifier', label: t('lastModifier') }, |
|
||||
{ name: 'lastModifyDate', label: t('lastModifyDate') }, |
|
||||
{ name: 'corporationCode', label: t('corporationCode') }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
></w-grid> |
|
||||
</q-tab-panel> |
|
||||
<q-tab-panel name="org" class="px-0"> |
|
||||
<w-grid |
|
||||
ref="orgTreeGridRef" |
|
||||
:tree="true" |
|
||||
:title="$t('system.org.grid.title')" |
|
||||
:data-url="orgQueryUrl" |
|
||||
selection="multiple" |
|
||||
:full-screen-button="false" |
|
||||
:toolbar-configure="{ noIcon: true }" |
|
||||
:toolbar-actions="[ |
|
||||
'refresh', |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'save', |
|
||||
label: $t('save'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
'view', |
|
||||
]" |
|
||||
:pagination="{ |
|
||||
sortBy: 'name', |
|
||||
descending: false, |
|
||||
reqPageStart: 0, |
|
||||
rowsPerPage: 0, |
|
||||
}" |
|
||||
:columns="[ |
|
||||
{ width: 100, name: 'code', label: $t('code') }, |
|
||||
{ width: 100, name: 'name', label: $t('name') }, |
|
||||
{ |
|
||||
width: 60, |
|
||||
name: 'status', |
|
||||
label: t('status'), |
|
||||
format: (value, row) => { |
|
||||
return { |
|
||||
componentType: RoleStatusTag, |
|
||||
attrs: row, |
|
||||
}; |
|
||||
}, |
|
||||
}, |
|
||||
]" |
|
||||
:viewer="{ |
|
||||
panel: { |
|
||||
columnNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'id', label: t('id') }, |
|
||||
{ name: 'code', label: t('code') }, |
|
||||
{ name: 'name', label: t('name') }, |
|
||||
{ name: 'description', label: t('description') }, |
|
||||
{ name: 'enable', label: t('enable'), format: Formater.yesNo() }, |
|
||||
{ name: 'dataComeFrom', label: t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
|
||||
{ name: 'creator', label: t('creator') }, |
|
||||
{ name: 'createDate', label: t('createDate') }, |
|
||||
{ name: 'lastModifier', label: t('lastModifier') }, |
|
||||
{ name: 'lastModifyDate', label: t('lastModifyDate') }, |
|
||||
{ name: 'corporationCode', label: t('corporationCode') }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
></w-grid> |
|
||||
</q-tab-panel> |
|
||||
</q-tab-panels> |
|
||||
</div> |
|
||||
</template> |
|
||||
<SelectRoleDialog ref="selectRoleDialog"></SelectRoleDialog> |
|
||||
<SetPasswordDialog ref="setPasswordDialogRef"></SetPasswordDialog> |
|
||||
</q-splitter> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref } from 'vue'; |
|
||||
import { useI18n } from 'vue-i18n'; |
|
||||
import { Environment, axios, EnumTools, NotifyManager, DialogManager, Formater, Options, Tools } from '@/platform'; |
|
||||
import SelectRoleDialog from './SelectRoleDialog.vue'; |
|
||||
import SetPasswordDialog from './SetPasswordDialog.vue'; |
|
||||
import UserStatusTag from './UserStatusTag.vue'; |
|
||||
import RoleStatusTag from './RoleStatusTag.vue'; |
|
||||
import { nextTick } from 'vue'; |
|
||||
|
|
||||
const { t } = useI18n(); |
|
||||
|
|
||||
const userGridRef = ref(); |
|
||||
const roleGridRef = ref(); |
|
||||
const orgTreeGridRef = ref(); |
|
||||
|
|
||||
const selectRoleDialog = ref(); |
|
||||
const selectedTabRef = ref('role'); |
|
||||
const setPasswordDialogRef = ref(); |
|
||||
|
|
||||
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
|
||||
const currentSelectedUserId = ref(); |
|
||||
|
|
||||
const roleQueryUrl = ref(''); |
|
||||
const orgQueryUrl = ref(''); |
|
||||
|
|
||||
const orgConfigure = { |
|
||||
actions: [ |
|
||||
{ |
|
||||
name: 'save', |
|
||||
label: '保存', |
|
||||
click: () => { |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/user/updateOrgs'), { |
|
||||
one: userGridRef.value.getSelectedRows()[0].id, |
|
||||
many: orgTreeGridRef.value.getTicked(), |
|
||||
}) |
|
||||
.then((response) => {}); |
|
||||
}, |
|
||||
}, |
|
||||
], |
|
||||
}; |
|
||||
</script> --> |
|
||||
|
|
||||
<template> |
<template> |
||||
<q-splitter :model-value="60" class="w-full h-full"> |
<div class="q-pa-md"> |
||||
<template #before> |
<q-table v-model:selected="selected" title="Treats" row-key="name" selection="multiple" :rows="rows" :columns="columns"> |
||||
<div class="px-1"> |
<template #body="scope"> |
||||
<w-grid |
<q-tr ref="trRef" class="selected" :props="scope"> |
||||
ref="roleGridRef" |
<q-td class="text-center" style="padding: 0; width: 50px"> |
||||
:title="$t('system.role.grid.title')" |
<q-checkbox v-model="scope.row['selected']" flat @update:model-value="updateTicked($event, scope.row)" /> |
||||
:data-url="Environment.apiContextPath('/api/system/role')" |
</q-td> |
||||
selection="multiple" |
<q-td v-for="col in scope.cols" :key="col.name" :props="scope"> |
||||
:query-form-fields="[ |
<GridFormat :value="col.value"></GridFormat> |
||||
{ name: 'code', label: $t('code'), type: 'text' }, |
</q-td> |
||||
{ name: 'name', label: $t('name'), type: 'text' }, |
</q-tr> |
||||
{ name: 'enable', label: $t('isEnable'), type: 'select', options: Options.yesNo() }, |
</template> |
||||
{ name: 'dataComeFrom', label: $t('dataComeFrom'), type: 'select', options: Options.enum(DataComeFromEnum) }, |
</q-table> |
||||
]" |
|
||||
:toolbar-configure="{ noIcon: false }" |
|
||||
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'export']" |
|
||||
:columns="[ |
|
||||
{ name: 'code', label: $t('code') }, |
|
||||
{ name: 'name', label: $t('name') }, |
|
||||
{ width: 80, name: 'status', label: $t('status'), format: Formater.enableTag() }, |
|
||||
{ width: 100, name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
|
||||
{ width: 120, name: 'lastModifier', label: $t('lastModifier') }, |
|
||||
{ width: 120, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, |
|
||||
]" |
|
||||
:editor="{ |
|
||||
dialog: { |
|
||||
width: '600px', |
|
||||
height: '300px', |
|
||||
}, |
|
||||
form: { |
|
||||
colsNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'code', label: $t('code'), type: 'text', required: true }, |
|
||||
{ name: 'name', label: $t('name'), type: 'text', required: true }, |
|
||||
{ name: 'description', label: $t('description'), type: 'textarea', rows: 1 }, |
|
||||
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
:viewer="{ |
|
||||
panel: { |
|
||||
columnNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'id', label: $t('id') }, |
|
||||
{ name: 'code', label: $t('code') }, |
|
||||
{ name: 'name', label: $t('name') }, |
|
||||
{ name: 'description', label: $t('description') }, |
|
||||
{ name: 'enable', label: $t('enable'), format: Formater.yesNo() }, |
|
||||
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
|
||||
{ name: 'creator', label: $t('creator') }, |
|
||||
{ name: 'createDate', label: $t('createDate') }, |
|
||||
{ name: 'lastModifier', label: $t('lastModifier') }, |
|
||||
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
|
||||
{ name: 'corporationCode', label: $t('corporationCode') }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
@row-click=" |
|
||||
(evt, row, index) => { |
|
||||
currentSelectedRoleId = row.id; |
|
||||
userGridRef?.refresh(); |
|
||||
menuTreeGridRef?.refresh(); |
|
||||
} |
|
||||
" |
|
||||
> |
|
||||
</w-grid> |
|
||||
</div> |
</div> |
||||
</template> |
</template> |
||||
<template #after> |
|
||||
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0" no-caps> |
|
||||
<q-tab name="menu" icon="bi-people" :label="$t('menu')" /> |
|
||||
<q-tab name="user" icon="bi-diagram-3" :label="$t('user')" /> |
|
||||
</q-tabs> |
|
||||
|
|
||||
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive> |
|
||||
<q-tab-panel name="menu" class="px-0"> |
|
||||
<w-grid |
|
||||
ref="menuTreeGridRef" |
|
||||
:tree="true" |
|
||||
:title="$t('system.org.grid.title')" |
|
||||
:data-url="Environment.apiContextPath('/api/system/menu/listAllMenusWithSelectedStatusByRole?roleId=') + currentSelectedRoleId" |
|
||||
selection="multiple" |
|
||||
:pageable="false" |
|
||||
:full-screen-button="false" |
|
||||
:toolbar-configure="{ noIcon: true }" |
|
||||
:toolbar-actions="[ |
|
||||
'refresh', |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'save', |
|
||||
label: $t('save'), |
|
||||
click: () => { |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/role/updateMenus'), { |
|
||||
one: userGridRef.getSelectedRows()[0].id, |
|
||||
many: menuTreeGridRef.getTicked(), |
|
||||
}) |
|
||||
.then((response) => {}); |
|
||||
}, |
|
||||
}, |
|
||||
'view', |
|
||||
]" |
|
||||
:columns="[ |
|
||||
{ |
|
||||
width: 100, |
|
||||
name: 'titleI18nKey', |
|
||||
label: $t('name'), |
|
||||
format: (value, row) => { |
|
||||
return $t(value); |
|
||||
}, |
|
||||
}, |
|
||||
{ width: 60, name: 'enable', label: $t('status'), format: Formater.enableTag() }, |
|
||||
]" |
|
||||
:viewer="{ |
|
||||
panel: { |
|
||||
columnNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'id', label: $t('id') }, |
|
||||
{ name: 'code', label: $t('code') }, |
|
||||
{ name: 'name', label: $t('name') }, |
|
||||
{ name: 'description', label: $t('description') }, |
|
||||
{ name: 'enable', label: $t('enable'), format: Formater.yesNo() }, |
|
||||
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
|
||||
{ name: 'creator', label: $t('creator') }, |
|
||||
{ name: 'createDate', label: $t('createDate') }, |
|
||||
{ name: 'lastModifier', label: $t('lastModifier') }, |
|
||||
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
|
||||
{ name: 'corporationCode', label: $t('corporationCode') }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
></w-grid> |
|
||||
</q-tab-panel> |
|
||||
|
|
||||
<q-tab-panel name="user" class="px-0"> |
|
||||
<w-grid |
|
||||
ref="userGridRef" |
|
||||
:title="$t('system.role.selectUser.grid.title')" |
|
||||
:fetch-data-url="Environment.apiContextPath('/api/system/user/queryUsersByRole?roleId=') + currentSelectedRoleId" |
|
||||
:auto-fetch-data="false" |
|
||||
selection="multiple" |
|
||||
:full-screen-button="false" |
|
||||
:toolbar-configure="{ noIcon: true }" |
|
||||
:toolbar-actions="[ |
|
||||
'refresh', |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'addUser', |
|
||||
label: $t('system.role.selectUser.grid.toolbar.addUser'), |
|
||||
enableIf: () => { |
|
||||
if (roleGridRef) { |
|
||||
return roleGridRef.getSelectedRows().length > 0; |
|
||||
} |
|
||||
return false; |
|
||||
}, |
|
||||
click: () => { |
|
||||
selectUserDialog.open({ roleId: roleGridRef.getSelectedRows()[0].id, userGrid: userGridRef }); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'addAllUser', |
|
||||
label: $t('system.role.selectUser.grid.toolbar.addAllUser'), |
|
||||
enableIf: () => { |
|
||||
if (roleGridRef) { |
|
||||
return roleGridRef.getSelectedRows().length > 0; |
|
||||
} |
|
||||
return false; |
|
||||
}, |
|
||||
click: () => { |
|
||||
const selectedRole = roleGridRef.getSelectedRows()[0]; |
|
||||
DialogManager.confirm($t('system.role.selectUser.grid.toolbar.addAllUser.tip'), () => { |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/role/addAllUsers'), { |
|
||||
one: selectedRole.id, |
|
||||
many: [], |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
userGridRef?.refresh(); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'removeUser', |
|
||||
label: $t('system.role.selectUser.grid.toolbar.removeUser'), |
|
||||
enableIf: () => { |
|
||||
if (roleGridRef && userGridRef) { |
|
||||
return roleGridRef.getSelectedRows().length > 0 && userGridRef.getSelectedRows().length > 0; |
|
||||
} |
|
||||
return false; |
|
||||
}, |
|
||||
click: (selecteds) => { |
|
||||
const selectedRole = roleGridRef.getSelectedRows()[0]; |
|
||||
const userIds = Tools.extractProperties(selecteds, 'id'); |
|
||||
DialogManager.confirm($t('system.role.selectUser.grid.toolbar.removeUser.tip'), () => { |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/role/removeUsers'), { |
|
||||
one: selectedRole.id, |
|
||||
many: userIds, |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
userGridRef?.refresh(); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'removeAllUser', |
|
||||
label: $t('system.role.selectUser.grid.toolbar.removeAllUser'), |
|
||||
enableIf: () => { |
|
||||
if (roleGridRef) { |
|
||||
return roleGridRef.getSelectedRows().length > 0; |
|
||||
} |
|
||||
return false; |
|
||||
}, |
|
||||
click: () => { |
|
||||
const selectedRole = roleGridRef.getSelectedRows()[0]; |
|
||||
DialogManager.confirm($t('system.role.selectUser.grid.toolbar.removeAllUser.tip'), () => { |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/role/removeAllUsers'), { |
|
||||
one: selectedRole.id, |
|
||||
many: [], |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
userGridRef?.refresh(); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
'separator', |
|
||||
'view', |
|
||||
]" |
|
||||
:columns="[ |
|
||||
{ width: 100, name: 'loginName', label: t('loginName') }, |
|
||||
{ width: 100, name: 'userName', label: t('userName') }, |
|
||||
{ |
|
||||
name: 'status', |
|
||||
label: $t('status'), |
|
||||
format: (value, row) => { |
|
||||
return { |
|
||||
componentType: UserStatusTag, |
|
||||
attrs: row, |
|
||||
}; |
|
||||
}, |
|
||||
}, |
|
||||
]" |
|
||||
> |
|
||||
</w-grid> |
|
||||
</q-tab-panel> |
|
||||
</q-tab-panels> |
|
||||
</template> |
|
||||
<SelectUserDialog ref="selectUserDialog"></SelectUserDialog> |
|
||||
</q-splitter> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { ref } from 'vue'; |
import { ref } from 'vue'; |
||||
import { useI18n } from 'vue-i18n'; |
import { Tools } from '@/platform'; |
||||
import { Environment, axios, DialogManager, Tools, EnumTools, Options, Formater } from '@/platform'; |
import GridFormat from './GridForamt.vue'; |
||||
import SelectUserDialog from './SelectUserDialog.vue'; |
|
||||
import UserStatusTag from './UserStatusTag.vue'; |
|
||||
|
|
||||
const { t } = useI18n(); |
const selected = ref([]); |
||||
|
|
||||
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
const updateTicked = (event, row) => { |
||||
|
row['selected'] = !row['selected']; |
||||
const roleGridRef = ref(); |
|
||||
const userGridRef = ref(); |
|
||||
const menuTreeGridRef = ref(); |
|
||||
|
|
||||
const selectUserDialog = ref(); |
|
||||
const selectedTabRef = ref('user'); |
|
||||
const currentSelectedRoleId = ref(''); |
|
||||
|
|
||||
const menuConfigure = { |
|
||||
actions: [ |
|
||||
{ |
|
||||
name: 'save', |
|
||||
label: '保存', |
|
||||
click: () => { |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/role/updateMenus'), { |
|
||||
one: roleGridRef.value.getSelectedRows()[0].id, |
|
||||
many: menuTreeGridRef.value.getTicked(), |
|
||||
}) |
|
||||
.then((response) => {}); |
|
||||
}, |
|
||||
}, |
|
||||
], |
|
||||
}; |
}; |
||||
|
|
||||
|
const columns = [ |
||||
|
{ |
||||
|
name: 'name', |
||||
|
required: true, |
||||
|
label: 'Dessert (100g serving)', |
||||
|
align: 'left', |
||||
|
field: (row) => row.name, |
||||
|
sortable: true, |
||||
|
}, |
||||
|
{ name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true }, |
||||
|
{ |
||||
|
name: 'fat', |
||||
|
label: 'Fat (g)', |
||||
|
field: 'fat', |
||||
|
sortable: true, |
||||
|
format: (val, row) => { |
||||
|
console.info('format.val====', val); |
||||
|
return val; |
||||
|
}, |
||||
|
}, |
||||
|
{ name: 'carbs', label: 'Carbs (g)', field: 'carbs' }, |
||||
|
{ name: 'protein', label: 'Protein (g)', field: 'protein' }, |
||||
|
{ name: 'sodium', label: 'Sodium (mg)', field: 'sodium' }, |
||||
|
{ name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, |
||||
|
{ name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, |
||||
|
]; |
||||
|
|
||||
|
const rows = [ |
||||
|
{ |
||||
|
name: 'Frozen Yogurt', |
||||
|
calories: 159, |
||||
|
fat: 6.0, |
||||
|
carbs: 24, |
||||
|
protein: 4.0, |
||||
|
sodium: 87, |
||||
|
calcium: '14%', |
||||
|
iron: '1%', |
||||
|
selected: false, |
||||
|
}, |
||||
|
]; |
||||
</script> |
</script> |
||||
|
@ -1,178 +0,0 @@ |
|||||
<template> |
|
||||
<div style="height: 100%"> |
|
||||
<w-grid |
|
||||
ref="gridRef" |
|
||||
:title="$t('re.resources.designer.processor.grid.title')" |
|
||||
dense-body |
|
||||
class="px-1" |
|
||||
hide-bottom |
|
||||
:config-button="false" |
|
||||
selection="multiple" |
|
||||
:checkbox-selection="true" |
|
||||
:tree="false" |
|
||||
:fetch-data-url="Environment.apiContextPath('/api/re/model/parameter/processor/findByParameterId?parameterId=' + parameterId)" |
|
||||
:data-url="Environment.apiContextPath('/api/re/model/parameter/processor')" |
|
||||
:pageable="false" |
|
||||
:toolbar-configure="{ noIcon: false }" |
|
||||
:toolbar-actions="[ |
|
||||
'refresh', |
|
||||
'separator', |
|
||||
{ |
|
||||
extend: 'edit', |
|
||||
enableIf: (arg) => { |
|
||||
return arg.selected; |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
extend: 'remove', |
|
||||
enableIf: (arg) => { |
|
||||
return !readOnly && arg.selected; |
|
||||
}, |
|
||||
}, |
|
||||
'separator', |
|
||||
'view', |
|
||||
'separator', |
|
||||
'export', |
|
||||
]" |
|
||||
:columns="[ |
|
||||
{ width: 80, name: 'enable', label: $t('isEnable'), align: 'center', sortable: false, format: Formater.enableTag() }, |
|
||||
{ width: 60, name: 'order', label: $t('order'), sortable: false, align: 'right' }, |
|
||||
{ width: 150, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ProcessorType) }, |
|
||||
{ |
|
||||
width: '100%', |
|
||||
name: 'content', |
|
||||
label: $t('re.resources.designer.processor.grid.entity.content'), |
|
||||
sortable: false, |
|
||||
format: (value, row) => { |
|
||||
const type = row.type; |
|
||||
if ('MATH_FORMULA' === type) { |
|
||||
return { |
|
||||
componentType: 'w-expression', |
|
||||
attrs: { |
|
||||
modelValue: row.mathFormula, |
|
||||
readOnly: true, |
|
||||
zoom: 2, |
|
||||
}, |
|
||||
}; |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
]" |
|
||||
:editor="{ |
|
||||
dialog: { |
|
||||
width: '1024px', |
|
||||
}, |
|
||||
form: { |
|
||||
colsNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'parameter', label: 'parameter', type: 'text', defaultValue: parameterId, hidden: true }, |
|
||||
{ name: 'id', label: $t('id'), type: 'text', hidden: true }, |
|
||||
{ name: 'order', label: $t('order'), type: 'number', hidden: true }, |
|
||||
{ name: 'type', label: $t('type'), type: 'text', hidden: true }, |
|
||||
{ name: 'description', label: $t('description'), type: 'text', hidden: true }, |
|
||||
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true, hidden: true }, |
|
||||
{ |
|
||||
name: 'mathFormula', |
|
||||
label: $t('re.resources.designer.processor.grid.entity.mathFormula'), |
|
||||
type: 'expression', |
|
||||
showIf: (arg) => { |
|
||||
return 'MATH_FORMULA' === arg.form.getFieldValue('type'); |
|
||||
}, |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
:viewer="{ |
|
||||
panel: { |
|
||||
columnNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'order', label: $t('order') }, |
|
||||
{ name: 'id', label: $t('id'), primaryKey: true }, |
|
||||
{ name: 'parameter', label: $t('parameter') }, |
|
||||
{ name: 'description', label: $t('description') }, |
|
||||
{ name: 'enable', label: $t('enable') }, |
|
||||
{ name: 'type', label: $t('type') }, |
|
||||
{ name: 'optionCode', label: $t('re.resources.designer.processor.grid.entity.optionCode') }, |
|
||||
{ name: 'arithmetic', label: $t('re.resources.designer.processor.grid.entity.arithmetic') }, |
|
||||
{ name: 'ternaryCondition', label: $t('re.resources.designer.processor.grid.entity.ternaryCondition') }, |
|
||||
{ name: 'ternaryTrue', label: $t('re.resources.designer.processor.grid.entity.ternaryTrue') }, |
|
||||
{ name: 'ternaryFalse', label: $t('re.resources.designer.processor.grid.entity.ternaryFalse') }, |
|
||||
{ name: 'when', label: $t('re.resources.designer.processor.grid.entity.when') }, |
|
||||
{ name: 'then', label: $t('re.resources.designer.processor.grid.entity.then') }, |
|
||||
{ name: 'isWhenThenShorted', label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted') }, |
|
||||
{ name: 'rule', label: $t('re.resources.designer.processor.grid.entity.rule') }, |
|
||||
{ name: 'singleRule', label: $t('re.resources.designer.processor.grid.entity.singleRule') }, |
|
||||
{ name: 'numberRange', label: $t('re.resources.designer.processor.grid.entity.numberRange') }, |
|
||||
{ name: 'conditionRange', label: $t('re.resources.designer.processor.grid.entity.conditionRange') }, |
|
||||
{ name: 'decisionTable2C', label: $t('re.resources.designer.processor.grid.entity.decisionTable2C') }, |
|
||||
{ name: 'decisionTable', label: $t('re.resources.designer.processor.grid.entity.decisionTable') }, |
|
||||
{ name: 'groovyScript', label: $t('re.resources.designer.processor.grid.entity.groovyScript') }, |
|
||||
|
|
||||
{ name: 'sqlDatasourceName', label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName') }, |
|
||||
{ name: 'sql', label: $t('re.resources.designer.processor.grid.entity.sql') }, |
|
||||
{ name: 'sqlParameterValues', label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues') }, |
|
||||
{ name: 'sqlFieldMapping', label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping') }, |
|
||||
|
|
||||
{ name: 'dataComeFrom', label: $t('dataComeFrom') }, |
|
||||
{ name: 'creator', label: $t('creator') }, |
|
||||
{ name: 'createDate', label: $t('createDate') }, |
|
||||
{ name: 'lastModifier', label: $t('lastModifier') }, |
|
||||
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
@before-editor-data-submit=" |
|
||||
(data, callback) => { |
|
||||
console.log(data); |
|
||||
} |
|
||||
" |
|
||||
></w-grid> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref, onMounted } from 'vue'; |
|
||||
import { axios, Environment, Formater, Tools, EnumTools, Options } from '@/platform'; |
|
||||
import { ComponentContainer } from '@univerjs/ui'; |
|
||||
import { RowHeaderLayout } from '@univerjs/engine-render'; |
|
||||
|
|
||||
const props = defineProps({ |
|
||||
fetchDataUrl: { type: String, default: '' }, |
|
||||
dataUrl: { type: String, default: '' }, |
|
||||
parameter: { type: Object, default: undefined }, |
|
||||
readOnly: { type: Boolean, default: false }, |
|
||||
}); |
|
||||
|
|
||||
const emit = defineEmits<{ |
|
||||
(e: 'rowClick', evt: Event, row: any, index: number): void; |
|
||||
(e: 'beforeRequestData', requestParams: URLSearchParams | any, callback: any): void; |
|
||||
}>(); |
|
||||
|
|
||||
const gridRef = ref(); |
|
||||
const autoCompletionOptionsRef = ref([]); |
|
||||
const optionOptionsRef = ref([]); |
|
||||
const decisionTreeDialogRef = ref(); |
|
||||
const executionFlowDialogRef = ref(); |
|
||||
const parameterId = '8c114166-aae3-4590-b63a-6daa64eb15ac'; |
|
||||
|
|
||||
const transfromContent = (xml) => { |
|
||||
const div = document.createElement('div'); |
|
||||
div.textContent = xml; |
|
||||
const result = div.outerHTML; |
|
||||
div.parentNode?.removeChild(div); |
|
||||
return result; |
|
||||
}; |
|
||||
|
|
||||
const refresh = () => { |
|
||||
gridRef.value.refresh(); |
|
||||
}; |
|
||||
|
|
||||
onMounted(() => { |
|
||||
gridRef.value.refresh(); |
|
||||
}); |
|
||||
|
|
||||
defineExpose({ |
|
||||
refresh, |
|
||||
}); |
|
||||
|
|
||||
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ProcessorType']); |
|
||||
</script> |
|
Loading…
Reference in new issue