-- 收款工作台 —— 长期收款码(2026-09-22) -- 手工执行: psycopg2 连接 payment_platform_java 库 -- -- 背景: 用户口径(design 文档 §0.9)—— 商户拿**一个长期固定的二维码**发到群里, -- 群里任何人扫这个码进收银台,**顾客自己输金额**、点确认,直接唤起支付 App。 -- 码可建多个、可命名、可停用,绑定到某个商户。 -- -- ★ 不分渠道(2026-09-22 定): 一个码微信和支付宝都能扫。码里编的是**我们自己的地址** -- /payment/cashier/{code_no},分流按扫码环境的 UA 做,与码本身无关 —— 所以没有 channel 列。 -- 理由与证据链见 design 文档 §4.2。**普通浏览器(系统相机扫)那条腿的渠道由顾客点选**(§4.4)。 -- -- ★ 与旧设计的根本区别: **不是一单一码**。码只承载「入口」,不承载金额; -- 订单在顾客点「确认支付」那一刻才创建。 -- -- 本脚本只建表,**不动任何存量表**,可安全重复执行(全部 IF NOT EXISTS)。 CREATE TABLE IF NOT EXISTS pay_receive_code ( id BIGINT PRIMARY KEY, tenant_id BIGINT NOT NULL, code_no VARCHAR(64) NOT NULL, name VARCHAR(64) NOT NULL, merchant_id BIGINT NOT NULL, status VARCHAR(32) NOT NULL DEFAULT 'ENABLED', remark VARCHAR(255), created_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), updated_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now() ); -- code_no 出现在**公开 URL** 上(/payment/cashier/{code_no}),必须全局唯一: -- 不带 tenant_id 的全局唯一索引。若改成 (tenant_id, code_no),两个租户撞码就是串户 —— -- 顾客扫 A 商户的码,钱进了 B 商户的账。 CREATE UNIQUE INDEX IF NOT EXISTS uk_receive_code_no ON pay_receive_code (code_no); -- 同租户内不允许重名:不然商户在列表里看到两个「前台」没法选。 CREATE UNIQUE INDEX IF NOT EXISTS uk_receive_code_name ON pay_receive_code (tenant_id, name); CREATE INDEX IF NOT EXISTS idx_receive_code_mch ON pay_receive_code (merchant_id); COMMENT ON TABLE pay_receive_code IS '收款码(长期固定码,商户可建多个、可命名、可停用;只承载入口不承载金额,订单由顾客在收银台确认时创建)'; COMMENT ON COLUMN pay_receive_code.id IS '主键ID(应用侧雪花生成)'; COMMENT ON COLUMN pay_receive_code.tenant_id IS '租户ID(由 MyBatis-Plus 拦截器填,归属只来自认证上下文)'; COMMENT ON COLUMN pay_receive_code.code_no IS 'URL 短码(32 位随机,不可枚举;出现在公开收银台地址上,全局唯一)'; COMMENT ON COLUMN pay_receive_code.name IS '码名称(商户自取,如「前台」「3号桌」;同租户内唯一)'; COMMENT ON COLUMN pay_receive_code.merchant_id IS '绑定的商户,指向 pay_lsy_merchant.id'; COMMENT ON COLUMN pay_receive_code.status IS '状态(ENABLED 启用 / DISABLED 停用;停用后收银台返回「链接无效」页)'; COMMENT ON COLUMN pay_receive_code.remark IS '备注'; COMMENT ON COLUMN pay_receive_code.created_time IS '创建时间'; COMMENT ON COLUMN pay_receive_code.updated_time IS '更新时间'; -- 只读核对(执行后可手工跑一遍确认) -- SELECT column_name, data_type, is_nullable FROM information_schema.columns -- WHERE table_name = 'pay_receive_code' ORDER BY ordinal_position; -- 期望 9 列 -- SELECT indexname FROM pg_indexes WHERE tablename = 'pay_receive_code'; -- 期望含上述三条