fix: 修复SegmentEditor添加分段按钮无响应问题
- 使用独立的 showEditor 状态控制编辑器面板显隐 - 初始状态隐藏编辑器,点击添加分段后显示 - 确认/取消后正确复位状态
This commit is contained in:
@@ -13,7 +13,6 @@ const emit = defineEmits<{
|
|||||||
(e: 'update:modelValue', value: BaseCodeRuleApi.SegmentConfig[]): void;
|
(e: 'update:modelValue', value: BaseCodeRuleApi.SegmentConfig[]): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
/** 内部编辑的 segments 列表 */
|
|
||||||
const segments = ref<BaseCodeRuleApi.SegmentConfig[]>([]);
|
const segments = ref<BaseCodeRuleApi.SegmentConfig[]>([]);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -24,57 +23,47 @@ watch(
|
|||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
/** 触发更新 */
|
|
||||||
function emitUpdate() {
|
function emitUpdate() {
|
||||||
emit('update:modelValue', [...segments.value]);
|
emit('update:modelValue', [...segments.value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 段类型选项 */
|
|
||||||
const typeOptions = [
|
const typeOptions = [
|
||||||
{ label: '固定前缀 (PREFIX)', value: 'PREFIX' },
|
{ label: '固定前缀 (PREFIX)', value: 'PREFIX' },
|
||||||
{ label: '日期 (DATE)', value: 'DATE' },
|
{ label: '日期 (DATE)', value: 'DATE' },
|
||||||
{ label: '流水序号 (SEQUENCE)', value: 'SEQUENCE' },
|
{ label: '流水序号 (SEQUENCE)', value: 'SEQUENCE' },
|
||||||
];
|
];
|
||||||
|
|
||||||
/** 重置维度选项 */
|
|
||||||
const resetByOptions = [
|
const resetByOptions = [
|
||||||
{ label: '按天重置', value: 'DAY' },
|
{ label: '按天', value: 'DAY' },
|
||||||
{ label: '按月重置', value: 'MONTH' },
|
{ label: '按月', value: 'MONTH' },
|
||||||
{ label: '按年重置', value: 'YEAR' },
|
{ label: '按年', value: 'YEAR' },
|
||||||
{ label: '全局不重置', value: 'GLOBAL' },
|
{ label: '全局', value: 'GLOBAL' },
|
||||||
];
|
];
|
||||||
|
|
||||||
/** 正在编辑的段索引(-1 表示新增) */
|
/** 是否显示编辑器面板 */
|
||||||
|
const showEditor = ref(false);
|
||||||
|
/** 编辑中的段索引(-1 = 新增) */
|
||||||
const editingIndex = ref(-1);
|
const editingIndex = ref(-1);
|
||||||
/** 编辑中的段类型 */
|
/** 编辑中的段类型 */
|
||||||
const editingType = ref<string>('');
|
const editingType = ref('');
|
||||||
/** 编辑中的配置数据 */
|
/** 编辑中的数据 */
|
||||||
const editingData = ref<Record<string, unknown>>({});
|
const editingData = ref<Record<string, unknown>>({});
|
||||||
|
|
||||||
/** 当前正在编辑的是新增还是修改 */
|
|
||||||
const isNewSegment = computed(() => editingIndex.value === -1);
|
const isNewSegment = computed(() => editingIndex.value === -1);
|
||||||
|
|
||||||
/** 开始新增段 */
|
/** 点击"添加分段"按钮 */
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
editingIndex.value = -1;
|
editingIndex.value = -1;
|
||||||
editingType.value = '';
|
editingType.value = '';
|
||||||
editingData.value = {};
|
editingData.value = {};
|
||||||
|
showEditor.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 选择段类型后进入配置 */
|
/** 选择段类型 */
|
||||||
function handleSelectType(type: string) {
|
function handleSelectType(type: string) {
|
||||||
editingType.value = type;
|
editingType.value = type;
|
||||||
editingData.value = { type };
|
|
||||||
// 设置默认值
|
|
||||||
if (type === 'SEQUENCE') {
|
if (type === 'SEQUENCE') {
|
||||||
editingData.value = {
|
editingData.value = { type, resetBy: 'DAY', startAt: 1, paddingLen: 4, paddingChar: '0', maxValue: 9999 };
|
||||||
type,
|
|
||||||
resetBy: 'DAY',
|
|
||||||
startAt: 1,
|
|
||||||
paddingLen: 4,
|
|
||||||
paddingChar: '0',
|
|
||||||
maxValue: 9999,
|
|
||||||
};
|
|
||||||
} else if (type === 'DATE') {
|
} else if (type === 'DATE') {
|
||||||
editingData.value = { type, format: 'yyyyMMdd' };
|
editingData.value = { type, format: 'yyyyMMdd' };
|
||||||
} else {
|
} else {
|
||||||
@@ -85,8 +74,10 @@ function handleSelectType(type: string) {
|
|||||||
/** 编辑已有段 */
|
/** 编辑已有段 */
|
||||||
function handleEdit(index: number) {
|
function handleEdit(index: number) {
|
||||||
editingIndex.value = index;
|
editingIndex.value = index;
|
||||||
editingData.value = { ...segments.value[index] };
|
const seg = segments.value[index];
|
||||||
editingType.value = segments.value[index].type || '';
|
editingType.value = seg.type || '';
|
||||||
|
editingData.value = { ...seg };
|
||||||
|
showEditor.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 确认编辑 */
|
/** 确认编辑 */
|
||||||
@@ -95,17 +86,13 @@ function handleConfirmEdit() {
|
|||||||
message.warning('请选择段类型');
|
message.warning('请选择段类型');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (editingType.value === 'PREFIX' && !editingData.value.value) {
|
const seg = { ...editingData.value, type: editingType.value } as BaseCodeRuleApi.SegmentConfig;
|
||||||
message.warning('请输入前缀值');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isNewSegment.value) {
|
if (isNewSegment.value) {
|
||||||
segments.value.push({ ...editingData.value } as BaseCodeRuleApi.SegmentConfig);
|
segments.value.push(seg);
|
||||||
} else {
|
} else {
|
||||||
segments.value[editingIndex.value] = {
|
segments.value[editingIndex.value] = seg;
|
||||||
...editingData.value,
|
|
||||||
} as BaseCodeRuleApi.SegmentConfig;
|
|
||||||
}
|
}
|
||||||
|
showEditor.value = false;
|
||||||
editingIndex.value = -1;
|
editingIndex.value = -1;
|
||||||
editingType.value = '';
|
editingType.value = '';
|
||||||
editingData.value = {};
|
editingData.value = {};
|
||||||
@@ -114,49 +101,38 @@ function handleConfirmEdit() {
|
|||||||
|
|
||||||
/** 取消编辑 */
|
/** 取消编辑 */
|
||||||
function handleCancelEdit() {
|
function handleCancelEdit() {
|
||||||
|
showEditor.value = false;
|
||||||
editingIndex.value = -1;
|
editingIndex.value = -1;
|
||||||
editingType.value = '';
|
editingType.value = '';
|
||||||
editingData.value = {};
|
editingData.value = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除段 */
|
/** 删除 */
|
||||||
function handleDelete(index: number) {
|
function handleDelete(index: number) {
|
||||||
segments.value.splice(index, 1);
|
segments.value.splice(index, 1);
|
||||||
if (editingIndex.value === index) {
|
|
||||||
handleCancelEdit();
|
|
||||||
}
|
|
||||||
emitUpdate();
|
emitUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 上移 */
|
/** 上移 */
|
||||||
function handleMoveUp(index: number) {
|
function handleMoveUp(index: number) {
|
||||||
if (index <= 0) return;
|
if (index <= 0) return;
|
||||||
const item = segments.value[index];
|
[segments.value[index], segments.value[index - 1]] = [segments.value[index - 1], segments.value[index]];
|
||||||
segments.value[index] = segments.value[index - 1];
|
|
||||||
segments.value[index - 1] = item;
|
|
||||||
emitUpdate();
|
emitUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 下移 */
|
/** 下移 */
|
||||||
function handleMoveDown(index: number) {
|
function handleMoveDown(index: number) {
|
||||||
if (index >= segments.value.length - 1) return;
|
if (index >= segments.value.length - 1) return;
|
||||||
const item = segments.value[index];
|
[segments.value[index], segments.value[index + 1]] = [segments.value[index + 1], segments.value[index]];
|
||||||
segments.value[index] = segments.value[index + 1];
|
|
||||||
segments.value[index + 1] = item;
|
|
||||||
emitUpdate();
|
emitUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取段的描述文本 */
|
|
||||||
function getSegmentSummary(seg: BaseCodeRuleApi.SegmentConfig): string {
|
function getSegmentSummary(seg: BaseCodeRuleApi.SegmentConfig): string {
|
||||||
switch (seg.type) {
|
switch (seg.type) {
|
||||||
case 'PREFIX':
|
case 'PREFIX': return `固定值: ${seg.value || '-'}`;
|
||||||
return `固定值: ${seg.value || '-'}`;
|
case 'DATE': return `格式: ${seg.format || 'yyyyMMdd'}`;
|
||||||
case 'DATE':
|
case 'SEQUENCE': return `${seg.resetBy || 'DAY'} | 起${seg.startAt || 1} | ${seg.paddingLen || 4}位补"${seg.paddingChar || '0'}" | 上限${seg.maxValue || 9999}`;
|
||||||
return `格式: ${seg.format || 'yyyyMMdd'}`;
|
default: return JSON.stringify(seg);
|
||||||
case 'SEQUENCE':
|
|
||||||
return `${seg.resetBy || 'DAY'}重置 | ${seg.startAt || 1}起 | ${seg.paddingLen || 4}位补${seg.paddingChar || '0'} | 上限${seg.maxValue || 9999}`;
|
|
||||||
default:
|
|
||||||
return JSON.stringify(seg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -168,34 +144,22 @@ function getSegmentSummary(seg: BaseCodeRuleApi.SegmentConfig): string {
|
|||||||
<div
|
<div
|
||||||
v-for="(seg, index) in segments"
|
v-for="(seg, index) in segments"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="segment-item mb-2 flex items-center justify-between rounded border p-2"
|
class="segment-item mb-2 flex items-center justify-between rounded border border-gray-200 p-2"
|
||||||
:class="{
|
|
||||||
'border-blue-400 bg-blue-50': editingIndex === index,
|
|
||||||
'border-gray-200': editingIndex !== index,
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span
|
<span
|
||||||
class="rounded px-2 py-0.5 text-xs font-bold"
|
class="rounded px-2 py-0.5 text-xs font-bold text-white"
|
||||||
:class="{
|
:class="{
|
||||||
'bg-blue-500 text-white': seg.type === 'PREFIX',
|
'bg-blue-500': seg.type === 'PREFIX',
|
||||||
'bg-green-500 text-white': seg.type === 'DATE',
|
'bg-green-500': seg.type === 'DATE',
|
||||||
'bg-orange-500 text-white': seg.type === 'SEQUENCE',
|
'bg-orange-500': seg.type === 'SEQUENCE',
|
||||||
}"
|
}"
|
||||||
>
|
>{{ seg.type }}</span>
|
||||||
{{ seg.type }}
|
<span class="text-sm text-gray-600">{{ getSegmentSummary(seg) }}</span>
|
||||||
</span>
|
|
||||||
<span class="text-sm text-gray-600">
|
|
||||||
{{ getSegmentSummary(seg) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<a-button size="small" @click="handleMoveUp(index)" :disabled="index === 0">
|
<a-button size="small" @click="handleMoveUp(index)" :disabled="index === 0">↑</a-button>
|
||||||
↑
|
<a-button size="small" @click="handleMoveDown(index)" :disabled="index === segments.length - 1">↓</a-button>
|
||||||
</a-button>
|
|
||||||
<a-button size="small" @click="handleMoveDown(index)" :disabled="index === segments.length - 1">
|
|
||||||
↓
|
|
||||||
</a-button>
|
|
||||||
<a-button size="small" @click="handleEdit(index)">编辑</a-button>
|
<a-button size="small" @click="handleEdit(index)">编辑</a-button>
|
||||||
<a-button size="small" danger @click="handleDelete(index)">删除</a-button>
|
<a-button size="small" danger @click="handleDelete(index)">删除</a-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -203,41 +167,41 @@ function getSegmentSummary(seg: BaseCodeRuleApi.SegmentConfig): string {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 编辑面板 -->
|
<!-- 编辑面板 -->
|
||||||
<div v-if="editingIndex !== -1 || (editingIndex === -1 && editingType.value === '')" class="mb-3 rounded border border-dashed border-gray-300 p-3">
|
<div v-if="showEditor" class="mb-3 rounded border border-dashed border-blue-300 bg-blue-50 p-3">
|
||||||
<!-- 选择类型 -->
|
<!-- 选择类型 -->
|
||||||
<div v-if="!editingType.value" class="flex items-center gap-2">
|
<template v-if="!editingType">
|
||||||
<span class="text-sm text-gray-600">选择段类型:</span>
|
<div class="mb-2 text-sm text-gray-600">选择段类型:</div>
|
||||||
<a-button
|
<div class="flex gap-2">
|
||||||
v-for="opt in typeOptions"
|
<a-button
|
||||||
:key="opt.value"
|
v-for="opt in typeOptions"
|
||||||
size="small"
|
:key="opt.value"
|
||||||
@click="handleSelectType(opt.value)"
|
size="small"
|
||||||
>
|
@click="handleSelectType(opt.value)"
|
||||||
{{ opt.label }}
|
>{{ opt.label }}</a-button>
|
||||||
</a-button>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
|
||||||
<!-- 配置详情 -->
|
<!-- 配置详情 -->
|
||||||
<div v-else>
|
<template v-else>
|
||||||
<div class="mb-2 text-sm font-bold">
|
<div class="mb-2 text-sm font-bold">
|
||||||
{{ isNewSegment ? '新增' : '编辑' }}
|
{{ isNewSegment ? '新增' : '编辑' }} {{ typeOptions.find(t => t.value === editingType)?.label }}
|
||||||
{{ typeOptions.find((t) => t.value === editingType.value)?.label }}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- PREFIX 配置 -->
|
<!-- PREFIX -->
|
||||||
<template v-if="editingType.value === 'PREFIX'">
|
<template v-if="editingType === 'PREFIX'">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="mb-1 block text-sm">固定前缀值</label>
|
<label class="mb-1 block text-sm">固定前缀值</label>
|
||||||
<a-input v-model:value="(editingData.value as string)" placeholder="如 ORD、CK" />
|
<a-input v-model:value="editingData.value" placeholder="如 ORD、CK" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- DATE 配置 -->
|
<!-- DATE -->
|
||||||
<template v-if="editingType.value === 'DATE'">
|
<template v-if="editingType === 'DATE'">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="mb-1 block text-sm">日期格式</label>
|
<label class="mb-1 block text-sm">日期格式</label>
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="editingData.format"
|
v-model:value="editingData.format"
|
||||||
|
style="width: 100%"
|
||||||
:options="[
|
:options="[
|
||||||
{ label: 'yyyyMMdd (20260715)', value: 'yyyyMMdd' },
|
{ label: 'yyyyMMdd (20260715)', value: 'yyyyMMdd' },
|
||||||
{ label: 'yyyyMM (202607)', value: 'yyyyMM' },
|
{ label: 'yyyyMM (202607)', value: 'yyyyMM' },
|
||||||
@@ -248,23 +212,20 @@ function getSegmentSummary(seg: BaseCodeRuleApi.SegmentConfig): string {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- SEQUENCE 配置 -->
|
<!-- SEQUENCE -->
|
||||||
<template v-if="editingType.value === 'SEQUENCE'">
|
<template v-if="editingType === 'SEQUENCE'">
|
||||||
<div class="grid grid-cols-2 gap-2">
|
<div class="grid grid-cols-2 gap-2">
|
||||||
<div>
|
<div>
|
||||||
<label class="mb-1 block text-sm">重置维度</label>
|
<label class="mb-1 block text-sm">重置维度</label>
|
||||||
<a-select
|
<a-select v-model:value="editingData.resetBy" style="width: 100%" :options="resetByOptions" />
|
||||||
v-model:value="editingData.resetBy"
|
|
||||||
:options="resetByOptions"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="mb-1 block text-sm">起始值</label>
|
<label class="mb-1 block text-sm">起始值</label>
|
||||||
<a-input-number v-model:value="editingData.startAt" :min="0" class="!w-full" />
|
<a-input-number v-model:value="editingData.startAt" :min="0" style="width: 100%" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="mb-1 block text-sm">补位长度</label>
|
<label class="mb-1 block text-sm">补位长度</label>
|
||||||
<a-input-number v-model:value="editingData.paddingLen" :min="0" class="!w-full" placeholder="如 4 → 0001" />
|
<a-input-number v-model:value="editingData.paddingLen" :min="0" style="width: 100%" placeholder="如 4" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="mb-1 block text-sm">补位字符</label>
|
<label class="mb-1 block text-sm">补位字符</label>
|
||||||
@@ -272,32 +233,24 @@ function getSegmentSummary(seg: BaseCodeRuleApi.SegmentConfig): string {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="mb-1 block text-sm">最大值上限</label>
|
<label class="mb-1 block text-sm">最大值上限</label>
|
||||||
<a-input-number v-model:value="editingData.maxValue" :min="1" class="!w-full" placeholder="如 9999" />
|
<a-input-number v-model:value="editingData.maxValue" :min="1" style="width: 100%" placeholder="如 9999" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="mt-3 flex gap-2">
|
<div class="mt-3 flex gap-2">
|
||||||
<a-button type="primary" size="small" @click="handleConfirmEdit">
|
<a-button type="primary" size="small" @click="handleConfirmEdit">{{ isNewSegment ? '添加' : '保存' }}</a-button>
|
||||||
{{ isNewSegment ? '添加' : '保存' }}
|
|
||||||
</a-button>
|
|
||||||
<a-button size="small" @click="handleCancelEdit">取消</a-button>
|
<a-button size="small" @click="handleCancelEdit">取消</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 添加按钮 -->
|
<!-- 添加按钮 -->
|
||||||
<a-button v-if="editingIndex === -1 && !editingType.value" type="dashed" block @click="handleAdd">
|
<a-button v-if="!showEditor" type="dashed" block @click="handleAdd">+ 添加分段</a-button>
|
||||||
+ 添加分段
|
|
||||||
</a-button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.segment-editor {
|
.segment-editor { width: 100%; }
|
||||||
width: 100%;
|
.segment-item:hover { border-color: #1890ff; }
|
||||||
}
|
|
||||||
.segment-item:hover {
|
|
||||||
border-color: #1890ff;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user