Browse Source

增加w-query-builder组件

main
likunming 5 months ago
parent
commit
2f80425ae1
  1. 16
      io.sc.platform.core.frontend/src/platform/components/grid/GridBody.vue
  2. 34
      io.sc.platform.core.frontend/src/platform/components/grid/GridTd.vue
  3. 75
      io.sc.platform.core.frontend/src/platform/components/grid/TreeGridRow.vue
  4. 15
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue
  5. 6
      io.sc.platform.core.frontend/src/platform/components/grid/css/grid.css
  6. 8
      io.sc.platform.core.frontend/src/platform/components/grid/ts/grid.ts
  7. 3
      io.sc.platform.core.frontend/src/platform/components/toolbar/ChildrenBtn.vue
  8. 9
      io.sc.platform.core.frontend/src/platform/components/toolbar/WToolbar.vue
  9. 4
      io.sc.platform.core.frontend/src/views/likm/Grid.vue

16
io.sc.platform.core.frontend/src/platform/components/grid/GridBody.vue

@ -22,7 +22,8 @@
<template v-else>
<q-tr
ref="trRef"
:class="props.scope.row[table.selectedField] ? 'selected' : ''"
:no-hover="!props.grid.props.cellSelected ? false : true"
:class="props.scope.row[table.selectedField] && !props.grid.props.cellSelected ? 'selected' : ''"
:props="props.scope"
:draggable="draggableComputed"
@click.stop="props.rowClick($event, scope.row, scope.rowIndex)"
@ -68,7 +69,7 @@
<script setup lang="ts">
import { computed, inject, ref, toRaw } from 'vue';
import { Tools, noErrorAxios, NotifyManager, t } from '@/platform';
import { draggableImage } from './ts/grid';
import { draggableImage, draggableMode } from './ts/grid';
import TreeGridRow from './TreeGridRow.vue';
import GridTd from './GridTd.vue';
import GridEditToolbar from './GridEditToolbar.vue';
@ -178,9 +179,12 @@ const setTreeRowComponentRef = (el, row) => {
};
const draggableComputed = computed(() => {
if (typeof props.grid.props.draggable === 'boolean' && props.grid.props.draggable && table.bodyEditStatus === 'none') {
return true;
} else if (typeof props.grid.props.draggable === 'string' && props.grid.props.draggable === 'local' && table.bodyEditStatus === 'none') {
if (
props.grid.props.draggable &&
typeof props.grid.props.draggable === 'string' &&
!Tools.isEmpty(draggableMode[props.grid.props.draggable]) &&
table.bodyEditStatus === 'none'
) {
return true;
}
return false;
@ -329,7 +333,7 @@ const onDrop = (e, scope) => {
updateData.push(toRaw(item));
}
});
if (typeof props.grid.props.draggable === 'boolean' && props.grid.props.draggable) {
if (props.grid.props.draggable === draggableMode.remote && updateData.length > 0) {
// 访
updates(updateData, () => {});
}

34
io.sc.platform.core.frontend/src/platform/components/grid/GridTd.vue

@ -1,5 +1,23 @@
<template>
<q-td :key="col.name" :props="scope" :title="col.classes?.indexOf('truncate') > -1 && !Tools.isEmpty(value) && typeof value !== 'object' ? value : ''">
<q-td
:key="col.name"
:props="scope"
:title="col.classes?.indexOf('truncate') > -1 && !Tools.isEmpty(value) && typeof value !== 'object' ? value : ''"
:class="props.grid.props.cellSelected ? tdClassComputed : ''"
@click="
() => {
if (table && props.grid.props.cellSelected) {
table['cellSelected'] = {
row: toRaw(scope.row),
rowKey: scope.row[props.rowKeyName],
primaryKey: scope.row[props.grid.props.primaryKey],
colName: col['name'],
value: value,
};
}
}
"
>
<template v-if="col.name === '_sortNo_'">
{{ scope.rowIndex + 1 }}
</template>
@ -26,7 +44,7 @@
</q-td>
</template>
<script setup lang="ts">
import { inject, computed, ref } from 'vue';
import { inject, computed, ref, toRaw } from 'vue';
import { Tools } from '@/platform';
const componentRef = ref();
@ -70,6 +88,18 @@ const getComponentRef = () => {
return componentRef.value;
};
const tdClassComputed = computed(() => {
const tdClass = <any>[];
if (props.grid.props.cellSelected) {
tdClass.push('cellSelected_hover');
}
if (table && table['cellSelected'] && Tools.hasOwnProperty(table['cellSelected'], 'colName')) {
if (table['cellSelected']['colName'] === props.col['name'] && table['cellSelected']['rowKey'] === props.scope.row[props.rowKeyName])
tdClass.push('cellSelected');
}
return tdClass;
});
defineExpose({
getComponentRef,
});

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

@ -1,7 +1,8 @@
<template>
<q-tr
ref="trRef"
:class="row[table.selectedField] ? 'selected ' : ''"
:no-hover="!props.grid.props.cellSelected ? false : true"
:class="row[table.selectedField] && !props.grid.props.cellSelected ? 'selected' : ''"
:draggable="draggableComputed"
@click.stop.prevent="click($event, row, props.rowIndex)"
@dblclick.stop.prevent="dbClick($event, row, props.rowIndex)"
@ -10,7 +11,22 @@
@drop="draggableComputed ? onDrop($event, row) : () => {}"
@dragstart="draggableComputed ? onDragStart($event, row) : () => {}"
>
<q-td class="nowrap text-nowrap">
<q-td
:class="props.grid.props.cellSelected ? firstTdClassComputed : 'nowrap text-nowrap'"
@click="
() => {
if (table && props.grid.props.cellSelected) {
table['cellSelected'] = {
row: toRaw(props.row),
rowKey: props.row[props.rowKey],
primaryKey: props.row[props.grid.props.primaryKey],
colName: cols[0]['name'],
value: cols[0]['value'],
};
}
}
"
>
<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>
@ -65,9 +81,22 @@
<template v-for="(col, index) in cols" :key="col.name">
<q-td
v-if="index > 0"
:class="col.__thClass + ' ' + col.classes"
:class="props.grid.props.cellSelected ? tdClassComputed(col) : col.__thClass + ' ' + col.classes"
:title="col.classes?.indexOf('truncate') > -1 && col.value && typeof col.value !== 'object' ? col.value : ''"
:style="col.style"
@click="
() => {
if (table && props.grid.props.cellSelected) {
table['cellSelected'] = {
row: toRaw(props.row),
rowKey: props.row[props.rowKey],
primaryKey: props.row[props.grid.props.primaryKey],
colName: col['name'],
value: col['value'],
};
}
}
"
>
<template v-if="!Tools.isEmpty(col['type']) && ((isSelectedRowComputed && table.bodyEditStatus === 'rowEdit') || table.bodyEditStatus === 'rowsEdit')">
<component
@ -132,7 +161,7 @@
import { ref, computed, inject, toRaw } from 'vue';
import { Tools, NotifyManager } from '@/platform';
import GridEditToolbar from './GridEditToolbar.vue';
import { draggableImage } from './ts/grid';
import { draggableImage, draggableMode } from './ts/grid';
const trRef = ref();
const tdDivRef = ref();
@ -236,10 +265,40 @@ const style = {
},
};
const firstTdClassComputed = computed(() => {
const tdClass = <any>['nowrap', 'text-nowrap'];
if (props.grid.props.cellSelected) {
tdClass.push('cellSelected_hover');
}
if (table && table['cellSelected'] && Tools.hasOwnProperty(table['cellSelected'], 'colName')) {
if (table['cellSelected']['colName'] === props.cols[0]['name'] && table['cellSelected']['rowKey'] === props.row[props.rowKey]) {
tdClass.push('cellSelected');
}
}
return tdClass;
});
const tdClassComputed = computed(() => {
return (col) => {
let tdClass = col.__thClass + ' ' + col.classes;
if (props.grid.props.cellSelected) {
tdClass += ' cellSelected_hover';
}
if (table && table['cellSelected'] && Tools.hasOwnProperty(table['cellSelected'], 'colName')) {
if (table['cellSelected']['colName'] === col['name'] && table['cellSelected']['rowKey'] === props.row[props.rowKey]) {
tdClass += ' cellSelected';
}
}
return tdClass;
};
});
const draggableComputed = computed(() => {
if (typeof props.grid.props.draggable === 'boolean' && props.grid.props.draggable && table.bodyEditStatus === 'none') {
return true;
} else if (typeof props.grid.props.draggable === 'string' && props.grid.props.draggable === 'local' && table.bodyEditStatus === 'none') {
if (
props.grid.props.draggable &&
typeof props.grid.props.draggable === 'string' &&
!Tools.isEmpty(draggableMode[props.grid.props.draggable]) &&
table.bodyEditStatus === 'none'
) {
return true;
}
return false;
@ -672,7 +731,7 @@ const onDrop = (e, dataRow) => {
resetOrder(e, table.dragRecords, table.rows, dataRow);
//
if (typeof props.grid.props.draggable === 'boolean' && props.grid.props.draggable && updateOrderData?.length > 0) {
if (props.grid.props.draggable === draggableMode.remote && updateOrderData?.length > 0) {
props.updates(updateOrderData);
}

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

@ -147,7 +147,8 @@ const props = defineProps({
title: { type: String, default: '' }, //
autoFetchData: { type: Boolean, default: true }, //
// localMode: { type: Boolean, default: false },// autoFetchData
draggable: { type: [Boolean, String], default: false }, // true访local
cellSelected: { type: Boolean, default: false }, //
draggable: { type: String, default: undefined }, // `local``remote`
draggableOrderBy: { type: String, default: 'order' }, //
pageable: { type: Boolean, default: true }, //
configButton: { type: Boolean, default: true }, //
@ -379,6 +380,7 @@ const table = reactive({
rows: <any>[],
inFullscreen: false, //
bodyEditStatus: 'none', // none()rowEdit()rowsEdit()
cellSelected: {}, //
});
provide('table', table);
@ -1129,6 +1131,16 @@ const getCascadeChildrenData = (rows: [], propertyName) => {
}
return data;
};
/**
* 获得选中的单元格
*/
const getSelectedCell = () => {
return {
row: table.cellSelected['row'],
colName: table.cellSelected['colName'],
value: table.cellSelected['value'],
};
};
/**
* 获取选择的行记录及所有子记录
* @param propertyName 属性名称
@ -1683,6 +1695,7 @@ defineExpose({
getTickedRows,
getCascadeChildren,
getCascadeParents,
getSelectedCell,
// =========refAPI=========
getQueryForm,
getEditorDialog,

6
io.sc.platform.core.frontend/src/platform/components/grid/css/grid.css

@ -1,3 +1,9 @@
.w-grid .cellSelected {
background-color: #0000001f;
}
.w-grid .cellSelected_hover:hover {
background-color: #0000001f;
}
.w-grid .q-table__top {
padding: var(--tableTopPadding) var(--tableTopPadding);
}

8
io.sc.platform.core.frontend/src/platform/components/grid/ts/grid.ts

@ -1,5 +1,11 @@
import { Tools, t } from '@/platform';
export const draggableMode = {
local: 'local',
remote: 'remote',
};
export const draggableImage = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' %3E%3Cpath /%3E%3C/svg%3E`;
// 列样式处理
const columnStyle = (item: any) => {
let style = '';
@ -53,5 +59,3 @@ export const columnDefaultProps = (columns: any, sortNo: boolean = true) => {
}
return [];
};
export const draggableImage = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' %3E%3Cpath /%3E%3C/svg%3E`;

3
io.sc.platform.core.frontend/src/platform/components/toolbar/ChildrenBtn.vue

@ -9,6 +9,7 @@
ticked: firstTickedComputed,
tickeds: tickedComputed,
grid: grid,
selectedColName: props.grid.getSelectedCell()['colName'],
})
: false
"
@ -46,6 +47,7 @@
ticked: firstTickedComputed,
tickeds: tickedComputed,
grid: grid,
selectedColName: props.grid.getSelectedCell()['colName'],
})
: button[0].enableIf
? !button[0].enableIf({
@ -54,6 +56,7 @@
ticked: firstTickedComputed,
tickeds: tickedComputed,
grid: grid,
selectedColName: props.grid.getSelectedCell()['colName'],
})
: false
"

9
io.sc.platform.core.frontend/src/platform/components/toolbar/WToolbar.vue

@ -26,6 +26,7 @@
selecteds: selectedComputed,
ticked: firstTickedComputed,
tickeds: tickedComputed,
selectedColName: props.grid.getSelectedCell()['colName'],
grid: grid,
})
: false
@ -66,6 +67,7 @@
ticked: firstTickedComputed,
tickeds: tickedComputed,
grid: grid,
selectedColName: props.grid.getSelectedCell()['colName'],
})
: false
"
@ -93,6 +95,7 @@
ticked: firstTickedComputed,
tickeds: tickedComputed,
grid: grid,
selectedColName: props.grid.getSelectedCell()['colName'],
})
: false
"
@ -155,6 +158,7 @@
ticked: firstTickedComputed,
tickeds: tickedComputed,
grid: grid,
selectedColName: props.grid.getSelectedCell()['colName'],
})
: false
"
@ -406,6 +410,7 @@ const getIcon = (icon) => {
ticked: firstTickedComputed.value,
tickeds: tickedComputed.value,
grid: props.grid,
selectedColName: props.grid.getSelectedCell()['colName'],
});
} else {
return icon;
@ -421,6 +426,7 @@ const getLabel = (label) => {
ticked: firstTickedComputed.value,
tickeds: tickedComputed.value,
grid: props.grid,
selectedColName: props.grid.getSelectedCell()['colName'],
});
} else {
return label;
@ -455,6 +461,7 @@ const buttonClick = async (button) => {
tickeds: tickedComputed.value,
grid: props.grid,
context: context,
selectedColName: props.grid.getSelectedCell()['colName'],
});
}
if (beforeResult && button.click) {
@ -466,6 +473,7 @@ const buttonClick = async (button) => {
grid: props.grid,
_click: button._click,
context: context,
selectedColName: props.grid.getSelectedCell()['colName'],
});
if (button.afterClick) {
nextTick(() => {
@ -476,6 +484,7 @@ const buttonClick = async (button) => {
tickeds: tickedComputed.value,
grid: props.grid,
context: context,
selectedColName: props.grid.getSelectedCell()['colName'],
});
});
}

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

@ -5,13 +5,15 @@
title="示例列表"
:data-url="Environment.apiContextPath('/api/system/application')"
db-click-operation="testAdd"
:cell-selected="true"
:toolbar-actions="[
'add',
{
extend: 'add',
name: 'testAdd',
click: (args) => {
console.info('testAdd======', args);
const cell = args.grid.getSelectedCell();
console.info('cell=========', args);
},
},
[

Loading…
Cancel
Save