Files
kami_frontend/src/views/camel-oil-info/prefetch/components/settings-form.vue
danial 86252f67db fix(prefetch): 修正库存阈值默认值及校验逻辑
- 将库存阈值输入框最小值由1改为0,提示改为“库存阈值(默认为0)”
- 新增新增面额时库存容量默认值为0
- 修改校验逻辑,容量为空时自动设置为0
- 校验库存阈值不能小于0,提示信息相应更新
- 优化了面额和库存阈值的必填校验提示内容
2025-12-07 23:08:09 +08:00

407 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<a-card :bordered="false">
<a-form
:model="formModel"
:label-col-props="{ span: 6 }"
:wrapper-col-props="{ span: 18 }"
>
<!-- 第一部分豪猪平台设置 -->
<a-card title="豪猪平台设置" :bordered="false">
<template #extra>
<a-space>
<icon-mobile />
<span style="color: var(--color-text-3); font-size: 13px">
配置豪猪平台的登录信息和账号获取设置
</span>
</a-space>
</template>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item field="useHaozhuPlatform" label="豪猪平台">
<a-switch
v-model="formModel.useHaozhuPlatform"
checked-text="启用"
unchecked-text="禁用"
/>
<template #help>是否从豪猪平台获取手机号登录</template>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item
field="haozhuUsername"
label="豪猪用户名"
:rules="[
{
required: formModel.useHaozhuPlatform,
message: '启用豪猪平台时请输入用户名'
}
]"
>
<a-input
v-model="formModel.haozhuUsername"
placeholder="请输入豪猪平台用户名"
:disabled="!formModel.useHaozhuPlatform"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item
field="haozhuPassword"
label="豪猪密码"
:rules="[
{
required: formModel.useHaozhuPlatform,
message: '启用豪猪平台时请输入密码'
}
]"
>
<a-input-password
v-model="formModel.haozhuPassword"
placeholder="请输入豪猪平台密码"
:disabled="!formModel.useHaozhuPlatform"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item
field="loginAccountCount"
label="登录账号数量"
:rules="[
{ required: true, message: '请输入登录账号数量' },
{
type: 'number',
min: 1,
max: 100,
message: '请输入1-100之间的数字'
}
]"
>
<a-input-number
v-model="formModel.loginAccountCount"
:min="1"
:max="100"
placeholder="请输入要登录的手机号数量"
style="width: 100%"
/>
</a-form-item>
</a-col>
</a-row>
</a-card>
<!-- 第二部分账号并发设置 -->
<a-card title="账号并发设置" :bordered="false" style="margin-top: 16px">
<template #extra>
<a-space>
<icon-thunderbolt />
<span style="color: var(--color-text-3); font-size: 13px">
配置预拉取订单的并发账号数量和单个账号的并发数
</span>
</a-space>
</template>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item
field="prefetchConcurrencyAccounts"
label="并发账号数"
:rules="[
{ required: true, message: '请输入并发账号数量' },
{
type: 'number',
min: 1,
max: 50,
message: '请输入1-50之间的数字'
}
]"
>
<a-input-number
v-model="formModel.prefetchConcurrencyAccounts"
:min="1"
:max="50"
placeholder="请输入提前拉单并发的账号数量"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item
field="singleAccountConcurrency"
label="单账号并发数"
:rules="[
{ required: true, message: '请输入单账号并发数量' },
{
type: 'number',
min: 1,
max: 20,
message: '请输入1-20之间的数字'
}
]"
>
<a-input-number
v-model="formModel.singleAccountConcurrency"
:min="1"
:max="20"
placeholder="请输入单个账号的并发数量"
style="width: 100%"
/>
</a-form-item>
</a-col>
</a-row>
</a-card>
<!-- 第三部分面额库存设置 -->
<a-card title="面额库存设置" :bordered="false" style="margin-top: 16px">
<template #extra>
<a-space>
<icon-currency-dollar />
<span style="color: var(--color-text-3); font-size: 13px">
配置不同面额卡券的库存阈值系统将根据此阈值管理预拉取订单库存
</span>
</a-space>
</template>
<!-- 添加面额按钮 -->
<div style="margin-bottom: 16px; text-align: right">
<a-button type="primary" size="small" @click="addDenomination">
<template #icon>
<icon-plus />
</template>
添加面额
</a-button>
</div>
<a-table
v-if="
formModel.targetDenominations &&
formModel.targetDenominations.length > 0
"
:data="formModel.targetDenominations"
:columns="columns"
:pagination="false"
:bordered="{ cell: true }"
row-key="denomination"
>
<template #denomination="{ rowIndex }">
<a-input-number
v-model="formModel.targetDenominations[rowIndex].denomination"
:min="1"
placeholder="如100、200、500"
style="width: 100%"
@change="validateDenomination(rowIndex)"
/>
</template>
<template #capacity="{ rowIndex }">
<a-input-number
v-model="formModel.targetDenominations[rowIndex].capacity"
:min="0"
placeholder="库存阈值默认为0"
style="width: 100%"
/>
</template>
<template #actions="{ rowIndex }">
<a-button
type="text"
status="danger"
size="small"
@click="removeDenomination(rowIndex)"
>
<template #icon>
<icon-delete />
</template>
删除
</a-button>
</template>
</a-table>
<a-empty v-else description="暂无面额设置,请添加面额配置" />
</a-card>
</a-form>
</a-card>
</template>
<script lang="ts" setup>
import { reactive, onMounted } from 'vue';
import { Message } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading';
import type { KamiApiCamelOilV1DenominationSetting } from '@/api/generated/index.ts';
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
import { jdV2SettingsClient } from '@/api/index.ts';
interface Emits {
(e: 'success'): void;
(e: 'error'): void;
}
const emit = defineEmits<Emits>();
const { loading, setLoading } = useLoading(false);
const formModel = reactive({
useHaozhuPlatform: false,
haozhuUsername: '',
haozhuPassword: '',
loginAccountCount: 5,
prefetchConcurrencyAccounts: 2,
singleAccountConcurrency: 3,
targetDenominations: [] as KamiApiCamelOilV1DenominationSetting[]
});
// 表格列配置
const columns: TableColumnData[] = [
{
title: '序号',
dataIndex: 'index',
width: 80,
render: ({ rowIndex }) => rowIndex + 1
},
{
title: '面额值',
dataIndex: 'denomination',
width: 150,
slotName: 'denomination'
},
{
title: '库存阈值',
dataIndex: 'capacity',
width: 150,
slotName: 'capacity'
},
{
title: '操作',
dataIndex: 'actions',
width: 100,
slotName: 'actions'
}
];
const addDenomination = () => {
formModel.targetDenominations.push({
denomination: null,
capacity: 0
});
};
const validateDenomination = (index: number) => {
const currentItem = formModel.targetDenominations[index];
if (!currentItem.denomination) return;
// 检查是否有重复的面额
const duplicateIndex = formModel.targetDenominations.findIndex(
(item, i) => i !== index && item.denomination === currentItem.denomination
);
if (duplicateIndex !== -1) {
Message.warning(
`面额 ${currentItem.denomination} 已存在,请修改为不同的面额值`
);
currentItem.denomination = null;
}
};
const removeDenomination = (index: number) => {
formModel.targetDenominations.splice(index, 1);
};
const handleSubmit = async () => {
try {
// 验证豪猪平台设置
if (formModel.useHaozhuPlatform) {
if (!formModel.haozhuUsername || !formModel.haozhuPassword) {
Message.warning('启用豪猪平台时请填写用户名和密码');
return;
}
}
// 验证面额设置
if (
formModel.targetDenominations &&
formModel.targetDenominations.length > 0
) {
for (let i = 0; i < formModel.targetDenominations.length; i++) {
const item = formModel.targetDenominations[i];
if (!item.denomination) {
Message.warning(`请填写第${i + 1}个面额设置的面额值`);
return;
}
if (item.capacity === null || item.capacity === undefined) {
// capacity为空时默认设置为0
item.capacity = 0;
}
if (item.capacity < 0) {
Message.warning(`${i + 1}个面额设置的库存阈值不能小于0`);
return;
}
}
// 检查面额重复
const denominations = formModel.targetDenominations.map(
item => item.denomination
);
const uniqueDenominations = [...new Set(denominations)];
if (denominations.length !== uniqueDenominations.length) {
Message.warning('存在重复的面额设置,请确保每个面额值都是唯一的');
return;
}
}
setLoading(true);
await jdV2SettingsClient.apiJdV2SettingsUpdatePost({
kamiApiCamelOilV1UpdateSettingsReq: { ...formModel }
});
Message.success('设置保存成功');
// 通知父组件保存成功
emit('success');
} catch (error) {
console.error('保存设置失败:', error);
Message.error('保存设置失败');
// 通知父组件保存失败
emit('error');
} finally {
setLoading(false);
}
};
const resetForm = () => {
loadSettings();
};
// 加载设置数据
const loadSettings = async () => {
setLoading(true);
try {
const { data } = await jdV2SettingsClient.apiJdV2SettingsGetGet();
Object.assign(formModel, data);
if (!formModel.targetDenominations) {
formModel.targetDenominations = [];
}
} catch (error) {
console.error('获取设置失败:', error);
Message.error('获取设置失败');
} finally {
setLoading(false);
}
};
// 暴露方法给父组件
defineExpose({
handleSubmit,
resetForm,
loading
});
// 组件挂载时加载设置
onMounted(loadSettings);
</script>
<style scoped>
/* Arco Design 已经处理了大部分样式,只需要覆盖必要的布局样式 */
:deep(.arco-form-item-content-flex) {
display: block;
}
</style>