feat: 物品规则支持按数量计价(二次匹配SKU文字数量)
- 规则新增单价(unit_price_fen,0 关闭),开启后接单总价 = 单价 × 商品名称文字中的规格数量 - 新增 resolveSkuNameQuantity:支持阿拉伯数字与中文数字(如 指挥官秘钥15个 → 15、三个 → 3) - 建单同步时按文字数量计算奖励,skuQuantity 记入工单 material.source 便于核对 - 规则表单新增计价方式(固定金额/按数量×单价),列表展示单价 - 新增 3 个数量解析单元测试(269 全通过)
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
-- 物品规则支持按数量计价:unit_price_fen > 0 时,工单接单总价 = 单价 × SKU 名称文字中的规格数量(如 指挥官秘钥15个 → 15);0 表示按固定接单金额。
|
||||||
|
ALTER TABLE work_product_rules
|
||||||
|
ADD COLUMN unit_price_fen INTEGER NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
COMMENT ON COLUMN work_product_rules.unit_price_fen IS '按数量计价单价(分),0 表示未启用,按固定接单金额;数量取自商品名称文字(如 15个/三个)';
|
||||||
@@ -119,6 +119,7 @@ export type WorkProductRuleRow = {
|
|||||||
enabled: boolean
|
enabled: boolean
|
||||||
auto_create: boolean
|
auto_create: boolean
|
||||||
reward_amount: number
|
reward_amount: number
|
||||||
|
unit_price_fen: number
|
||||||
required_deposit_amount: number
|
required_deposit_amount: number
|
||||||
deposit_threshold_amount: number
|
deposit_threshold_amount: number
|
||||||
sharing_enabled: boolean
|
sharing_enabled: boolean
|
||||||
|
|||||||
@@ -413,6 +413,7 @@ export async function upsertWorkProductRule(input: {
|
|||||||
enabled: boolean
|
enabled: boolean
|
||||||
autoCreate: boolean
|
autoCreate: boolean
|
||||||
rewardAmount: number
|
rewardAmount: number
|
||||||
|
unitPriceFen?: number
|
||||||
requiredDepositAmount: number
|
requiredDepositAmount: number
|
||||||
depositThresholdAmount: number
|
depositThresholdAmount: number
|
||||||
sharingEnabled?: boolean
|
sharingEnabled?: boolean
|
||||||
@@ -429,6 +430,7 @@ export async function upsertWorkProductRule(input: {
|
|||||||
INSERT INTO work_product_rules (
|
INSERT INTO work_product_rules (
|
||||||
rule_key, provider, platform, shop_id, sku_code, product_name,
|
rule_key, provider, platform, shop_id, sku_code, product_name,
|
||||||
match_type, category_id, enabled, auto_create, reward_amount,
|
match_type, category_id, enabled, auto_create, reward_amount,
|
||||||
|
unit_price_fen,
|
||||||
required_deposit_amount, deposit_threshold_amount,
|
required_deposit_amount, deposit_threshold_amount,
|
||||||
sharing_enabled, sharing_total_quantity, sharing_unit_reward,
|
sharing_enabled, sharing_total_quantity, sharing_unit_reward,
|
||||||
timeout_minutes, timeout_policy,
|
timeout_minutes, timeout_policy,
|
||||||
@@ -437,11 +439,12 @@ export async function upsertWorkProductRule(input: {
|
|||||||
) VALUES (
|
) VALUES (
|
||||||
$1, $2, $3, $4, $5, $6,
|
$1, $2, $3, $4, $5, $6,
|
||||||
$7, $8, $9, $10, $11,
|
$7, $8, $9, $10, $11,
|
||||||
$12, $13,
|
$12,
|
||||||
$14, $15, $16,
|
$13, $14,
|
||||||
$17, $18,
|
$15, $16, $17,
|
||||||
$19::jsonb,
|
$18, $19,
|
||||||
$20, $21, $22
|
$20::jsonb,
|
||||||
|
$21, $22, $23
|
||||||
)
|
)
|
||||||
ON CONFLICT (rule_key) DO UPDATE
|
ON CONFLICT (rule_key) DO UPDATE
|
||||||
SET
|
SET
|
||||||
@@ -455,6 +458,7 @@ export async function upsertWorkProductRule(input: {
|
|||||||
enabled = EXCLUDED.enabled,
|
enabled = EXCLUDED.enabled,
|
||||||
auto_create = EXCLUDED.auto_create,
|
auto_create = EXCLUDED.auto_create,
|
||||||
reward_amount = EXCLUDED.reward_amount,
|
reward_amount = EXCLUDED.reward_amount,
|
||||||
|
unit_price_fen = EXCLUDED.unit_price_fen,
|
||||||
required_deposit_amount = EXCLUDED.required_deposit_amount,
|
required_deposit_amount = EXCLUDED.required_deposit_amount,
|
||||||
deposit_threshold_amount = EXCLUDED.deposit_threshold_amount,
|
deposit_threshold_amount = EXCLUDED.deposit_threshold_amount,
|
||||||
sharing_enabled = EXCLUDED.sharing_enabled,
|
sharing_enabled = EXCLUDED.sharing_enabled,
|
||||||
@@ -479,6 +483,7 @@ export async function upsertWorkProductRule(input: {
|
|||||||
input.enabled,
|
input.enabled,
|
||||||
input.autoCreate,
|
input.autoCreate,
|
||||||
input.rewardAmount,
|
input.rewardAmount,
|
||||||
|
Math.max(0, toPositiveInteger(input.unitPriceFen, 0)),
|
||||||
input.requiredDepositAmount,
|
input.requiredDepositAmount,
|
||||||
input.depositThresholdAmount,
|
input.depositThresholdAmount,
|
||||||
input.sharingEnabled === true,
|
input.sharingEnabled === true,
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ import {
|
|||||||
saveWorkerFinanceConfig,
|
saveWorkerFinanceConfig,
|
||||||
} from './worker-finance-config-service.js'
|
} from './worker-finance-config-service.js'
|
||||||
|
|
||||||
import { DEFAULT_CATEGORY_KEY, DEFAULT_DEPOSIT_THRESHOLD_AMOUNT, DEFAULT_LEVEL_KEY, DEFAULT_LEVEL_NAME, mapFinanceRequest, mapWallet, mapWorkCategory, mapWorkOrderAdmin, mapWorkOrderShare, mapWorkProductRule, mapWorkerLevel, mapWorkerUser, normalizeAdminFinanceReviewStatus, normalizeAmountFen, normalizeBoolean, normalizeEnabledStatus, normalizeFinanceRequestStatus, normalizeFinanceRequestType, normalizeInteger, normalizeMatchType, normalizeOptionalId, normalizePositiveInteger, normalizeProblemResolutionAction, normalizeRequirementFields, normalizeRequirementFieldsFromPayload, normalizeReviewStatus, normalizeSessionVersion, normalizeSlugKey, normalizeSubmittedFields, normalizeUploadedFiles, normalizeWorkerType, resolveFreezeDepositAmount, resolveMatchingProductRule, resolveRequirementFields, resolveWorkerPermissions } from './mappers.js'
|
import { DEFAULT_CATEGORY_KEY, DEFAULT_DEPOSIT_THRESHOLD_AMOUNT, DEFAULT_LEVEL_KEY, DEFAULT_LEVEL_NAME, mapFinanceRequest, mapWallet, mapWorkCategory, mapWorkOrderAdmin, mapWorkOrderShare, mapWorkProductRule, mapWorkerLevel, mapWorkerUser, normalizeAdminFinanceReviewStatus, normalizeAmountFen, normalizeBoolean, normalizeEnabledStatus, normalizeFinanceRequestStatus, normalizeFinanceRequestType, normalizeInteger, normalizeMatchType, normalizeOptionalId, normalizePositiveInteger, normalizeProblemResolutionAction, normalizeRequirementFields, normalizeRequirementFieldsFromPayload, normalizeReviewStatus, normalizeSessionVersion, normalizeSlugKey, normalizeSubmittedFields, normalizeUploadedFiles, normalizeWorkerType, resolveFreezeDepositAmount, resolveMatchingProductRule, resolveRequirementFields, resolveSkuNameQuantity, resolveWorkerPermissions } from './mappers.js'
|
||||||
import { ensureWorkerPlatformDefaults, getRequiredWorkOrder, getRequiredWorker, normalizeWorkOrderTimeoutPolicy } from './worker-service.js'
|
import { ensureWorkerPlatformDefaults, getRequiredWorkOrder, getRequiredWorker, normalizeWorkOrderTimeoutPolicy } from './worker-service.js'
|
||||||
|
|
||||||
export async function listAdminWorkerLevels() {
|
export async function listAdminWorkerLevels() {
|
||||||
@@ -288,6 +288,10 @@ export async function saveAdminWorkProductRule(payload: JsonObject = {}) {
|
|||||||
enabled: normalizeBoolean(payload.enabled, true),
|
enabled: normalizeBoolean(payload.enabled, true),
|
||||||
autoCreate: normalizeBoolean(payload.autoCreate ?? payload.auto_create, false),
|
autoCreate: normalizeBoolean(payload.autoCreate ?? payload.auto_create, false),
|
||||||
rewardAmount: finalRewardAmount,
|
rewardAmount: finalRewardAmount,
|
||||||
|
unitPriceFen:
|
||||||
|
payload.unitPrice === undefined && payload.unitPriceYuan === undefined
|
||||||
|
? 0
|
||||||
|
: normalizeAmountFen(payload.unitPrice ?? payload.unitPriceYuan, 0),
|
||||||
requiredDepositAmount,
|
requiredDepositAmount,
|
||||||
depositThresholdAmount,
|
depositThresholdAmount,
|
||||||
sharingEnabled,
|
sharingEnabled,
|
||||||
@@ -1177,7 +1181,11 @@ export async function syncWorkerOrdersForSourceOrder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fields = normalizeRequirementFields(safeParseJson(rule.requirement_json).fields)
|
const fields = normalizeRequirementFields(safeParseJson(rule.requirement_json).fields)
|
||||||
const rewardAmount = Number(rule.reward_amount || 0)
|
const skuQuantity = resolveSkuNameQuantity(item.sku_name)
|
||||||
|
const unitPriceFen = Number(rule.unit_price_fen || 0)
|
||||||
|
// 按数量计价:单价 × SKU 名称文字中的规格数量(如 指挥官秘钥15个);未启用则用固定接单金额
|
||||||
|
const rewardAmount =
|
||||||
|
unitPriceFen > 0 ? unitPriceFen * skuQuantity : Number(rule.reward_amount || 0)
|
||||||
const depositThresholdAmount = Number(
|
const depositThresholdAmount = Number(
|
||||||
rule.deposit_threshold_amount || DEFAULT_DEPOSIT_THRESHOLD_AMOUNT,
|
rule.deposit_threshold_amount || DEFAULT_DEPOSIT_THRESHOLD_AMOUNT,
|
||||||
)
|
)
|
||||||
@@ -1213,6 +1221,7 @@ export async function syncWorkerOrdersForSourceOrder(
|
|||||||
shopName: order.shop_name,
|
shopName: order.shop_name,
|
||||||
skuCode: item.sku_code,
|
skuCode: item.sku_code,
|
||||||
skuName: item.sku_name,
|
skuName: item.sku_name,
|
||||||
|
skuQuantity,
|
||||||
quantity: Number(item.quantity || 1),
|
quantity: Number(item.quantity || 1),
|
||||||
orderAmountFen: Number(order.total_amount || 0),
|
orderAmountFen: Number(order.total_amount || 0),
|
||||||
currency: order.currency || 'CNY',
|
currency: order.currency || 'CNY',
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ export function mapWorkProductRule(rule: WorkProductRuleRow | null | undefined)
|
|||||||
enabled: Boolean(rule.enabled),
|
enabled: Boolean(rule.enabled),
|
||||||
autoCreate: Boolean(rule.auto_create),
|
autoCreate: Boolean(rule.auto_create),
|
||||||
rewardAmount: Number(rule.reward_amount || 0),
|
rewardAmount: Number(rule.reward_amount || 0),
|
||||||
|
unitPriceFen: Number(rule.unit_price_fen || 0),
|
||||||
requiredDepositAmount: Number(rule.required_deposit_amount || 0),
|
requiredDepositAmount: Number(rule.required_deposit_amount || 0),
|
||||||
depositThresholdAmount: Number(
|
depositThresholdAmount: Number(
|
||||||
rule.deposit_threshold_amount || DEFAULT_DEPOSIT_THRESHOLD_AMOUNT,
|
rule.deposit_threshold_amount || DEFAULT_DEPOSIT_THRESHOLD_AMOUNT,
|
||||||
@@ -664,8 +665,67 @@ export function resolveMatchingProductRule(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function matchesOptionalText(ruleValue: unknown, sourceValue: unknown) {
|
/**
|
||||||
const ruleText = String(ruleValue || '')
|
* 从商品名称文字中解析规格数量(二次匹配数量)。
|
||||||
|
* 支持阿拉伯数字与中文数字,如:指挥官秘钥1个 → 1、指挥官秘钥15个 → 15、指挥官秘钥三个 → 3。
|
||||||
|
* 解析不到时返回 1。
|
||||||
|
*/
|
||||||
|
export function resolveSkuNameQuantity(productName: unknown): number {
|
||||||
|
const text = String(productName || '').trim()
|
||||||
|
if (!text) return 1
|
||||||
|
|
||||||
|
const arabicMatch = text.match(/(\d+)\s*(?:个|份|张|枚)/)
|
||||||
|
if (arabicMatch) {
|
||||||
|
const parsed = Number(arabicMatch[1])
|
||||||
|
if (Number.isSafeInteger(parsed) && parsed > 0) return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
const chineseMatch = text.match(
|
||||||
|
/([零一二三四五六七八九十百千两]+)\s*(?:个|份|张|枚)/,
|
||||||
|
)
|
||||||
|
if (chineseMatch?.[1]) {
|
||||||
|
const parsed = parseChineseNumber(chineseMatch[1])
|
||||||
|
if (parsed > 0) return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const CHINESE_DIGITS: Record<string, number> = {
|
||||||
|
零: 0,
|
||||||
|
一: 1,
|
||||||
|
二: 2,
|
||||||
|
两: 2,
|
||||||
|
三: 3,
|
||||||
|
四: 4,
|
||||||
|
五: 5,
|
||||||
|
六: 6,
|
||||||
|
七: 7,
|
||||||
|
八: 8,
|
||||||
|
九: 9,
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseChineseNumber(text: string): number {
|
||||||
|
let section = 0
|
||||||
|
let digit = 0
|
||||||
|
for (const char of text) {
|
||||||
|
if (char === '十') {
|
||||||
|
section += (digit || 1) * 10
|
||||||
|
digit = 0
|
||||||
|
} else if (char === '百') {
|
||||||
|
section += (digit || 1) * 100
|
||||||
|
digit = 0
|
||||||
|
} else if (char === '千') {
|
||||||
|
section += (digit || 1) * 1000
|
||||||
|
digit = 0
|
||||||
|
} else if (char in CHINESE_DIGITS) {
|
||||||
|
digit = CHINESE_DIGITS[char] ?? 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return section + digit
|
||||||
|
}
|
||||||
|
|
||||||
|
export function matchesOptionalText(ruleValue: unknown, sourceValue: unknown) { const ruleText = String(ruleValue || '')
|
||||||
.trim()
|
.trim()
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
if (!ruleText) {
|
if (!ruleText) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
assertWorkerLoginAllowed,
|
assertWorkerLoginAllowed,
|
||||||
normalizeRequirementFields,
|
normalizeRequirementFields,
|
||||||
resolveCollectSubmitTargetWorkOrder,
|
resolveCollectSubmitTargetWorkOrder,
|
||||||
|
resolveSkuNameQuantity,
|
||||||
} from './index.js'
|
} from './index.js'
|
||||||
|
|
||||||
function buildWorkerUserRow(overrides: Partial<WorkerUserRow> = {}): WorkerUserRow {
|
function buildWorkerUserRow(overrides: Partial<WorkerUserRow> = {}): WorkerUserRow {
|
||||||
@@ -98,6 +99,26 @@ test('normalizeRequirementFields default template marks serverZone optional with
|
|||||||
assert.deepEqual(serverZone?.options, ['QQ区', '微信区'])
|
assert.deepEqual(serverZone?.options, ['QQ区', '微信区'])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('resolveSkuNameQuantity parses arabic quantities from sku names', () => {
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥1个'), 1)
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥15个'), 15)
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥2个'), 2)
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥10个'), 10)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('resolveSkuNameQuantity parses chinese numeral quantities from sku names', () => {
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥三个'), 3)
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥十五个'), 15)
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥二十个'), 20)
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥三十个'), 30)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('resolveSkuNameQuantity falls back to 1 when no quantity is found', () => {
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥'), 1)
|
||||||
|
assert.equal(resolveSkuNameQuantity(''), 1)
|
||||||
|
assert.equal(resolveSkuNameQuantity('指挥官秘钥礼包'), 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
function buildWorkOrderRow(
|
function buildWorkOrderRow(
|
||||||
overrides: Partial<WorkOrderRow> = {},
|
overrides: Partial<WorkOrderRow> = {},
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
InputNumber,
|
InputNumber,
|
||||||
Modal,
|
Modal,
|
||||||
Popconfirm,
|
Popconfirm,
|
||||||
|
Radio,
|
||||||
Select,
|
Select,
|
||||||
Space,
|
Space,
|
||||||
Statistic,
|
Statistic,
|
||||||
@@ -114,6 +115,8 @@ export default function ProductRulesPanel() {
|
|||||||
rewardAmount?: number
|
rewardAmount?: number
|
||||||
requiredDepositAmount?: number
|
requiredDepositAmount?: number
|
||||||
depositThresholdAmount?: number
|
depositThresholdAmount?: number
|
||||||
|
pricingMode?: string
|
||||||
|
unitPrice?: number
|
||||||
sharingEnabled?: boolean
|
sharingEnabled?: boolean
|
||||||
sharingTotalQuantity?: number
|
sharingTotalQuantity?: number
|
||||||
sharingUnitReward?: number
|
sharingUnitReward?: number
|
||||||
@@ -123,11 +126,15 @@ export default function ProductRulesPanel() {
|
|||||||
fieldsText?: string
|
fieldsText?: string
|
||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
autoCreate?: boolean
|
autoCreate?: boolean
|
||||||
|
sortOrder?: number
|
||||||
}) {
|
}) {
|
||||||
try {
|
try {
|
||||||
|
const unitMode = values.pricingMode === 'unit'
|
||||||
|
const { pricingMode: _pricingMode, ...payload } = values
|
||||||
await saveAdminWorkProductRule({
|
await saveAdminWorkProductRule({
|
||||||
...values,
|
...payload,
|
||||||
ruleId: editingRule?.ruleId,
|
ruleId: editingRule?.ruleId,
|
||||||
|
unitPrice: unitMode ? Number(values.unitPrice || 0) : 0,
|
||||||
})
|
})
|
||||||
message.success(editingRule ? '物品规则已更新' : '物品规则已创建')
|
message.success(editingRule ? '物品规则已更新' : '物品规则已创建')
|
||||||
resetRuleForm()
|
resetRuleForm()
|
||||||
@@ -160,7 +167,9 @@ export default function ProductRulesPanel() {
|
|||||||
productName: rule.productName,
|
productName: rule.productName,
|
||||||
matchType: rule.matchType,
|
matchType: rule.matchType,
|
||||||
categoryId: rule.categoryId || undefined,
|
categoryId: rule.categoryId || undefined,
|
||||||
|
pricingMode: rule.unitPriceFen > 0 ? 'unit' : 'fixed',
|
||||||
rewardAmount: rule.rewardAmount / 100,
|
rewardAmount: rule.rewardAmount / 100,
|
||||||
|
unitPrice: rule.unitPriceFen / 100,
|
||||||
requiredDepositAmount: rule.requiredDepositAmount / 100,
|
requiredDepositAmount: rule.requiredDepositAmount / 100,
|
||||||
depositThresholdAmount: rule.depositThresholdAmount / 100,
|
depositThresholdAmount: rule.depositThresholdAmount / 100,
|
||||||
sharingEnabled: rule.sharing?.enabled || false,
|
sharingEnabled: rule.sharing?.enabled || false,
|
||||||
@@ -250,8 +259,17 @@ export default function ProductRulesPanel() {
|
|||||||
{ title: '分类', width: 140, render: (_, row) => row.categoryName || '-' },
|
{ title: '分类', width: 140, render: (_, row) => row.categoryName || '-' },
|
||||||
{
|
{
|
||||||
title: '接单金额',
|
title: '接单金额',
|
||||||
width: 120,
|
width: 150,
|
||||||
render: (_, row) => formatMoney(row.rewardAmount),
|
render: (_, row) => (
|
||||||
|
<div className="cell-stack">
|
||||||
|
<span>{formatMoney(row.rewardAmount)}</span>
|
||||||
|
{row.unitPriceFen > 0 ? (
|
||||||
|
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
||||||
|
按数量计价:{formatMoney(row.unitPriceFen)} × 数量
|
||||||
|
</Typography.Text>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '押金',
|
title: '押金',
|
||||||
@@ -333,6 +351,7 @@ export default function ProductRulesPanel() {
|
|||||||
initialValues={{
|
initialValues={{
|
||||||
platform: 'kuaishou',
|
platform: 'kuaishou',
|
||||||
matchType: 'contains',
|
matchType: 'contains',
|
||||||
|
pricingMode: 'fixed',
|
||||||
rewardAmount: 25,
|
rewardAmount: 25,
|
||||||
depositThresholdAmount: 200,
|
depositThresholdAmount: 200,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
@@ -405,14 +424,47 @@ export default function ProductRulesPanel() {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="接单金额" name="rewardAmount">
|
<Form.Item
|
||||||
<InputNumber
|
label="计价方式"
|
||||||
min={0.01}
|
name="pricingMode"
|
||||||
step={1}
|
tooltip="按数量计价时,接单总价 = 单价 × 商品名称文字中的规格数量(如「指挥官秘钥15个」→ 15)"
|
||||||
addonAfter="元"
|
>
|
||||||
|
<Radio.Group
|
||||||
className="full-width"
|
className="full-width"
|
||||||
|
options={[
|
||||||
|
{ value: 'fixed', label: '固定金额' },
|
||||||
|
{ value: 'unit', label: '按数量 × 单价' },
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item noStyle shouldUpdate>
|
||||||
|
{({ getFieldValue }) =>
|
||||||
|
getFieldValue('pricingMode') === 'unit' ? (
|
||||||
|
<Form.Item
|
||||||
|
label="单价"
|
||||||
|
name="unitPrice"
|
||||||
|
rules={[{ required: true, message: '请填写单价' }]}
|
||||||
|
extra="接单总价 = 单价 × 商品名称文字中的数量"
|
||||||
|
>
|
||||||
|
<InputNumber
|
||||||
|
min={0.01}
|
||||||
|
step={1}
|
||||||
|
addonAfter="元"
|
||||||
|
className="full-width"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
) : (
|
||||||
|
<Form.Item label="接单金额" name="rewardAmount">
|
||||||
|
<InputNumber
|
||||||
|
min={0.01}
|
||||||
|
step={1}
|
||||||
|
addonAfter="元"
|
||||||
|
className="full-width"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Form.Item>
|
||||||
<Form.Item label="押金阈值" name="depositThresholdAmount">
|
<Form.Item label="押金阈值" name="depositThresholdAmount">
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={0}
|
min={0}
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ export function saveAdminWorkProductRule(payload: {
|
|||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
autoCreate?: boolean
|
autoCreate?: boolean
|
||||||
rewardAmount?: number
|
rewardAmount?: number
|
||||||
|
unitPrice?: number
|
||||||
requiredDepositAmount?: number
|
requiredDepositAmount?: number
|
||||||
depositThresholdAmount?: number
|
depositThresholdAmount?: number
|
||||||
sharingEnabled?: boolean
|
sharingEnabled?: boolean
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ export type WorkProductRule = {
|
|||||||
enabled: boolean
|
enabled: boolean
|
||||||
autoCreate: boolean
|
autoCreate: boolean
|
||||||
rewardAmount: number
|
rewardAmount: number
|
||||||
|
unitPriceFen: number
|
||||||
requiredDepositAmount: number
|
requiredDepositAmount: number
|
||||||
depositThresholdAmount: number
|
depositThresholdAmount: number
|
||||||
sharing?: WorkOrderSharingConfig
|
sharing?: WorkOrderSharingConfig
|
||||||
|
|||||||
Reference in New Issue
Block a user