feat:寄卖增加对接客服,db脚本迁移修复

This commit is contained in:
2026-10-27 13:56:08 +08:00
parent 622bd779dd
commit a53321ef30
16 changed files with 43 additions and 225 deletions
@@ -7,8 +7,6 @@
CREATE TABLE IF NOT EXISTS consignment_contact_supporters (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
phone TEXT NOT NULL DEFAULT '',
wechat TEXT NOT NULL DEFAULT '',
note TEXT NOT NULL DEFAULT '',
enabled BOOLEAN NOT NULL DEFAULT TRUE,
sort_order INTEGER NOT NULL DEFAULT 0,
@@ -35,7 +33,7 @@ CREATE INDEX IF NOT EXISTS idx_consignment_inventories_contact_supporter
ON consignment_inventories (contact_supporter_id);
-- 首次部署给一个可用默认项:打手端「必填 + 默认选第一个」不会因名单为空而无法发布。
-- 后台可直接改名/补充联系方式,不会重复插入。
-- 后台可直接改名/补充备注,不会重复插入。
INSERT INTO consignment_contact_supporters (name, note, sort_order)
SELECT '默认客服', '系统初始化,请在「配置 - 对接客服」中修改', 0
WHERE NOT EXISTS (SELECT 1 FROM consignment_contact_supporters);
@@ -9,8 +9,6 @@ import { query } from '../../db/client.js'
export type ConsignmentContactRow = {
id: string | number
name: string
phone: string
wechat: string
note: string
enabled: boolean
sort_order: number
@@ -31,9 +29,7 @@ export async function listConsignmentContacts(filters: {
}
if (filters.keyword) {
values.push(`%${filters.keyword.trim()}%`)
conditions.push(
`(name ILIKE $${values.length} OR phone ILIKE $${values.length} OR wechat ILIKE $${values.length} OR note ILIKE $${values.length})`,
)
conditions.push(`(name ILIKE $${values.length} OR note ILIKE $${values.length})`)
}
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''
@@ -76,8 +72,6 @@ export async function findConsignmentContactByName(
export async function createConsignmentContact(input: {
name: string
phone?: string | undefined
wechat?: string | undefined
note?: string | undefined
enabled?: boolean | undefined
sortOrder?: number | undefined
@@ -85,18 +79,10 @@ export async function createConsignmentContact(input: {
}): Promise<ConsignmentContactRow> {
const res = await query<ConsignmentContactRow>(
`INSERT INTO consignment_contact_supporters (
name, phone, wechat, note, enabled, sort_order, created_at, updated_at
) VALUES ($1, $2, $3, $4, $5, $6, $7, $7)
name, note, enabled, sort_order, created_at, updated_at
) VALUES ($1, $2, $3, $4, $5, $5)
RETURNING *`,
[
input.name,
input.phone || '',
input.wechat || '',
input.note || '',
input.enabled !== false,
input.sortOrder || 0,
input.now,
],
[input.name, input.note || '', input.enabled !== false, input.sortOrder || 0, input.now],
)
return res.rows[0]!
}
@@ -105,8 +91,6 @@ export async function updateConsignmentContact(
id: number | string,
input: {
name?: string | undefined
phone?: string | undefined
wechat?: string | undefined
note?: string | undefined
sortOrder?: number | undefined
now: string
@@ -119,14 +103,6 @@ export async function updateConsignmentContact(
values.push(input.name)
updates.push(`name = $${values.length}`)
}
if (input.phone !== undefined) {
values.push(input.phone)
updates.push(`phone = $${values.length}`)
}
if (input.wechat !== undefined) {
values.push(input.wechat)
updates.push(`wechat = $${values.length}`)
}
if (input.note !== undefined) {
values.push(input.note)
updates.push(`note = $${values.length}`)
@@ -53,8 +53,6 @@ export type ConsignmentInventoryRow = {
/** 对接客服(发布/审核入库时选定,用于提成归属与联系) */
contact_supporter_id?: string | number | null
contact_supporter_name?: string
contact_supporter_phone?: string
contact_supporter_wechat?: string
inbound_at: string
consumed_at: string | null
created_at: string
@@ -87,8 +85,6 @@ export type ConsignmentSubmissionRow = {
/** 对接客服(发布时选定,用于提成归属与联系) */
contact_supporter_id?: string | number | null
contact_supporter_name?: string
contact_supporter_phone?: string
contact_supporter_wechat?: string
status: 'pending_review' | 'approved' | 'rejected'
review_note: string
reviewer_name: string
@@ -213,9 +209,7 @@ export async function listConsignmentInventories(filters: {
wo.friend_added_at AS gift_friend_added_at,
wo.material_json AS bound_work_order_material_json,
wo.requirement_json AS bound_work_order_requirement_json,
ccs.name AS contact_supporter_name,
ccs.phone AS contact_supporter_phone,
ccs.wechat AS contact_supporter_wechat
ccs.name AS contact_supporter_name
FROM consignment_inventories ci
LEFT JOIN work_categories wc ON wc.id = ci.category_id
LEFT JOIN consignment_submissions cs ON cs.id = ci.source_submission_id
@@ -336,9 +330,7 @@ export async function getConsignmentInventoryById(
wo.friend_added_at AS gift_friend_added_at,
wo.material_json AS bound_work_order_material_json,
wo.requirement_json AS bound_work_order_requirement_json,
ccs.name AS contact_supporter_name,
ccs.phone AS contact_supporter_phone,
ccs.wechat AS contact_supporter_wechat
ccs.name AS contact_supporter_name
FROM consignment_inventories ci
LEFT JOIN work_categories wc ON wc.id = ci.category_id
LEFT JOIN consignment_submissions cs ON cs.id = ci.source_submission_id
@@ -363,9 +355,7 @@ export async function listConsignmentInventoriesByIds(
wc.name AS category_name,
cs.submission_no AS source_submission_no,
cs.screenshots_json AS submission_screenshots_json,
ccs.name AS contact_supporter_name,
ccs.phone AS contact_supporter_phone,
ccs.wechat AS contact_supporter_wechat
ccs.name AS contact_supporter_name
FROM consignment_inventories ci
LEFT JOIN work_categories wc ON wc.id = ci.category_id
LEFT JOIN consignment_submissions cs ON cs.id = ci.source_submission_id
@@ -911,9 +901,7 @@ export async function listActiveConsignmentInventoriesForMatching(options?: {
SELECT
ci.*,
cs.submission_no AS source_submission_no,
ccs.name AS contact_supporter_name,
ccs.phone AS contact_supporter_phone,
ccs.wechat AS contact_supporter_wechat
ccs.name AS contact_supporter_name
FROM consignment_inventories ci
LEFT JOIN consignment_submissions cs ON cs.id = ci.source_submission_id
LEFT JOIN consignment_contact_supporters ccs ON ccs.id = ci.contact_supporter_id
@@ -969,9 +957,7 @@ export async function listConsignmentSubmissions(filters: {
wo.acceptance_json AS gift_evidence_json,
wo.work_order_no AS gift_work_order_no,
wo.status AS gift_work_order_status,
ccs.name AS contact_supporter_name,
ccs.phone AS contact_supporter_phone,
ccs.wechat AS contact_supporter_wechat
ccs.name AS contact_supporter_name
FROM consignment_submissions cs
LEFT JOIN work_categories wc ON wc.id = cs.category_id
LEFT JOIN consignment_contact_supporters ccs ON ccs.id = cs.contact_supporter_id
@@ -1191,9 +1177,7 @@ export async function listConsignmentSubmissionsByIds(
wo.acceptance_json AS gift_evidence_json,
wo.work_order_no AS gift_work_order_no,
wo.status AS gift_work_order_status,
ccs.name AS contact_supporter_name,
ccs.phone AS contact_supporter_phone,
ccs.wechat AS contact_supporter_wechat
ccs.name AS contact_supporter_name
FROM consignment_submissions cs
LEFT JOIN work_categories wc ON wc.id = cs.category_id
LEFT JOIN consignment_contact_supporters ccs ON ccs.id = cs.contact_supporter_id
@@ -1222,9 +1206,7 @@ export async function getConsignmentInventoryBySubmissionId(
ci.*,
wc.name AS category_name,
cs.submission_no AS source_submission_no,
ccs.name AS contact_supporter_name,
ccs.phone AS contact_supporter_phone,
ccs.wechat AS contact_supporter_wechat
ccs.name AS contact_supporter_name
FROM consignment_inventories ci
LEFT JOIN work_categories wc ON wc.id = ci.category_id
LEFT JOIN consignment_submissions cs ON cs.id = ci.source_submission_id
@@ -1248,9 +1230,7 @@ export async function getConsignmentSubmissionById(
wo.acceptance_json AS gift_evidence_json,
wo.work_order_no AS gift_work_order_no,
wo.status AS gift_work_order_status,
ccs.name AS contact_supporter_name,
ccs.phone AS contact_supporter_phone,
ccs.wechat AS contact_supporter_wechat
ccs.name AS contact_supporter_name
FROM consignment_submissions cs
LEFT JOIN work_categories wc ON wc.id = cs.category_id
LEFT JOIN consignment_contact_supporters ccs ON ccs.id = cs.contact_supporter_id
@@ -228,8 +228,6 @@ export function mapConsignmentInventory(row: ConsignmentInventoryRow) {
depositAmountFen: Number(row.deposit_amount_fen || 0),
contactSupporterId: row.contact_supporter_id ? Number(row.contact_supporter_id) : null,
contactSupporterName: row.contact_supporter_name || '',
contactSupporterPhone: row.contact_supporter_phone || '',
contactSupporterWechat: row.contact_supporter_wechat || '',
inboundAt: row.inbound_at || row.created_at,
consumedAt: row.consumed_at,
createdAt: row.created_at,
@@ -272,8 +270,6 @@ export function mapConsignmentSubmission(row: ConsignmentSubmissionRow) {
depositAmountFen: Number(row.deposit_amount_fen || 0),
contactSupporterId: row.contact_supporter_id ? Number(row.contact_supporter_id) : null,
contactSupporterName: row.contact_supporter_name || '',
contactSupporterPhone: row.contact_supporter_phone || '',
contactSupporterWechat: row.contact_supporter_wechat || '',
status: row.status,
reviewNote: row.review_note || '',
reviewerName: row.reviewer_name || '',
@@ -18,8 +18,6 @@ export function mapConsignmentContact(row: ConsignmentContactRow) {
return {
id: Number(row.id),
name: row.name,
phone: row.phone || '',
wechat: row.wechat || '',
note: row.note || '',
enabled: Boolean(row.enabled),
sortOrder: Number(row.sort_order || 0),
@@ -92,8 +90,6 @@ export async function createAdminConsignmentContact(payload: JsonObject) {
await assertContactNameAvailable(name)
const row = await createConsignmentContact({
name,
phone: normalizeText(payload.phone),
wechat: normalizeText(payload.wechat),
note: normalizeText(payload.note),
enabled: payload.enabled !== false,
sortOrder: normalizeSortOrder(payload.sortOrder),
@@ -118,8 +114,6 @@ export async function updateAdminConsignmentContact(id: number | string, payload
const updated = await updateConsignmentContact(id, {
name,
phone: payload.phone !== undefined ? normalizeText(payload.phone) : undefined,
wechat: payload.wechat !== undefined ? normalizeText(payload.wechat) : undefined,
note: payload.note !== undefined ? normalizeText(payload.note) : undefined,
sortOrder: payload.sortOrder !== undefined ? normalizeSortOrder(payload.sortOrder) : undefined,
now: nowIso(),
@@ -511,8 +511,6 @@ export async function fulfillWorkOrderWithConsignment(input: {
? Number(inventory.contact_supporter_id)
: null,
contactSupporterName: inventory.contact_supporter_name || '',
contactSupporterPhone: inventory.contact_supporter_phone || '',
contactSupporterWechat: inventory.contact_supporter_wechat || '',
workerName: inv.worker_name || '',
workerPhone: inv.worker_phone || '',
remark: inv.remark || '',
@@ -771,8 +769,6 @@ export async function assignWorkOrderWithConsignmentWorker(input: {
? Number(inventory.contact_supporter_id)
: null,
contactSupporterName: inventory.contact_supporter_name || '',
contactSupporterPhone: inventory.contact_supporter_phone || '',
contactSupporterWechat: inventory.contact_supporter_wechat || '',
workerId: Number(targetWorkerId),
workerName: claimed.worker_name || '',
workerPhone: claimed.worker_phone || '',
@@ -48,14 +48,10 @@ function toRecord(value: unknown): Record<string, unknown> | null {
function mapConsignmentContactSupporter(source: {
contact_supporter_id?: string | number | null
contact_supporter_name?: string
contact_supporter_phone?: string
contact_supporter_wechat?: string
}) {
return {
contactSupporterId: source.contact_supporter_id ? Number(source.contact_supporter_id) : null,
contactSupporterName: source.contact_supporter_name || '',
contactSupporterPhone: source.contact_supporter_phone || '',
contactSupporterWechat: source.contact_supporter_wechat || '',
}
}
@@ -354,8 +350,6 @@ export async function publishWorkerConsignment(workerId: number, payload: JsonOb
? Number(submission.contact_supporter_id)
: null,
contactSupporterName: contactSupporter.name,
contactSupporterPhone: contactSupporter.phone || '',
contactSupporterWechat: contactSupporter.wechat || '',
createdAt: submission.created_at,
}
} catch (error) {