Browse Source

普通表格与树表格拖拽排序代码提交

main
likunming 7 months ago
parent
commit
3d8ec8321f
  1. 118
      io.sc.platform.core.frontend/src/platform/components/grid/TreeGridRow.vue
  2. 126
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue
  3. 254
      io.sc.platform.core.frontend/src/views/likm/Grid.vue
  4. 12
      io.sc.platform.core.frontend/src/views/likm/TreeGrid.vue
  5. 25
      io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/support/RestCrudController.java

118
io.sc.platform.core.frontend/src/platform/components/grid/TreeGridRow.vue

@ -2,18 +2,20 @@
<q-tr
ref="trRef"
:class="row[table.selectedField] ? 'selected ' : ''"
:draggable="
(typeof gridProps.draggable === 'boolean' && gridProps.draggable) || (typeof gridProps.draggable === 'string' && gridProps.draggable === 'local')
? true
: false
"
@click.stop.prevent="click($event, row, row.rowIndex)"
@dblclick.stop.prevent="dbClick($event, row, row.rowIndex)"
@dragenter="onDragEnter($event, row)"
@dragleave="onDragLeave($event, row)"
@dragover="onDragOver($event, row)"
@drop="onDrop($event, row)"
@dragstart="onDragStart($event, row)"
>
<q-td
class="nowrap text-nowrap"
:draggable="gridProps.draggable"
@dragenter="onDragEnter($event, row)"
@dragleave="onDragLeave($event, row)"
@dragover="onDragOver($event, row)"
@drop="onDrop($event, row)"
@dragstart="onDragStart($event, row)"
>
<q-td class="nowrap text-nowrap">
<div ref="tdDivRef" class="flex flex-nowrap items-center h-full w-full" style="flex-wrap: nowrap">
<!--层级占位符-->
<span :style="`width:${24 * props.level}px;`"></span>
@ -58,12 +60,6 @@
:class="col.__thClass + ' ' + col.classes"
:title="col.classes?.indexOf('truncate') > -1 && col.value && typeof col.value !== 'object' ? col.value : ''"
:style="col.style"
:draggable="gridProps.draggable"
@dragenter="onDragEnter($event, row)"
@dragleave="onDragLeave($event, row)"
@dragover="onDragOver($event, row)"
@drop="onDrop($event, row)"
@dragstart="onDragStart($event, row)"
>
<template v-if="col.value && typeof col.value === 'object' && col.value.componentType && col.value.bindModelValue">
<component :is="col.value.componentType" v-bind="col.value.attrs" v-model="getRow(table.rows, row[props.rowKey], false)[col.name]"></component>
@ -90,11 +86,12 @@
:grid="props.grid"
:grid-row-click="props.gridRowClick"
:grid-row-db-click="gridRowDbClick"
:after-row-draggable="props.afterRowDraggable"
></TreeGridRow>
</template>
</template>
<script setup lang="ts">
import { ref, reactive, computed, watch, inject, toRwa } from 'vue';
import { ref, reactive, computed, watch, inject, toRaw, nextTick } from 'vue';
import { Tools } from '@/platform';
const trRef = ref();
@ -140,6 +137,10 @@ const props = defineProps({
type: Function,
default: () => {},
},
afterRowDraggable: {
type: Function,
default: () => {},
},
});
const table = inject('table');
@ -433,11 +434,26 @@ const dragRecordsContains = (dataRow) => {
);
};
//
const isLastNode = (dataRow) => {
if (Tools.isEmpty(dataRow[props.gridProps.foreignKey])) {
if (table.rows[table.rows.length - 1][props.gridProps.primaryKey] === dataRow[props.gridProps.primaryKey]) {
return true;
}
} else {
const parent = getRow(table.rows, dataRow[props.gridProps.foreignKey], true);
if (parent.children[parent.children.length - 1][props.gridProps.primaryKey] === dataRow[props.gridProps.primaryKey]) {
return true;
}
}
return false;
};
//
const onDragEnter = (e, dataRow) => {
if (e.target.nodeName === 'TD' && e.offsetY <= gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) {
addDragTopStyle(e);
} else if (e.target.nodeName === 'TD' && e.offsetY > gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) {
} else if (isLastNode(dataRow) && e.target.nodeName === 'TD' && e.offsetY > gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) {
addDragBottomStyle(e);
}
};
@ -467,7 +483,7 @@ const onDragOver = (e, dataRow) => {
if (e.target.nodeName === 'TD' && e.offsetY <= gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) {
removeDragBottomStyle(e);
addDragTopStyle(e);
} else if (e.target.nodeName === 'TD' && e.offsetY > gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) {
} else if (isLastNode(dataRow) && e.target.nodeName === 'TD' && e.offsetY > gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) {
removeDragTopStyle(e);
addDragBottomStyle(e);
}
@ -482,58 +498,86 @@ const onDragOver = (e, dataRow) => {
//
const removeRecord = (arr, removeData) => {
let index = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i][props.rowKey] === removeData[props.rowKey]) {
arr.splice(i, 1);
index = i;
break;
} else if (arr[i].children && arr[i].children.length > 0) {
removeRecord(arr[i].children, removeData);
const a = removeRecord(arr[i].children, removeData);
if (a > 0) {
index = a;
}
}
}
return index;
};
//
const updateOrderData = <any>[];
//
const setOrder = (arr) => {
arr.forEach((item, index) => {
item[props.gridProps.orderBy] = index + 1;
//
updateOrderData.push(toRaw(item));
});
};
//
const addRecord = (arr, addData, targetData, targetIndex) => {
const addRecord = (e, arr, addData, targetData, dragIndex, targetIndex) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i][props.gridProps.primaryKey] === targetData[props.gridProps.foreignKey]) {
if (
e.offsetY <= gridTrMiddleHeightComputed.value &&
isTrue(dragIndex, targetIndex) &&
addData[props.gridProps.foreignKey] === targetData[props.gridProps.foreignKey]
) {
arr[i].children.splice(targetIndex - 1, 0, addData);
} else if (e.offsetY > gridTrMiddleHeightComputed.value && addData[props.gridProps.foreignKey] !== targetData[props.gridProps.foreignKey]) {
arr[i].children.splice(arr[i].children.length, 0, addData);
} else {
arr[i].children.splice(targetIndex, 0, addData);
}
//
addData[props.gridProps.foreignKey] = arr[i][props.gridProps.primaryKey];
arr[i].children.splice(targetIndex + 1, 0, addData);
//
setOrder(arr[i].children);
break;
} else if (arr[i].children && arr[i].children.length > 0) {
addRecord(arr[i].children, addData, targetData, targetIndex);
addRecord(e, arr[i].children, addData, targetData, dragIndex, targetIndex);
}
}
};
const isTrue = (dragIndex, targetIndex) => {
if (dragIndex < targetIndex) {
return true;
}
return false;
};
//
const resetOrderDataHandler = (e, dragRecords, targetData, targetIndex) => {
// 1
dragRecords.forEach((item) => {
removeRecord(table.rows, item);
const itemIndex = removeRecord(table.rows, item);
// 2
if (Tools.isEmpty(targetData[props.gridProps.foreignKey])) {
if (e.offsetY <= gridTrMiddleHeightComputed.value) {
item[props.gridProps.foreignKey] = null;
table.rows.splice(targetIndex, 0, item);
setOrder(table.rows);
// 3使splice-11
if (e.offsetY <= gridTrMiddleHeightComputed.value && Tools.isEmpty(item[props.gridProps.foreignKey]) && isTrue(itemIndex, targetIndex)) {
table.rows.splice(targetIndex - 1, 0, item);
} else {
item[props.gridProps.foreignKey] = null;
table.rows.splice(targetIndex + 1, 0, item);
setOrder(table.rows);
table.rows.splice(targetIndex, 0, item);
}
item[props.gridProps.foreignKey] = null;
setOrder(table.rows);
//
updateOrderData.push(...toRaw(table.rows));
} else {
addRecord(table.rows, item, targetData, targetIndex);
addRecord(e, table.rows, item, targetData, itemIndex, targetIndex);
}
});
};
@ -563,9 +607,17 @@ const onDrop = (e, dataRow) => {
) {
return;
}
//
updateOrderData.splice(0, updateOrderData.length);
//
resetOrder(e, table.dragRecords, table.rows, dataRow);
// emit('afterRowDraggable');
//
if (typeof props.gridProps.draggable === 'boolean' && props.gridProps.draggable && updateOrderData?.length > 0) {
props.grid.updates(updateOrderData);
}
props.afterRowDraggable(updateOrderData);
};
const click = (evt, row, rowIndex) => {

126
io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue

@ -120,66 +120,44 @@
:grid="instance"
:grid-row-click="rowClick"
:grid-row-db-click="rowDbClick"
:after-row-draggable="afterRowDraggable"
></TreeGridRow>
</template>
<q-tr
v-else
:class="scope.row[table.selectedField] ? 'selected' : ''"
:props="scope"
:draggable="(typeof draggable === 'boolean' && draggable) || (typeof draggable === 'string' && draggable === 'local') ? 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="scope.row[table.tickedField]" flat :dense="denseBodyComputed" @update:model-value="updateTicked($event, scope.row)" />
</q-td>
<template v-if="draggable">
<q-td
v-for="col in scope.cols"
:key="col.name"
draggable="true"
:props="scope"
:title="col.classes?.indexOf('truncate') > -1 ? col.value : ''"
@dragenter="onDragEnter($event, scope)"
@dragleave="onDragLeave"
@dragover="onDragOver($event, scope)"
@drop="onDrop($event, scope)"
@dragstart="onDragStart($event, scope)"
>
<template v-if="col.name === '_sortNo_'">
{{ scope.rowIndex + 1 }}
</template>
<template v-else-if="col.value && typeof col.value === 'object' && col.value.componentType && col.value.bindModelValue">
<component :is="col.value.componentType" v-bind="col.value.attrs" v-model="scope.row[col.name]"></component>
</template>
<template v-else-if="col.value && typeof col.value === 'object' && col.value.componentType">
<component :is="col.value.componentType" v-bind="col.value.attrs"></component>
</template>
<template v-else>
<span v-dompurify-html="Tools.isUndefinedOrNull(col.value) ? '' : col.value"></span>
</template>
</q-td>
</template>
<template v-else>
<q-td
v-for="col in scope.cols"
:key="col.name"
:props="scope"
:title="col.classes?.indexOf('truncate') > -1 && col.value && typeof col.value !== 'object' ? col.value : ''"
>
<template v-if="col.name === '_sortNo_'">
{{ scope.rowIndex + 1 }}
</template>
<template v-else-if="col.value && typeof col.value === 'object' && col.value.componentType && col.value.bindModelValue">
<component :is="col.value.componentType" v-bind="col.value.attrs" v-model="scope.row[col.name]"></component>
</template>
<template v-else-if="col.value && typeof col.value === 'object' && col.value.componentType">
<component :is="col.value.componentType" v-bind="col.value.attrs"></component>
</template>
<template v-else>
<span v-dompurify-html="Tools.isUndefinedOrNull(col.value) ? '' : col.value"></span>
</template>
</q-td>
</template>
<q-td
v-for="col in scope.cols"
:key="col.name"
:props="scope"
:title="col.classes?.indexOf('truncate') > -1 && col.value && typeof col.value !== 'object' ? col.value : ''"
>
<template v-if="col.name === '_sortNo_'">
{{ scope.rowIndex + 1 }}
</template>
<template v-else-if="col.value && typeof col.value === 'object' && col.value.componentType && col.value.bindModelValue">
<component :is="col.value.componentType" v-bind="col.value.attrs" v-model="scope.row[col.name]"></component>
</template>
<template v-else-if="col.value && typeof col.value === 'object' && col.value.componentType">
<component :is="col.value.componentType" v-bind="col.value.attrs"></component>
</template>
<template v-else>
<span v-dompurify-html="Tools.isUndefinedOrNull(col.value) ? '' : col.value"></span>
</template>
</q-td>
</q-tr>
</template>
<!-- <template v-if="table.rows.length === 0" #top-row>
@ -269,7 +247,7 @@ const props = defineProps({
height: { type: Number, default: 0 }, //
title: { type: String, default: '' }, //
autoFetchData: { type: Boolean, default: true }, //
draggable: { type: Boolean, default: false }, //
draggable: { type: [Boolean, String], default: false }, // true访local
pageable: { type: Boolean, default: true }, //
configButton: { type: Boolean, default: true }, //
dataUrl: { type: String, default: '' }, // URL
@ -294,7 +272,7 @@ const props = defineProps({
treeRelationship: { type: String, default: 'parent' }, // parent, childrenparentchildren
primaryKey: { type: String, default: 'id' }, // APIRestCrudControllerupdate
foreignKey: { type: String, default: 'parent' }, //
orderBy: { type: String, default: 'order' }, //
orderBy: { type: String, default: 'order' }, //
refreshData: { type: Boolean, default: false }, // primaryKey
dbClickOperation: { type: String, default: 'view' }, // vieweditcloneexpand
sortBy: {
@ -399,6 +377,10 @@ const props = defineProps({
type: Function,
default: undefined,
},
onAfterRowDraggable: {
type: Function,
default: undefined,
},
});
const emit = defineEmits<{
//
@ -440,6 +422,8 @@ const emit = defineEmits<{
): void;
(
e: 'afterRowDraggable', //
grid: any,
data: any,
): void;
}>();
@ -594,8 +578,8 @@ const table = reactive({
denseBody: props.denseBody !== undefined ? props.denseBody : false,
denseBottom: props.denseBottom !== undefined ? props.denseBottom : false,
queryFormFields: <any>[],
moreQueryStatus: false, //
rows: <any>[],
moreQueryStatus: false, //
inFullscreen: false, //
});
provide('table', table);
@ -2456,18 +2440,49 @@ const onDrop = (e, scope) => {
return;
}
const dragRow = table.rows[dragRowIndex];
if (e.offsetY < state.bodyCellHeight / 2 && dragRowIndex !== scope.rowIndex && e.target.parentNode.parentNode.children.length === scope.rowIndex + 1) {
table.rows.splice(dragRowIndex, 1);
table.rows.splice(dragRowIndex, 1);
if (e.offsetY < state.bodyCellHeight / 2 && dragRowIndex < scope.rowIndex) {
table.rows.splice(scope.rowIndex - 1, 0, dragRow);
} else {
table.rows.splice(dragRowIndex, 1);
table.rows.splice(scope.rowIndex, 0, dragRow);
}
removeDragTopStyle(e);
removeDragBottomStyle(e);
emit('afterRowDraggable');
const updateData = <any>[];
table.rows.forEach((item, index) => {
item[props.orderBy] = index + 1;
updateData.push(toRaw(item));
});
if (typeof props.draggable === 'boolean' && props.draggable) {
// 访
updates(updateData);
}
afterRowDraggable(updateData);
};
const afterRowDraggable = (updateData) => {
if (!Tools.isUndefined(props.onAfterRowDraggable)) {
emit('afterRowDraggable', instance, updateData);
}
};
//
const updates = (data) => {
const requestParams = {
method: 'PUT',
headers: { 'content-type': 'application/json;charset=utf-8;' },
data: data,
url: url.dataUrl + '/updates',
};
axios(requestParams).catch((error) => {
console.info('=======error======', error);
});
};
// form
const handlerQueryFormShowField = () => {
table.queryFormFields = [];
@ -2694,6 +2709,7 @@ defineExpose({
refresh,
getLocalData,
setLocalData,
updates,
replaceRow,
removeRows,
addRow,

254
io.sc.platform.core.frontend/src/views/likm/Grid.vue

@ -57,14 +57,14 @@
</q-tab-panels>
</template>
</q-splitter> -->
<w-grid
<!-- <w-grid
ref="gridRef"
:title="testGrid.title"
draggable
:dense="state.dense"
:hide-bottom="false"
:data-url="testGrid.tableDataUrl"
:auto-fetch-data="false"
:auto-fetch-data="true"
:checkbox-selection="true"
selection="multiple"
:query-form-cols-num="6"
@ -95,16 +95,86 @@
@row-db-click="rowDbClick"
@after-request-data="
() => {
// console.info('1111111111111111111111111111');
}
"
></w-grid>
></w-grid> -->
<w-grid
ref="applicationGridRef"
:title="$t('system.application.grid.title')"
:config-button="true"
selection="multiple"
:checkbox-selection="true"
:sort-no="true"
:draggable="true"
:data-url="Environment.apiContextPath('/api/system/application')"
:sort-by="['order']"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text' },
{ name: 'enable', label: $t('isEnable'), type: 'select', options: Options.yesNo() },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'separator', 'export']"
:columns="[
{ width: 60, name: 'order', label: $t('order') },
{ width: 100, name: 'code', label: $t('code') },
{ width: '100%', name: 'name', label: $t('name') },
{ width: 80, name: 'enable', label: $t('status'), format: Formater.enableTag() },
{ 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: 'order', label: $t('order'), type: 'number' },
{ 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.none() },
{ name: 'order', label: $t('order') },
{ 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() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
@row-click="(evt, row, index) => {}"
@before-request-data="() => {}"
@after-row-draggable="
(grid, updateDatas) => {
console.info('grid=====', grid);
console.info('updateDatas======', updateDatas);
}
"
>
</w-grid>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, nextTick, reactive, computed } from 'vue';
import { axios, Environment, EnumTools, Options } from '@/platform';
import { axios, Environment, EnumTools, Options, Formater } from '@/platform';
import EnableIcon from '@/platform/components/grid/EnableIcon.vue';
import { IconEnum } from '@/platform/enums';
@ -300,52 +370,52 @@ const testGrid = {
// { label: '', name: 'lastModifyDate', type: 'w-date' },
],
tableColumns: [
{
name: 'info',
label: '用户信息',
columns: [
{ name: 'loginName', label: '登录名', align: 'right' },
{ name: 'userName', label: '用户名' },
],
},
// { name: 'loginName', label: '', align: 'right' },
// { name: 'userName', label: '' },
{
name: 'lxxx',
label: '联系方式',
columns: [
{
name: 'email',
label: '邮箱地址',
columns: [
{ width: 100, name: 'auc', label: 'auc' },
{ width: 100, name: 'ar', label: 'ar' },
{ width: 100, name: 'ks', label: 'ks' },
],
},
{
name: 'tx',
label: '通讯',
columns: [
{ name: 'phone', label: '电话' },
{ name: 'mobile', label: '手机号' },
],
},
{
name: 'qq',
label: 'QQ',
// columns: [
// { width: 100, name: 'aucQualitative', label: 'aucQualitative' },
// { width: 100, name: 'arQualitative', label: 'arQualitative' },
// { width: 100, name: 'ksQualitative', label: 'ksQualitative' },
// ],
},
],
},
// { name: 'email', label: '' },
// { name: 'phone', label: '' },
// { name: 'mobile', label: '' },
// { name: 'qq', label: 'QQ' },
// {
// name: 'info',
// label: '',
// columns: [
// { name: 'loginName', label: '', align: 'right' },
// { name: 'userName', label: '' },
// ],
// },
{ name: 'loginName', label: '登录名', align: 'right' },
{ name: 'userName', label: '用户名' },
// {
// name: 'lxxx',
// label: '',
// columns: [
// {
// name: 'email',
// label: '',
// columns: [
// { width: 100, name: 'auc', label: 'auc' },
// { width: 100, name: 'ar', label: 'ar' },
// { width: 100, name: 'ks', label: 'ks' },
// ],
// },
// {
// name: 'tx',
// label: '',
// columns: [
// { name: 'phone', label: '' },
// { name: 'mobile', label: '' },
// ],
// },
// {
// name: 'qq',
// label: 'QQ',
// // columns: [
// // { width: 100, name: 'aucQualitative', label: 'aucQualitative' },
// // { width: 100, name: 'arQualitative', label: 'arQualitative' },
// // { width: 100, name: 'ksQualitative', label: 'ksQualitative' },
// // ],
// },
// ],
// },
{ name: 'email', label: '邮箱地址' },
{ name: 'phone', label: '电话' },
{ name: 'mobile', label: '手机号' },
{ name: 'qq', label: 'QQ' },
{ name: 'description', label: '描述', width: 400 },
{
name: 'enable',
@ -417,46 +487,46 @@ const testGrid = {
};
onMounted(() => {
gridRef.value.setLocalData([
{
loginName: 'admin1',
},
{
loginName: 'admin2',
},
{
loginName: 'admin3',
},
{
loginName: 'admin4',
},
{
loginName: 'admin5',
},
{
loginName: 'admin6',
},
{
loginName: 'admin7',
},
{
loginName: 'admin8',
},
{
loginName: 'admin9',
},
{
loginName: 'admin10',
},
{
loginName: 'admin11',
},
{
loginName: 'admin12',
},
{
loginName: 'admin13',
},
]);
// gridRef.value.setLocalData([
// {
// loginName: 'admin1',
// },
// {
// loginName: 'admin2',
// },
// {
// loginName: 'admin3',
// },
// {
// loginName: 'admin4',
// },
// {
// loginName: 'admin5',
// },
// {
// loginName: 'admin6',
// },
// {
// loginName: 'admin7',
// },
// {
// loginName: 'admin8',
// },
// {
// loginName: 'admin9',
// },
// {
// loginName: 'admin10',
// },
// {
// loginName: 'admin11',
// },
// {
// loginName: 'admin12',
// },
// {
// loginName: 'admin13',
// },
// ]);
});
</script>

12
io.sc.platform.core.frontend/src/views/likm/TreeGrid.vue

@ -1,5 +1,5 @@
<template>
<div>
<div class="h-full">
<w-grid
ref="gridRef"
:title="testGrid.title"
@ -15,6 +15,12 @@
:query-form-fields="testGrid.queryFormFields"
:query-form-cols-num="3"
@update-ticked="updateTicked"
@after-row-draggable="
(grid, updateDatas) => {
console.info('grid=====', grid);
console.info('updateDatas======', updateDatas);
}
"
></w-grid>
</div>
</template>
@ -29,8 +35,8 @@ import { IconEnum } from '@/platform/enums';
const { t } = useI18n();
const updateTicked = (event, row) => {
console.info('treeGrid.updateTicked.event====', event);
console.info('treeGrid.updateTicked.row====', row);
// console.info('treeGrid.updateTicked.event====', event);
// console.info('treeGrid.updateTicked.row====', row);
};
const startY = ref(0);

25
io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/support/RestCrudController.java

@ -14,6 +14,7 @@ import io.sc.platform.orm.service.support.QueryResult;
import io.sc.platform.orm.service.support.criteria.Criteria;
import io.sc.platform.orm.service.support.criteria.impl.Equals;
import io.sc.platform.orm.service.support.criteria.impl.IContains;
import io.sc.platform.orm.util.EntityVoUtil;
import io.sc.platform.security.util.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
@ -124,6 +125,30 @@ public abstract class RestCrudController<V extends BaseVo, E extends BaseEntity<
return update(request,response,id,entity);
}
/**
* 更新多个实体
* @param request Http 请求对象
* @param response Http 响应对象
* @param entitys 实体对象集合
* @return 更新后的实体 VO 对象
* @throws Exception 违例
*/
@AuditLog(action=AuditLogAction.UPDATE)
@PutMapping("updates")
@ResponseBody
public List<V> updates(HttpServletRequest request,HttpServletResponse response,@RequestBody List<E> entitys) throws Exception{
Map<ID, E> map = new HashMap<>();
List<E> list = new ArrayList<>();
if (entitys!=null && entitys.size() > 0) {
for(E entity: entitys) {
ID id = service.getRepository().getId(entity);
map.put(id, entity);
}
list = service.update(map);
}
return EntityVoUtil.toVo(list);
}
protected V update(HttpServletRequest request,HttpServletResponse response,@PathVariable(name="id")ID id,@RequestBody @Valid E entity) throws Exception{
E updatedEntity =service.update(id,entity);
if(updatedEntity instanceof BaseEntity){

Loading…
Cancel
Save