refactor(style-edit): 优化样式编辑界面的表格编辑逻辑

- 移除 `styleNumber` 字段,简化 `StyleDtl` 实体类
- 修改表格编辑配置,支持手动触发编辑模式
- 新增 `addDtlEvent`、`editDtlEvent`、`saveDtlEvent` 和 `cancelDtlEvent` 方法,增强编辑功能
- 修复排序逻辑,默认按 `sortNo` 排序
This commit is contained in:
user 2025-04-14 23:33:31 +08:00
parent 186639175d
commit 21b7dd1621
5 changed files with 148 additions and 45 deletions

View File

@ -23,9 +23,6 @@ public class StyleDtl extends AbstractAuditingEntity<Long> implements Serializab
@Column("name")
private String name;
@Column("style_number")
private String styleNumber;
@Column("quality")
private String quality;
@ -101,14 +98,6 @@ public class StyleDtl extends AbstractAuditingEntity<Long> implements Serializab
this.name = name;
}
public String getStyleNumber() {
return styleNumber;
}
public void setStyleNumber(String styleNumber) {
this.styleNumber = styleNumber;
}
public String getQuality() {
return quality;
}
@ -257,9 +246,6 @@ public class StyleDtl extends AbstractAuditingEntity<Long> implements Serializab
", name='" +
getName() +
"'" +
", styleNumber='" +
getStyleNumber() +
"'" +
", quality='" +
getQuality() +
"'" +

View File

