feat(glt): 水票功能模块重构优化

- 将水票模板表单的标题从"编辑水票"改为"规则设置"
- 统一表单数据绑定方式,移除computed计算属性直接使用form绑定
- 调整includeBuyQty字段类型从string改为boolean并更新相关逻辑
- 添加normalizeBoolean函数处理布尔值转换
- 更新商品列表API调用参数从pageSize改为limit
- 优化水票模板表格列配置,调整列标题和对齐方式
- 隐藏部分不必要的表格列如备注、排序、状态等
- 移除水票编辑表单中的多余字段如用户ID、状态等
- 重构搜索组件,使用关键词搜索替换按钮添加功能
- 在表格中新增用户信息展示列,包含头像、昵称、ID和手机号
- 调整水票记录和释放记录的表格列布局和标题
- 移除表格中的操作列和修改时间列
- 修复布尔值在表单提交时的类型转换问题
- 添加表单验证前的数据类型标准化处理
This commit is contained in:
2026-02-04 02:45:24 +08:00
parent a95fa6d95d
commit 1d8da2c5be
11 changed files with 330 additions and 409 deletions

View File

@@ -6,7 +6,7 @@
:maskClosable="false"
:maxable="maxable"
:confirm-loading="loading"
:title="isUpdate ? '编辑水票' : '添加水票'"
:title="isUpdate ? '规则设置' : '添加水票'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
@@ -72,7 +72,7 @@
<a-col :span="12">
<a-form-item label="启用" name="enabled">
<a-switch
v-model:checked="enabledChecked"
v-model:checked="form.enabled"
checked-children="启用"
un-checked-children="停用"
/>
@@ -147,7 +147,7 @@
<a-col :span="12">
<a-form-item label="计入购买量" name="includeBuyQty">
<a-switch
v-model:checked="includeBuyQtyChecked"
v-model:checked="form.includeBuyQty"
checked-children=""
un-checked-children=""
/>
@@ -216,7 +216,7 @@
</template>
<script lang="ts" setup>
import { computed, ref, reactive, watch } from 'vue';
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject } from 'ele-admin-pro';
import {
@@ -255,19 +255,19 @@
const maxable = ref(true);
const formRef = ref<FormInstance | null>(null);
const defaultForm: GltTicketTemplate = {
id: undefined,
goodsId: undefined,
name: '',
enabled: undefined,
unitName: '',
minBuyQty: 1,
startSendQty: 0,
giftMultiplier: 0,
includeBuyQty: '0',
monthlyReleaseQty: 10,
releasePeriods: 0,
firstReleaseMode: 0,
const defaultForm: GltTicketTemplate = {
id: undefined,
goodsId: undefined,
name: '',
enabled: true,
unitName: '',
minBuyQty: 1,
startSendQty: 0,
giftMultiplier: 0,
includeBuyQty: false,
monthlyReleaseQty: 10,
releasePeriods: 0,
firstReleaseMode: 0,
userId: undefined,
sortNumber: 100,
comments: '',
@@ -300,46 +300,34 @@
]
});
const enabledChecked = computed<boolean>({
get() {
return form.enabled === '1' || form.enabled === 1 || form.enabled === true;
},
set(v) {
form.enabled = v ? '1' : '0';
}
});
const { resetFields } = useForm(form, rules);
const includeBuyQtyChecked = computed<boolean>({
get() {
return (
form.includeBuyQty === '1' ||
form.includeBuyQty === 1 ||
form.includeBuyQty === true
);
},
set(v) {
form.includeBuyQty = v ? '1' : '0';
}
});
const normalizeBoolean = (v: any, fallback = false): boolean => {
if (v === true || v === false) return v;
// Spring/Jackson Boolean only accepts true/false; never send "1"/"0".
if (v === 1 || v === '1' || v === 'true') return true;
if (v === 0 || v === '0' || v === 'false') return false;
return fallback;
};
const { resetFields } = useForm(form, rules);
const normalizeNumber = (v: any): number | undefined => {
if (v === undefined || v === null || v === '') return undefined;
const n = Number(v);
return Number.isFinite(n) ? n : undefined;
};
const normalizeNumber = (v: any): number | undefined => {
if (v === undefined || v === null || v === '') return undefined;
const n = Number(v);
return Number.isFinite(n) ? n : undefined;
};
const normalizeFormTypes = () => {
form.goodsId = normalizeNumber(form.goodsId);
form.minBuyQty = normalizeNumber(form.minBuyQty) ?? 1;
form.startSendQty = normalizeNumber(form.startSendQty) ?? 0;
form.giftMultiplier = normalizeNumber(form.giftMultiplier) ?? 0;
form.monthlyReleaseQty = normalizeNumber(form.monthlyReleaseQty) ?? 10;
form.releasePeriods = normalizeNumber(form.releasePeriods) ?? 0;
form.firstReleaseMode = normalizeNumber(form.firstReleaseMode) ?? 0;
form.sortNumber = normalizeNumber(form.sortNumber) ?? 100;
};
const normalizeFormTypes = () => {
form.goodsId = normalizeNumber(form.goodsId);
form.enabled = normalizeBoolean(form.enabled, true);
form.includeBuyQty = normalizeBoolean(form.includeBuyQty, false);
form.minBuyQty = normalizeNumber(form.minBuyQty) ?? 1;
form.startSendQty = normalizeNumber(form.startSendQty) ?? 0;
form.giftMultiplier = normalizeNumber(form.giftMultiplier) ?? 0;
form.monthlyReleaseQty = normalizeNumber(form.monthlyReleaseQty) ?? 10;
form.releasePeriods = normalizeNumber(form.releasePeriods) ?? 0;
form.firstReleaseMode = normalizeNumber(form.firstReleaseMode) ?? 0;
form.sortNumber = normalizeNumber(form.sortNumber) ?? 100;
};
const ensureSelectedGoodsLoaded = async (goodsId?: number) => {
if (!goodsId) {
@@ -366,7 +354,7 @@
if (goodsLoading.value) return;
goodsLoading.value = true;
try {
const res = await listShopGoods({ pageSize: 50 });
const res = await listShopGoods({ limit: 50 });
goodsList.value = res || [];
} catch {
goodsList.value = [];
@@ -382,7 +370,7 @@
goodsLoading.value = true;
try {
const res = await listShopGoods({ keywords, pageSize: 50 });
const res = await listShopGoods({ keywords, limit: 50 });
goodsList.value = res || [];
} catch {
goodsList.value = [];
@@ -414,6 +402,7 @@
formRef.value
.validate()
.then(() => {
normalizeFormTypes();
loading.value = true;
const formData: GltTicketTemplate = { ...form };
const saveOrUpdate = isUpdate.value