- 做了什么: - 新增客服手动录单数据库迁移 000084 及对应模型,支持编号唯一校验、客服快照绑定与 CRUD 操作; - 后端提供 csmanualentry 业务模块及相关 API,并在仪表盘摘要中聚合今日各客服录单数量; - 前端增加客服手动录单视图页面、路由与侧边栏导航,支持录单二次确认与细粒度权限控制; - 管理后台仪表盘增加今日客服手动录单卡片展示。 - 为什么: - 满足客服在后台手动登记外部业务编号需求,并便于运营按客服统计今日录单业绩和追溯对账。 - 验证方式: - 执行后端全量测试 go test ./... 与静态检查 go vet ./... 全部通过; - 执行前端代码门禁 npm run check 与 vite build 全部通过; - 执行 goose down/up 迁移回滚与应用测试通过,角色权限分配正确; - 本地 dev 联调 POST /api/admin/manual-entries 录单成功返回 201。
46 lines
1.2 KiB
Go
46 lines
1.2 KiB
Go
package csmanualentry
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestNormalizeEntryNo(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
want string
|
|
wantErr error
|
|
}{
|
|
{name: "trim", input: " 202610120013 ", want: "202610120013"},
|
|
{name: "plain", input: "202610120013", want: "202610120013"},
|
|
{name: "empty", input: " ", wantErr: ErrEntryNoInvalid},
|
|
{name: "inner space", input: "2026 1001", wantErr: ErrEntryNoInvalid},
|
|
{name: "too long", input: strings.Repeat("1", 65), wantErr: ErrEntryNoInvalid},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := normalizeEntryNo(tt.input)
|
|
if !errors.Is(err, tt.wantErr) {
|
|
t.Fatalf("normalizeEntryNo(%q) error = %v, want %v", tt.input, err, tt.wantErr)
|
|
}
|
|
if tt.wantErr == nil && got != tt.want {
|
|
t.Fatalf("normalizeEntryNo(%q) = %q, want %q", tt.input, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsDuplicateEntry(t *testing.T) {
|
|
if isDuplicateEntry(nil) {
|
|
t.Fatal("nil should not be duplicate")
|
|
}
|
|
if !isDuplicateEntry(errors.New("Error 1062 (23000): Duplicate entry")) {
|
|
t.Fatal("1062 error should be duplicate")
|
|
}
|
|
if isDuplicateEntry(errors.New("some other error")) {
|
|
t.Fatal("unrelated error should not be duplicate")
|
|
}
|
|
}
|