@ -50,7 +50,6 @@ public class StyleDtlService {
.flatMap(existingStyleDtl -> {
existingStyleDtl.setNumber(styleDtl.getNumber());
existingStyleDtl.setName(styleDtl.getName());
existingStyleDtl.setStyleNumber(styleDtl.getStyleNumber());
existingStyleDtl.setQuality(styleDtl.getQuality());
existingStyleDtl.setSetGroup(styleDtl.getSetGroup());
existingStyleDtl.setProcess(styleDtl.getProcess());

View File

@ -3,6 +3,7 @@ import type { VxeFormInstance } from 'vxe-table';
import { useI18n } from 'vue-i18n';
import { useAlertService } from '@/shared/alert/alert.service';
import { useRoute, useRouter } from 'vue-router';
import buildPaginationQuery from '@/shared/sort/sorts';
import axios from 'axios';
import type { VxeTableInstance } from 'vxe-table';
import JhiCamera from '@/shared/components/jhi_camera.vue';
@ -25,6 +26,8 @@ export default defineComponent({
const settingDtls = ref([]);
const removeRow = ref(null);
const showDelete = ref(false);
const propOrder = ref('sortNo');
const reverse = ref(false);
const activeTab = ref('base');
const styleForm = ref<VxeFormInstance>();
const baseRef = ref<VxeTableInstance>();
@ -57,8 +60,12 @@ export default defineComponent({
const baseColumns = [
{ field: 'id', title: 'jewpmsApp.style.base.id', visible: false },
{ field: 'number', title: 'jewpmsApp.style.base.number', visible: false },
{ field: 'process', title: 'jewpmsApp.style.base.process', editRender: { name: 'select', options: processTypes } },
{ field: 'material', title: 'jewpmsApp.style.base.material', editRender: { name: 'input' } },
{
field: 'process',
title: 'jewpmsApp.style.base.process',
editRender: { name: 'select', options: processTypes, optionProps: { value: 'number', label: 'name' } },
},
{ field: 'material', title: 'jewpmsApp.style.base.material', editRender: { name: 'input', autoSelect: true } },
{ field: 'setGroup', title: 'jewpmsApp.style.base.setGroup', editRender: { name: 'input' } },
{ field: 'quantity', title: 'jewpmsApp.style.base.quantity', editRender: { name: 'input', props: { type: 'number' } } },
{ field: 'weight', title: 'jewpmsApp.style.base.weight', editRender: { name: 'input', props: { type: 'number' } } },
@ -74,8 +81,12 @@ export default defineComponent({
const settingColumns = [
{ field: 'id', title: 'jewpmsApp.style.setting.id', visible: false },
{ field: 'number', title: 'jewpmsApp.style.setting.number', visible: false },
{ field: 'process', title: 'jewpmsApp.style.setting.process', editRender: { name: 'select', options: settingTypes } },
{ field: 'material', title: 'jewpmsApp.style.setting.material', editRender: { name: 'input' } },
{
field: 'process',
title: 'jewpmsApp.style.setting.process',
editRender: { name: 'select', options: settingTypes, optionProps: { value: 'number', label: 'name' } },
},
{ field: 'material', title: 'jewpmsApp.style.setting.material', editRender: { name: 'input', autoSelect: true } },
{ field: 'setGroup', title: 'jewpmsApp.style.setting.setGroup', editRender: { name: 'input' } },
{ field: 'quantity', title: 'jewpmsApp.style.setting.quantity', editRender: { name: 'input', props: { type: 'number' } } },
{ field: 'weight', title: 'jewpmsApp.style.setting.weight', editRender: { name: 'input', props: { type: 'number' } } },
@ -88,6 +99,11 @@ export default defineComponent({
{ title: 'entity.action.actions', width: 100 },
];
const sort = () => {
const result = [`${propOrder.value},${reverse.value ? 'desc' : 'asc'}`];
return result;
};
const loadData = async () => {
loading.value = true;
try {
@ -141,10 +157,6 @@ export default defineComponent({
}
};
const previousState = () => {
router.push({ name: 'Style' });
};
const save = async () => {
const valid = await styleForm.value?.validate();
if (valid) {
@ -185,7 +197,7 @@ export default defineComponent({
try {
if (style.value.number) {
const [baseRes, settingRes] = await Promise.all([
axios.get('api/styledtls', {
axios.get(`api/styledtls?${buildPaginationQuery({ sort: sort() })}`, {
params: {
id: { name: '' },
number: { name: '', op: '=', value: style.value.number },
@ -205,11 +217,11 @@ export default defineComponent({
property: { name: '' },
remark: { name: '' },
sortNo: { name: '' },
status: { op: '=', value: '1' },
status: { name: '', op: '=', value: '1' },
version: { name: '' },
},
}),
axios.get('api/styledtls', {
axios.get(`api/styledtls?${buildPaginationQuery({ sort: sort() })}`, {
params: {
id: { name: '' },
number: { name: '', op: '=', value: style.value.number },
@ -229,7 +241,7 @@ export default defineComponent({
property: { name: '' },
remark: { name: '' },
sortNo: { name: '' },
status: { op: '=', value: '1' },
status: { name: '', op: '=', value: '1' },
version: { name: '' },
},
}),
@ -242,22 +254,97 @@ export default defineComponent({
}
};
const openAddEvent = () => {
activeTab.value = 'base';
console.log(baseDtls.value);
const hasEditStatus = row => {
if (activeTab.value === 'setting') {
return settingRef.value?.isEditByRow(row);
} else {
return baseRef.value?.isEditByRow(row);
}
};
const openEditEvent = async row => {
//activeTab.value = 'base';
console.log(activeTab.value);
const addDtlEvent = () => {
if (!style.value.number) {
alertService.showError(t$('entity.validation.required'));
return;
}
let newRow = {
number: style.value.number,
name: '',
process: '',
material: '',
setGroup: 'B',
quantity: 0,
weight: 0,
custPrice: 0,
costPrice: 0,
custLabor: 0,
costLabor: 0,
unitHour: 0,
remark: '',
sortNo: 0,
status: '1',
};
if (activeTab.value === 'setting') {
newRow.setGroup = 'S';
settingDtls.value.push(newRow);
} else {
baseDtls.value.push(newRow);
}
// 保存新行到数据库
axios
.post('api/styledtls', newRow)
.then(response => {
// 刷新数据
loadStyleDtls();
alertService.showSuccess(t$('jewpmsApp.style.created'));
})
.catch(e => {
alertService.showHttpError(e);
});
};
const editDtlEvent = async row => {
let $table = baseRef.value;
if (activeTab.value === 'setting') $table = settingRef.value;
if ($table) {
console.log(row);
await $table.setEditRow(row);
}
};
const saveDtlEvent = async row => {
try {
// 保存行数据到数据库
console.log(row);
await axios.put(`api/styledtls/${row.id}`, row);
// 提交编辑状态
let $table = baseRef.value;
if (activeTab.value === 'setting') $table = settingRef.value;
if ($table) {
await $table.clearEdit();
}
alertService.showInfo(t$('jewpmsApp.style.updated', { param: row.name || row.process }));
// 刷新数据
await loadStyleDtls();
} catch (e) {
alertService.showHttpError(e);
}
};
const cancelDtlEvent = row => {
let $table = baseRef.value;
if (activeTab.value === 'setting') $table = settingRef.value;
console.log($table);
if ($table) {
$table.clearEdit();
$table.revertData(row);
alertService.showInfo(t$('jewpmsApp.style.reverted'));
}
};
const prepareDelete = row => {
console.log('prepareDelete');
removeRow.value = { ...row };
showDelete.value = true;
};
@ -292,8 +379,11 @@ export default defineComponent({
activeTab,
baseColumns,
settingColumns,
openAddEvent,
openEditEvent,
hasEditStatus,
addDtlEvent,
editDtlEvent,
saveDtlEvent,
cancelDtlEvent,
prepareDelete,
showDelete,
removeRow,

View File

@ -129,7 +129,14 @@
<vxe-tabs v-model="activeTab">
<vxe-tab-pane name="base" :title="$t('jewpmsApp.style.base.title')" icon="vxe-icon-custom-column">
<vxe-table v-if="baseDtls" ref="baseRef" :data="baseDtls" stripe :edit-config="{ trigger: 'click', mode: 'cell' }">
<vxe-table
v-if="baseDtls"
ref="baseRef"
:data="baseDtls"
stripe
keepSource
:edit-config="{ trigger: 'manual', mode: 'cell', autoClear: false, showStatus: true }"
>
<vxe-column type="seq" width="50"></vxe-column>
<vxe-column
v-for="column in baseColumns.filter(col => col.visible !== false)"
@ -138,6 +145,7 @@
:title="$t(column.title)"
:sortable="column.sortable"
:width="column.width"
:edit-render="column.editRender"
>
<template #default="{ row }" v-if="column.field === 'process'">
{{ processTypes.find(s => s.number === String(row.process))?.name || row.process }}
@ -147,19 +155,32 @@
</template>
<template #header="{ column }" v-if="column.title === 'entity.action.actions'">
<span class="vxe-button">{{ column.title }}</span>
<vxe-button class="btn-circle text-success" icon="vxe-icon-square-plus-square" @click="openAddEvent"></vxe-button>
<vxe-button class="btn-circle text-success" icon="vxe-icon-square-plus-square" @click="addDtlEvent"></vxe-button>
</template>
<template #default="{ row }" v-if="column.title === 'entity.action.actions'">
<div class="vxe-group">
<vxe-button class="btn-circle text-primary" icon="vxe-icon-signature" @click="openEditEvent(row)"></vxe-button>
<vxe-button class="btn-circle text-danger" icon="vxe-icon-delete" @click="prepareDelete(row)"></vxe-button>
<template v-if="hasEditStatus(row)">
<vxe-button class="btn-circle text-primary" icon="vxe-icon-save" @click="saveDtlEvent(row)"></vxe-button>
<vxe-button class="btn-circle text-warning" icon="vxe-icon-undo" @click="cancelDtlEvent(row)"></vxe-button>
</template>
<template v-else>
<vxe-button class="btn-circle text-primary" icon="vxe-icon-signature" @click="editDtlEvent(row)"></vxe-button>
<vxe-button class="btn-circle text-danger" icon="vxe-icon-delete" @click="prepareDelete(row)"></vxe-button>
</template>
</div>
</template>
</vxe-column>
</vxe-table>
</vxe-tab-pane>
<vxe-tab-pane name="setting" :title="$t('jewpmsApp.style.setting.title')" icon="vxe-icon-setting-fill">
<vxe-table v-if="settingDtls" ref="settingRef" :data="settingDtls" stripe :edit-config="{ trigger: 'click', mode: 'cell' }">
<vxe-table
v-if="settingDtls"
ref="settingRef"
:data="settingDtls"
stripe
keepSource
:edit-config="{ trigger: 'manual', mode: 'cell', autoClear: false, showStatus: true }"
>
<vxe-column type="seq" width="50"></vxe-column>
<vxe-column
v-for="column in settingColumns.filter(col => col.visible !== false)"
@ -168,18 +189,25 @@
:title="$t(column.title)"
:sortable="column.sortable"
:width="column.width"
:edit-render="column.editRender"
>
<template #default="{ row }" v-if="column.field === 'process'">
{{ settingTypes.find(s => s.number === String(row.process))?.name || row.process }}
</template>
<template #header="{ column }" v-if="column.title === 'entity.action.actions'">
<span class="vxe-button">{{ column.title }}</span>
<vxe-button class="btn-circle text-success" icon="vxe-icon-square-plus-square" @click="openAddEvent"></vxe-button>
<vxe-button class="btn-circle text-success" icon="vxe-icon-square-plus-square" @click="addDtlEvent"></vxe-button>
</template>
<template #default="{ row }" v-if="column.title === 'entity.action.actions'">
<div class="vxe-group">
<vxe-button class="btn-circle text-primary" icon="vxe-icon-signature" @click="openEditEvent(row)"></vxe-button>
<vxe-button class="btn-circle text-danger" icon="vxe-icon-delete" @click="prepareDelete(row)"></vxe-button>
<template v-if="hasEditStatus(row)">
<vxe-button class="btn-circle text-primary" icon="vxe-icon-save" @click="saveDtlEvent(row)"></vxe-button>
<vxe-button class="btn-circle text-warning" icon="vxe-icon-undo" @click="cancelDtlEvent(row)"></vxe-button>
</template>
<template v-else>
<vxe-button class="btn-circle text-primary" icon="vxe-icon-signature" @click="editDtlEvent(row)"></vxe-button>
<vxe-button class="btn-circle text-danger" icon="vxe-icon-delete" @click="prepareDelete(row)"></vxe-button>
</template>
</div>
</template>
</vxe-column>

View File

@ -27,7 +27,7 @@ export default defineComponent({
const removeRow = ref(null);
const showDelete = ref(false);
const showFilter = ref(false);
const propOrder = ref('id');
const propOrder = ref('sortNo');
const reverse = ref(false);
const scannerActive = ref(false);
const selectedId = ref(null);