feat: add carrier-aware signature retirement alerts

This commit is contained in:
hectorzhao
2026-08-10 20:54:05 +08:00
parent 232d1c22a3
commit 55aa054005
52 changed files with 3074 additions and 152 deletions
+15 -8
View File
@@ -1,8 +1,8 @@
import { useState } from 'react';
import { Button, Input, Modal, Select } from '@/components/ui';
import { isValidMoneyInput, moneyUnitsToYuan, yuanToMoneyUnits } from '@/utils/currency';
import { carrierLabelMap, cmppVersionOptions, regionOptions } from './channelModel';
import type { Carrier, ChannelModalState, LongMessageReceiptMode, SmsChannel } from './channelTypes';
import { baseCarrierOptions, cmppVersionOptions, regionOptions } from './channelModel';
import type { BaseCarrier, ChannelModalState, LongMessageReceiptMode, SmsChannel } from './channelTypes';
export function ChannelFormModal({
modal,
@@ -15,7 +15,8 @@ export function ChannelFormModal({
}) {
const channel = modal.channel;
const [name, setName] = useState(channel?.name ?? '');
const [carrier, setCarrier] = useState<Carrier>(channel?.carrier ?? 'mobile');
const [carriers, setCarriers] = useState<BaseCarrier[]>(channel?.carriers ?? ['mobile']);
const [carrierError, setCarrierError] = useState('');
const [unitPrice, setUnitPrice] = useState(channel ? moneyUnitsToYuan(channel.unitPrice).toFixed(4) : '0.0300');
const [unitPriceError, setUnitPriceError] = useState('');
const [region, setRegion] = useState(channel?.sendRegion ?? '全国');
@@ -36,6 +37,10 @@ export function ChannelFormModal({
const [longMessageReceiptMode, setLongMessageReceiptMode] = useState<LongMessageReceiptMode>(channel?.longMessageReceiptMode ?? 'per_segment');
function submit() {
if (carriers.length === 0) {
setCarrierError('至少选择一个运营商');
return;
}
if (!isValidMoneyInput(unitPrice)) {
setUnitPriceError('单价必须是非负金额,且最多保留小数点后 4 位');
return;
@@ -43,7 +48,8 @@ export function ChannelFormModal({
onSubmit({
id: channel?.id ?? String(Math.floor(10000 + Math.random() * 80000)),
name: name || '新建短信通道',
carrier,
carrier: carriers.length === 3 ? 'all' : carriers[0],
carriers,
sendRegion: region,
unitPrice: yuanToMoneyUnits(unitPrice),
status: channel?.status ?? 'connecting',
@@ -94,12 +100,13 @@ export function ChannelFormModal({
<Input label="* 通道名称" onChange={(event) => setName(event.target.value)} placeholder="请输入通道名称" value={name} />
<div className="sms-channel-radio-row">
<span>* </span>
{(['mobile', 'unicom', 'telecom', 'all'] as const).map((item) => (
<label key={item}>
<input checked={carrier === item} onChange={() => setCarrier(item)} type="radio" />
{carrierLabelMap[item]}
{baseCarrierOptions.map((item) => (
<label key={item.value}>
<input checked={carriers.includes(item.value)} onChange={() => { setCarriers((current) => current.includes(item.value) ? current.filter((carrier) => carrier !== item.value) : [...current, item.value]); setCarrierError(''); }} type="checkbox" />
{item.label}
</label>
))}
{carrierError ? <small className="form-error">{carrierError}</small> : null}
</div>
<Input error={unitPriceError} label="* 单价(元)" min="0" onChange={(event) => { setUnitPrice(event.target.value); setUnitPriceError(''); }} step="0.0001" type="number" value={unitPrice} />
<Select label="* 发送地区" onChange={(event) => setRegion(event.target.value)} options={regionOptions} value={region} />