chore: establish V1.1 recovery baseline
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /api/v1
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: danyang-match-platform
|
||||
|
||||
profiles:
|
||||
active: dev
|
||||
|
||||
datasource:
|
||||
url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:danyang_match}
|
||||
username: ${DB_USER:postgres}
|
||||
password: ${DB_PASSWORD:postgres}
|
||||
driver-class-name: org.postgresql.Driver
|
||||
hikari:
|
||||
maximum-pool-size: 20
|
||||
minimum-idle: 5
|
||||
idle-timeout: 30000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
|
||||
jackson:
|
||||
default-property-inclusion: non_null
|
||||
serialization:
|
||||
write-dates-as-timestamps: false
|
||||
deserialization:
|
||||
fail-on-unknown-properties: false
|
||||
|
||||
flyway:
|
||||
enabled: true
|
||||
locations: classpath:db/migration
|
||||
baseline-on-migrate: true
|
||||
baseline-version: 0
|
||||
out-of-order: false
|
||||
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:localhost}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: ${REDIS_PASSWORD:}
|
||||
timeout: 5000ms
|
||||
|
||||
main:
|
||||
allow-bean-definition-overriding: false
|
||||
|
||||
# MyBatis-Plus
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
|
||||
type-handlers-package: com.danyang.match.platform.shared.typehandler
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: assign_uuid
|
||||
|
||||
# Logging
|
||||
logging:
|
||||
level:
|
||||
root: INFO
|
||||
com.danyang.match.platform: DEBUG
|
||||
org.springframework.security: INFO
|
||||
org.mybatis: DEBUG
|
||||
pattern:
|
||||
console: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{requestId}] %-5level %logger{36} - %msg%n'
|
||||
|
||||
# Actuator
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus
|
||||
endpoint:
|
||||
health:
|
||||
show-details: when_authorized
|
||||
show-components: always
|
||||
health:
|
||||
db:
|
||||
enabled: true
|
||||
redis:
|
||||
enabled: true
|
||||
|
||||
# Spring Security (default disable for dev, will be configured in security module)
|
||||
spring.security:
|
||||
user:
|
||||
name: admin
|
||||
password: admin
|
||||
|
||||
# Rate limiting
|
||||
rate-limit:
|
||||
max-requests-per-window: 20
|
||||
window-seconds: 60
|
||||
@@ -0,0 +1,7 @@
|
||||
# App metadata
|
||||
info:
|
||||
app:
|
||||
name: danyang-match-platform
|
||||
version: 0.0.1-SNAPSHOT
|
||||
description: 丹阳公益婚恋服务平台 V1.0
|
||||
encodedName: 丹��公益婚恋服务平台
|
||||
@@ -0,0 +1,482 @@
|
||||
-- ============================================================
|
||||
-- 丹阳公益婚恋服务平台 — Demo Seed 最终版(单次事务,纯 SQL)
|
||||
-- ============================================================
|
||||
BEGIN;
|
||||
SET session_replication_role = 'replica';
|
||||
|
||||
-- 1. 组织
|
||||
INSERT INTO organizations (name, type, contact_name, status) VALUES
|
||||
('丹阳市妇女联合会', 'women_federation', '张丽华', 'active'),
|
||||
('丹阳市总工会', 'trade_union', '李明远', 'active'),
|
||||
('丹阳市慈善基金会', 'charity_center', '王秀英', 'active');
|
||||
|
||||
-- 2. 工作人员(V1.0原有 + V1.1新增)
|
||||
INSERT INTO operators (organization_id, name, username, password_hash, status)
|
||||
SELECT id, '陈主任', 'admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'
|
||||
FROM organizations WHERE type='women_federation' LIMIT 1
|
||||
UNION ALL
|
||||
SELECT id, '红娘小王', 'wanghongniang', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'
|
||||
FROM organizations WHERE type='women_federation' LIMIT 1
|
||||
UNION ALL
|
||||
SELECT id, '审核员小张', 'reviewer01', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'
|
||||
FROM organizations WHERE type='charity_center' LIMIT 1
|
||||
UNION ALL
|
||||
SELECT id, '活动管理员赵', 'activitymgr','$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'
|
||||
FROM organizations WHERE type='trade_union' LIMIT 1
|
||||
-- V1.1 新增演示操作员
|
||||
UNION ALL
|
||||
SELECT id, '服务站小李', 'stationop', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'
|
||||
FROM organizations WHERE type='women_federation' LIMIT 1
|
||||
UNION ALL
|
||||
SELECT id, '咨询师小周', 'counselor', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'
|
||||
FROM organizations WHERE type='charity_center' LIMIT 1
|
||||
UNION ALL
|
||||
SELECT id, '内容编辑小吴', 'contenteditor','$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'
|
||||
FROM organizations WHERE type='women_federation' LIMIT 1;
|
||||
|
||||
-- 操作员角色绑定(V1.0原有 + V1.1新增)
|
||||
INSERT INTO operator_roles (operator_id, role_id)
|
||||
-- V1.0: admin = super_admin + platform_admin
|
||||
SELECT o.id, '00000000-0000-0000-0000-000000000001' FROM operators WHERE username='admin'
|
||||
UNION ALL SELECT o.id, '00000000-0000-0000-0000-000000000002' FROM operators WHERE username='admin'
|
||||
-- V1.0: wanghongniang = matchmaker + activity_manager
|
||||
SELECT o.id, '00000000-0000-0000-0000-000000000005' FROM operators WHERE username='wanghongniang'
|
||||
UNION ALL SELECT o.id, '00000000-0000-0000-0000-000000000006' FROM operators WHERE username='wanghongniang'
|
||||
-- V1.0: reviewer01 = reviewer + risk_operator
|
||||
SELECT o.id, '00000000-0000-0000-0000-000000000004' FROM operators WHERE username='reviewer01'
|
||||
UNION ALL SELECT o.id, '00000000-0000-0000-0000-000000000007' FROM operators WHERE username='reviewer01'
|
||||
-- V1.0: activitymgr = activity_manager + volunteer
|
||||
SELECT o.id, '00000000-0000-0000-0000-000000000006' FROM operators WHERE username='activitymgr'
|
||||
UNION ALL SELECT o.id, '00000000-0000-0000-0000-000000000008' FROM operators WHERE username='activitymgr'
|
||||
-- V1.1: stationop = service_station_operator
|
||||
SELECT o.id, '00000000-0000-0000-0000-000000000010' FROM operators WHERE username='stationop'
|
||||
-- V1.1: counselor = counselor
|
||||
SELECT o.id, '00000000-0000-0000-0000-000000000011' FROM operators WHERE username='counselor'
|
||||
-- V1.1: contenteditor = content_editor
|
||||
SELECT o.id, '00000000-0000-0000-0000-000000000013' FROM operators WHERE username='contenteditor';
|
||||
|
||||
-- 3. 用户 + 资料 + 偏好 + 实名 + 兴趣 + 隐私 + 照片(一次性生成UUID并关联)
|
||||
WITH demo_users AS (
|
||||
INSERT INTO users (wechat_openid, account_status, relationship_status, recommendation_enabled, created_at)
|
||||
VALUES
|
||||
('demo_openid_f01','normal','searching',true,'2026-03-15T10:00:00Z'),
|
||||
('demo_openid_f02','normal','searching',true,'2026-03-20T14:30:00Z'),
|
||||
('demo_openid_f03','normal','searching',true,'2026-04-01T09:15:00Z'),
|
||||
('demo_openid_f04','normal','paused',true,'2026-04-10T16:00:00Z'),
|
||||
('demo_openid_f05','normal','searching',true,'2026-05-01T11:20:00Z'),
|
||||
('demo_openid_f06','normal','searching',true,'2026-05-15T08:45:00Z'),
|
||||
('demo_openid_m01','normal','searching',true,'2026-03-10T09:00:00Z'),
|
||||
('demo_openid_m02','normal','getting_to_know',true,'2026-03-25T13:00:00Z'),
|
||||
('demo_openid_m03','normal','searching',true,'2026-04-05T15:30:00Z'),
|
||||
('demo_openid_m04','normal','searching',true,'2026-04-20T10:00:00Z'),
|
||||
('demo_openid_m05','normal','matched_successfully',true,'2026-05-01T14:00:00Z'),
|
||||
('demo_openid_m06','normal','searching',true,'2026-05-10T16:30:00Z')
|
||||
RETURNING id, wechat_openid
|
||||
), user_map AS (
|
||||
SELECT id, wechat_openid,
|
||||
CASE wechat_openid
|
||||
WHEN 'demo_openid_f01' THEN 'f01' WHEN 'demo_openid_f02' THEN 'f02'
|
||||
WHEN 'demo_openid_f03' THEN 'f03' WHEN 'demo_openid_f04' THEN 'f04'
|
||||
WHEN 'demo_openid_f05' THEN 'f05' WHEN 'demo_openid_f06' THEN 'f06'
|
||||
WHEN 'demo_openid_m01' THEN 'm01' WHEN 'demo_openid_m02' THEN 'm02'
|
||||
WHEN 'demo_openid_m03' THEN 'm03' WHEN 'demo_openid_m04' THEN 'm04'
|
||||
WHEN 'demo_openid_m05' THEN 'm05' WHEN 'demo_openid_m06' THEN 'm06'
|
||||
END as alias
|
||||
FROM demo_users
|
||||
),
|
||||
user_data AS (
|
||||
SELECT id, wechat_openid, alias,
|
||||
CASE alias WHEN 'f01' THEN '小芳' WHEN 'f02' THEN '晓燕' WHEN 'f03' THEN '婷婷'
|
||||
WHEN 'f04' THEN '美玲' WHEN 'f05' THEN '慧琴' WHEN 'f06' THEN '秀英'
|
||||
WHEN 'm01' THEN '张伟' WHEN 'm02' THEN '李强' WHEN 'm03' THEN '王磊'
|
||||
WHEN 'm04' THEN '赵明' WHEN 'm05' THEN '孙浩' WHEN 'm06' THEN '周洋' END as display_name,
|
||||
CASE WHEN alias LIKE 'f%' THEN 'female' ELSE 'male' END as gender,
|
||||
CASE alias
|
||||
WHEN 'f01' THEN '1995-06-15' WHEN 'f02' THEN '1993-09-20' WHEN 'f03' THEN '1998-02-10'
|
||||
WHEN 'f04' THEN '1990-11-05' WHEN 'f05' THEN '1996-07-22' WHEN 'f06' THEN '1992-04-18'
|
||||
WHEN 'm01' THEN '1992-01-10' WHEN 'm02' THEN '1990-08-25' WHEN 'm03' THEN '1997-12-03'
|
||||
WHEN 'm04' THEN '1988-05-30' WHEN 'm05' THEN '1994-03-14' WHEN 'm06' THEN '1999-08-08'
|
||||
END as birth_date,
|
||||
CASE alias
|
||||
WHEN 'f01' THEN 162 WHEN 'f02' THEN 165 WHEN 'f03' THEN 158
|
||||
WHEN 'f04' THEN 160 WHEN 'f05' THEN 163 WHEN 'f06' THEN 157
|
||||
WHEN 'm01' THEN 175 WHEN 'm02' THEN 178 WHEN 'm03' THEN 180
|
||||
WHEN 'm04' THEN 172 WHEN 'm05' THEN 182 WHEN 'm06' THEN 176
|
||||
END as height_cm,
|
||||
CASE WHEN alias IN ('f01','f02','f04','f05','m01','m02','m04','m05') THEN '321181'
|
||||
WHEN alias IN ('f03','m03') THEN '321100' WHEN alias='m06' THEN '320500' END as region_code,
|
||||
CASE WHEN alias IN ('f01','f02','f04','f05','m01','m02','m04','m05') THEN '丹阳'
|
||||
WHEN alias IN ('f03','m03') THEN '镇江' WHEN alias='m06' THEN '苏州' END as region_name,
|
||||
CASE alias WHEN 'f02' THEN 'divorced' WHEN 'f06' THEN 'widowed' ELSE 'never_married' END as marital_status,
|
||||
CASE alias
|
||||
WHEN 'f01' THEN 'bachelor' WHEN 'f02' THEN 'college' WHEN 'f03' THEN 'master'
|
||||
WHEN 'f04' THEN 'senior_high' WHEN 'f05' THEN 'bachelor' WHEN 'f06' THEN 'junior_high'
|
||||
WHEN 'm01' THEN 'bachelor' WHEN 'm02' THEN 'master' WHEN 'm03' THEN 'college'
|
||||
WHEN 'm04' THEN 'senior_high' WHEN 'm05' THEN 'bachelor' WHEN 'm06' THEN 'master'
|
||||
END as education_code,
|
||||
CASE alias
|
||||
WHEN 'f01' THEN 'clerical' WHEN 'f02' THEN 'teacher' WHEN 'f03' THEN 'designer'
|
||||
WHEN 'f04' THEN 'factory' WHEN 'f05' THEN 'nurse' WHEN 'f06' THEN 'farmer'
|
||||
WHEN 'm01' THEN 'engineer' WHEN 'm02' THEN 'manager' WHEN 'm03' THEN 'programmer'
|
||||
WHEN 'm04' THEN 'sales' WHEN 'm05' THEN 'doctor' WHEN 'm06' THEN 'researcher'
|
||||
END as occupation_code,
|
||||
CASE alias WHEN 'f03' THEN 'sometimes' WHEN 'f06' THEN 'often' WHEN 'm02' THEN 'sometimes'
|
||||
WHEN 'm04' THEN 'often' WHEN 'm05' THEN 'sometimes' ELSE 'never' END as smoking,
|
||||
CASE alias WHEN 'f03' THEN 'often' WHEN 'f06' THEN 'often' WHEN 'm02' THEN 'often'
|
||||
WHEN 'm04' THEN 'often' ELSE 'sometimes' END as drinking,
|
||||
CASE WHEN alias IN ('f03','m06') THEN '否' ELSE '是' END as long_term,
|
||||
CASE WHEN alias IN ('f03','m06') THEN '否' ELSE '是' END as future,
|
||||
CASE WHEN alias IN ('f03','m06') THEN '恋爱' ELSE '结婚' END as goal,
|
||||
CASE alias
|
||||
WHEN 'f01' THEN 90 WHEN 'f02' THEN 95 WHEN 'f03' THEN 85 WHEN 'f04' THEN 70
|
||||
WHEN 'f05' THEN 92 WHEN 'f06' THEN 60 WHEN 'm01' THEN 88 WHEN 'm02' THEN 95
|
||||
WHEN 'm03' THEN 82 WHEN 'm04' THEN 75 WHEN 'm05' THEN 97 WHEN 'm06' THEN 80
|
||||
END as completion
|
||||
FROM user_map
|
||||
)
|
||||
INSERT INTO user_profiles (user_id, display_name, gender, birth_date, height_cm,
|
||||
region_code, region_name, marital_status, children_status,
|
||||
education_code, occupation_code, smoking_status, drinking_status,
|
||||
long_term_danyang, future_danyang, relationship_goal, profile_completion, profile_status)
|
||||
SELECT id, display_name, gender, birth_date::date, height_cm,
|
||||
region_code, region_name, marital_status, 'none',
|
||||
education_code, occupation_code, smoking, drinking,
|
||||
long_term, future, goal, completion, 'approved'
|
||||
FROM user_data;
|
||||
|
||||
-- 偏好
|
||||
INSERT INTO user_preferences (user_id, min_age, max_age, age_priority, min_height_cm, max_height_cm, height_priority, region_scope, region_priority, marital_statuses, marital_priority, min_education_code, education_priority)
|
||||
SELECT id,
|
||||
CASE WHEN alias LIKE 'f%' THEN 28 WHEN alias LIKE 'm%' THEN 22 ELSE 25 END,
|
||||
CASE WHEN alias LIKE 'f%' THEN 40 WHEN alias LIKE 'm%' THEN 38 ELSE 35 END,
|
||||
'required',
|
||||
CASE WHEN alias LIKE 'f%' THEN 155 WHEN alias LIKE 'm%' THEN 170 ELSE 158 END,
|
||||
CASE WHEN alias LIKE 'f%' THEN 172 WHEN alias LIKE 'm%' THEN 188 ELSE 185 END,
|
||||
'preferred',
|
||||
'[\"321181\",\"321100\"]', 'required', '[\"never_married\"]', 'required',
|
||||
CASE alias WHEN 'f02' THEN 'college' WHEN 'm02' THEN 'college' WHEN 'f01' THEN 'bachelor'
|
||||
WHEN 'm01' THEN 'bachelor' WHEN 'm05' THEN 'bachelor' ELSE NULL END,
|
||||
'preferred'
|
||||
FROM user_data;
|
||||
|
||||
-- 实名认证
|
||||
INSERT INTO user_identities (id, user_id, real_name_enc, id_number_enc, id_number_hash, gender, birth_date, verification_status, provider, verified_at)
|
||||
SELECT gen_random_uuid(), id, encode(('demo_enc_'||alias)::bytea,'escape'), encode(('demo_id_'||alias)::bytea,'escape'), 'demo_sha256_'||alias, gender, birth_date::date, 'verified', 'mock', NOW()-INTERVAL '1 day')
|
||||
FROM user_data;
|
||||
|
||||
-- 兴趣
|
||||
WITH interests AS (
|
||||
SELECT ud.id as user_id, ic.code
|
||||
FROM user_data ud
|
||||
CROSS JOIN (VALUES ('reading'),('cooking'),('travel'),('sports'),('music'),('outdoor'),
|
||||
('photography'),('dance'),('movie'),('pets'),('fitness'),('charity'),('gardening'),
|
||||
('gaming'),('hiking'),('coding'),('cars'),('running'),('research')) ic(code)
|
||||
WHERE (ud.alias='f01' AND ic.code IN ('reading','cooking','travel'))
|
||||
OR (ud.alias='f02' AND ic.code IN ('sports','music','outdoor'))
|
||||
OR (ud.alias='f03' AND ic.code IN ('photography','dance','movie'))
|
||||
OR (ud.alias='f04' AND ic.code IN ('pets','cooking'))
|
||||
OR (ud.alias='f05' AND ic.code IN ('reading','fitness','charity'))
|
||||
OR (ud.alias='f06' AND ic.code IN ('gardening','cooking'))
|
||||
OR (ud.alias='m01' AND ic.code IN ('sports','gaming','travel'))
|
||||
OR (ud.alias='m02' AND ic.code IN ('reading','investment','hiking'))
|
||||
OR (ud.alias='m03' AND ic.code IN ('gaming','music','coding'))
|
||||
OR (ud.alias='m04' AND ic.code IN ('cars','cooking'))
|
||||
OR (ud.alias='m05' AND ic.code IN ('running','reading','charity'))
|
||||
OR (ud.alias='m06' AND ic.code IN ('research','travel','photography'))
|
||||
)
|
||||
INSERT INTO user_interests (user_id, interest_code) SELECT user_id, code FROM interests;
|
||||
|
||||
-- 隐私设置
|
||||
INSERT INTO user_privacy_settings (user_id, visible_in_recommendations, visible_in_search, show_occupation, show_lifestyle_photos, receive_activity_recommendations, accept_matchmaker_recommendations)
|
||||
SELECT id, true,
|
||||
CASE WHEN alias IN ('f03','f06','m04') THEN false ELSE true END,
|
||||
CASE WHEN alias IN ('f02','f04','m02','m03') THEN false ELSE true END,
|
||||
CASE WHEN alias IN ('f02','m02','m03') THEN false ELSE true END,
|
||||
CASE WHEN alias IN ('f05','m03') THEN false ELSE true END,
|
||||
CASE WHEN alias='f03' THEN false ELSE true END
|
||||
FROM user_data;
|
||||
|
||||
-- 照片
|
||||
WITH photo_source AS (
|
||||
SELECT id, alias FROM user_data
|
||||
)
|
||||
INSERT INTO user_photos (id, user_id, file_key, photo_type, sort_order, review_status)
|
||||
SELECT gen_random_uuid(), id, 'photos/demo/'||alias||'/avatar.jpg', 'avatar', 0, 'approved' FROM photo_source
|
||||
UNION ALL
|
||||
SELECT gen_random_uuid(), id, 'photos/demo/'||alias||'/lifestyle1.jpg', 'lifestyle', 1, 'approved' FROM photo_source;
|
||||
|
||||
-- ============================================================
|
||||
-- 4. 审核任务
|
||||
-- ============================================================
|
||||
INSERT INTO review_tasks (id, user_id, review_type, status, assigned_operator_id, submitted_at, started_at, completed_at, final_comment, version)
|
||||
SELECT gen_random_uuid(), ud.id, 'initial_profile', 'approved',
|
||||
(SELECT id FROM operators WHERE username='reviewer01'),
|
||||
NOW()-INTERVAL '60 days', NOW()-INTERVAL '59 days', NOW()-INTERVAL '58 days', '资料完整', 1
|
||||
FROM user_data ud WHERE ud.alias IN ('f01','f02','f03','m01','m02','m03','m05');
|
||||
|
||||
-- ============================================================
|
||||
-- 5. 用户关系
|
||||
-- ============================================================
|
||||
WITH f01 AS (SELECT id FROM user_data WHERE alias='f01'),
|
||||
f02 AS (SELECT id FROM user_data WHERE alias='f02'),
|
||||
f03 AS (SELECT id FROM user_data WHERE alias='f03'),
|
||||
f04 AS (SELECT id FROM user_data WHERE alias='f04'),
|
||||
f05 AS (SELECT id FROM user_data WHERE alias='f05'),
|
||||
f06 AS (SELECT id FROM user_data WHERE alias='f06'),
|
||||
m01 AS (SELECT id FROM user_data WHERE alias='m01'),
|
||||
m02 AS (SELECT id FROM user_data WHERE alias='m02'),
|
||||
m03 AS (SELECT id FROM user_data WHERE alias='m03'),
|
||||
m04 AS (SELECT id FROM user_data WHERE alias='m04'),
|
||||
m05 AS (SELECT id FROM user_data WHERE alias='m05'),
|
||||
m06 AS (SELECT id FROM user_data WHERE alias='m06')
|
||||
INSERT INTO user_relations (id, user_id, target_user_id, relation_type, created_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f01), (SELECT id FROM m01), 'liked', '2026-06-01T10:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m01), (SELECT id FROM f01), 'liked', '2026-06-01T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f02), (SELECT id FROM m02), 'liked', '2026-06-02T14:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f03), (SELECT id FROM m03), 'liked', '2026-06-03T09:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m03), (SELECT id FROM f03), 'liked', '2026-06-03T09:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m04), (SELECT id FROM f02), 'liked', '2026-06-04T11:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f04), (SELECT id FROM m04), 'passed', '2026-06-04T12:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), (SELECT id FROM m05), 'liked', '2026-06-05T10:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m05), (SELECT id FROM f05), 'liked', '2026-06-05T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m06), (SELECT id FROM f01), 'liked', '2026-06-06T14:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f04), (SELECT id FROM m06), 'passed', '2026-06-06T15:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f06), (SELECT id FROM m04), 'blocked', '2026-06-07T09:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m02), (SELECT id FROM f03), 'passed', '2026-06-07T10:00:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 6. Match
|
||||
-- ====================================================
|
||||
WITH f01 AS (SELECT id FROM user_data WHERE alias='f01'),
|
||||
f03 AS (SELECT id FROM user_data WHERE alias='f03'),
|
||||
f05 AS (SELECT id FROM user_data WHERE alias='f05'),
|
||||
m01 AS (SELECT id FROM user_data WHERE alias='m01'),
|
||||
m03 AS (SELECT id FROM user_data WHERE alias='m03'),
|
||||
m05 AS (SELECT id FROM user_data WHERE alias='m05')
|
||||
INSERT INTO matches (id, user_a_id, user_b_id, status, source, matched_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f01), (SELECT id FROM m01), 'active', 'user_like', '2026-06-01T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f03), (SELECT id FROM m03), 'active', 'user_like', '2026-06-03T09:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), (SELECT id FROM m05), 'successful', 'user_like', '2026-06-05T10:05:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 7. 成功牵手请求
|
||||
-- ====================================================
|
||||
WITH match_success AS (SELECT id FROM matches WHERE status='successful' LIMIT 1),
|
||||
match_active AS (SELECT id FROM matches WHERE status='active' ORDER BY created_at LIMIT 1),
|
||||
f01 AS (SELECT id FROM user_data WHERE alias='f01'),
|
||||
m05 AS (SELECT id FROM user_data WHERE alias='m05'),
|
||||
f05 AS (SELECT id FROM user_data WHERE alias='f05')
|
||||
INSERT INTO relationship_success_requests (id, match_id, initiated_by, status, confirmed_by, created_at, resolved_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM match_success), (SELECT id FROM f05), 'confirmed', (SELECT id FROM m05), '2026-07-01T10:00:00Z', '2026-07-01T10:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM match_active), (SELECT id FROM f01), 'pending', NULL, '2026-07-15T14:00:00Z', NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 8. Conversations & Messages
|
||||
-- ====================================================
|
||||
WITH conv_ids AS (
|
||||
SELECT gen_random_uuid() as id, match_id FROM matches WHERE status='active' ORDER BY created_at
|
||||
)
|
||||
INSERT INTO conversations (id, match_id, status, last_message_at)
|
||||
SELECT id, match_id, 'active', NOW()-INTERVAL '5 days' FROM conv_ids
|
||||
RETURNING id, match_id INTO TEMP TABLE _conv_result (id, match_id);
|
||||
|
||||
-- members
|
||||
WITH _match_pairs AS (
|
||||
SELECT m.user_a_id, m.user_b_id FROM matches m JOIN _conv_result c ON c.match_id=m.id
|
||||
)
|
||||
INSERT INTO conversation_members (conversation_id, user_id, unread_count, can_send, joined_at)
|
||||
SELECT (SELECT id FROM _conv_result WHERE match_id=(SELECT match_id FROM _match_pairs WHERE user_a_id=up.user_a_id LIMIT 1)), up.user_a_id, 0, true, NOW() FROM _match_pairs up
|
||||
UNION ALL
|
||||
SELECT (SELECT id FROM _conv_result WHERE match_id=(SELECT match_id FROM _match_pairs WHERE user_b_id=up.user_b_id LIMIT 1)), up.user_b_id, 0, true, NOW() FROM _match_pairs up;
|
||||
|
||||
-- messages
|
||||
INSERT INTO messages (id, conversation_id, sender_id, message_type, content, status, risk_level, created_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at LIMIT 1), (SELECT id FROM user_data WHERE alias='f01'), 'text', '你好!看到你的资料觉得挺合适的~', 'sent', 'normal', '2026-06-15T14:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at LIMIT 1), (SELECT id FROM user_data WHERE alias='m01'), 'text', '你好!谢谢你的喜欢,我也觉得挺有缘的', 'sent', 'normal', '2026-06-15T14:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at LIMIT 1), (SELECT id FROM user_data WHERE alias='f01'), 'text', '你也在丹阳工作吗?平时喜欢做些什么?', 'sent', 'normal', '2026-06-15T14:10:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at OFFSET 1 LIMIT 1), (SELECT id FROM user_data WHERE alias='m03'), 'text', '嗨,你好!很高兴认识你', 'sent', 'normal', '2026-07-05T19:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at OFFSET 1 LIMIT 1), (SELECT id FROM user_data WHERE alias='f03'), 'text', '你好呀!我平时喜欢拍照和跳舞,你呢?', 'sent', 'normal', '2026-07-05T19:35:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at OFFSET 2 LIMIT 1), (SELECT id FROM user_data WHERE alias='m05'), 'text', '你好,很高兴认识你!', 'sent', 'normal', '2026-06-10T10:00:00Z');
|
||||
|
||||
-- update last_message_at
|
||||
UPDATE conversations SET last_message_at = (SELECT MAX(created_at) FROM messages WHERE messages.conversation_id = conversations.id);
|
||||
|
||||
-- ============================================================
|
||||
-- 9. 推荐记录
|
||||
-- ====================================================
|
||||
WITH f01 AS (SELECT id FROM user_data WHERE alias='f01'), f03 AS (SELECT id FROM user_data WHERE alias='f03'),
|
||||
f05 AS (SELECT id FROM user_data WHERE alias='f05'),
|
||||
m01 AS (SELECT id FROM user_data WHERE alias='m01'), m03 AS (SELECT id FROM user_data WHERE alias='m03'),
|
||||
m05 AS (SELECT id FROM user_data WHERE alias='m05'), m06 AS (SELECT id FROM user_data WHERE alias='m06')
|
||||
INSERT INTO recommendation_records (id, user_id, target_user_id, source, score, level, shown_at, action, action_at, rule_version)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f01), (SELECT id FROM m01), 'daily', 82.50, 'high', '2026-05-28T10:00:00Z', 'liked', '2026-06-01T10:00:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM f01), (SELECT id FROM m03), 'daily', 70.00, 'medium', '2026-05-28T10:00:00Z', 'passed','2026-05-28T10:01:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM m01), (SELECT id FROM f01), 'daily', 85.00, 'high', '2026-05-28T11:00:00Z', 'liked', '2026-06-01T10:05:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM f03), (SELECT id FROM m03), 'daily', 78.00, 'high', '2026-06-01T09:00:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM m03), (SELECT id FROM f03), 'daily', 75.00, 'high', '2026-06-01T09:30:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), (SELECT id FROM m05), 'daily', 88.00, 'high', '2026-06-01T10:00:00Z', 'liked', '2026-06-05T10:00:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM m05), (SELECT id FROM f05), 'daily', 86.00, 'high', '2026-06-01T10:30:00Z', 'liked', '2026-06-05T10:05:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM m06), (SELECT id FROM f01), 'daily', 62.00, 'medium','2026-06-06T14:00:00Z', 'liked', '2026-06-06T14:00:00Z', 1);
|
||||
|
||||
-- ============================================================
|
||||
-- 10. 相亲活动
|
||||
-- ====================================================
|
||||
WITH women_org AS (SELECT id FROM organizations WHERE type='women_federation' LIMIT 1),
|
||||
trade_org AS (SELECT id FROM organizations WHERE type='trade_union' LIMIT 1),
|
||||
mgr AS (SELECT id FROM operators WHERE username='activitymgr' LIMIT 1)
|
||||
INSERT INTO activities (id, title, description, organizer_org_id, coorganizer_text,
|
||||
start_at, end_at, location_name, location_address,
|
||||
male_limit, female_limit, total_limit, min_age, max_age,
|
||||
registration_start_at, registration_end_at, need_review, status, created_by)
|
||||
VALUES
|
||||
(gen_random_uuid(), '丹阳公益单身联谊会(夏季场)',
|
||||
'面向丹阳市区及周边乡镇的单身青年,由妇联、工会联合主办。',
|
||||
(SELECT id FROM women_org), '丹阳市总工会、丹阳市慈善基金会',
|
||||
'2026-08-15T14:00:00Z', '2026-08-15T17:30:00Z', '丹阳市文化馆多功能厅', '丹阳市丹北路168号',
|
||||
15, 15, 30, 22, 40, '2026-07-01T00:00:00Z', '2026-08-10T23:59:59Z', true, 'registration_open', (SELECT id FROM mgr)),
|
||||
(gen_random_uuid(), '七夕特别活动·丹阳缘来是你',
|
||||
'七夕节特别策划,浪漫主题相亲活动。',
|
||||
(SELECT id FROM trade_org), '丹阳市新时代文明实践中心',
|
||||
'2026-08-29T15:00:00Z', '2026-08-29T18:00:00Z', '丹阳大剧院报告厅', '丹阳市书院路28号',
|
||||
20, 20, 40, 25, 45, '2026-08-01T00:00:00Z', '2026-08-25T23:59:59Z', true, 'draft', (SELECT id FROM mgr));
|
||||
|
||||
-- ============================================================
|
||||
-- 11. 活动报名
|
||||
-- ====================================================
|
||||
WITH act1 AS (SELECT id FROM activities WHERE title LIKE '夏季%' LIMIT 1),
|
||||
mgr2 AS (SELECT id FROM operators WHERE username='activitymgr' LIMIT 1)
|
||||
INSERT INTO activity_registrations (id, activity_id, user_id, status, registered_at, reviewed_by, reviewed_at, checkin_status)
|
||||
SELECT gen_random_uuid(), (SELECT id FROM act1), ud.id,
|
||||
CASE ud.alias WHEN 'f01' THEN 'approved' WHEN 'f02' THEN 'pending' WHEN 'f03' THEN 'approved'
|
||||
WHEN 'f04' THEN 'rejected' WHEN 'f05' THEN 'approved' WHEN 'm01' THEN 'approved'
|
||||
WHEN 'm02' THEN 'approved' WHEN 'm03' THEN 'approved' WHEN 'm05' THEN 'approved' END,
|
||||
NOW()-INTERVAL '30 days',
|
||||
CASE WHEN ud.alias='f02' THEN NULL ELSE (SELECT id FROM mgr2) END,
|
||||
CASE WHEN ud.alias='f02' THEN NULL ELSE NOW()-INTERVAL '29 days' END,
|
||||
'not_checked_in'
|
||||
FROM user_data ud WHERE ud.alias IN ('f01','f02','f03','f04','f05','m01','m02','m03','m05');
|
||||
|
||||
-- ============================================================
|
||||
-- 12. 活动互选意向
|
||||
-- ====================================================
|
||||
WITH act1 AS (SELECT id FROM activities WHERE title LIKE '夏季%' LIMIT 1)
|
||||
INSERT INTO activity_interests (id, source_user_id, target_user_id, activity_id, status, confirmed_at, created_at)
|
||||
SELECT gen_random_uuid(),
|
||||
(SELECT id FROM user_data WHERE alias='f01'), (SELECT id FROM user_data WHERE alias='m01'), (SELECT id FROM act1), 'mutual', '2026-08-15T17:00:00Z', '2026-08-15T17:00:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(),
|
||||
(SELECT id FROM user_data WHERE alias='f03'), (SELECT id FROM user_data WHERE alias='m03'), (SELECT id FROM act1), 'mutual', '2026-08-15T17:05:00Z', '2026-08-15T17:05:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(),
|
||||
(SELECT id FROM user_data WHERE alias='f05'), (SELECT id FROM user_data WHERE alias='m05'), (SELECT id FROM act1), 'expressed','2026-08-15T17:10:00Z', '2026-08-15T17:10:00Z';
|
||||
|
||||
-- ============================================================
|
||||
-- 13. 红娘服务
|
||||
-- ====================================================
|
||||
WITH mh_op AS (SELECT id FROM operators WHERE username='wanghongniang' LIMIT 1),
|
||||
women_org AS (SELECT id FROM organizations WHERE type='women_federation' LIMIT 1),
|
||||
charity_org AS (SELECT id FROM organizations WHERE type='charity_center' LIMIT 1)
|
||||
INSERT INTO matchmaker_services (id, user_id, service_type, description, status, organization_id, assigned_operator_id, assigned_at, completed_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f02'), 'recommend_partner', '离异用户希望找到合适的伴侣', 'in_service', (SELECT id FROM women_org), (SELECT id FROM mh_op), '2026-06-20T10:00:00Z', NULL),
|
||||
(gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f06'), 'no_match_help', '丧偶用户希望重新融入社交', 'waiting_user', (SELECT id FROM charity_org), (SELECT id FROM mh_op), '2026-06-25T14:00:00Z', NULL),
|
||||
(gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f04'), 'review_preference', '用户希望调整择偶条件', 'completed', (SELECT id FROM women_org), (SELECT id FROM mh_op), '2026-06-15T09:00:00Z', '2026-06-20T11:00:00Z');
|
||||
|
||||
-- 红娘推荐
|
||||
WITH ms_f02 AS (SELECT id FROM matchmaker_services WHERE user_id=(SELECT id FROM user_data WHERE alias='f02') LIMIT 1),
|
||||
mh_op2 AS (SELECT id FROM operators WHERE username='wanghongniang' LIMIT 1)
|
||||
INSERT INTO matchmaker_recommendations (id, service_id, user_id, target_user_id, operator_id, reason, status, created_at, viewed_at, responded_at)
|
||||
VALUES (gen_random_uuid(), (SELECT id FROM ms_f02), (SELECT id FROM user_data WHERE alias='f02'), (SELECT id FROM user_data WHERE alias='m02'), (SELECT id FROM mh_op2),
|
||||
'两人同在丹阳工作,年龄相仿,都离过婚有共同语言', 'viewed', '2026-06-21T10:00:00Z', '2026-06-22T09:00:00Z', NULL);
|
||||
|
||||
-- 红娘跟进
|
||||
WITH ms_f02_2 AS (SELECT id FROM matchmaker_services WHERE user_id=(SELECT id FROM user_data WHERE alias='f02') LIMIT 1),
|
||||
ms_f04 AS (SELECT id FROM matchmaker_services WHERE user_id=(SELECT id FROM user_data WHERE alias='f04') LIMIT 1),
|
||||
mh_op3 AS (SELECT id FROM operators WHERE username='wanghongniang' LIMIT 1)
|
||||
INSERT INTO matchmaker_followups (id, service_id, operator_id, followup_type, content, result_code, next_followup_at, created_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM ms_f02_2), (SELECT id FROM mh_op3), 'phone_call', '电话沟通用户情况,了解离异原因及择偶期望', '正常', '2026-07-01T10:00:00Z', '2026-06-22T10:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM ms_f04), (SELECT id FROM mh_op3), 'face_to_face','面对面交流,帮助用户调整身高要求', '已调整', NULL, '2026-06-18T15:00:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 14. 系统通知
|
||||
-- ====================================================
|
||||
INSERT INTO notifications (id, user_id, type, title, content, business_type, read_status, created_at)
|
||||
SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f01'), 'match', '你们互相喜欢!', '张伟也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-01T10:05:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='m01'), 'match', '你们互相喜欢!', '小芳也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-01T10:05:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f03'), 'match', '你们互相喜欢!', '王磊也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-03T09:30:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='m03'), 'match', '你们互相喜欢!', '婷婷也喜欢了你,可以开始聊天啦~', 'match', 'unread','2026-06-03T09:30:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f05'), 'match', '你们互相喜欢!', '孙浩也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-05T10:05:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='m05'), 'match', '你们互相喜欢!', '慧琴也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-05T10:05:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f05'), 'system', '恭喜牵手成功!', '您与孙浩已成功牵手,祝你们幸福!', 'match', 'read', '2026-07-01T10:30:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='m05'), 'system', '恭喜牵手成功!', '您与慧琴已成功牵手,祝你们幸福!', 'match', 'read', '2026-07-01T10:30:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f01'), 'activity', '活动报名已确认', '您已成功报名「丹阳公益单身联谊会」', 'activity', 'read', '2026-07-05T10:30:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f05'), 'activity', '活动报名已确认', '您已成功报名「丹阳公益单身联谊会」', 'activity', 'unread','2026-07-07T09:20:00Z'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f02'), 'matchmaker', '红娘已为您服务', '您的红娘服务申请已被分配,红娘小王将在24小时内与您联系', 'matchmaker', 'read', '2026-06-20T10:30:00Z';
|
||||
|
||||
-- ============================================================
|
||||
-- 15. 同意记录
|
||||
-- ====================================================
|
||||
INSERT INTO consent_records (id, user_id, type, version, agreed_at, ip_address, user_agent)
|
||||
SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f01'), 'terms_of_service', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='f01'), 'privacy_policy', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='m01'), 'terms_of_service', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0'
|
||||
UNION ALL SELECT gen_random_uuid(), (SELECT id FROM user_data WHERE alias='m01'), 'privacy_policy', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0';
|
||||
|
||||
-- ============================================================
|
||||
-- 16. 审核原因字典
|
||||
-- ====================================================
|
||||
INSERT INTO review_reasons (code, name, category, enabled, sort_order)
|
||||
VALUES
|
||||
('profile_incomplete', '资料不完整', 'quality', true, 1),
|
||||
('photo_unclear', '照片不清晰', 'quality', true, 2),
|
||||
('fake_info', '信息疑似虚假', 'trust', true, 3),
|
||||
('inappropriate_photo', '照片内容不当', 'safety', true, 4),
|
||||
('duplicate_identity', '重复注册', 'duplicate', true, 5),
|
||||
('suspicious_behavior', '行为异常', 'risk', true, 6),
|
||||
('manual_review_needed', '需人工复核', 'quality', true, 7)
|
||||
ON CONFLICT (code) DO NOTHING;
|
||||
|
||||
SET session_replication_role = 'origin';
|
||||
DROP TABLE IF EXISTS _conv_result;
|
||||
|
||||
-- ============================================================
|
||||
-- V1.1 Feature Flag 初始化
|
||||
-- ============================================================
|
||||
INSERT INTO system_configs (config_key, config_value, description) VALUES
|
||||
('livenessVerification.enabled', 'false', '人脸核验功能开关(V1.1预留,默认关闭)'),
|
||||
('localEligibility.evidencePolicy', 'need_based', '本地资格佐证策略:need_based=按需触发 / mandatory=全部强制'),
|
||||
('counseling.enabled', 'true', '婚恋咨询功能开关'),
|
||||
('premarital.enabled', 'true', '婚前辅导功能开关'),
|
||||
('serviceLocation.enabled', 'true', '善缘服务站功能开关'),
|
||||
('content.enabled', 'true', '内容中心功能开关'),
|
||||
('localEligibility.enabled', 'true', '本地资格功能开关'),
|
||||
('banner.maxActiveCount', '5', 'Banner最大活跃数量')
|
||||
ON CONFLICT (config_key) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 验证
|
||||
-- ====================================================
|
||||
DO $$
|
||||
DECLARE
|
||||
u_cnt INTEGER; op_cnt INTEGER; m_cnt INTEGER; a_cnt INTEGER; r_cnt INTEGER; n_cnt INTEGER; p_cnt INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO u_cnt FROM users WHERE deleted_at IS NULL;
|
||||
SELECT COUNT(*) INTO op_cnt FROM operators;
|
||||
SELECT COUNT(*) INTO m_cnt FROM matches;
|
||||
SELECT COUNT(*) INTO a_cnt FROM activities WHERE deleted_at IS NULL;
|
||||
SELECT COUNT(*) INTO r_cnt FROM user_relations;
|
||||
SELECT COUNT(*) INTO n_cnt FROM notifications;
|
||||
SELECT COUNT(*) INTO p_cnt FROM user_profiles;
|
||||
RAISE NOTICE '========================================';
|
||||
RAISE NOTICE '✅ Demo 数据填充完成!';
|
||||
RAISE NOTICE '========================================';
|
||||
RAISE NOTICE ' 用户: %人 | 资料: %条 | 操作员: %人', u_cnt, p_cnt, op_cnt;
|
||||
RAISE NOTICE ' Match: %对 | 关系: %条 | 活动: %个 | 通知: %条', m_cnt, r_cnt, a_cnt, n_cnt;
|
||||
RAISE NOTICE '========================================';
|
||||
END $$;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,463 @@
|
||||
-- ============================================================
|
||||
-- 丹阳公益婚恋服务平台 — Demo Seed 数据脚本 v2
|
||||
-- 版本: 1.0.0-RC.2
|
||||
-- 说明: 所有 id 使用真实 UUID 格式(36字符含连字符)
|
||||
-- 执行: psql -U postgres -d danyang_match -f demo-seed-v2.sql
|
||||
-- ============================================================
|
||||
|
||||
SET session_replication_role = 'replica';
|
||||
|
||||
-- ============================================================
|
||||
-- 1. 组织
|
||||
-- ============================================================
|
||||
INSERT INTO organizations (id, name, type, contact_name, status) VALUES
|
||||
(gen_random_uuid(), '丹阳市妇女联合会', 'women_federation', '张丽华', 'active'),
|
||||
(gen_random_uuid(), '丹阳市总工会', 'trade_union', '李明远', 'active'),
|
||||
(gen_random_uuid(), '丹阳市慈善基金会', 'charity_center', '王秀英', 'active');
|
||||
|
||||
-- 取回生成的 org id
|
||||
WITH org_ids AS (
|
||||
SELECT id FROM organizations ORDER BY created_at LIMIT 1
|
||||
),
|
||||
org2 AS (
|
||||
SELECT id FROM organizations WHERE id NOT IN (SELECT id FROM org_ids) ORDER BY created_at LIMIT 1
|
||||
),
|
||||
org3 AS (
|
||||
SELECT id FROM organizations WHERE id NOT IN (SELECT id FROM org_ids, org2) ORDER BY created_at LIMIT 1
|
||||
)
|
||||
SELECT 'org-women' as org1_placeholder, 'org-trade' as org2_placeholder, 'org-charity' as org3_placeholder
|
||||
INTO TEMP TABLE _org_placeholders;
|
||||
|
||||
-- ============================================================
|
||||
-- 2. 工作人员(BCrypt hash of "demo123")
|
||||
-- ============================================================
|
||||
INSERT INTO operators (id, organization_id, name, username, password_hash, status) VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM organizations WHERE type='women_federation' LIMIT 1), '陈主任', 'admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
(gen_random_uuid(), (SELECT id FROM organizations WHERE type='women_federation' LIMIT 1), '红娘小王', 'wanghongniang','$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
(gen_random_uuid(), (SELECT id FROM organizations WHERE type='charity_center' LIMIT 1), '审核员小张', 'reviewer01', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
(gen_random_uuid(), (SELECT id FROM organizations WHERE type='trade_union' LIMIT 1), '活动管理员赵', 'activitymgr','$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active');
|
||||
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES
|
||||
((SELECT id FROM operators WHERE username='admin'), '00000000-0000-0000-0000-000000000001'),
|
||||
((SELECT id FROM operators WHERE username='admin'), '00000000-0000-0000-0000-000000000002'),
|
||||
((SELECT id FROM operators WHERE username='wanghongniang'), '00000000-0000-0000-0000-000000000005'),
|
||||
((SELECT id FROM operators WHERE username='wanghongniang'), '00000000-0000-0000-0000-000000000006'),
|
||||
((SELECT id FROM operators WHERE username='reviewer01'), '00000000-0000-0000-0000-000000000004'),
|
||||
((SELECT id FROM operators WHERE username='reviewer01'), '00000000-0000-0000-0000-000000000007'),
|
||||
((SELECT id FROM operators WHERE username='activitymgr'), '00000000-0000-0000-0000-000000000006'),
|
||||
((SELECT id FROM operators WHERE username='activitymgr'), '00000000-0000-0000-0000-000000000008');
|
||||
|
||||
-- ============================================================
|
||||
-- 3. Demo 用户 — 12人(6女6男),ID 使用字符串但不含连字符(VARCHAR(36)兼容)
|
||||
-- ============================================================
|
||||
-- 注意:users.id 是 VARCHAR(36),我们使用短UUID格式(32位hex无连字符)
|
||||
INSERT INTO users (id, wechat_openid, phone, account_status, relationship_status, recommendation_enabled, created_at) VALUES
|
||||
('f01a2b3c4d5e6f70000000000000001', 'demo_openid_f01', NULL, 'normal', 'searching', true, '2026-03-15T10:00:00Z'),
|
||||
('f02a2b3c4d5e6f70000000000000002', 'demo_openid_f02', NULL, 'normal', 'searching', true, '2026-03-20T14:30:00Z'),
|
||||
('f03a2b3c4d5e6f70000000000000003', 'demo_openid_f03', NULL, 'normal', 'searching', true, '2026-04-01T09:15:00Z'),
|
||||
('f04a2b3c4d5e6f70000000000000004', 'demo_openid_f04', NULL, 'normal', 'paused', true, '2026-04-10T16:00:00Z'),
|
||||
('f05a2b3c4d5e6f70000000000000005', 'demo_openid_f05', NULL, 'normal', 'searching', true, '2026-05-01T11:20:00Z'),
|
||||
('f06a2b3c4d5e6f70000000000000006', 'demo_openid_f06', NULL, 'normal', 'searching', true, '2026-05-15T08:45:00Z'),
|
||||
('m01a2b3c4d5e6f70000000000000001', 'demo_openid_m01', NULL, 'normal', 'searching', true, '2026-03-10T09:00:00Z'),
|
||||
('m02a2b3c4d5e6f70000000000000002', 'demo_openid_m02', NULL, 'normal', 'getting_to_know', true, '2026-03-25T13:00:00Z'),
|
||||
('m03a2b3c4d5e6f70000000000000003', 'demo_openid_m03', NULL, 'normal', 'searching', true, '2026-04-05T15:30:00Z'),
|
||||
('m04a2b3c4d5e6f70000000000000004', 'demo_openid_m04', NULL, 'normal', 'searching', true, '2026-04-20T10:00:00Z'),
|
||||
('m05a2b3c4d5e6f70000000000000005', 'demo_openid_m05', NULL, 'normal', 'matched_successfully', true, '2026-05-01T14:00:00Z'),
|
||||
('m06a2b3c4d5e6f70000000000000006', 'demo_openid_m06', NULL, 'normal', 'searching', true, '2026-05-10T16:30:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 4. 用户资料
|
||||
-- ============================================================
|
||||
INSERT INTO user_profiles (
|
||||
user_id, display_name, gender, birth_date, height_cm,
|
||||
region_code, region_name, marital_status, children_status,
|
||||
education_code, occupation_code, smoking_status, drinking_status,
|
||||
long_term_danyang, future_danyang, relationship_goal, profile_completion, profile_status
|
||||
) VALUES
|
||||
('f01a2b3c4d5e6f70000000000000001', '小芳', 'female', '1995-06-15', 162, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'clerical', 'never', 'sometimes', '是', '是', '结婚', 90, 'approved'),
|
||||
('f02a2b3c4d5e6f70000000000000002', '晓燕', 'female', '1993-09-20', 165, '321181', '丹阳', 'divorced', 'none', 'college', 'teacher', 'never', 'never', '是', '是', '结婚', 95, 'approved'),
|
||||
('f03a2b3c4d5e6f70000000000000003', '婷婷', 'female', '1998-02-10', 158, '321100', '镇江', 'never_married', 'none', 'master', 'designer', 'sometimes', 'often', '是', '否', '恋爱', 85, 'approved'),
|
||||
('f04a2b3c4d5e6f70000000000000004', '美玲', 'female', '1990-11-05', 160, '321181', '丹阳', 'never_married', 'none', 'senior_high', 'factory', 'never', 'never', '是', '是', '结婚', 70, 'approved'),
|
||||
('f05a2b3c4d5e6f70000000000000005', '慧琴', 'female', '1996-07-22', 163, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'nurse', 'never', 'sometimes','是', '是', '结婚', 92, 'approved'),
|
||||
('f06a2b3c4d5e6f70000000000000006', '秀英', 'female', '1992-04-18', 157, '321181', '丹阳', 'widowed', 'none', 'junior_high','farmer', 'often', 'often', '是', '是', '结婚', 60, 'approved'),
|
||||
('m01a2b3c4d5e6f70000000000000001', '张伟', 'male', '1992-01-10', 175, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'engineer', 'never', 'sometimes','是', '是', '结婚', 88, 'approved'),
|
||||
('m02a2b3c4d5e6f70000000000000002', '李强', 'male', '1990-08-25', 178, '321181', '丹阳', 'divorced', 'none', 'master', 'manager', 'sometimes', 'often', '是', '是', '结婚', 95, 'approved'),
|
||||
('m03a2b3c4d5e6f70000000000000003', '王磊', 'male', '1997-12-03', 180, '321100', '镇江', 'never_married', 'none', 'college', 'programmer', 'never', 'never', '是', '是', '恋爱', 82, 'approved'),
|
||||
('m04a2b3c4d5e6f70000000000000004', '赵明', 'male', '1988-05-30', 172, '321181', '丹阳', 'never_married', 'none', 'senior_high','sales', 'often', 'often', '否', '是', '结婚', 75, 'approved'),
|
||||
('m05a2b3c4d5e6f70000000000000005', '孙浩', 'male', '1994-03-14', 182, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'doctor', 'never', 'sometimes','是', '是', '结婚', 97, 'approved'),
|
||||
('m06a2b3c4d5e6f70000000000000006', '周洋', 'male', '1999-08-08', 176, '320500', '苏州', 'never_married', 'none', 'master', 'researcher', 'never', 'never', '是', '否', '恋爱', 80, 'approved');
|
||||
|
||||
-- ============================================================
|
||||
-- 5. 用户择偶偏好
|
||||
-- ============================================================
|
||||
INSERT INTO user_preferences (
|
||||
user_id, min_age, max_age, age_priority,
|
||||
min_height_cm, max_height_cm, height_priority,
|
||||
region_scope, region_priority,
|
||||
marital_statuses, marital_priority,
|
||||
min_education_code, education_priority
|
||||
) VALUES
|
||||
('f01a2b3c4d5e6f70000000000000001', 28, 38, 'required', 170, 185, 'required',
|
||||
'["321181","321100"]', 'required', '["never_married"]', 'required', 'bachelor', 'preferred'),
|
||||
('f02a2b3c4d5e6f70000000000000002', 28, 40, 'required', 170, 188, 'required',
|
||||
'["321181"]', 'required', '["never_married","divorced"]', 'preferred', 'college', 'preferred'),
|
||||
('f03a2b3c4d5e6f70000000000000003', 25, 35, 'preferred', 172, 185, 'preferred',
|
||||
'["321181","321100","320500"]', 'preferred', '["never_married"]', 'required', NULL, NULL),
|
||||
('f04a2b3c4d5e6f70000000000000004', 30, 45, 'required', 168, 185, 'required',
|
||||
'["321181"]', 'required', '["never_married","divorced"]', 'preferred', 'senior_high', 'preferred'),
|
||||
('f05a2b3c4d5e6f70000000000000005', 27, 36, 'required', 172, 186, 'required',
|
||||
'["321181","321100"]', 'preferred', '["never_married"]', 'required', 'bachelor', 'preferred'),
|
||||
('f06a2b3c4d5e6f70000000000000006', 30, 50, 'required', 165, 185, 'required',
|
||||
'["321181"]', 'required', '["never_married","divorced","widowed"]', 'preferred', NULL, NULL),
|
||||
('m01a2b3c4d5e6f70000000000000001', 22, 32, 'required', 155, 170, 'preferred',
|
||||
'["321181","321100"]', 'required', '["never_married"]', 'required', 'junior_high', 'preferred'),
|
||||
('m02a2b3c4d5e6f70000000000000002', 25, 38, 'preferred', 158, 172, 'preferred',
|
||||
'["321181"]', 'preferred', '["never_married","divorced"]', 'preferred', 'college', 'preferred'),
|
||||
('m03a2b3c4d5e6f70000000000000003', 22, 30, 'preferred', 155, 168, 'preferred',
|
||||
'["321181","321100","320500"]', 'preferred', '["never_married"]', 'required', 'college', 'preferred'),
|
||||
('m04a2b3c4d5e6f70000000000000004', 25, 40, 'preferred', 155, 170, 'preferred',
|
||||
'["321181"]', 'required', '["never_married","divorced"]', 'preferred', NULL, NULL),
|
||||
('m05a2b3c4d5e6f70000000000000005', 23, 33, 'required', 158, 170, 'preferred',
|
||||
'["321181","321100"]', 'preferred', '["never_married"]', 'required', 'bachelor', 'preferred'),
|
||||
('m06a2b3c4d5e6f70000000000000006', 22, 32, 'preferred', 155, 170, 'preferred',
|
||||
'["321181","321100","320500"]', 'preferred', '["never_married"]', 'required', 'master', 'preferred');
|
||||
|
||||
-- ============================================================
|
||||
-- 6. 实名认证(user_identities)— mock
|
||||
-- ============================================================
|
||||
INSERT INTO user_identities (
|
||||
id, user_id, real_name_enc, id_number_enc, id_number_hash,
|
||||
gender, birth_date, verification_status, provider, verified_at
|
||||
) VALUES
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', E'\\xenc_f01', E'\\xenc_id_f01', 'sha256_f01_demo_hash', 'female', '1995-06-15', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
(gen_random_uuid(), 'f02a2b3c4d5e6f70000000000000002', E'\\xenc_f02', E'\\xenc_id_f02', 'sha256_f02_demo_hash', 'female', '1993-09-20', 'verified', 'mock', '2026-03-21T14:30:00Z'),
|
||||
(gen_random_uuid(), 'f03a2b3c4d5e6f70000000000000003', E'\\xenc_f03', E'\\xenc_id_f03', 'sha256_f03_demo_hash', 'female', '1998-02-10', 'verified', 'mock', '2026-04-02T09:15:00Z'),
|
||||
(gen_random_uuid(), 'f04a2b3c4d5e6f70000000000000004', E'\\xenc_f04', E'\\xenc_id_f04', 'sha256_f04_demo_hash', 'female', '1990-11-05', 'verified', 'mock', '2026-04-11T16:00:00Z'),
|
||||
(gen_random_uuid(), 'f05a2b3c4d5e6f70000000000000005', E'\\xenc_f05', E'\\xenc_id_f05', 'sha256_f05_demo_hash', 'female', '1996-07-22', 'verified', 'mock', '2026-05-02T11:20:00Z'),
|
||||
(gen_random_uuid(), 'f06a2b3c4d5e6f70000000000000006', E'\\xenc_f06', E'\\xenc_id_f06', 'sha256_f06_demo_hash', 'female', '1992-04-18', 'verified', 'mock', '2026-05-16T08:45:00Z'),
|
||||
(gen_random_uuid(), 'm01a2b3c4d5e6f70000000000000001', E'\\xenc_m01', E'\\xenc_id_m01', 'sha256_m01_demo_hash', 'male', '1992-01-10', 'verified', 'mock', '2026-03-11T09:00:00Z'),
|
||||
(gen_random_uuid(), 'm02a2b3c4d5e6f70000000000000002', E'\\xenc_m02', E'\\xenc_id_m02', 'sha256_m02_demo_hash', 'male', '1990-08-25', 'verified', 'mock', '2026-03-26T13:00:00Z'),
|
||||
(gen_random_uuid(), 'm03a2b3c4d5e6f70000000000000003', E'\\xenc_m03', E'\\xenc_id_m03', 'sha256_m03_demo_hash', 'male', '1997-12-03', 'verified', 'mock', '2026-04-06T15:30:00Z'),
|
||||
(gen_random_uuid(), 'm04a2b3c4d5e6f70000000000000004', E'\\xenc_m04', E'\\xenc_id_m04', 'sha256_m04_demo_hash', 'male', '1988-05-30', 'verified', 'mock', '2026-04-21T10:00:00Z'),
|
||||
(gen_random_uuid(), 'm05a2b3c4d5e6f70000000000000005', E'\\xenc_m05', E'\\xenc_id_m05', 'sha256_m05_demo_hash', 'male', '1994-03-14', 'verified', 'mock', '2026-05-02T14:00:00Z'),
|
||||
(gen_random_uuid(), 'm06a2b3c4d5e6f70000000000000006', E'\\xenc_m06', E'\\xenc_id_m06', 'sha256_m06_demo_hash', 'male', '1999-08-08', 'verified', 'mock', '2026-05-11T16:30:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 7. 兴趣标签
|
||||
-- ============================================================
|
||||
INSERT INTO user_interests (user_id, interest_code) VALUES
|
||||
('f01a2b3c4d5e6f70000000000000001', 'reading'), ('f01a2b3c4d5e6f70000000000000001', 'cooking'), ('f01a2b3c4d5e6f70000000000000001', 'travel'),
|
||||
('f02a2b3c4d5e6f70000000000000002', 'sports'), ('f02a2b3c4d5e6f70000000000000002', 'music'), ('f02a2b3c4d5e6f70000000000000002', 'outdoor'),
|
||||
('f03a2b3c4d5e6f70000000000000003', 'photography'), ('f03a2b3c4d5e6f70000000000000003', 'dance'), ('f03a2b3c4d5e6f70000000000000003', 'movie'),
|
||||
('f04a2b3c4d5e6f70000000000000004', 'pets'), ('f04a2b3c4d5e6f70000000000000004', 'cooking'),
|
||||
('f05a2b3c4d5e6f70000000000000005', 'reading'), ('f05a2b3c4d5e6f70000000000000005', 'fitness'), ('f05a2b3c4d5e6f70000000000000005', 'charity'),
|
||||
('f06a2b3c4d5e6f70000000000000006', 'gardening'), ('f06a2b3c4d5e6f70000000000000006', 'cooking'),
|
||||
('m01a2b3c4d5e6f70000000000000001', 'sports'), ('m01a2b3c4d5e6f70000000000000001', 'gaming'), ('m01a2b3c4d5e6f70000000000000001', 'travel'),
|
||||
('m02a2b3c4d5e6f70000000000000002', 'reading'), ('m02a2b3c4d5e6f70000000000000002', 'investment'), ('m02a2b3c4d5e6f70000000000000002', 'hiking'),
|
||||
('m03a2b3c4d5e6f70000000000000003', 'gaming'), ('m03a2b3c4d5e6f70000000000000003', 'music'), ('m03a2b3c4d5e6f70000000000000003', 'coding'),
|
||||
('m04a2b3c4d5e6f70000000000000004', 'cars'), ('m04a2b3c4d5e6f70000000000000004', 'cooking'),
|
||||
('m05a2b3c4d5e6f70000000000000005', 'running'), ('m05a2b3c4d5e6f70000000000000005', 'reading'), ('m05a2b3c4d5e6f70000000000000005', 'charity'),
|
||||
('m06a2b3c4d5e6f70000000000000006', 'research'), ('m06a2b3c4d5e6f70000000000000006', 'travel'), ('m06a2b3c4d5e6f70000000000000006', 'photography');
|
||||
|
||||
-- ============================================================
|
||||
-- 8. 隐私设置
|
||||
-- ============================================================
|
||||
INSERT INTO user_privacy_settings (user_id, visible_in_recommendations, visible_in_search, show_occupation, show_lifestyle_photos, receive_activity_recommendations, accept_matchmaker_recommendations) VALUES
|
||||
('f01a2b3c4d5e6f70000000000000001', true, true, true, true, true, true),
|
||||
('f02a2b3c4d5e6f70000000000000002', true, true, true, false, true, true),
|
||||
('f03a2b3c4d5e6f70000000000000003', true, false, true, true, true, false),
|
||||
('f04a2b3c4d5e6f70000000000000004', true, true, false, true, true, true),
|
||||
('f05a2b3c4d5e6f70000000000000005', true, true, true, true, false, true),
|
||||
('f06a2b3c4d5e6f70000000000000006', true, false, true, true, true, true),
|
||||
('m01a2b3c4d5e6f70000000000000001', true, true, true, true, true, true),
|
||||
('m02a2b3c4d5e6f70000000000000002', true, true, true, false, true, true),
|
||||
('m03a2b3c4d5e6f70000000000000003', true, true, true, true, true, false),
|
||||
('m04a2b3c4d5e6f70000000000000004', true, false, true, true, true, true),
|
||||
('m05a2b3c4d5e6f70000000000000005', true, true, true, true, true, true),
|
||||
('m06a2b3c4d5e6f70000000000000006', true, true, true, true, true, true);
|
||||
|
||||
-- ============================================================
|
||||
-- 9. 照片(user_photos)
|
||||
-- ============================================================
|
||||
INSERT INTO user_photos (id, user_id, file_key, photo_type, sort_order, review_status) VALUES
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'photos/demo/f01/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'photos/demo/f01/lifestyle1.jpg','lifestyle',1, 'approved'),
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'photos/demo/f01/lifestyle2.jpg','lifestyle',2, 'approved'),
|
||||
(gen_random_uuid(), 'f02a2b3c4d5e6f70000000000000002', 'photos/demo/f02/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'f02a2b3c4d5e6f70000000000000002', 'photos/demo/f02/lifestyle1.jpg','lifestyle',1, 'approved'),
|
||||
(gen_random_uuid(), 'f03a2b3c4d5e6f70000000000000003', 'photos/demo/f03/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'f03a2b3c4d5e6f70000000000000003', 'photos/demo/f03/lifestyle1.jpg','lifestyle',1, 'approved'),
|
||||
(gen_random_uuid(), 'f03a2b3c4d5e6f70000000000000003', 'photos/demo/f03/lifestyle2.jpg','lifestyle',2, 'approved'),
|
||||
(gen_random_uuid(), 'f04a2b3c4d5e6f70000000000000004', 'photos/demo/f04/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'f05a2b3c4d5e6f70000000000000005', 'photos/demo/f05/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'f05a2b3c4d5e6f70000000000000005', 'photos/demo/f05/lifestyle1.jpg','lifestyle',1, 'approved'),
|
||||
(gen_random_uuid(), 'f06a2b3c4d5e6f70000000000000006', 'photos/demo/f06/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'm01a2b3c4d5e6f70000000000000001', 'photos/demo/m01/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'm01a2b3c4d5e6f70000000000000001', 'photos/demo/m01/lifestyle1.jpg','lifestyle',1, 'approved'),
|
||||
(gen_random_uuid(), 'm01a2b3c4d5e6f70000000000000001', 'photos/demo/m01/lifestyle2.jpg','lifestyle',2, 'approved'),
|
||||
(gen_random_uuid(), 'm02a2b3c4d5e6f70000000000000002', 'photos/demo/m02/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'm02a2b3c4d5e6f70000000000000002', 'photos/demo/m02/lifestyle1.jpg','lifestyle',1, 'approved'),
|
||||
(gen_random_uuid(), 'm03a2b3c4d5e6f70000000000000003', 'photos/demo/m03/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'm03a2b3c4d5e6f70000000000000003', 'photos/demo/m03/lifestyle1.jpg','lifestyle',1, 'approved'),
|
||||
(gen_random_uuid(), 'm04a2b3c4d5e6f70000000000000004', 'photos/demo/m04/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'm05a2b3c4d5e6f70000000000000005', 'photos/demo/m05/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
(gen_random_uuid(), 'm05a2b3c4d5e6f70000000000000005', 'photos/demo/m05/lifestyle1.jpg','lifestyle',1, 'approved'),
|
||||
(gen_random_uuid(), 'm05a2b3c4d5e6f70000000000000005', 'photos/demo/m05/lifestyle2.jpg','lifestyle',2, 'approved'),
|
||||
(gen_random_uuid(), 'm06a2b3c4d5e6f70000000000000006', 'photos/demo/m06/avatar.jpg', 'avatar', 0, 'approved');
|
||||
|
||||
-- ============================================================
|
||||
-- 10. 审核任务
|
||||
-- ============================================================
|
||||
INSERT INTO review_tasks (id, user_id, review_type, status, assigned_operator_id, submitted_at, started_at, completed_at, final_comment, version) VALUES
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'initial_profile', 'approved', (SELECT id FROM operators WHERE username='reviewer01'), '2026-03-15T11:00:00Z', '2026-03-15T11:30:00Z', '2026-03-15T12:00:00Z', '资料完整,信息真实', 1),
|
||||
(gen_random_uuid(), 'f02a2b3c4d5e6f70000000000000002', 'initial_profile', 'approved', (SELECT id FROM operators WHERE username='reviewer01'), '2026-03-20T15:00:00Z', '2026-03-20T15:30:00Z', '2026-03-20T16:00:00Z', '资料完整', 1),
|
||||
(gen_random_uuid(), 'f03a2b3c4d5e6f70000000000000003', 'initial_profile', 'approved', (SELECT id FROM operators WHERE username='reviewer01'), '2026-04-01T10:00:00Z', '2026-04-01T10:30:00Z', '2026-04-01T11:00:00Z', '资料完整', 1),
|
||||
(gen_random_uuid(), 'm01a2b3c4d5e6f70000000000000001', 'initial_profile', 'approved', (SELECT id FROM operators WHERE username='reviewer01'), '2026-03-10T10:00:00Z', '2026-03-10T10:30:00Z', '2026-03-10T11:00:00Z', '资料完整', 1),
|
||||
(gen_random_uuid(), 'm02a2b3c4d5e6f70000000000000002', 'initial_profile', 'approved', (SELECT id FROM operators WHERE username='reviewer01'), '2026-03-25T14:00:00Z', '2026-03-25T14:30:00Z', '2026-03-25T15:00:00Z', '资料完整', 1),
|
||||
(gen_random_uuid(), 'm03a2b3c4d5e6f70000000000000003', 'initial_profile', 'approved', (SELECT id FROM operators WHERE username='reviewer01'), '2026-04-05T16:00:00Z', '2026-04-05T16:30:00Z', '2026-04-05T17:00:00Z', '资料完整', 1),
|
||||
(gen_random_uuid(), 'm05a2b3c4d5e6f70000000000000005', 'initial_profile', 'approved', (SELECT id FROM operators WHERE username='reviewer01'), '2026-05-01T15:00:00Z', '2026-05-01T15:30:00Z', '2026-05-01T16:00:00Z', '资料完整', 1);
|
||||
|
||||
-- ============================================================
|
||||
-- 11. 用户关系
|
||||
-- ============================================================
|
||||
INSERT INTO user_relations (id, user_id, target_user_id, relation_type, created_at) VALUES
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'm01a2b3c4d5e6f70000000000000001', 'liked', '2026-06-01T10:00:00Z'),
|
||||
(gen_random_uuid(), 'm01a2b3c4d5e6f70000000000000001', 'f01a2b3c4d5e6f70000000000000001', 'liked', '2026-06-01T10:05:00Z'),
|
||||
(gen_random_uuid(), 'f02a2b3c4d5e6f70000000000000002', 'm02a2b3c4d5e6f70000000000000002', 'liked', '2026-06-02T14:00:00Z'),
|
||||
(gen_random_uuid(), 'f03a2b3c4d5e6f70000000000000003', 'm03a2b3c4d5e6f70000000000000003', 'liked', '2026-06-03T09:00:00Z'),
|
||||
(gen_random_uuid(), 'm03a2b3c4d5e6f70000000000000003', 'f03a2b3c4d5e6f70000000000000003', 'liked', '2026-06-03T09:30:00Z'),
|
||||
(gen_random_uuid(), 'm04a2b3c4d5e6f70000000000000004', 'f02a2b3c4d5e6f70000000000000002', 'liked', '2026-06-04T11:00:00Z'),
|
||||
(gen_random_uuid(), 'f04a2b3c4d5e6f70000000000000004', 'm04a2b3c4d5e6f70000000000000004', 'passed', '2026-06-04T12:00:00Z'),
|
||||
(gen_random_uuid(), 'f05a2b3c4d5e6f70000000000000005', 'm05a2b3c4d5e6f70000000000000005', 'liked', '2026-06-05T10:00:00Z'),
|
||||
(gen_random_uuid(), 'm05a2b3c4d5e6f70000000000000005', 'f05a2b3c4d5e6f70000000000000005', 'liked', '2026-06-05T10:05:00Z'),
|
||||
(gen_random_uuid(), 'm06a2b3c4d5e6f70000000000000006', 'f01a2b3c4d5e6f70000000000000001', 'liked', '2026-06-06T14:00:00Z'),
|
||||
(gen_random_uuid(), 'f04a2b3c4d5e6f70000000000000004', 'm06a2b3c4d5e6f70000000000000006', 'passed', '2026-06-06T15:00:00Z'),
|
||||
(gen_random_uuid(), 'f06a2b3c4d5e6f70000000000000006', 'm04a2b3c4d5e6f70000000000000004', 'blocked', '2026-06-07T09:00:00Z'),
|
||||
(gen_random_uuid(), 'm02a2b3c4d5e6f70000000000000002', 'f03a2b3c4d5e6f70000000000000003', 'passed', '2026-06-07T10:00:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 12. Match
|
||||
-- ============================================================
|
||||
INSERT INTO matches (id, user_a_id, user_b_id, status, source, matched_at) VALUES
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'm01a2b3c4d5e6f70000000000000001', 'active', 'user_like', '2026-06-01T10:05:00Z'),
|
||||
(gen_random_uuid(), 'f03a2b3c4d5e6f70000000000000003', 'm03a2b3c4d5e6f70000000000000003', 'active', 'user_like', '2026-06-03T09:30:00Z'),
|
||||
(gen_random_uuid(), 'f05a2b3c4d5e6f70000000000000005', 'm05a2b3c4d5e6f70000000000000005', 'successful', 'user_like', '2026-06-05T10:05:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 13. 成功牵手请求
|
||||
-- ============================================================
|
||||
INSERT INTO relationship_success_requests (id, match_id, initiated_by, status, confirmed_by, created_at, resolved_at) VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM matches WHERE user_a_id='f05a2b3c4d5e6f70000000000000005'), 'f05a2b3c4d5e6f70000000000000005', 'confirmed', 'm05a2b3c4d5e6f70000000000000005', '2026-07-01T10:00:00Z', '2026-07-01T10:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM matches WHERE user_a_id='f01a2b3c4d5e6f70000000000000001'), 'f01a2b3c4d5e6f70000000000000001', 'pending', NULL, '2026-07-15T14:00:00Z', NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 14. Conversations & Messages
|
||||
-- ============================================================
|
||||
INSERT INTO conversations (id, match_id, status, last_message_id, last_message_at) VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM matches WHERE user_a_id='f01a2b3c4d5e6f70000000000000001'), 'active', NULL, '2026-07-10T16:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM matches WHERE user_a_id='f03a2b3c4d5e6f70000000000000003'), 'active', NULL, '2026-07-08T20:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM matches WHERE user_a_id='f05a2b3c4d5e6f70000000000000005'), 'active', NULL, '2026-07-01T18:00:00Z');
|
||||
|
||||
-- 取回 conversation ids
|
||||
WITH conv_ids AS (
|
||||
SELECT id, match_id FROM conversations ORDER BY created_at
|
||||
)
|
||||
INSERT INTO conversation_members (conversation_id, user_id, last_read_message_id, unread_count, can_send, joined_at)
|
||||
SELECT c.id, CASE WHEN m.user_a_id='f01a2b3c4d5e6f70000000000000001' OR m.user_a_id='f03a2b3c4d5e6f70000000000000003' OR m.user_a_id='f05a2b3c4d5e6f70000000000000005' THEN u else NULL end, NULL, 0, true, NOW()
|
||||
FROM conv_ids c
|
||||
JOIN matches m ON m.id = c.match_id
|
||||
JOIN LATERAL (SELECT 'f01a2b3c4d5e6f70000000000000001' as uid UNION ALL SELECT 'm01a2b3c4d5e6f70000000000000001' UNION ALL SELECT 'f03a2b3c4d5e6f70000000000000003' UNION ALL SELECT 'm03a2b3c4d5e6f70000000000000003' UNION ALL SELECT 'f05a2b3c4d5e6f70000000000000005' UNION ALL SELECT 'm05a2b3c4d5e6f70000000000000005') u ON TRUE
|
||||
WHERE (m.user_a_id='f01a2b3c4d5e6f70000000000000001' AND u.uid IN ('f01a2b3c4d5e6f70000000000000001','m01a2b3c4d5e6f70000000000000001'))
|
||||
OR (m.user_a_id='f03a2b3c4d5e6f70000000000000003' AND u.uid IN ('f03a2b3c4d5e6f70000000000000003','m03a2b3c4d5e6f70000000000000003'))
|
||||
OR (m.user_a_id='f05a2b3c4d5e6f70000000000000005' AND u.uid IN ('f05a2b3c4d5e6f70000000000000005','m05a2b3c4d5e6f70000000000000005'));
|
||||
|
||||
-- 简化的 conversation_members 插入
|
||||
DELETE FROM conversation_members;
|
||||
WITH conv AS (
|
||||
SELECT id, match_id FROM conversations
|
||||
), match_users AS (
|
||||
SELECT c.id as conv_id, m.user_a_id, m.user_b_id
|
||||
FROM conv c JOIN matches m ON m.id = c.match_id
|
||||
)
|
||||
INSERT INTO conversation_members (conversation_id, user_id, last_read_message_id, unread_count, can_send, joined_at)
|
||||
SELECT mu.conv_id, mu.user_a_id, NULL, 0, true, NOW() FROM match_users mu
|
||||
UNION ALL
|
||||
SELECT mu.conv_id, mu.user_b_id, NULL, 0, true, NOW() FROM match_users mu;
|
||||
|
||||
INSERT INTO messages (id, conversation_id, sender_id, message_type, content, status, risk_level, created_at) VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at LIMIT 1), 'f01a2b3c4d5e6f70000000000000001', 'text', '你好!看到你的资料觉得挺合适的~', 'sent', 'normal', '2026-06-15T14:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at LIMIT 1), 'm01a2b3c4d5e6f70000000000000001', 'text', '你好!谢谢你的喜欢,我也觉得挺有缘的', 'sent', 'normal', '2026-06-15T14:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at LIMIT 1), 'f01a2b3c4d5e6f70000000000000001', 'text', '你也在丹阳工作吗?平时喜欢做些什么?', 'sent', 'normal', '2026-06-15T14:10:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at OFFSET 1 LIMIT 1), 'm03a2b3c4d5e6f70000000000000003', 'text', '嗨,你好!很高兴认识你', 'sent', 'normal', '2026-07-05T19:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at OFFSET 1 LIMIT 1), 'f03a2b3c4d5e6f70000000000000003', 'text', '你好呀!我平时喜欢拍照和跳舞,你呢?', 'sent', 'normal', '2026-07-05T19:35:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conversations ORDER BY created_at OFFSET 2 LIMIT 1), 'm05a2b3c4d5e6f70000000000000005', 'text', '你好,很高兴认识你!', 'sent', 'normal', '2026-06-10T10:00:00Z');
|
||||
|
||||
-- 更新 conversations.last_message_id
|
||||
UPDATE conversations SET last_message_id = (SELECT id FROM messages WHERE conversation_id = conversations.id ORDER BY created_at DESC LIMIT 1);
|
||||
|
||||
-- ============================================================
|
||||
-- 15. 推荐记录
|
||||
-- ============================================================
|
||||
INSERT INTO recommendation_records (id, user_id, target_user_id, source, score, level, shown_at, action, action_at, rule_version) VALUES
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'm01a2b3c4d5e6f70000000000000001', 'daily', 82.50, 'high', '2026-05-28T10:00:00Z', 'liked', '2026-06-01T10:00:00Z', 1),
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'm03a2b3c4d5e6f70000000000000003', 'daily', 70.00, 'medium', '2026-05-28T10:00:00Z', 'passed','2026-05-28T10:01:00Z', 1),
|
||||
(gen_random_uuid(), 'm01a2b3c4d5e6f70000000000000001', 'f01a2b3c4d5e6f70000000000000001', 'daily', 85.00, 'high', '2026-05-28T11:00:00Z', 'liked', '2026-06-01T10:05:00Z', 1),
|
||||
(gen_random_uuid(), 'f03a2b3c4d5e6f70000000000000003', 'm03a2b3c4d5e6f70000000000000003', 'daily', 78.00, 'high', '2026-06-01T09:00:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
(gen_random_uuid(), 'm03a2b3c4d5e6f70000000000000003', 'f03a2b3c4d5e6f70000000000000003', 'daily', 75.00, 'high', '2026-06-01T09:30:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
(gen_random_uuid(), 'f05a2b3c4d5e6f70000000000000005', 'm05a2b3c4d5e6f70000000000000005', 'daily', 88.00, 'high', '2026-06-01T10:00:00Z', 'liked', '2026-06-05T10:00:00Z', 1),
|
||||
(gen_random_uuid(), 'm05a2b3c4d5e6f70000000000000005', 'f05a2b3c4d5e6f70000000000000005', 'daily', 86.00, 'high', '2026-06-01T10:30:00Z', 'liked', '2026-06-05T10:05:00Z', 1),
|
||||
(gen_random_uuid(), 'm06a2b3c4d5e6f70000000000000006', 'f01a2b3c4d5e6f70000000000000001', 'daily', 62.00, 'medium','2026-06-06T14:00:00Z', 'liked', '2026-06-06T14:00:00Z', 1);
|
||||
|
||||
-- ============================================================
|
||||
-- 16. 相亲活动
|
||||
-- ============================================================
|
||||
WITH act_org AS (
|
||||
SELECT id FROM organizations WHERE type='women_federation' LIMIT 1
|
||||
), act_mgr AS (
|
||||
SELECT id FROM operators WHERE username='activitymgr' LIMIT 1
|
||||
)
|
||||
INSERT INTO activities (id, title, description, organizer_org_id, coorganizer_text,
|
||||
start_at, end_at, location_name, location_address,
|
||||
male_limit, female_limit, total_limit, min_age, max_age,
|
||||
registration_start_at, registration_end_at, need_review, status, created_by)
|
||||
VALUES
|
||||
((SELECT id FROM act_org),
|
||||
'丹阳公益单身联谊会(夏季场)',
|
||||
'面向丹阳市区及周边乡镇的单身青年,由妇联、工会联合主办,提供安全、真实的交友平台。现场设有互动游戏、自由交流环节,红娘全程辅助。',
|
||||
(SELECT id FROM act_org),
|
||||
'丹阳市总工会、丹阳市慈善基金会',
|
||||
'2026-08-15T14:00:00Z', '2026-08-15T17:30:00Z',
|
||||
'丹阳市文化馆多功能厅', '丹阳市丹北路168号',
|
||||
15, 15, 30, 22, 40,
|
||||
'2026-07-01T00:00:00Z', '2026-08-10T23:59:59Z',
|
||||
true, 'registration_open', (SELECT id FROM act_mgr)),
|
||||
|
||||
((SELECT id FROM organizations WHERE type='trade_union' LIMIT 1),
|
||||
'七夕特别活动·丹阳缘来是你',
|
||||
'七夕节特别策划,浪漫主题相亲活动。适合寻找认真关系的单身人士。',
|
||||
(SELECT id FROM organizations WHERE type='trade_union' LIMIT 1),
|
||||
'丹阳市新时代文明实践中心',
|
||||
'2026-08-29T15:00:00Z', '2026-08-29T18:00:00Z',
|
||||
'丹阳大剧院报告厅', '丹阳市书院路28号',
|
||||
20, 20, 40, 25, 45,
|
||||
'2026-08-01T00:00:00Z', '2026-08-25T23:59:59Z',
|
||||
true, 'draft', (SELECT id FROM operators WHERE username='activitymgr' LIMIT 1));
|
||||
|
||||
-- ============================================================
|
||||
-- 17. 活动报名
|
||||
-- ============================================================
|
||||
WITH act1 AS (SELECT id FROM activities WHERE title LIKE '夏季%' LIMIT 1),
|
||||
mgr AS (SELECT id FROM operators WHERE username='activitymgr' LIMIT 1)
|
||||
INSERT INTO activity_registrations (id, activity_id, user_id, status, registered_at, reviewed_by, reviewed_at, checkin_status) VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM act1), 'f01a2b3c4d5e6f70000000000000001', 'approved', '2026-07-05T10:00:00Z', (SELECT id FROM mgr), '2026-07-05T10:30:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), 'f03a2b3c4d5e6f70000000000000003', 'approved', '2026-07-06T14:00:00Z', (SELECT id FROM mgr), '2026-07-06T14:15:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), 'f05a2b3c4d5e6f70000000000000005', 'approved', '2026-07-07T09:00:00Z', (SELECT id FROM mgr), '2026-07-07T09:20:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), 'm01a2b3c4d5e6f70000000000000001', 'approved', '2026-07-08T11:00:00Z', (SELECT id FROM mgr), '2026-07-08T11:10:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), 'm03a2b3c4d5e6f70000000000000003', 'approved', '2026-07-09T15:00:00Z', (SELECT id FROM mgr), '2026-07-09T15:20:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), 'm05a2b3c4d5e6f70000000000000005', 'approved', '2026-07-10T08:30:00Z', (SELECT id FROM mgr), '2026-07-10T08:45:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), 'f02a2b3c4d5e6f70000000000000002', 'pending', '2026-07-12T10:00:00Z', NULL, NULL, 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), 'm02a2b3c4d5e6f70000000000000002', 'approved', '2026-07-11T16:00:00Z', (SELECT id FROM mgr), '2026-07-11T16:30:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), 'f04a2b3c4d5e6f70000000000000004', 'rejected', '2026-07-13T09:00:00Z', (SELECT id FROM mgr), '2026-07-13T09:15:00Z', 'not_checked_in');
|
||||
|
||||
-- ============================================================
|
||||
-- 18. 活动互选意向
|
||||
-- ============================================================
|
||||
WITH act1 AS (SELECT id FROM activities WHERE title LIKE '夏季%' LIMIT 1)
|
||||
INSERT INTO activity_interests (id, source_user_id, target_user_id, activity_id, status, confirmed_at, created_at) VALUES
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'm01a2b3c4d5e6f70000000000000001', (SELECT id FROM act1), 'mutual', '2026-08-15T17:00:00Z', '2026-08-15T17:00:00Z'),
|
||||
(gen_random_uuid(), 'f03a2b3c4d5e6f70000000000000003', 'm03a2b3c4d5e6f70000000000000003', (SELECT id FROM act1), 'mutual', '2026-08-15T17:05:00Z', '2026-08-15T17:05:00Z'),
|
||||
(gen_random_uuid(), 'f05a2b3c4d5e6f70000000000000005', 'm05a2b3c4d5e6f70000000000000005', (SELECT id FROM act1), 'expressed','2026-08-15T17:10:00Z', '2026-08-15T17:10:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 19. 红娘服务
|
||||
-- ============================================================
|
||||
WITH mh_op AS (SELECT id FROM operators WHERE username='wanghongniang' LIMIT 1),
|
||||
women_org AS (SELECT id FROM organizations WHERE type='women_federation' LIMIT 1),
|
||||
charity_org AS (SELECT id FROM organizations WHERE type='charity_center' LIMIT 1)
|
||||
INSERT INTO matchmaker_services (id, user_id, service_type, description, status, organization_id, assigned_operator_id, assigned_at, completed_at) VALUES
|
||||
(gen_random_uuid(), 'f02a2b3c4d5e6f70000000000000002', 'recommend_partner', '离异用户希望找到合适的伴侣,需要红娘协助筛选',
|
||||
'in_service', (SELECT id FROM women_org), (SELECT id FROM mh_op), '2026-06-20T10:00:00Z', NULL),
|
||||
(gen_random_uuid(), 'f06a2b3c4d5e6f70000000000000006', 'no_match_help', '丧偶用户希望重新融入社交,找到新伴侣',
|
||||
'waiting_user', (SELECT id FROM charity_org), (SELECT id FROM mh_op), '2026-06-25T14:00:00Z', NULL),
|
||||
(gen_random_uuid(), 'f04a2b3c4d5e6f70000000000000004', 'review_preference', '用户希望调整择偶条件,请红娘帮助评估',
|
||||
'completed', (SELECT id FROM women_org), (SELECT id FROM mh_op), '2026-06-15T09:00:00Z', '2026-06-20T11:00:00Z');
|
||||
|
||||
-- 红娘推荐
|
||||
WITH ms_f02 AS (SELECT id FROM matchmaker_services WHERE user_id='f02a2b3c4d5e6f70000000000000002' LIMIT 1),
|
||||
mh_op2 AS (SELECT id FROM operators WHERE username='wanghongniang' LIMIT 1)
|
||||
INSERT INTO matchmaker_recommendations (id, service_id, user_id, target_user_id, operator_id, reason, status, created_at, viewed_at, responded_at)
|
||||
VALUES (gen_random_uuid(), (SELECT id FROM ms_f02), 'f02a2b3c4d5e6f70000000000000002', 'm02a2b3c4d5e6f70000000000000002', (SELECT id FROM mh_op2),
|
||||
'两人同在丹阳工作,年龄相仿,都离过婚有共同语言', 'viewed', '2026-06-21T10:00:00Z', '2026-06-22T09:00:00Z', NULL);
|
||||
|
||||
-- 红娘跟进
|
||||
WITH ms_f02_2 AS (SELECT id FROM matchmaker_services WHERE user_id='f02a2b3c4d5e6f70000000000000002' LIMIT 1),
|
||||
ms_f04 AS (SELECT id FROM matchmaker_services WHERE user_id='f04a2b3c4d5e6f70000000000000004' LIMIT 1),
|
||||
mh_op3 AS (SELECT id FROM operators WHERE username='wanghongniang' LIMIT 1)
|
||||
INSERT INTO matchmaker_followups (id, service_id, operator_id, followup_type, content, result_code, next_followup_at, created_at) VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM ms_f02_2), (SELECT id FROM mh_op3), 'phone_call', '电话沟通用户情况,了解离异原因及择偶期望', '正常', '2026-07-01T10:00:00Z', '2026-06-22T10:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM ms_f04), (SELECT id FROM mh_op3), 'face_to_face', '面对面交流,帮助用户调整身高要求从170改为168', '已调整', NULL, '2026-06-18T15:00:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 20. 系统通知
|
||||
-- ============================================================
|
||||
WITH notif_users AS (
|
||||
SELECT 'f01a2b3c4d5e6f70000000000000001' as uid, 'f03a2b3c4d5e6f70000000000000003' as u2, 'f05a2b3c4d5e6f70000000000000005' as u3,
|
||||
'm01a2b3c4d5e6f70000000000000001' as mu1, 'm03a2b3c4d5e6f70000000000000003' as mu2, 'm05a2b3c4d5e6f70000000000000005' as mu3,
|
||||
'f02a2b3c4d5e6f70000000000000002' as mf2
|
||||
)
|
||||
INSERT INTO notifications (id, user_id, type, title, content, business_type, business_id, read_status, created_at)
|
||||
SELECT gen_random_uuid(), uid, type, title, content, business_type, NULL::uuid, read_status, created_at FROM (
|
||||
VALUES
|
||||
('match','f01a2b3c4d5e6f70000000000000001','match','你们互相喜欢!','张伟也喜欢了你,可以开始聊天啦~','match','read','2026-06-01T10:05:00Z'),
|
||||
('match','m01a2b3c4d5e6f70000000000000001','match','你们互相喜欢!','小芳也喜欢了你,可以开始聊天啦~','match','read','2026-06-01T10:05:00Z'),
|
||||
('match','f03a2b3c4d5e6f70000000000000003','match','你们互相喜欢!','王磊也喜欢了你,可以开始聊天啦~','match','read','2026-06-03T09:30:00Z'),
|
||||
('match','m03a2b3c4d5e6f70000000000000003','match','你们互相喜欢!','婷婷也喜欢了你,可以开始聊天啦~','match','unread','2026-06-03T09:30:00Z'),
|
||||
('match','f05a2b3c4d5e6f70000000000000005','match','你们互相喜欢!','孙浩也喜欢了你,可以开始聊天啦~','match','read','2026-06-05T10:05:00Z'),
|
||||
('match','m05a2b3c4d5e6f70000000000000005','match','你们互相喜欢!','慧琴也喜欢了你,可以开始聊天啦~','match','read','2026-06-05T10:05:00Z'),
|
||||
('system','f05a2b3c4d5e6f70000000000000005','system','恭喜牵手成功!','您与孙浩已成功牵手,祝你们幸福!','match','read','2026-07-01T10:30:00Z'),
|
||||
('system','m05a2b3c4d5e6f70000000000000005','system','恭喜牵手成功!','您与慧琴已成功牵手,祝你们幸福!','match','read','2026-07-01T10:30:00Z'),
|
||||
('activity','f01a2b3c4d5e6f70000000000000001','activity','活动报名已确认','您已成功报名「丹阳公益单身联谊会」','activity','read','2026-07-05T10:30:00Z'),
|
||||
('activity','f05a2b3c4d5e6f70000000000000005','activity','活动报名已确认','您已成功报名「丹阳公益单身联谊会」','activity','unread','2026-07-07T09:20:00Z'),
|
||||
('matchmaker','f02a2b3c4d5e6f70000000000000002','matchmaker','红娘已为您服务','您的红娘服务申请已被分配,红娘小王将在24小时内与您联系','matchmaker','read','2026-06-20T10:30:00Z')
|
||||
) AS t(type, user_id, ntype, title, content, business_type, read_status, created_at);
|
||||
|
||||
-- ============================================================
|
||||
-- 21. 同意记录
|
||||
-- ============================================================
|
||||
INSERT INTO consent_records (id, user_id, type, version, agreed_at, ip_address, user_agent) VALUES
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'terms_of_service', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
(gen_random_uuid(), 'f01a2b3c4d5e6f70000000000000001', 'privacy_policy', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
(gen_random_uuid(), 'm01a2b3c4d5e6f70000000000000001', 'terms_of_service', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
(gen_random_uuid(), 'm01a2b3c4d5e6f70000000000000001', 'privacy_policy', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0');
|
||||
|
||||
-- ============================================================
|
||||
-- 22. 审核原因字典
|
||||
-- ============================================================
|
||||
INSERT INTO review_reasons (code, name, category, enabled, sort_order) VALUES
|
||||
('profile_incomplete', '资料不完整', 'quality', true, 1),
|
||||
('photo_unclear', '照片不清晰', 'quality', true, 2),
|
||||
('fake_info', '信息疑似虚假', 'trust', true, 3),
|
||||
('inappropriate_photo', '照片内容不当', 'safety', true, 4),
|
||||
('duplicate_identity', '重复注册', 'duplicate', true, 5),
|
||||
('suspicious_behavior', '行为异常', 'risk', true, 6),
|
||||
('manual_review_needed', '需人工复核', 'quality', true, 7);
|
||||
|
||||
SET session_replication_role = 'origin';
|
||||
|
||||
-- ============================================================
|
||||
-- 验证数据量
|
||||
-- ============================================================
|
||||
DO $$
|
||||
DECLARE
|
||||
u_cnt INTEGER; op_cnt INTEGER; m_cnt INTEGER; a_cnt INTEGER; r_cnt INTEGER; n_cnt INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO u_cnt FROM users WHERE deleted_at IS NULL;
|
||||
SELECT COUNT(*) INTO op_cnt FROM operators;
|
||||
SELECT COUNT(*) INTO m_cnt FROM matches;
|
||||
SELECT COUNT(*) INTO a_cnt FROM activities WHERE deleted_at IS NULL;
|
||||
SELECT COUNT(*) INTO r_cnt FROM user_relations;
|
||||
SELECT COUNT(*) INTO n_cnt FROM notifications;
|
||||
RAISE NOTICE '✅ Demo 数据填充完成:';
|
||||
RAISE NOTICE ' 用户: %人 | 操作员: %人 | Match: %对', u_cnt, op_cnt, m_cnt;
|
||||
RAISE NOTICE ' 关系: %条 | 活动: %个 | 通知: %条', r_cnt, a_cnt, n_cnt;
|
||||
END $$;
|
||||
@@ -0,0 +1,565 @@
|
||||
-- ============================================================
|
||||
-- 丹阳公益婚恋服务平台 — Demo Seed 数据脚本 v3(纯 UUID)
|
||||
-- 所有 ID 使用 gen_random_uuid() 生成,完全兼容 PostgreSQL UUID 类型
|
||||
-- ============================================================
|
||||
|
||||
SET session_replication_role = 'replica';
|
||||
|
||||
-- ============================================================
|
||||
-- 1. 组织
|
||||
-- ============================================================
|
||||
INSERT INTO organizations (name, type, contact_name, status) VALUES
|
||||
('丹阳市妇女联合会', 'women_federation', '张丽华', 'active'),
|
||||
('丹阳市总工会', 'trade_union', '李明远', 'active'),
|
||||
('丹阳市慈善基金会', 'charity_center', '王秀英', 'active');
|
||||
|
||||
-- ============================================================
|
||||
-- 2. 工作人员
|
||||
-- ============================================================
|
||||
INSERT INTO operators (organization_id, name, username, password_hash, status) VALUES
|
||||
((SELECT id FROM organizations WHERE type='women_federation' LIMIT 1), '陈主任', 'admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
((SELECT id FROM organizations WHERE type='women_federation' LIMIT 1), '红娘小王', 'wanghongniang','$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
((SELECT id FROM organizations WHERE type='charity_center' LIMIT 1), '审核员小张', 'reviewer01', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
((SELECT id FROM organizations WHERE type='trade_union' LIMIT 1), '活动管理员赵', 'activitymgr', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active');
|
||||
|
||||
-- 操作员角色绑定
|
||||
INSERT INTO operator_roles (operator_id, role_id) SELECT id, '00000000-0000-0000-0000-000000000001' FROM operators WHERE username='admin';
|
||||
INSERT INTO operator_roles (operator_id, role_id) SELECT id, '00000000-0000-0000-0000-000000000002' FROM operators WHERE username='admin';
|
||||
INSERT INTO operator_roles (operator_id, role_id) SELECT id, '00000000-0000-0000-0000-000000000005' FROM operators WHERE username='wanghongniang';
|
||||
INSERT INTO operator_roles (operator_id, role_id) SELECT id, '00000000-0000-0000-0000-000000000006' FROM operators WHERE username='wanghongniang';
|
||||
INSERT INTO operator_roles (operator_id, role_id) SELECT id, '00000000-0000-0000-0000-000000000004' FROM operators WHERE username='reviewer01';
|
||||
INSERT INTO operator_roles (operator_id, role_id) SELECT id, '00000000-0000-0000-0000-000000000007' FROM operators WHERE username='reviewer01';
|
||||
INSERT INTO operator_roles (operator_id, role_id) SELECT id, '00000000-0000-0000-0000-000000000006' FROM operators WHERE username='activitymgr';
|
||||
INSERT INTO operator_roles (operator_id, role_id) SELECT id, '00000000-0000-0000-0000-000000000008' FROM operators WHERE username='activitymgr';
|
||||
|
||||
-- ============================================================
|
||||
-- 3. Demo 用户 12人(UUID 格式)
|
||||
-- ============================================================
|
||||
WITH demo_users AS (
|
||||
INSERT INTO users (wechat_openid, account_status, relationship_status, recommendation_enabled, created_at)
|
||||
VALUES
|
||||
('demo_openid_f01', 'normal', 'searching', true, '2026-03-15T10:00:00Z'),
|
||||
('demo_openid_f02', 'normal', 'searching', true, '2026-03-20T14:30:00Z'),
|
||||
('demo_openid_f03', 'normal', 'searching', true, '2026-04-01T09:15:00Z'),
|
||||
('demo_openid_f04', 'normal', 'paused', true, '2026-04-10T16:00:00Z'),
|
||||
('demo_openid_f05', 'normal', 'searching', true, '2026-05-01T11:20:00Z'),
|
||||
('demo_openid_f06', 'normal', 'searching', true, '2026-05-15T08:45:00Z'),
|
||||
('demo_openid_m01', 'normal', 'searching', true, '2026-03-10T09:00:00Z'),
|
||||
('demo_openid_m02', 'normal', 'getting_to_know', true, '2026-03-25T13:00:00Z'),
|
||||
('demo_openid_m03', 'normal', 'searching', true, '2026-04-05T15:30:00Z'),
|
||||
('demo_openid_m04', 'normal', 'searching', true, '2026-04-20T10:00:00Z'),
|
||||
('demo_openid_m05', 'normal', 'matched_successfully', true, '2026-05-01T14:00:00Z'),
|
||||
('demo_openid_m06', 'normal', 'searching', true, '2026-05-10T16:30:00Z')
|
||||
RETURNING id, wechat_openid
|
||||
)
|
||||
SELECT * FROM demo_users;
|
||||
|
||||
-- 将生成的用户ID放入临时表供后续引用
|
||||
CREATE TEMP TABLE demo_user_ids ON COMMIT DROP AS
|
||||
SELECT id, wechat_openid FROM users WHERE wechat_openid LIKE 'demo_openid_%';
|
||||
|
||||
-- 建立映射别名
|
||||
CREATE TEMP TABLE demo_user_map ON COMMIT DROP AS
|
||||
SELECT
|
||||
id,
|
||||
wechat_openid,
|
||||
CASE wechat_openid
|
||||
WHEN 'demo_openid_f01' THEN 'f01'
|
||||
WHEN 'demo_openid_f02' THEN 'f02'
|
||||
WHEN 'demo_openid_f03' THEN 'f03'
|
||||
WHEN 'demo_openid_f04' THEN 'f04'
|
||||
WHEN 'demo_openid_f05' THEN 'f05'
|
||||
WHEN 'demo_openid_f06' THEN 'f06'
|
||||
WHEN 'demo_openid_m01' THEN 'm01'
|
||||
WHEN 'demo_openid_m02' THEN 'm02'
|
||||
WHEN 'demo_openid_m03' THEN 'm03'
|
||||
WHEN 'demo_openid_m04' THEN 'm04'
|
||||
WHEN 'demo_openid_m05' THEN 'm05'
|
||||
WHEN 'demo_openid_m06' THEN 'm06'
|
||||
END as alias
|
||||
FROM demo_user_ids;
|
||||
|
||||
SELECT 'users inserted' as step, COUNT(*) as cnt FROM demo_user_map;
|
||||
|
||||
-- ============================================================
|
||||
-- 4. 用户资料
|
||||
-- ============================================================
|
||||
INSERT INTO user_profiles (
|
||||
user_id, display_name, gender, birth_date, height_cm,
|
||||
region_code, region_name, marital_status, children_status,
|
||||
education_code, occupation_code, smoking_status, drinking_status,
|
||||
long_term_danyang, future_danyang, relationship_goal, profile_completion, profile_status
|
||||
)
|
||||
SELECT
|
||||
m.id,
|
||||
CASE m.alias WHEN 'f01' THEN '小芳' WHEN 'f02' THEN '晓燕' WHEN 'f03' THEN '婷婷'
|
||||
WHEN 'f04' THEN '美玲' WHEN 'f05' THEN '慧琴' WHEN 'f06' THEN '秀英'
|
||||
WHEN 'm01' THEN '张伟' WHEN 'm02' THEN '李强' WHEN 'm03' THEN '王磊'
|
||||
WHEN 'm04' THEN '赵明' WHEN 'm05' THEN '孙浩' WHEN 'm06' THEN '周洋' END,
|
||||
CASE WHEN m.alias LIKE 'f%' THEN 'female' ELSE 'male' END,
|
||||
CASE m.alias
|
||||
WHEN 'f01' THEN '1995-06-15' WHEN 'f02' THEN '1993-09-20' WHEN 'f03' THEN '1998-02-10'
|
||||
WHEN 'f04' THEN '1990-11-05' WHEN 'f05' THEN '1996-07-22' WHEN 'f06' THEN '1992-04-18'
|
||||
WHEN 'm01' THEN '1992-01-10' WHEN 'm02' THEN '1990-08-25' WHEN 'm03' THEN '1997-12-03'
|
||||
WHEN 'm04' THEN '1988-05-30' WHEN 'm05' THEN '1994-03-14' WHEN 'm06' THEN '1999-08-08'
|
||||
END,
|
||||
CASE m.alias
|
||||
WHEN 'f01' THEN 162 WHEN 'f02' THEN 165 WHEN 'f03' THEN 158
|
||||
WHEN 'f04' THEN 160 WHEN 'f05' THEN 163 WHEN 'f06' THEN 157
|
||||
WHEN 'm01' THEN 175 WHEN 'm02' THEN 178 WHEN 'm03' THEN 180
|
||||
WHEN 'm04' THEN 172 WHEN 'm05' THEN 182 WHEN 'm06' THEN 176
|
||||
END,
|
||||
CASE WHEN m.alias IN ('f01','f02','f04','f05','m01','m02','m04','m05') THEN '321181'
|
||||
WHEN m.alias IN ('f03','m03') THEN '321100'
|
||||
WHEN m.alias = 'm06' THEN '320500' END,
|
||||
CASE WHEN m.alias IN ('f01','f02','f04','f05','m01','m02','m04','m05') THEN '丹阳'
|
||||
WHEN m.alias IN ('f03','m03') THEN '镇江'
|
||||
WHEN m.alias = 'm06' THEN '苏州' END,
|
||||
CASE m.alias
|
||||
WHEN 'f02' THEN 'divorced' WHEN 'f06' THEN 'widowed' ELSE 'never_married' END,
|
||||
'none',
|
||||
CASE m.alias
|
||||
WHEN 'f01' THEN 'bachelor' WHEN 'f02' THEN 'college' WHEN 'f03' THEN 'master'
|
||||
WHEN 'f04' THEN 'senior_high' WHEN 'f05' THEN 'bachelor' WHEN 'f06' THEN 'junior_high'
|
||||
WHEN 'm01' THEN 'bachelor' WHEN 'm02' THEN 'master' WHEN 'm03' THEN 'college'
|
||||
WHEN 'm04' THEN 'senior_high' WHEN 'm05' THEN 'bachelor' WHEN 'm06' THEN 'master'
|
||||
END,
|
||||
CASE m.alias
|
||||
WHEN 'f01' THEN 'clerical' WHEN 'f02' THEN 'teacher' WHEN 'f03' THEN 'designer'
|
||||
WHEN 'f04' THEN 'factory' WHEN 'f05' THEN 'nurse' WHEN 'f06' THEN 'farmer'
|
||||
WHEN 'm01' THEN 'engineer' WHEN 'm02' THEN 'manager' WHEN 'm03' THEN 'programmer'
|
||||
WHEN 'm04' THEN 'sales' WHEN 'm05' THEN 'doctor' WHEN 'm06' THEN 'researcher'
|
||||
END,
|
||||
CASE m.alias WHEN 'f03' THEN 'sometimes' WHEN 'f06' THEN 'often' WHEN 'm02' THEN 'sometimes'
|
||||
WHEN 'm04' THEN 'often' WHEN 'm05' THEN 'sometimes' ELSE 'never' END,
|
||||
CASE m.alias WHEN 'f03' THEN 'often' WHEN 'f06' THEN 'often' WHEN 'm02' THEN 'often'
|
||||
WHEN 'm04' THEN 'often' ELSE 'sometimes' END,
|
||||
CASE WHEN m.alias IN ('f03','m06') THEN '否' ELSE '是' END,
|
||||
CASE WHEN m.alias IN ('f03','m06') THEN '否' ELSE '是' END,
|
||||
CASE WHEN m.alias IN ('f03','m06') THEN '恋爱' ELSE '结婚' END,
|
||||
CASE m.alias
|
||||
WHEN 'f01' THEN 90 WHEN 'f02' THEN 95 WHEN 'f03' THEN 85 WHEN 'f04' THEN 70
|
||||
WHEN 'f05' THEN 92 WHEN 'f06' THEN 60 WHEN 'm01' THEN 88 WHEN 'm02' THEN 95
|
||||
WHEN 'm03' THEN 82 WHEN 'm04' THEN 75 WHEN 'm05' THEN 97 WHEN 'm06' THEN 80
|
||||
END,
|
||||
'approved'
|
||||
FROM demo_user_map m;
|
||||
|
||||
-- ============================================================
|
||||
-- 5. 用户择偶偏好
|
||||
-- ============================================================
|
||||
INSERT INTO user_preferences (user_id, min_age, max_age, age_priority, min_height_cm, max_height_cm, height_priority, region_scope, region_priority, marital_statuses, marital_priority, min_education_code, education_priority)
|
||||
SELECT m.id,
|
||||
CASE WHEN m.alias LIKE 'f%' THEN 28 WHEN m.alias LIKE 'm%' THEN 22 ELSE 25 END,
|
||||
CASE WHEN m.alias LIKE 'f%' THEN 40 WHEN m.alias LIKE 'm%' THEN 38 ELSE 35 END,
|
||||
'required',
|
||||
CASE WHEN m.alias LIKE 'f%' THEN 155 WHEN m.alias LIKE 'm%' THEN 170 ELSE 158 END,
|
||||
CASE WHEN m.alias LIKE 'f%' THEN 172 WHEN m.alias LIKE 'm%' THEN 188 ELSE 185 END,
|
||||
'preferred',
|
||||
'["321181","321100"]',
|
||||
'required',
|
||||
'["never_married"]',
|
||||
'required',
|
||||
CASE WHEN m.alias IN ('f02','m02') THEN 'college' WHEN m.alias IN ('f01','m01','m05') THEN 'bachelor' ELSE NULL END,
|
||||
'preferred'
|
||||
FROM demo_user_map m;
|
||||
|
||||
-- ============================================================
|
||||
-- 6. 实名认证(mock)
|
||||
-- ============================================================
|
||||
INSERT INTO user_identities (id, user_id, real_name_enc, id_number_enc, id_number_hash, gender, birth_date, verification_status, provider, verified_at)
|
||||
SELECT gen_random_uuid(), m.id,
|
||||
encode(('[demo_enc_' || m.alias || ']')::bytea, 'escape'),
|
||||
encode(('[demo_id_' || m.alias || ']')::bytea, 'escape'),
|
||||
'demo_sha256_hash_' || m.alias,
|
||||
CASE WHEN m.alias LIKE 'f%' THEN 'female' ELSE 'male' END,
|
||||
CASE m.alias
|
||||
WHEN 'f01' THEN '1995-06-15' WHEN 'f02' THEN '1993-09-20' WHEN 'f03' THEN '1998-02-10'
|
||||
WHEN 'f04' THEN '1990-11-05' WHEN 'f05' THEN '1996-07-22' WHEN 'f06' THEN '1992-04-18'
|
||||
WHEN 'm01' THEN '1992-01-10' WHEN 'm02' THEN '1990-08-25' WHEN 'm03' THEN '1997-12-03'
|
||||
WHEN 'm04' THEN '1988-05-30' WHEN 'm05' THEN '1994-03-14' WHEN 'm06' THEN '1999-08-08'
|
||||
END,
|
||||
'verified', 'mock', NOW() - INTERVAL '1 day'
|
||||
FROM demo_user_map m;
|
||||
|
||||
-- ============================================================
|
||||
-- 7. 兴趣标签
|
||||
-- ============================================================
|
||||
INSERT INTO user_interests (user_id, interest_code)
|
||||
SELECT m.id, ic.code
|
||||
FROM demo_user_map m
|
||||
CROSS JOIN (
|
||||
VALUES
|
||||
('reading'),('cooking'),('travel'),('sports'),('music'),('outdoor'),
|
||||
('photography'),('dance'),('movie'),('pets'),('fitness'),('charity'),
|
||||
('gardening'),('gaming'),('hiking'),('coding'),('cars'),('running'),('research')
|
||||
) ic(code)
|
||||
WHERE (m.alias = 'f01' AND ic.code IN ('reading','cooking','travel'))
|
||||
OR (m.alias = 'f02' AND ic.code IN ('sports','music','outdoor'))
|
||||
OR (m.alias = 'f03' AND ic.code IN ('photography','dance','movie'))
|
||||
OR (m.alias = 'f04' AND ic.code IN ('pets','cooking'))
|
||||
OR (m.alias = 'f05' AND ic.code IN ('reading','fitness','charity'))
|
||||
OR (m.alias = 'f06' AND ic.code IN ('gardening','cooking'))
|
||||
OR (m.alias = 'm01' AND ic.code IN ('sports','gaming','travel'))
|
||||
OR (m.alias = 'm02' AND ic.code IN ('reading','investment','hiking'))
|
||||
OR (m.alias = 'm03' AND ic.code IN ('gaming','music','coding'))
|
||||
OR (m.alias = 'm04' AND ic.code IN ('cars','cooking'))
|
||||
OR (m.alias = 'm05' AND ic.code IN ('running','reading','charity'))
|
||||
OR (m.alias = 'm06' AND ic.code IN ('research','travel','photography'));
|
||||
|
||||
-- ============================================================
|
||||
-- 8. 隐私设置
|
||||
-- ============================================================
|
||||
INSERT INTO user_privacy_settings (user_id, visible_in_recommendations, visible_in_search, show_occupation, show_lifestyle_photos, receive_activity_recommendations, accept_matchmaker_recommendations)
|
||||
SELECT m.id,
|
||||
true,
|
||||
CASE WHEN m.alias IN ('f03','f06','m04') THEN false ELSE true END,
|
||||
CASE WHEN m.alias IN ('f02','f04','m02','m03') THEN false ELSE true END,
|
||||
CASE WHEN m.alias IN ('f02','m02','m03') THEN false ELSE true END,
|
||||
CASE WHEN m.alias IN ('f05','m03') THEN false ELSE true END,
|
||||
CASE WHEN m.alias IN ('f03') THEN false ELSE true END
|
||||
FROM demo_user_map m;
|
||||
|
||||
-- ============================================================
|
||||
-- 9. 照片
|
||||
-- ============================================================
|
||||
INSERT INTO user_photos (id, user_id, file_key, photo_type, sort_order, review_status)
|
||||
SELECT gen_random_uuid(), m.id,
|
||||
'photos/demo/' || m.alias || '/avatar.jpg',
|
||||
'avatar', 0, 'approved'
|
||||
FROM demo_user_map m
|
||||
UNION ALL
|
||||
SELECT gen_random_uuid(), m.id,
|
||||
'photos/demo/' || m.alias || '/lifestyle1.jpg',
|
||||
'lifestyle', 1, 'approved'
|
||||
FROM demo_user_map m;
|
||||
|
||||
-- ============================================================
|
||||
-- 10. 审核任务
|
||||
-- ============================================================
|
||||
INSERT INTO review_tasks (id, user_id, review_type, status, assigned_operator_id, submitted_at, started_at, completed_at, final_comment, version)
|
||||
SELECT gen_random_uuid(), m.id, 'initial_profile', 'approved',
|
||||
(SELECT id FROM operators WHERE username='reviewer01'),
|
||||
NOW() - INTERVAL '60 days', NOW() - INTERVAL '59 days', NOW() - INTERVAL '58 days',
|
||||
'资料完整,信息真实', 1
|
||||
FROM demo_user_map m
|
||||
WHERE m.alias IN ('f01','f02','f03','m01','m02','m03','m05');
|
||||
|
||||
-- ============================================================
|
||||
-- 11. 用户关系
|
||||
-- ============================================================
|
||||
WITH f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
f02 AS (SELECT id FROM demo_user_map WHERE alias='f02'),
|
||||
f03 AS (SELECT id FROM demo_user_map WHERE alias='f03'),
|
||||
f04 AS (SELECT id FROM demo_user_map WHERE alias='f04'),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
f06 AS (SELECT id FROM demo_user_map WHERE alias='f06'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01'),
|
||||
m02 AS (SELECT id FROM demo_user_map WHERE alias='m02'),
|
||||
m03 AS (SELECT id FROM demo_user_map WHERE alias='m03'),
|
||||
m04 AS (SELECT id FROM demo_user_map WHERE alias='m04'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05'),
|
||||
m06 AS (SELECT id FROM demo_user_map WHERE alias='m06')
|
||||
INSERT INTO user_relations (id, user_id, target_user_id, relation_type, created_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f01), (SELECT id FROM m01), 'liked', '2026-06-01T10:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m01), (SELECT id FROM f01), 'liked', '2026-06-01T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f02), (SELECT id FROM m02), 'liked', '2026-06-02T14:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f03), (SELECT id FROM m03), 'liked', '2026-06-03T09:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m03), (SELECT id FROM f03), 'liked', '2026-06-03T09:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m04), (SELECT id FROM f02), 'liked', '2026-06-04T11:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f04), (SELECT id FROM m04), 'passed', '2026-06-04T12:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), (SELECT id FROM m05), 'liked', '2026-06-05T10:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m05), (SELECT id FROM f05), 'liked', '2026-06-05T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m06), (SELECT id FROM f01), 'liked', '2026-06-06T14:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f04), (SELECT id FROM m06), 'passed', '2026-06-06T15:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f06), (SELECT id FROM m04), 'blocked', '2026-06-07T09:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m02), (SELECT id FROM f03), 'passed', '2026-06-07T10:00:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 12. Match
|
||||
-- ====================================================
|
||||
WITH f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
f03 AS (SELECT id FROM demo_user_map WHERE alias='f03'),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01'),
|
||||
m03 AS (SELECT id FROM demo_user_map WHERE alias='m03'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05')
|
||||
INSERT INTO matches (id, user_a_id, user_b_id, status, source, matched_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f01), (SELECT id FROM m01), 'active', 'user_like', '2026-06-01T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f03), (SELECT id FROM m03), 'active', 'user_like', '2026-06-03T09:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), (SELECT id FROM m05), 'successful', 'user_like', '2026-06-05T10:05:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 13. 成功牵手请求
|
||||
-- ============================================================
|
||||
WITH match_f05 AS (SELECT id FROM matches WHERE status='successful' LIMIT 1),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05')
|
||||
INSERT INTO relationship_success_requests (id, match_id, initiated_by, status, confirmed_by, created_at, resolved_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM match_f05), (SELECT id FROM f05), 'confirmed', (SELECT id FROM m05), '2026-07-01T10:00:00Z', '2026-07-01T10:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM matches WHERE status='active' ORDER BY created_at LIMIT 1), (SELECT id FROM f01), 'pending', NULL, '2026-07-15T14:00:00Z', NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 14. Conversations & Messages
|
||||
-- ============================================================
|
||||
WITH active_matches AS (
|
||||
SELECT id FROM matches WHERE status='active' ORDER BY created_at
|
||||
), conv1 AS (SELECT id FROM active_matches LIMIT 1),
|
||||
conv2 AS (SELECT id FROM active_matches OFFSET 1 LIMIT 1),
|
||||
conv3 AS (SELECT id FROM active_matches OFFSET 2 LIMIT 1),
|
||||
f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01'),
|
||||
f03 AS (SELECT id FROM demo_user_map WHERE alias='f03'),
|
||||
m03 AS (SELECT id FROM demo_user_map WHERE alias='m03'),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05')
|
||||
INSERT INTO conversations (id, match_id, status, last_message_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM conv1), 'active', '2026-07-10T16:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conv2), 'active', '2026-07-08T20:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conv3), 'active', '2026-07-01T18:00:00Z');
|
||||
|
||||
-- conversation_members
|
||||
WITH conv AS (SELECT id FROM conversations ORDER BY created_at),
|
||||
f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01'),
|
||||
f03 AS (SELECT id FROM demo_user_map WHERE alias='f03'),
|
||||
m03 AS (SELECT id FROM demo_user_map WHERE alias='m03'),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05')
|
||||
INSERT INTO conversation_members (conversation_id, user_id, unread_count, can_send, joined_at)
|
||||
SELECT c.id, f01.id, 0, true, NOW() FROM conv c WHERE c.id = (SELECT id FROM conv LIMIT 1)
|
||||
UNION ALL
|
||||
SELECT c.id, m01.id, 0, true, NOW() FROM conv c WHERE c.id = (SELECT id FROM conv LIMIT 1)
|
||||
UNION ALL
|
||||
SELECT c.id, f03.id, 1, true, NOW() FROM conv c WHERE c.id = (SELECT id FROM conv OFFSET 1 LIMIT 1)
|
||||
UNION ALL
|
||||
SELECT c.id, m03.id, 0, true, NOW() FROM conv c WHERE c.id = (SELECT id FROM conv OFFSET 1 LIMIT 1)
|
||||
UNION ALL
|
||||
SELECT c.id, f05.id, 0, true, NOW() FROM conv c WHERE c.id = (SELECT id FROM conv OFFSET 2 LIMIT 1)
|
||||
UNION ALL
|
||||
SELECT c.id, m05.id, 0, true, NOW() FROM conv c WHERE c.id = (SELECT id FROM conv OFFSET 2 LIMIT 1);
|
||||
|
||||
-- messages
|
||||
WITH conv AS (SELECT id FROM conversations ORDER BY created_at),
|
||||
f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01'),
|
||||
f03 AS (SELECT id FROM demo_user_map WHERE alias='f03'),
|
||||
m03 AS (SELECT id FROM demo_user_map WHERE alias='m03'),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05')
|
||||
INSERT INTO messages (id, conversation_id, sender_id, message_type, content, status, risk_level, created_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM conv LIMIT 1), (SELECT id FROM f01), 'text', '你好!看到你的资料觉得挺合适的~', 'sent', 'normal', '2026-06-15T14:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conv LIMIT 1), (SELECT id FROM m01), 'text', '你好!谢谢你的喜欢,我也觉得挺有缘的', 'sent', 'normal', '2026-06-15T14:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conv LIMIT 1), (SELECT id FROM f01), 'text', '你也在丹阳工作吗?平时喜欢做些什么?', 'sent', 'normal', '2026-06-15T14:10:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conv OFFSET 1 LIMIT 1), (SELECT id FROM m03), 'text', '嗨,你好!很高兴认识你', 'sent', 'normal', '2026-07-05T19:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conv OFFSET 1 LIMIT 1), (SELECT id FROM f03), 'text', '你好呀!我平时喜欢拍照和跳舞,你呢?', 'sent', 'normal', '2026-07-05T19:35:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM conv OFFSET 2 LIMIT 1), (SELECT id FROM m05), 'text', '你好,很高兴认识你!', 'sent', 'normal', '2026-06-10T10:00:00Z');
|
||||
|
||||
-- update last_message_at
|
||||
UPDATE conversations SET last_message_at = (
|
||||
SELECT MAX(created_at) FROM messages WHERE messages.conversation_id = conversations.id
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- 15. 推荐记录
|
||||
-- ============================================================
|
||||
WITH f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
f03 AS (SELECT id FROM demo_user_map WHERE alias='f03'),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01'),
|
||||
m03 AS (SELECT id FROM demo_user_map WHERE alias='m03'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05'),
|
||||
m06 AS (SELECT id FROM demo_user_map WHERE alias='m06')
|
||||
INSERT INTO recommendation_records (id, user_id, target_user_id, source, score, level, shown_at, action, action_at, rule_version)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f01), (SELECT id FROM m01), 'daily', 82.50, 'high', '2026-05-28T10:00:00Z', 'liked', '2026-06-01T10:00:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM f01), (SELECT id FROM m03), 'daily', 70.00, 'medium', '2026-05-28T10:00:00Z', 'passed','2026-05-28T10:01:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM m01), (SELECT id FROM f01), 'daily', 85.00, 'high', '2026-05-28T11:00:00Z', 'liked', '2026-06-01T10:05:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM f03), (SELECT id FROM m03), 'daily', 78.00, 'high', '2026-06-01T09:00:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM m03), (SELECT id FROM f03), 'daily', 75.00, 'high', '2026-06-01T09:30:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), (SELECT id FROM m05), 'daily', 88.00, 'high', '2026-06-01T10:00:00Z', 'liked', '2026-06-05T10:00:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM m05), (SELECT id FROM f05), 'daily', 86.00, 'high', '2026-06-01T10:30:00Z', 'liked', '2026-06-05T10:05:00Z', 1),
|
||||
(gen_random_uuid(), (SELECT id FROM m06), (SELECT id FROM f01), 'daily', 62.00, 'medium','2026-06-06T14:00:00Z', 'liked', '2026-06-06T14:00:00Z', 1);
|
||||
|
||||
-- ============================================================
|
||||
-- 16. 相亲活动
|
||||
-- ============================================================
|
||||
WITH women_org AS (SELECT id FROM organizations WHERE type='women_federation' LIMIT 1),
|
||||
trade_org AS (SELECT id FROM organizations WHERE type='trade_union' LIMIT 1),
|
||||
mgr AS (SELECT id FROM operators WHERE username='activitymgr' LIMIT 1)
|
||||
INSERT INTO activities (id, title, description, organizer_org_id, coorganizer_text,
|
||||
start_at, end_at, location_name, location_address,
|
||||
male_limit, female_limit, total_limit, min_age, max_age,
|
||||
registration_start_at, registration_end_at, need_review, status, created_by)
|
||||
VALUES
|
||||
(gen_random_uuid(),
|
||||
'丹阳公益单身联谊会(夏季场)',
|
||||
'面向丹阳市区及周边乡镇的单身青年,由妇联、工会联合主办,提供安全、真实的交友平台。',
|
||||
(SELECT id FROM women_org), '丹阳市总工会、丹阳市慈善基金会',
|
||||
'2026-08-15T14:00:00Z', '2026-08-15T17:30:00Z',
|
||||
'丹阳市文化馆多功能厅', '丹阳市丹北路168号',
|
||||
15, 15, 30, 22, 40,
|
||||
'2026-07-01T00:00:00Z', '2026-08-10T23:59:59Z',
|
||||
true, 'registration_open', (SELECT id FROM mgr)),
|
||||
(gen_random_uuid(),
|
||||
'七夕特别活动·丹阳缘来是你',
|
||||
'七夕节特别策划,浪漫主题相亲活动。',
|
||||
(SELECT id FROM trade_org), '丹阳市新时代文明实践中心',
|
||||
'2026-08-29T15:00:00Z', '2026-08-29T18:00:00Z',
|
||||
'丹阳大剧院报告厅', '丹阳市书院路28号',
|
||||
20, 20, 40, 25, 45,
|
||||
'2026-08-01T00:00:00Z', '2026-08-25T23:59:59Z',
|
||||
true, 'draft', (SELECT id FROM mgr));
|
||||
|
||||
-- ============================================================
|
||||
-- 17. 活动报名
|
||||
-- ============================================================
|
||||
WITH act1 AS (SELECT id FROM activities WHERE title LIKE '夏季%' LIMIT 1),
|
||||
mgr2 AS (SELECT id FROM operators WHERE username='activitymgr' LIMIT 1),
|
||||
f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
f02 AS (SELECT id FROM demo_user_map WHERE alias='f02'),
|
||||
f03 AS (SELECT id FROM demo_user_map WHERE alias='f03'),
|
||||
f04 AS (SELECT id FROM demo_user_map WHERE alias='f04'),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01'),
|
||||
m02 AS (SELECT id FROM demo_user_map WHERE alias='m02'),
|
||||
m03 AS (SELECT id FROM demo_user_map WHERE alias='m03'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05')
|
||||
INSERT INTO activity_registrations (id, activity_id, user_id, status, registered_at, reviewed_by, reviewed_at, checkin_status)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM act1), (SELECT id FROM f01), 'approved', '2026-07-05T10:00:00Z', (SELECT id FROM mgr2), '2026-07-05T10:30:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), (SELECT id FROM f03), 'approved', '2026-07-06T14:00:00Z', (SELECT id FROM mgr2), '2026-07-06T14:15:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), (SELECT id FROM f05), 'approved', '2026-07-07T09:00:00Z', (SELECT id FROM mgr2), '2026-07-07T09:20:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), (SELECT id FROM m01), 'approved', '2026-07-08T11:00:00Z', (SELECT id FROM mgr2), '2026-07-08T11:10:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), (SELECT id FROM m03), 'approved', '2026-07-09T15:00:00Z', (SELECT id FROM mgr2), '2026-07-09T15:20:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), (SELECT id FROM m05), 'approved', '2026-07-10T08:30:00Z', (SELECT id FROM mgr2), '2026-07-10T08:45:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), (SELECT id FROM f02), 'pending', '2026-07-12T10:00:00Z', NULL, NULL, 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), (SELECT id FROM m02), 'approved', '2026-07-11T16:00:00Z', (SELECT id FROM mgr2), '2026-07-11T16:30:00Z', 'not_checked_in'),
|
||||
(gen_random_uuid(), (SELECT id FROM act1), (SELECT id FROM f04), 'rejected', '2026-07-13T09:00:00Z', (SELECT id FROM mgr2), '2026-07-13T09:15:00Z', 'not_checked_in');
|
||||
|
||||
-- ============================================================
|
||||
-- 18. 活动互选意向
|
||||
-- ============================================================
|
||||
WITH act1 AS (SELECT id FROM activities WHERE title LIKE '夏季%' LIMIT 1),
|
||||
f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01'),
|
||||
f03 AS (SELECT id FROM demo_user_map WHERE alias='f03'),
|
||||
m03 AS (SELECT id FROM demo_user_map WHERE alias='m03'),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05')
|
||||
INSERT INTO activity_interests (id, source_user_id, target_user_id, activity_id, status, confirmed_at, created_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f01), (SELECT id FROM m01), (SELECT id FROM act1), 'mutual', '2026-08-15T17:00:00Z', '2026-08-15T17:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f03), (SELECT id FROM m03), (SELECT id FROM act1), 'mutual', '2026-08-15T17:05:00Z', '2026-08-15T17:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), (SELECT id FROM m05), (SELECT id FROM act1), 'expressed','2026-08-15T17:10:00Z', '2026-08-15T17:10:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 19. 红娘服务
|
||||
-- ====================================================
|
||||
WITH mh_op AS (SELECT id FROM operators WHERE username='wanghongniang' LIMIT 1),
|
||||
women_org AS (SELECT id FROM organizations WHERE type='women_federation' LIMIT 1),
|
||||
charity_org AS (SELECT id FROM organizations WHERE type='charity_center' LIMIT 1),
|
||||
f02 AS (SELECT id FROM demo_user_map WHERE alias='f02'),
|
||||
f04 AS (SELECT id FROM demo_user_map WHERE alias='f04'),
|
||||
f06 AS (SELECT id FROM demo_user_map WHERE alias='f06'),
|
||||
m02 AS (SELECT id FROM demo_user_map WHERE alias='m02')
|
||||
INSERT INTO matchmaker_services (id, user_id, service_type, description, status, organization_id, assigned_operator_id, assigned_at, completed_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f02), 'recommend_partner', '离异用户希望找到合适的伴侣,需要红娘协助筛选', 'in_service', (SELECT id FROM women_org), (SELECT id FROM mh_op), '2026-06-20T10:00:00Z', NULL),
|
||||
(gen_random_uuid(), (SELECT id FROM f06), 'no_match_help', '丧偶用户希望重新融入社交,找到新伴侣', 'waiting_user', (SELECT id FROM charity_org), (SELECT id FROM mh_op), '2026-06-25T14:00:00Z', NULL),
|
||||
(gen_random_uuid(), (SELECT id FROM f04), 'review_preference', '用户希望调整择偶条件,请红娘帮助评估', 'completed', (SELECT id FROM women_org), (SELECT id FROM mh_op), '2026-06-15T09:00:00Z', '2026-06-20T11:00:00Z');
|
||||
|
||||
-- 红娘推荐
|
||||
WITH ms_f02 AS (SELECT id FROM matchmaker_services WHERE user_id=(SELECT id FROM demo_user_map WHERE alias='f02') LIMIT 1),
|
||||
mh_op2 AS (SELECT id FROM operators WHERE username='wanghongniang' LIMIT 1),
|
||||
f02 AS (SELECT id FROM demo_user_map WHERE alias='f02'),
|
||||
m02 AS (SELECT id FROM demo_user_map WHERE alias='m02')
|
||||
INSERT INTO matchmaker_recommendations (id, service_id, user_id, target_user_id, operator_id, reason, status, created_at, viewed_at, responded_at)
|
||||
VALUES (gen_random_uuid(), (SELECT id FROM ms_f02), (SELECT id FROM f02), (SELECT id FROM m02), (SELECT id FROM mh_op2),
|
||||
'两人同在丹阳工作,年龄相仿,都离过婚有共同语言', 'viewed', '2026-06-21T10:00:00Z', '2026-06-22T09:00:00Z', NULL);
|
||||
|
||||
-- 红娘跟进
|
||||
WITH ms_f02_2 AS (SELECT id FROM matchmaker_services WHERE user_id=(SELECT id FROM demo_user_map WHERE alias='f02') LIMIT 1),
|
||||
ms_f04 AS (SELECT id FROM matchmaker_services WHERE user_id=(SELECT id FROM demo_user_map WHERE alias='f04') LIMIT 1),
|
||||
mh_op3 AS (SELECT id FROM operators WHERE username='wanghongniang' LIMIT 1)
|
||||
INSERT INTO matchmaker_followups (id, service_id, operator_id, followup_type, content, result_code, next_followup_at, created_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM ms_f02_2), (SELECT id FROM mh_op3), 'phone_call', '电话沟通用户情况,了解离异原因及择偶期望', '正常', '2026-07-01T10:00:00Z', '2026-06-22T10:00:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM ms_f04), (SELECT id FROM mh_op3), 'face_to_face', '面对面交流,帮助用户调整身高要求从170改为168', '已调整', NULL, '2026-06-18T15:00:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 20. 系统通知
|
||||
-- ====================================================
|
||||
WITH f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
f02 AS (SELECT id FROM demo_user_map WHERE alias='f02'),
|
||||
f03 AS (SELECT id FROM demo_user_map WHERE alias='f03'),
|
||||
f05 AS (SELECT id FROM demo_user_map WHERE alias='f05'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01'),
|
||||
m03 AS (SELECT id FROM demo_user_map WHERE alias='m03'),
|
||||
m05 AS (SELECT id FROM demo_user_map WHERE alias='m05')
|
||||
INSERT INTO notifications (id, user_id, type, title, content, business_type, read_status, created_at)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f01), 'match', '你们互相喜欢!', '张伟也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-01T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m01), 'match', '你们互相喜欢!', '小芳也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-01T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f03), 'match', '你们互相喜欢!', '王磊也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-03T09:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m03), 'match', '你们互相喜欢!', '婷婷也喜欢了你,可以开始聊天啦~', 'match', 'unread','2026-06-03T09:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), 'match', '你们互相喜欢!', '孙浩也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-05T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m05), 'match', '你们互相喜欢!', '慧琴也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-05T10:05:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), 'system', '恭喜牵手成功!', '您与孙浩已成功牵手,祝你们幸福!', 'match', 'read', '2026-07-01T10:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM m05), 'system', '恭喜牵手成功!', '您与慧琴已成功牵手,祝你们幸福!', 'match', 'read', '2026-07-01T10:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f01), 'activity', '活动报名已确认', '您已成功报名「丹阳公益单身联谊会」', 'activity', 'read', '2026-07-05T10:30:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f05), 'activity', '活动报名已确认', '您已成功报名「丹阳公益单身联谊会」', 'activity', 'unread','2026-07-07T09:20:00Z'),
|
||||
(gen_random_uuid(), (SELECT id FROM f02), 'matchmaker', '红娘已为您服务', '您的红娘服务申请已被分配,红娘小王将在24小时内与您联系', 'matchmaker', 'read', '2026-06-20T10:30:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 21. 同意记录
|
||||
-- ====================================================
|
||||
WITH f01 AS (SELECT id FROM demo_user_map WHERE alias='f01'),
|
||||
m01 AS (SELECT id FROM demo_user_map WHERE alias='m01')
|
||||
INSERT INTO consent_records (id, user_id, type, version, agreed_at, ip_address, user_agent)
|
||||
VALUES
|
||||
(gen_random_uuid(), (SELECT id FROM f01), 'terms_of_service', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
(gen_random_uuid(), (SELECT id FROM f01), 'privacy_policy', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
(gen_random_uuid(), (SELECT id FROM m01), 'terms_of_service', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
(gen_random_uuid(), (SELECT id FROM m01), 'privacy_policy', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0');
|
||||
|
||||
-- ============================================================
|
||||
-- 22. 审核原因字典(仅插入不存在的)
|
||||
-- ====================================================
|
||||
INSERT INTO review_reasons (code, name, category, enabled, sort_order)
|
||||
SELECT * FROM (VALUES
|
||||
('profile_incomplete', '资料不完整', 'quality', true, 1),
|
||||
('photo_unclear', '照片不清晰', 'quality', true, 2),
|
||||
('fake_info', '信息疑似虚假', 'trust', true, 3),
|
||||
('inappropriate_photo', '照片内容不当', 'safety', true, 4),
|
||||
('duplicate_identity', '重复注册', 'duplicate', true, 5),
|
||||
('suspicious_behavior', '行为异常', 'risk', true, 6),
|
||||
('manual_review_needed', '需人工复核', 'quality', true, 7)
|
||||
) AS t(code, name, category, enabled, sort_order)
|
||||
WHERE NOT EXISTS (SELECT 1 FROM review_reasons r WHERE r.code = t.code);
|
||||
|
||||
SET session_replication_role = 'origin';
|
||||
|
||||
-- ============================================================
|
||||
-- 验证数据量
|
||||
-- ============================================================
|
||||
DO $$
|
||||
DECLARE
|
||||
u_cnt INTEGER; op_cnt INTEGER; m_cnt INTEGER; a_cnt INTEGER; r_cnt INTEGER; n_cnt INTEGER; p_cnt INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO u_cnt FROM users WHERE deleted_at IS NULL;
|
||||
SELECT COUNT(*) INTO op_cnt FROM operators;
|
||||
SELECT COUNT(*) INTO m_cnt FROM matches;
|
||||
SELECT COUNT(*) INTO a_cnt FROM activities WHERE deleted_at IS NULL;
|
||||
SELECT COUNT(*) INTO r_cnt FROM user_relations;
|
||||
SELECT COUNT(*) INTO n_cnt FROM notifications;
|
||||
SELECT COUNT(*) INTO p_cnt FROM user_profiles;
|
||||
RAISE NOTICE '✅ Demo 数据填充完成:';
|
||||
RAISE NOTICE ' 用户: %人 | 资料: %条 | 操作员: %人', u_cnt, p_cnt, op_cnt;
|
||||
RAISE NOTICE ' Match: %对 | 关系: %条 | 活动: %个 | 通知: %条', m_cnt, r_cnt, a_cnt, n_cnt;
|
||||
END $$;
|
||||
@@ -0,0 +1,409 @@
|
||||
SET session_replication_role = 'replica';
|
||||
|
||||
-- 1. 组织
|
||||
|
||||
INSERT INTO organizations (id, name, type, contact_name, status) VALUES
|
||||
|
||||
('c74863d4-be10-4efa-b22c-f3f84e2e4e59', '丹阳市妇女联合会', 'women_federation', '张丽华', 'active'),
|
||||
|
||||
('a35f0043-be09-4bdf-ad5d-05a72ff19c2a', '丹阳市总工会', 'trade_union', '李明远', 'active'),
|
||||
|
||||
('bcd9e5b6-3b66-454c-96d7-3fade6866135', '丹阳市慈善基金会', 'charity_center', '王秀英', 'active');
|
||||
|
||||
-- 2. 工作人员
|
||||
|
||||
INSERT INTO operators (id, organization_id, name, username, password_hash, status) VALUES
|
||||
|
||||
('f54eedf5-a281-4289-a63d-57de1ea83fbc', 'c74863d4-be10-4efa-b22c-f3f84e2e4e59', '陈主任', 'admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
|
||||
('a98c0d97-d272-4577-887e-5c05e27db19b', 'c74863d4-be10-4efa-b22c-f3f84e2e4e59', '红娘小王', 'wanghongniang', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
|
||||
('e9312b05-c263-4901-8145-0b38e4d81c45', 'bcd9e5b6-3b66-454c-96d7-3fade6866135', '审核员小张', 'reviewer01', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
|
||||
('b4cdeb91-bbce-4587-be58-22ff55ef89da', 'a35f0043-be09-4bdf-ad5d-05a72ff19c2a', '活动管理员赵', 'activitymgr', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active');
|
||||
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES ('f54eedf5-a281-4289-a63d-57de1ea83fbc', '00000000-0000-0000-0000-000000000001');
|
||||
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES ('f54eedf5-a281-4289-a63d-57de1ea83fbc', '00000000-0000-0000-0000-000000000002');
|
||||
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES ('a98c0d97-d272-4577-887e-5c05e27db19b', '00000000-0000-0000-0000-000000000005');
|
||||
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES ('a98c0d97-d272-4577-887e-5c05e27db19b', '00000000-0000-0000-0000-000000000006');
|
||||
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES ('e9312b05-c263-4901-8145-0b38e4d81c45', '00000000-0000-0000-0000-000000000004');
|
||||
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES ('e9312b05-c263-4901-8145-0b38e4d81c45', '00000000-0000-0000-0000-000000000007');
|
||||
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES ('b4cdeb91-bbce-4587-be58-22ff55ef89da', '00000000-0000-0000-0000-000000000006');
|
||||
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES ('b4cdeb91-bbce-4587-be58-22ff55ef89da', '00000000-0000-0000-0000-000000000008');
|
||||
|
||||
-- 3. 用户 12人
|
||||
|
||||
INSERT INTO users (id, wechat_openid, account_status, relationship_status, recommendation_enabled, created_at) VALUES
|
||||
|
||||
('c4541dae-c864-459e-b5db-3381867ffbd1', 'demo_openid_f01', 'normal', 'searching', true, '2026-03-15T10:00:00Z'),
|
||||
('f047dbe2-0202-4c57-aa12-1aed76253b62', 'demo_openid_f02', 'normal', 'searching', true, '2026-03-20T14:30:00Z'),
|
||||
('cdef6f94-f406-4f37-a5c1-319569fc4e69', 'demo_openid_f03', 'normal', 'searching', true, '2026-04-01T09:15:00Z'),
|
||||
('2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 'demo_openid_f04', 'normal', 'paused', true, '2026-04-10T16:00:00Z'),
|
||||
('84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'demo_openid_f05', 'normal', 'searching', true, '2026-05-01T11:20:00Z'),
|
||||
('bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', 'demo_openid_f06', 'normal', 'searching', true, '2026-05-15T08:45:00Z'),
|
||||
('fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'demo_openid_m01', 'normal', 'searching', true, '2026-03-10T09:00:00Z'),
|
||||
('205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'demo_openid_m02', 'normal', 'getting_to_know', true, '2026-03-25T13:00:00Z'),
|
||||
('f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'demo_openid_m03', 'normal', 'searching', true, '2026-04-05T15:30:00Z'),
|
||||
('c9f5c328-04fe-4ec6-92af-6073df3af0b0', 'demo_openid_m04', 'normal', 'searching', true, '2026-04-20T10:00:00Z'),
|
||||
('34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'demo_openid_m05', 'normal', 'matched_successfully', true, '2026-05-01T14:00:00Z'),
|
||||
('b8846d00-ed0d-4c46-8f36-56c392b9c803', 'demo_openid_m06', 'normal', 'searching', true, '2026-05-10T16:30:00Z');
|
||||
|
||||
-- 4. 用户资料
|
||||
|
||||
INSERT INTO user_profiles (user_id, display_name, gender, birth_date, height_cm, region_code, region_name, marital_status, children_status, education_code, occupation_code, smoking_status, drinking_status, long_term_danyang, future_danyang, relationship_goal, profile_completion, profile_status) VALUES
|
||||
|
||||
('c4541dae-c864-459e-b5db-3381867ffbd1', '小芳', 'female', '1995-06-15', 162, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'clerical', 'never', 'sometimes', '是', '是', '结婚', 90, 'approved'),
|
||||
('f047dbe2-0202-4c57-aa12-1aed76253b62', '晓燕', 'female', '1993-09-20', 165, '321181', '丹阳', 'divorced', 'none', 'college', 'teacher', 'never', 'never', '是', '是', '结婚', 95, 'approved'),
|
||||
('cdef6f94-f406-4f37-a5c1-319569fc4e69', '婷婷', 'female', '1998-02-10', 158, '321100', '镇江', 'never_married', 'none', 'master', 'designer', 'sometimes', 'often', '是', '否', '恋爱', 85, 'approved'),
|
||||
('2db3db2d-ef0f-4f1e-8964-28be1566d1a9', '美玲', 'female', '1990-11-05', 160, '321181', '丹阳', 'never_married', 'none', 'senior_high', 'factory', 'never', 'never', '是', '是', '结婚', 70, 'approved'),
|
||||
('84431e32-c8f7-48d4-8e0e-fd14d86837e5', '慧琴', 'female', '1996-07-22', 163, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'nurse', 'never', 'sometimes', '是', '是', '结婚', 92, 'approved'),
|
||||
('bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', '秀英', 'female', '1992-04-18', 157, '321181', '丹阳', 'widowed', 'none', 'junior_high', 'farmer', 'often', 'often', '是', '是', '结婚', 60, 'approved'),
|
||||
('fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', '张伟', 'male', '1992-01-10', 175, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'engineer', 'never', 'sometimes', '是', '是', '结婚', 88, 'approved'),
|
||||
('205ddb91-56ef-4a8e-ade1-8cb35bb4affa', '李强', 'male', '1990-08-25', 178, '321181', '丹阳', 'divorced', 'none', 'master', 'manager', 'sometimes', 'often', '是', '是', '结婚', 95, 'approved'),
|
||||
('f81778e0-ec9e-472e-b7f4-6773e8e3dc81', '王磊', 'male', '1997-12-03', 180, '321100', '镇江', 'never_married', 'none', 'college', 'programmer', 'never', 'never', '是', '是', '恋爱', 82, 'approved'),
|
||||
('c9f5c328-04fe-4ec6-92af-6073df3af0b0', '赵明', 'male', '1988-05-30', 172, '321181', '丹阳', 'never_married', 'none', 'senior_high', 'sales', 'often', 'often', '否', '是', '结婚', 75, 'approved'),
|
||||
('34fb0bd1-4703-4744-a4ae-35d5059f5d32', '孙浩', 'male', '1994-03-14', 182, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'doctor', 'never', 'sometimes', '是', '是', '结婚', 97, 'approved'),
|
||||
('b8846d00-ed0d-4c46-8f36-56c392b9c803', '周洋', 'male', '1999-08-08', 176, '320500', '苏州', 'never_married', 'none', 'master', 'researcher', 'never', 'never', '是', '否', '恋爱', 80, 'approved');
|
||||
|
||||
-- 5. 用户择偶偏好
|
||||
|
||||
INSERT INTO user_preferences (user_id, min_age, max_age, age_priority, min_height_cm, max_height_cm, height_priority, region_scope, region_priority, marital_statuses, marital_priority, min_education_code, education_priority) VALUES
|
||||
|
||||
('c4541dae-c864-459e-b5db-3381867ffbd1', 28, 38, 'required', 170, 185, 'required', '["321181","321100"]', 'required', '["never_married"]', 'required', 'bachelor', 'preferred'),
|
||||
('f047dbe2-0202-4c57-aa12-1aed76253b62', 28, 40, 'required', 170, 188, 'required', '["321181"]', 'required', '["never_married","divorced"]', 'preferred', 'college', 'preferred'),
|
||||
('cdef6f94-f406-4f37-a5c1-319569fc4e69', 25, 35, 'preferred', 172, 185, 'preferred', '["321181","321100","320500"]', 'preferred', '["never_married"]', 'required', NULL, NULL),
|
||||
('2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 30, 45, 'required', 168, 185, 'required', '["321181"]', 'required', '["never_married","divorced"]', 'preferred', 'senior_high', 'preferred'),
|
||||
('84431e32-c8f7-48d4-8e0e-fd14d86837e5', 27, 36, 'required', 172, 186, 'required', '["321181","321100"]', 'preferred', '["never_married"]', 'required', 'bachelor', 'preferred'),
|
||||
('bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', 30, 50, 'required', 165, 185, 'required', '["321181"]', 'required', '["never_married","divorced","widowed"]', 'preferred', NULL, NULL),
|
||||
('fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 22, 32, 'required', 155, 170, 'preferred', '["321181","321100"]', 'required', '["never_married"]', 'required', 'junior_high', 'preferred'),
|
||||
('205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 25, 38, 'preferred', 158, 172, 'preferred', '["321181"]', 'preferred', '["never_married","divorced"]', 'preferred', 'college', 'preferred'),
|
||||
('f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 22, 30, 'preferred', 155, 168, 'preferred', '["321181","321100","320500"]', 'preferred', '["never_married"]', 'required', 'college', 'preferred'),
|
||||
('c9f5c328-04fe-4ec6-92af-6073df3af0b0', 25, 40, 'preferred', 155, 170, 'preferred', '["321181"]', 'required', '["never_married","divorced"]', 'preferred', NULL, NULL),
|
||||
('34fb0bd1-4703-4744-a4ae-35d5059f5d32', 23, 33, 'required', 158, 170, 'preferred', '["321181","321100"]', 'preferred', '["never_married"]', 'required', 'bachelor', 'preferred'),
|
||||
('b8846d00-ed0d-4c46-8f36-56c392b9c803', 22, 32, 'preferred', 155, 170, 'preferred', '["321181","321100","320500"]', 'preferred', '["never_married"]', 'required', 'master', 'preferred');
|
||||
|
||||
-- 6. 实名认证(mock)
|
||||
|
||||
INSERT INTO user_identities (id, user_id, real_name_enc, id_number_enc, id_number_hash, gender, birth_date, verification_status, provider, verified_at) VALUES
|
||||
|
||||
('da330615-46ad-4afd-997c-f9accb3808bc', 'c4541dae-c864-459e-b5db-3381867ffbd1', E'\\xenc_f01', E'\\xenc_id_f01', 'demo_sha256_f01', 'female', '1995-06-15', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('58eccd88-b1ba-4316-8eb8-d0900d0aea0e', 'f047dbe2-0202-4c57-aa12-1aed76253b62', E'\\xenc_f02', E'\\xenc_id_f02', 'demo_sha256_f02', 'female', '1993-09-20', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('f3abca38-b593-4375-9b64-2e792b1614a2', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', E'\\xenc_f03', E'\\xenc_id_f03', 'demo_sha256_f03', 'female', '1998-02-10', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('f01e9bcf-5044-4674-baa5-d98c36744925', '2db3db2d-ef0f-4f1e-8964-28be1566d1a9', E'\\xenc_f04', E'\\xenc_id_f04', 'demo_sha256_f04', 'female', '1990-11-05', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('a40fb330-0b08-4a48-9bf3-867ee7bdf51d', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', E'\\xenc_f05', E'\\xenc_id_f05', 'demo_sha256_f05', 'female', '1996-07-22', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('575885c7-7a1c-415e-be6e-452e06610204', 'bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', E'\\xenc_f06', E'\\xenc_id_f06', 'demo_sha256_f06', 'female', '1992-04-18', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('758ef8a8-404c-4b76-900a-ed7a2c568b6b', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', E'\\xenc_m01', E'\\xenc_id_m01', 'demo_sha256_m01', 'male', '1992-01-10', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('4a3618ea-060c-429c-9c7f-83abf39630df', '205ddb91-56ef-4a8e-ade1-8cb35bb4affa', E'\\xenc_m02', E'\\xenc_id_m02', 'demo_sha256_m02', 'male', '1990-08-25', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('2e3299e6-cde5-4cb2-9298-942a5f2a310a', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', E'\\xenc_m03', E'\\xenc_id_m03', 'demo_sha256_m03', 'male', '1997-12-03', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('4c8a6058-f8d8-42d8-9f20-9435cc823696', 'c9f5c328-04fe-4ec6-92af-6073df3af0b0', E'\\xenc_m04', E'\\xenc_id_m04', 'demo_sha256_m04', 'male', '1988-05-30', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('77a40aa0-7cd6-4571-b676-7f985da446e1', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', E'\\xenc_m05', E'\\xenc_id_m05', 'demo_sha256_m05', 'male', '1994-03-14', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('177fbf84-92bb-40d7-adb2-11e9ab9e7b05', 'b8846d00-ed0d-4c46-8f36-56c392b9c803', E'\\xenc_m06', E'\\xenc_id_m06', 'demo_sha256_m06', 'male', '1999-08-08', 'verified', 'mock', '2026-03-16T10:00:00Z');
|
||||
|
||||
-- 7. 兴趣标签
|
||||
|
||||
INSERT INTO user_interests (user_id, interest_code) VALUES
|
||||
|
||||
('c4541dae-c864-459e-b5db-3381867ffbd1', 'reading'),
|
||||
('c4541dae-c864-459e-b5db-3381867ffbd1', 'cooking'),
|
||||
('c4541dae-c864-459e-b5db-3381867ffbd1', 'travel'),
|
||||
('f047dbe2-0202-4c57-aa12-1aed76253b62', 'sports'),
|
||||
('f047dbe2-0202-4c57-aa12-1aed76253b62', 'music'),
|
||||
('f047dbe2-0202-4c57-aa12-1aed76253b62', 'outdoor'),
|
||||
('cdef6f94-f406-4f37-a5c1-319569fc4e69', 'photography'),
|
||||
('cdef6f94-f406-4f37-a5c1-319569fc4e69', 'dance'),
|
||||
('cdef6f94-f406-4f37-a5c1-319569fc4e69', 'movie'),
|
||||
('2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 'pets'),
|
||||
('2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 'cooking'),
|
||||
('84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'reading'),
|
||||
('84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'fitness'),
|
||||
('84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'charity'),
|
||||
('bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', 'gardening'),
|
||||
('bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', 'cooking'),
|
||||
('fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'sports'),
|
||||
('fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'gaming'),
|
||||
('fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'travel'),
|
||||
('205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'reading'),
|
||||
('205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'investment'),
|
||||
('205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'hiking'),
|
||||
('f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'gaming'),
|
||||
('f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'music'),
|
||||
('f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'coding'),
|
||||
('c9f5c328-04fe-4ec6-92af-6073df3af0b0', 'cars'),
|
||||
('c9f5c328-04fe-4ec6-92af-6073df3af0b0', 'cooking'),
|
||||
('34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'running'),
|
||||
('34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'reading'),
|
||||
('34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'charity'),
|
||||
('b8846d00-ed0d-4c46-8f36-56c392b9c803', 'research'),
|
||||
('b8846d00-ed0d-4c46-8f36-56c392b9c803', 'travel'),
|
||||
('b8846d00-ed0d-4c46-8f36-56c392b9c803', 'photography');
|
||||
|
||||
-- 8. 隐私设置
|
||||
|
||||
INSERT INTO user_privacy_settings (user_id, visible_in_recommendations, visible_in_search, show_occupation, show_lifestyle_photos, receive_activity_recommendations, accept_matchmaker_recommendations) VALUES
|
||||
|
||||
('c4541dae-c864-459e-b5db-3381867ffbd1', true, true, true, true, true, true),
|
||||
('f047dbe2-0202-4c57-aa12-1aed76253b62', true, true, true, false, true, true),
|
||||
('cdef6f94-f406-4f37-a5c1-319569fc4e69', true, false, true, true, true, false),
|
||||
('2db3db2d-ef0f-4f1e-8964-28be1566d1a9', true, true, false, true, true, true),
|
||||
('84431e32-c8f7-48d4-8e0e-fd14d86837e5', true, true, true, true, false, true),
|
||||
('bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', true, false, true, true, true, true),
|
||||
('fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', true, true, true, true, true, true),
|
||||
('205ddb91-56ef-4a8e-ade1-8cb35bb4affa', true, true, true, false, true, true),
|
||||
('f81778e0-ec9e-472e-b7f4-6773e8e3dc81', true, true, true, true, true, false),
|
||||
('c9f5c328-04fe-4ec6-92af-6073df3af0b0', true, false, true, true, true, true),
|
||||
('34fb0bd1-4703-4744-a4ae-35d5059f5d32', true, true, true, true, true, true),
|
||||
('b8846d00-ed0d-4c46-8f36-56c392b9c803', true, true, true, true, true, true);
|
||||
|
||||
-- 9. 照片
|
||||
|
||||
INSERT INTO user_photos (id, user_id, file_key, photo_type, sort_order, review_status) VALUES
|
||||
|
||||
('48ad218e-6776-4a71-aebd-a82c0e727b68', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'photos/demo/f01/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('1ce92025-554d-4f54-8d95-f469bcba6dc4', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'photos/demo/f01/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('c5e0ecd6-2aa3-488c-acf5-18f2a71879d5', 'f047dbe2-0202-4c57-aa12-1aed76253b62', 'photos/demo/f02/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('d63c7dfc-4280-4adb-a0fb-16bea69b804e', 'f047dbe2-0202-4c57-aa12-1aed76253b62', 'photos/demo/f02/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('6b6dfd9b-e5de-41a6-9d86-567149c87457', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'photos/demo/f03/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('e5a64a34-ce55-4f55-99d1-8399a94c0ca9', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'photos/demo/f03/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('2f7b7db2-bfbb-424c-ae23-246f0ef6e736', '2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 'photos/demo/f04/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('e6373dd7-2f65-40b3-8495-d39a6d85bc38', '2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 'photos/demo/f04/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('d06a1fab-a238-4026-a531-9ad0cd6d0964', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'photos/demo/f05/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('897dcb17-cbd1-477d-9d4f-48b9e1259f2f', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'photos/demo/f05/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('17c33ec0-f17c-4544-8a91-d2dae2261d7b', 'bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', 'photos/demo/f06/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('5076173d-d28e-4f0b-869f-b7b032fc44d8', 'bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', 'photos/demo/f06/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('527404ea-5110-45dd-9446-90eb7531b096', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'photos/demo/m01/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('5bb6b2b9-b398-49d6-ae42-5105ed0e485b', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'photos/demo/m01/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('d5ca9b88-6f82-4a4b-87ba-e2d40baa89e6', '205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'photos/demo/m02/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('17d5b522-6653-4d5c-a9b0-89d17357cbba', '205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'photos/demo/m02/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('036b1eec-b4c4-4596-815e-4500400835af', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'photos/demo/m03/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('4db14b12-26da-44a5-a901-e01cc6f7ced2', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'photos/demo/m03/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('42e0a447-9f30-401e-beda-9fe9fa31c1b9', 'c9f5c328-04fe-4ec6-92af-6073df3af0b0', 'photos/demo/m04/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('dffdc05a-3fa9-43f6-8624-fac879d8c99b', 'c9f5c328-04fe-4ec6-92af-6073df3af0b0', 'photos/demo/m04/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('684196ca-b76c-4028-94d1-dda8f2d167ff', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'photos/demo/m05/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('96afba03-b70b-4d2d-be25-13a94f8c9f5f', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'photos/demo/m05/lifestyle1.jpg', 'lifestyle', 1, 'approved'),
|
||||
('cd94a30d-a667-495f-8a89-575a906b37fa', 'b8846d00-ed0d-4c46-8f36-56c392b9c803', 'photos/demo/m06/avatar.jpg', 'avatar', 0, 'approved'),
|
||||
('c99f72ef-77e1-4785-a292-50d4499eae2b', 'b8846d00-ed0d-4c46-8f36-56c392b9c803', 'photos/demo/m06/lifestyle1.jpg', 'lifestyle', 1, 'approved');
|
||||
|
||||
-- 10. 审核任务
|
||||
|
||||
INSERT INTO review_tasks (id, user_id, review_type, status, assigned_operator_id, submitted_at, started_at, completed_at, final_comment, version) VALUES
|
||||
|
||||
('2a3d4499-444d-48c1-b648-05e97a195253', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'initial_profile', 'approved', 'e9312b05-c263-4901-8145-0b38e4d81c45', '2026-03-15T11:00:00Z', '2026-03-15T11:30:00Z', '2026-03-15T12:00:00Z', '资料完整', 1),
|
||||
('2f6fa325-3318-44e2-893f-0e148a200ce0', 'f047dbe2-0202-4c57-aa12-1aed76253b62', 'initial_profile', 'approved', 'e9312b05-c263-4901-8145-0b38e4d81c45', '2026-03-20T11:00:00Z', '2026-03-20T11:30:00Z', '2026-03-20T12:00:00Z', '资料完整', 1),
|
||||
('00ab8ee6-8a94-4d20-839f-d52a018afa19', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'initial_profile', 'approved', 'e9312b05-c263-4901-8145-0b38e4d81c45', '2026-04-01T11:00:00Z', '2026-04-01T11:30:00Z', '2026-04-01T12:00:00Z', '资料完整', 1),
|
||||
('e4043790-9aa1-4de8-8983-431bf277f8be', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'initial_profile', 'approved', 'e9312b05-c263-4901-8145-0b38e4d81c45', '2026-03-10T11:00:00Z', '2026-03-10T11:30:00Z', '2026-03-10T12:00:00Z', '资料完整', 1),
|
||||
('9befa465-201f-4aa6-bedf-2b22bbf3093d', '205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'initial_profile', 'approved', 'e9312b05-c263-4901-8145-0b38e4d81c45', '2026-03-25T11:00:00Z', '2026-03-25T11:30:00Z', '2026-03-25T12:00:00Z', '资料完整', 1),
|
||||
('2d653f28-a054-430e-b6f9-5e3cfe471e06', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'initial_profile', 'approved', 'e9312b05-c263-4901-8145-0b38e4d81c45', '2026-04-05T11:00:00Z', '2026-04-05T11:30:00Z', '2026-04-05T12:00:00Z', '资料完整', 1),
|
||||
('88477767-1aed-4490-8fa4-2591a8e498eb', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'initial_profile', 'approved', 'e9312b05-c263-4901-8145-0b38e4d81c45', '2026-05-01T11:00:00Z', '2026-05-01T11:30:00Z', '2026-05-01T12:00:00Z', '资料完整', 1);
|
||||
|
||||
-- 11. 用户关系
|
||||
|
||||
INSERT INTO user_relations (id, user_id, target_user_id, relation_type, created_at) VALUES
|
||||
|
||||
('bda459e2-dc16-4c08-8381-ebfe7eed2f37', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'liked', '2026-06-01T10:00:00Z'),
|
||||
('0fc82925-2b92-4c4e-a5a5-c4a8a987b2b2', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'liked', '2026-06-01T10:05:00Z'),
|
||||
('aaa0e94c-67d1-46d1-801e-23ad8d15336c', 'f047dbe2-0202-4c57-aa12-1aed76253b62', '205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'liked', '2026-06-02T14:00:00Z'),
|
||||
('3cb1c7c5-d00f-484e-abaf-e73e61197c48', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'liked', '2026-06-03T09:00:00Z'),
|
||||
('6d14800d-206c-48f0-bcbe-13294f2dace8', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'liked', '2026-06-03T09:30:00Z'),
|
||||
('6ebe4be5-9284-4a7f-9957-ef5a55bcf73e', 'c9f5c328-04fe-4ec6-92af-6073df3af0b0', 'f047dbe2-0202-4c57-aa12-1aed76253b62', 'liked', '2026-06-04T11:00:00Z'),
|
||||
('8f402a22-fb94-4714-af2b-51a9eae647b6', '2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 'c9f5c328-04fe-4ec6-92af-6073df3af0b0', 'passed', '2026-06-04T12:00:00Z'),
|
||||
('15528215-d21f-42c3-bd63-fdb118f376d3', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'liked', '2026-06-05T10:00:00Z'),
|
||||
('3c2b7e96-cf38-4c0c-899e-40eff50e0c5d', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'liked', '2026-06-05T10:05:00Z'),
|
||||
('15e580c3-3182-4131-a332-462d76626f9d', 'b8846d00-ed0d-4c46-8f36-56c392b9c803', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'liked', '2026-06-06T14:00:00Z'),
|
||||
('d279e35a-af73-45b4-847b-9e61c0f4e912', '2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 'b8846d00-ed0d-4c46-8f36-56c392b9c803', 'passed', '2026-06-06T15:00:00Z'),
|
||||
('0d038769-c289-4ca0-95e1-664485b1cdf1', 'bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', 'c9f5c328-04fe-4ec6-92af-6073df3af0b0', 'blocked', '2026-06-07T09:00:00Z'),
|
||||
('a93b823c-515f-4b2e-a42e-3038c0dd6bb8', '205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'passed', '2026-06-07T10:00:00Z');
|
||||
|
||||
-- 12. Match
|
||||
|
||||
INSERT INTO matches (id, user_a_id, user_b_id, status, source, matched_at) VALUES
|
||||
|
||||
('66dc8358-60a5-49d8-bdd2-fb191c6fe1ec', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'active', 'user_like', '2026-06-01T10:05:00Z'),
|
||||
|
||||
('e916d86e-5ed3-4ab7-b657-e5bbcf8d8649', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'active', 'user_like', '2026-06-03T09:30:00Z'),
|
||||
|
||||
('5b06ec2b-2ca7-4a11-811a-15b9e97a8a0c', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'successful', 'user_like', '2026-06-05T10:05:00Z');
|
||||
|
||||
-- 13. 成功牵手请求
|
||||
|
||||
INSERT INTO relationship_success_requests (id, match_id, initiated_by, status, confirmed_by, created_at, resolved_at) VALUES
|
||||
|
||||
('1d1b187e-bfec-4b5d-931a-165a543a0cce', '5b06ec2b-2ca7-4a11-811a-15b9e97a8a0c', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'confirmed', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', '2026-07-01T10:00:00Z', '2026-07-01T10:30:00Z'),
|
||||
|
||||
('a9c95cd2-953e-418a-8694-060f39f02d56', '66dc8358-60a5-49d8-bdd2-fb191c6fe1ec', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'pending', NULL, '2026-07-15T14:00:00Z', NULL);
|
||||
|
||||
-- 14. Conversations & Members
|
||||
|
||||
INSERT INTO conversations (id, match_id, status, last_message_at) VALUES
|
||||
|
||||
('d414d2ef-88a3-4ad1-a9e6-e4e133aa406f', '66dc8358-60a5-49d8-bdd2-fb191c6fe1ec', 'active', '2026-07-10T16:00:00Z'),
|
||||
|
||||
('376cb263-b4d5-4004-83cb-020136e27951', 'e916d86e-5ed3-4ab7-b657-e5bbcf8d8649', 'active', '2026-07-08T20:00:00Z'),
|
||||
|
||||
('f1166385-e9b3-456f-8853-36dcdf2d6585', '5b06ec2b-2ca7-4a11-811a-15b9e97a8a0c', 'active', '2026-07-01T18:00:00Z');
|
||||
|
||||
INSERT INTO conversation_members (conversation_id, user_id, unread_count, can_send, joined_at) VALUES
|
||||
|
||||
('d414d2ef-88a3-4ad1-a9e6-e4e133aa406f', 'c4541dae-c864-459e-b5db-3381867ffbd1', 0, true, '2026-06-01T10:05:00Z'),
|
||||
|
||||
('d414d2ef-88a3-4ad1-a9e6-e4e133aa406f', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 0, true, '2026-06-01T10:05:00Z'),
|
||||
|
||||
('376cb263-b4d5-4004-83cb-020136e27951', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 1, true, '2026-06-03T09:30:00Z'),
|
||||
|
||||
('376cb263-b4d5-4004-83cb-020136e27951', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 0, true, '2026-06-03T09:30:00Z'),
|
||||
|
||||
('f1166385-e9b3-456f-8853-36dcdf2d6585', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 0, true, '2026-06-05T10:05:00Z'),
|
||||
|
||||
('f1166385-e9b3-456f-8853-36dcdf2d6585', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 0, true, '2026-06-05T10:05:00Z');
|
||||
|
||||
INSERT INTO messages (id, conversation_id, sender_id, message_type, content, status, risk_level, created_at) VALUES
|
||||
|
||||
('1c18c46c-b0cb-44fd-9f6e-76aaff8f4c94', 'd414d2ef-88a3-4ad1-a9e6-e4e133aa406f', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'text', '你好!看到你的资料觉得挺合适的~', 'sent', 'normal', '2026-06-15T14:00:00Z'),
|
||||
('b334b8b9-d265-4616-9ad5-b492b84347a8', 'd414d2ef-88a3-4ad1-a9e6-e4e133aa406f', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'text', '你好!谢谢你的喜欢,我也觉得挺有缘的', 'sent', 'normal', '2026-06-15T14:05:00Z'),
|
||||
('bdf6f634-d923-413f-8e96-73cd596e4a6e', 'd414d2ef-88a3-4ad1-a9e6-e4e133aa406f', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'text', '你也在丹阳工作吗?平时喜欢做些什么?', 'sent', 'normal', '2026-06-15T14:10:00Z'),
|
||||
('512e7b14-e671-4cbb-b2e7-e3e90471d42f', '376cb263-b4d5-4004-83cb-020136e27951', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'text', '嗨,你好!很高兴认识你', 'sent', 'normal', '2026-07-05T19:30:00Z'),
|
||||
('e5bc8ec6-0edf-4c0d-998d-719460163dae', '376cb263-b4d5-4004-83cb-020136e27951', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'text', '你好呀!我平时喜欢拍照和跳舞,你呢?', 'sent', 'normal', '2026-07-05T19:35:00Z'),
|
||||
('b0067406-d65b-4347-b306-c86e99e06fa0', 'f1166385-e9b3-456f-8853-36dcdf2d6585', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'text', '你好,很高兴认识你!', 'sent', 'normal', '2026-06-10T10:00:00Z');
|
||||
|
||||
UPDATE conversations SET last_message_at = (SELECT MAX(created_at) FROM messages WHERE messages.conversation_id = conversations.id);
|
||||
|
||||
-- 15. 推荐记录
|
||||
|
||||
INSERT INTO recommendation_records (id, user_id, target_user_id, source, score, level, shown_at, action, action_at, rule_version) VALUES
|
||||
|
||||
('61c4c3c5-47d7-4992-ab99-da2ec12d2954', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'daily', 82.5, 'high', '2026-05-28T10:00:00Z', 'liked', '2026-06-01T10:00:00Z', 1),
|
||||
('246fc1b0-b892-4881-8a0c-1537a8fa267b', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'daily', 70.0, 'medium', '2026-05-28T10:00:00Z', 'passed', '2026-05-28T10:01:00Z', 1),
|
||||
('0763ff52-ed3d-453c-b801-df90992924b5', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'daily', 85.0, 'high', '2026-05-28T11:00:00Z', 'liked', '2026-06-01T10:05:00Z', 1),
|
||||
('d8004de7-ad32-4298-988e-1be9230e78b6', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'daily', 78.0, 'high', '2026-06-01T09:00:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
('9d9b26cf-4bf6-49e8-9a33-56d8d091e3c5', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'daily', 75.0, 'high', '2026-06-01T09:30:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
('4b3a63b1-3104-49b9-a3a2-10641d34bbf7', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'daily', 88.0, 'high', '2026-06-01T10:00:00Z', 'liked', '2026-06-05T10:00:00Z', 1),
|
||||
('1733c991-5d02-4f2b-b1cf-0531ee322508', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'daily', 86.0, 'high', '2026-06-01T10:30:00Z', 'liked', '2026-06-05T10:05:00Z', 1),
|
||||
('9316d0f2-c77c-4cd4-8308-a32d9513de89', 'b8846d00-ed0d-4c46-8f36-56c392b9c803', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'daily', 62.0, 'medium', '2026-06-06T14:00:00Z', 'liked', '2026-06-06T14:00:00Z', 1);
|
||||
|
||||
-- 16. 相亲活动
|
||||
|
||||
INSERT INTO activities (id, title, description, organizer_org_id, coorganizer_text, start_at, end_at, location_name, location_address, male_limit, female_limit, total_limit, min_age, max_age, registration_start_at, registration_end_at, need_review, status, created_by) VALUES
|
||||
|
||||
('ed89a418-c049-43cc-9cca-a71e403a451a', '丹阳公益单身联谊会(夏季场)', '面向丹阳市区及周边乡镇的单身青年,由妇联、工会联合主办。', 'c74863d4-be10-4efa-b22c-f3f84e2e4e59', '丹阳市总工会、丹阳市慈善基金会', '2026-08-15T14:00:00Z', '2026-08-15T17:30:00Z', '丹阳市文化馆多功能厅', '丹阳市丹北路168号', 15, 15, 30, 22, 40, '2026-07-01T00:00:00Z', '2026-08-10T23:59:59Z', true, 'registration_open', 'b4cdeb91-bbce-4587-be58-22ff55ef89da'),
|
||||
|
||||
('3fd86a27-605c-48ac-8f97-2bbb205f3a98', '七夕特别活动·丹阳缘来是你', '七夕节特别策划,浪漫主题相亲活动。', 'a35f0043-be09-4bdf-ad5d-05a72ff19c2a', '丹阳市新时代文明实践中心', '2026-08-29T15:00:00Z', '2026-08-29T18:00:00Z', '丹阳大剧院报告厅', '丹阳市书院路28号', 20, 20, 40, 25, 45, '2026-08-01T00:00:00Z', '2026-08-25T23:59:59Z', true, 'draft', 'b4cdeb91-bbce-4587-be58-22ff55ef89da');
|
||||
|
||||
-- 17. 活动报名
|
||||
|
||||
INSERT INTO activity_registrations (id, activity_id, user_id, status, registered_at, reviewed_by, reviewed_at, checkin_status) VALUES
|
||||
|
||||
('d094b282-21ab-4b79-9dfa-f5377a660473', 'ed89a418-c049-43cc-9cca-a71e403a451a', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'approved', '2026-07-05T10:00:00Z', 'b4cdeb91-bbce-4587-be58-22ff55ef89da', '2026-07-05T10:30:00Z', 'not_checked_in'),
|
||||
('b82c965d-2392-448e-9dc2-a6b7fc064346', 'ed89a418-c049-43cc-9cca-a71e403a451a', 'f047dbe2-0202-4c57-aa12-1aed76253b62', 'pending', '2026-07-12T10:00:00Z', NULL, NULL, 'not_checked_in'),
|
||||
('f4c7440e-76c2-4a41-b56d-ee4e7a6c48b4', 'ed89a418-c049-43cc-9cca-a71e403a451a', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'approved', '2026-07-06T14:00:00Z', 'b4cdeb91-bbce-4587-be58-22ff55ef89da', '2026-07-06T14:15:00Z', 'not_checked_in'),
|
||||
('7a5c3536-c2c9-4fc3-ab54-5ce8ee6a3e2b', 'ed89a418-c049-43cc-9cca-a71e403a451a', '2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 'rejected', '2026-07-13T09:00:00Z', 'b4cdeb91-bbce-4587-be58-22ff55ef89da', '2026-07-13T09:15:00Z', 'not_checked_in'),
|
||||
('ef981d5b-98ca-4a1b-b29f-c465a9f6d9e8', 'ed89a418-c049-43cc-9cca-a71e403a451a', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'approved', '2026-07-07T09:00:00Z', 'b4cdeb91-bbce-4587-be58-22ff55ef89da', '2026-07-07T09:20:00Z', 'not_checked_in'),
|
||||
('e3f8c9aa-54d6-401f-9135-75fdad8c5cc6', 'ed89a418-c049-43cc-9cca-a71e403a451a', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'approved', '2026-07-08T11:00:00Z', 'b4cdeb91-bbce-4587-be58-22ff55ef89da', '2026-07-08T11:10:00Z', 'not_checked_in'),
|
||||
('a2f14159-c7e0-442d-89af-f3bfc24a15c9', 'ed89a418-c049-43cc-9cca-a71e403a451a', '205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'approved', '2026-07-11T16:00:00Z', 'b4cdeb91-bbce-4587-be58-22ff55ef89da', '2026-07-11T16:30:00Z', 'not_checked_in'),
|
||||
('5a0ef97f-1c72-4c1d-a163-84f04a25f3ea', 'ed89a418-c049-43cc-9cca-a71e403a451a', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'approved', '2026-07-09T15:00:00Z', 'b4cdeb91-bbce-4587-be58-22ff55ef89da', '2026-07-09T15:20:00Z', 'not_checked_in'),
|
||||
('dd669f4a-2464-4f7f-b88a-a29cf5895791', 'ed89a418-c049-43cc-9cca-a71e403a451a', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'approved', '2026-07-10T08:30:00Z', 'b4cdeb91-bbce-4587-be58-22ff55ef89da', '2026-07-10T08:45:00Z', 'not_checked_in');
|
||||
|
||||
-- 18. 活动互选意向
|
||||
|
||||
INSERT INTO activity_interests (id, source_user_id, target_user_id, activity_id, status, confirmed_at, created_at) VALUES
|
||||
|
||||
('d16a150e-c4c4-4311-a1ce-840804ff4003', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'ed89a418-c049-43cc-9cca-a71e403a451a', 'mutual', '2026-08-15T17:00:00Z', '2026-08-15T17:00:00Z'),
|
||||
|
||||
('659f8441-ea7c-4fba-9d5a-557f10b02a03', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'ed89a418-c049-43cc-9cca-a71e403a451a', 'mutual', '2026-08-15T17:05:00Z', '2026-08-15T17:05:00Z'),
|
||||
|
||||
('a0f2cf79-d884-4584-8ee4-51772660e670', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'ed89a418-c049-43cc-9cca-a71e403a451a', 'expressed', '2026-08-15T17:10:00Z', '2026-08-15T17:10:00Z');
|
||||
|
||||
-- 19. 红娘服务
|
||||
|
||||
INSERT INTO matchmaker_services (id, user_id, service_type, description, status, organization_id, assigned_operator_id, assigned_at, completed_at) VALUES
|
||||
|
||||
('a85dc667-3d0c-4f0f-9eea-03dc213f9bec', 'f047dbe2-0202-4c57-aa12-1aed76253b62', 'recommend_partner', '离异用户希望找到合适的伴侣', 'in_service', 'c74863d4-be10-4efa-b22c-f3f84e2e4e59', 'a98c0d97-d272-4577-887e-5c05e27db19b', '2026-06-20T10:00:00Z', NULL),
|
||||
|
||||
('f0297c00-59cb-4f3e-ae86-c31fb4e55e6a', 'bc5ca4a9-08b5-413c-8d80-3afc76fbeb97', 'no_match_help', '丧偶用户希望重新融入社交', 'waiting_user', 'bcd9e5b6-3b66-454c-96d7-3fade6866135', 'a98c0d97-d272-4577-887e-5c05e27db19b', '2026-06-25T14:00:00Z', NULL),
|
||||
|
||||
('dd07da6e-d6b4-461c-be3c-2a0279c10c4a', '2db3db2d-ef0f-4f1e-8964-28be1566d1a9', 'review_preference', '用户希望调整择偶条件', 'completed', 'c74863d4-be10-4efa-b22c-f3f84e2e4e59', 'a98c0d97-d272-4577-887e-5c05e27db19b', '2026-06-15T09:00:00Z', '2026-06-20T11:00:00Z');
|
||||
|
||||
INSERT INTO matchmaker_recommendations (id, service_id, user_id, target_user_id, operator_id, reason, status, created_at, viewed_at, responded_at) VALUES
|
||||
|
||||
('e1c1cf64-24e5-4e6d-a02c-f11a154a0ccd', 'a85dc667-3d0c-4f0f-9eea-03dc213f9bec', 'f047dbe2-0202-4c57-aa12-1aed76253b62', '205ddb91-56ef-4a8e-ade1-8cb35bb4affa', 'a98c0d97-d272-4577-887e-5c05e27db19b', '两人同在丹阳工作,年龄相仿,都离过婚有共同语言', 'viewed', '2026-06-21T10:00:00Z', '2026-06-22T09:00:00Z', NULL);
|
||||
|
||||
INSERT INTO matchmaker_followups (id, service_id, operator_id, followup_type, content, result_code, next_followup_at, created_at) VALUES
|
||||
|
||||
('8cd728c6-8215-4941-994c-139d867efec9', 'a85dc667-3d0c-4f0f-9eea-03dc213f9bec', 'a98c0d97-d272-4577-887e-5c05e27db19b', 'phone_call', '电话沟通用户情况,了解离异原因及择偶期望', '正常', '2026-07-01T10:00:00Z', '2026-06-22T10:00:00Z'),
|
||||
|
||||
('1e952261-23aa-4a47-8de4-b906d7fb65e5', 'dd07da6e-d6b4-461c-be3c-2a0279c10c4a', 'a98c0d97-d272-4577-887e-5c05e27db19b', 'face_to_face', '面对面交流,帮助用户调整身高要求从170改为168', '已调整', NULL, '2026-06-18T15:00:00Z');
|
||||
|
||||
-- 20. 系统通知
|
||||
|
||||
INSERT INTO notifications (id, user_id, type, title, content, business_type, read_status, created_at) VALUES
|
||||
|
||||
('7ce61e30-5dae-464c-a597-5c5b0897889c', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'match', '你们互相喜欢!', '张伟也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-01T10:05:00Z'),
|
||||
('8f237f69-b647-4055-98fe-0b391d3997ac', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'match', '你们互相喜欢!', '小芳也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-01T10:05:00Z'),
|
||||
('866d0a81-366f-41fa-a8f4-12b0e0263a69', 'cdef6f94-f406-4f37-a5c1-319569fc4e69', 'match', '你们互相喜欢!', '王磊也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-03T09:30:00Z'),
|
||||
('892484ed-69c0-45bb-9581-18b74cea65be', 'f81778e0-ec9e-472e-b7f4-6773e8e3dc81', 'match', '你们互相喜欢!', '婷婷也喜欢了你,可以开始聊天啦~', 'match', 'unread', '2026-06-03T09:30:00Z'),
|
||||
('cff60e91-2b3b-4969-b84e-f61c7f4f1a32', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'match', '你们互相喜欢!', '孙浩也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-05T10:05:00Z'),
|
||||
('4365fe9f-ac11-4039-9d73-f5a0cb0aa782', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'match', '你们互相喜欢!', '慧琴也喜欢了你,可以开始聊天啦~', 'match', 'read', '2026-06-05T10:05:00Z'),
|
||||
('a5ca22bf-c269-4840-a7f3-79df800a9dfd', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'system', '恭喜牵手成功!', '您与孙浩已成功牵手,祝你们幸福!', 'match', 'read', '2026-07-01T10:30:00Z'),
|
||||
('7439e900-c532-4d23-a231-9fd0ef967387', '34fb0bd1-4703-4744-a4ae-35d5059f5d32', 'system', '恭喜牵手成功!', '您与慧琴已成功牵手,祝你们幸福!', 'match', 'read', '2026-07-01T10:30:00Z'),
|
||||
('c5e0d1b1-b840-4d64-9c5b-f4ccbd466a90', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'activity', '活动报名已确认', '您已成功报名「丹阳公益单身联谊会」', 'activity', 'read', '2026-07-05T10:30:00Z'),
|
||||
('b1bac483-1813-4196-b19a-b49f8fdabbfb', '84431e32-c8f7-48d4-8e0e-fd14d86837e5', 'activity', '活动报名已确认', '您已成功报名「丹阳公益单身联谊会」', 'activity', 'unread', '2026-07-07T09:20:00Z'),
|
||||
('f0ec9306-5764-4980-850c-6c9cb09f2771', 'f047dbe2-0202-4c57-aa12-1aed76253b62', 'matchmaker', '红娘已为您服务', '您的红娘服务申请已被分配,红娘小王将在24小时内与您联系', 'matchmaker', 'read', '2026-06-20T10:30:00Z');
|
||||
|
||||
-- 21. 同意记录
|
||||
|
||||
INSERT INTO consent_records (id, user_id, type, version, agreed_at, ip_address, user_agent) VALUES
|
||||
|
||||
('36f6a591-6cf0-4ca1-b146-c52c9706d463', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'terms_of_service', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
|
||||
('e7c45af8-5a56-4f46-bd8e-04b7a779b7a6', 'c4541dae-c864-459e-b5db-3381867ffbd1', 'privacy_policy', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
|
||||
('c479dc80-f0d8-4988-8f89-d1f833de64c5', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'terms_of_service', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
|
||||
('d344037f-b275-49fb-990f-0d7f4bda9291', 'fc27c8c4-7e7e-40b3-8e2e-0e9f0c0d73c7', 'privacy_policy', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0');
|
||||
|
||||
-- 22. 审核原因字典
|
||||
|
||||
INSERT INTO review_reasons (code, name, category, enabled, sort_order) VALUES
|
||||
|
||||
('profile_incomplete', '资料不完整', 'quality', true, 1),
|
||||
|
||||
('photo_unclear', '照片不清晰', 'quality', true, 2),
|
||||
|
||||
('fake_info', '信息疑似虚假', 'trust', true, 3),
|
||||
|
||||
('inappropriate_photo', '照片内容不当', 'safety', true, 4),
|
||||
|
||||
('duplicate_identity', '重复注册', 'duplicate', true, 5),
|
||||
|
||||
('suspicious_behavior', '行为异常', 'risk', true, 6),
|
||||
|
||||
('manual_review_needed', '需人工复核', 'quality', true, 7);
|
||||
|
||||
SET session_replication_role = 'origin';
|
||||
|
||||
DO $$ DECLARE u_cnt INTEGER; op_cnt INTEGER; m_cnt INTEGER; a_cnt INTEGER; p_cnt INTEGER;
|
||||
|
||||
BEGIN SELECT COUNT(*) INTO u_cnt FROM users WHERE deleted_at IS NULL;
|
||||
|
||||
SELECT COUNT(*) INTO op_cnt FROM operators; SELECT COUNT(*) INTO m_cnt FROM matches;
|
||||
|
||||
SELECT COUNT(*) INTO a_cnt FROM activities WHERE deleted_at IS NULL;
|
||||
|
||||
SELECT COUNT(*) INTO p_cnt FROM user_profiles;
|
||||
|
||||
RAISE NOTICE '========================================';
|
||||
|
||||
RAISE NOTICE 'Demo 数据填充完成!';
|
||||
|
||||
RAISE NOTICE ' 用户: %人 | 资料: %条 | 操作员: %人', u_cnt, p_cnt, op_cnt;
|
||||
|
||||
RAISE NOTICE ' Match: %对 | 活动: %个', m_cnt, a_cnt;
|
||||
|
||||
RAISE NOTICE '========================================';
|
||||
|
||||
END $$;
|
||||
@@ -0,0 +1,419 @@
|
||||
-- ============================================================
|
||||
-- 丹阳公益婚恋服务平台 — Demo Seed 数据脚本
|
||||
-- 版本: 1.0.0-RC.2
|
||||
-- 说明: 生成演示用数据,含组织、工作人员、用户、活动、聊天等
|
||||
-- 执行方式: psql -d danyang_match -f backend/src/main/resources/db/demo-seed.sql
|
||||
-- ============================================================
|
||||
|
||||
-- 禁用外键检查,允许乱序插入
|
||||
SET session_replication_role = 'replica';
|
||||
|
||||
-- ============================================================
|
||||
-- 1. 组织(organizations)
|
||||
-- ============================================================
|
||||
INSERT INTO organizations (id, name, type, contact_name, status) VALUES
|
||||
('org-danyang-women', '丹阳市妇女联合会', 'women_federation', '张丽华', 'active'),
|
||||
('org-danyang-trade', '丹阳市总工会', 'trade_union', '李明远', 'active'),
|
||||
('org-danyang-charity', '丹阳市慈善基金会', 'charity_center', '王秀英', 'active');
|
||||
|
||||
-- ============================================================
|
||||
-- 2. 工作人员(operators)— 密码均为 BCrypt hash of "demo123"
|
||||
-- ============================================================
|
||||
INSERT INTO operators (id, organization_id, name, username, password_hash, status) VALUES
|
||||
('op-admin-001', 'org-danyang-women', '陈主任', 'admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
('op-mh001', 'org-danyang-women', '红娘小王', 'wanghongniang', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
('op-rv001', 'org-danyang-charity', '审核员小张', 'reviewer01', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active'),
|
||||
('op-act01', 'org-danyang-trade', '活动管理员赵', 'activitymgr', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHdBfKYuPIiCTB6MJJDEaK', 'active');
|
||||
|
||||
-- 操作员角色绑定
|
||||
INSERT INTO operator_roles (operator_id, role_id) VALUES
|
||||
('op-admin-001', '00000000-0000-0000-0000-000000000001'),
|
||||
('op-admin-001', '00000000-0000-0000-0000-000000000002'),
|
||||
('op-mh001', '00000000-0000-0000-0000-000000000005'),
|
||||
('op-mh001', '00000000-0000-0000-0000-000000000006'),
|
||||
('op-rv001', '00000000-0000-0000-0000-000000000004'),
|
||||
('op-rv001', '00000000-0000-0000-0000-000000000007'),
|
||||
('op-act01', '00000000-0000-0000-0000-000000000006'),
|
||||
('op-act01', '00000000-0000-0000-0000-000000000008');
|
||||
|
||||
-- ============================================================
|
||||
-- 3. Demo 用户 — 12人(6男6女)
|
||||
-- ============================================================
|
||||
INSERT INTO users (id, wechat_openid, phone, account_status, relationship_status, recommendation_enabled, created_at) VALUES
|
||||
('user-f01', 'demo_openid_f01', NULL, 'normal', 'searching', true, '2026-03-15T10:00:00Z'),
|
||||
('user-f02', 'demo_openid_f02', NULL, 'normal', 'searching', true, '2026-03-20T14:30:00Z'),
|
||||
('user-f03', 'demo_openid_f03', NULL, 'normal', 'searching', true, '2026-04-01T09:15:00Z'),
|
||||
('user-f04', 'demo_openid_f04', NULL, 'normal', 'paused', true, '2026-04-10T16:00:00Z'),
|
||||
('user-f05', 'demo_openid_f05', NULL, 'normal', 'searching', true, '2026-05-01T11:20:00Z'),
|
||||
('user-f06', 'demo_openid_f06', NULL, 'normal', 'searching', true, '2026-05-15T08:45:00Z'),
|
||||
('user-m01', 'demo_openid_m01', NULL, 'normal', 'searching', true, '2026-03-10T09:00:00Z'),
|
||||
('user-m02', 'demo_openid_m02', NULL, 'normal', 'getting_to_know', true, '2026-03-25T13:00:00Z'),
|
||||
('user-m03', 'demo_openid_m03', NULL, 'normal', 'searching', true, '2026-04-05T15:30:00Z'),
|
||||
('user-m04', 'demo_openid_m04', NULL, 'normal', 'searching', true, '2026-04-20T10:00:00Z'),
|
||||
('user-m05', 'demo_openid_m05', NULL, 'normal', 'matched_successfully', true, '2026-05-01T14:00:00Z'),
|
||||
('user-m06', 'demo_openid_m06', NULL, 'normal', 'searching', true, '2026-05-10T16:30:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 4. 用户资料(user_profiles)
|
||||
-- ============================================================
|
||||
INSERT INTO user_profiles (
|
||||
user_id, display_name, gender, birth_date, height_cm,
|
||||
region_code, region_name, marital_status, children_status,
|
||||
education_code, occupation_code, smoking_status, drinking_status,
|
||||
long_term_danyang, future_danyang, relationship_goal, profile_completion, profile_status
|
||||
) VALUES
|
||||
('user-f01', '小芳', 'female', '1995-06-15', 162, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'clerical', 'never', 'sometimes', '是', '是', '结婚', 90, 'approved'),
|
||||
('user-f02', '晓燕', 'female', '1993-09-20', 165, '321181', '丹阳', 'divorced', 'none', 'college', 'teacher', 'never', 'never', '是', '是', '结婚', 95, 'approved'),
|
||||
('user-f03', '婷婷', 'female', '1998-02-10', 158, '321100', '镇江', 'never_married', 'none', 'master', 'designer', 'sometimes', 'often', '是', '否', '恋爱', 85, 'approved'),
|
||||
('user-f04', '美玲', 'female', '1990-11-05', 160, '321181', '丹阳', 'never_married', 'none', 'senior_high', 'factory', 'never', 'never', '是', '是', '结婚', 70, 'approved'),
|
||||
('user-f05', '慧琴', 'female', '1996-07-22', 163, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'nurse', 'never', 'sometimes','是', '是', '结婚', 92, 'approved'),
|
||||
('user-f06', '秀英', 'female', '1992-04-18', 157, '321181', '丹阳', 'widowed', 'none', 'junior_high','farmer', 'often', 'often', '是', '是', '结婚', 60, 'approved'),
|
||||
('user-m01', '张伟', 'male', '1992-01-10', 175, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'engineer', 'never', 'sometimes','是', '是', '结婚', 88, 'approved'),
|
||||
('user-m02', '李强', 'male', '1990-08-25', 178, '321181', '丹阳', 'divorced', 'none', 'master', 'manager', 'sometimes', 'often', '是', '是', '结婚', 95, 'approved'),
|
||||
('user-m03', '王磊', 'male', '1997-12-03', 180, '321100', '镇江', 'never_married', 'none', 'college', 'programmer', 'never', 'never', '是', '是', '恋爱', 82, 'approved'),
|
||||
('user-m04', '赵明', 'male', '1988-05-30', 172, '321181', '丹阳', 'never_married', 'none', 'senior_high','sales', 'often', 'often', '否', '是', '结婚', 75, 'approved'),
|
||||
('user-m05', '孙浩', 'male', '1994-03-14', 182, '321181', '丹阳', 'never_married', 'none', 'bachelor', 'doctor', 'never', 'sometimes','是', '是', '结婚', 97, 'approved'),
|
||||
('user-m06', '周洋', 'male', '1999-08-08', 176, '320500', '苏州', 'never_married', 'none', 'master', 'researcher', 'never', 'never', '是', '否', '恋爱', 80, 'approved');
|
||||
|
||||
-- ============================================================
|
||||
-- 5. 用户择偶偏好(user_preferences)
|
||||
-- ============================================================
|
||||
INSERT INTO user_preferences (
|
||||
user_id, min_age, max_age, age_priority,
|
||||
min_height_cm, max_height_cm, height_priority,
|
||||
region_scope, region_priority,
|
||||
marital_statuses, marital_priority,
|
||||
min_education_code, education_priority
|
||||
) VALUES
|
||||
('user-f01', 28, 38, 'required', 170, 185, 'required',
|
||||
'["321181","321100"]', 'required', '["never_married"]', 'required', 'bachelor', 'preferred'),
|
||||
('user-f02', 28, 40, 'required', 170, 188, 'required',
|
||||
'["321181"]', 'required', '["never_married","divorced"]', 'preferred', 'college', 'preferred'),
|
||||
('user-f03', 25, 35, 'preferred', 172, 185, 'preferred',
|
||||
'["321181","321100","320500"]', 'preferred', '["never_married"]', 'required', NULL, NULL),
|
||||
('user-f04', 30, 45, 'required', 168, 185, 'required',
|
||||
'["321181"]', 'required', '["never_married","divorced"]', 'preferred', 'senior_high', 'preferred'),
|
||||
('user-f05', 27, 36, 'required', 172, 186, 'required',
|
||||
'["321181","321100"]', 'preferred', '["never_married"]', 'required', 'bachelor', 'preferred'),
|
||||
('user-f06', 30, 50, 'required', 165, 185, 'required',
|
||||
'["321181"]', 'required', '["never_married","divorced","widowed"]', 'preferred', NULL, NULL),
|
||||
('user-m01', 22, 32, 'required', 155, 170, 'preferred',
|
||||
'["321181","321100"]', 'required', '["never_married"]', 'required', 'junior_high', 'preferred'),
|
||||
('user-m02', 25, 38, 'preferred', 158, 172, 'preferred',
|
||||
'["321181"]', 'preferred', '["never_married","divorced"]', 'preferred', 'college', 'preferred'),
|
||||
('user-m03', 22, 30, 'preferred', 155, 168, 'preferred',
|
||||
'["321181","321100","320500"]', 'preferred', '["never_married"]', 'required', 'college', 'preferred'),
|
||||
('user-m04', 25, 40, 'preferred', 155, 170, 'preferred',
|
||||
'["321181"]', 'required', '["never_married","divorced"]', 'preferred', NULL, NULL),
|
||||
('user-m05', 23, 33, 'required', 158, 170, 'preferred',
|
||||
'["321181","321100"]', 'preferred', '["never_married"]', 'required', 'bachelor', 'preferred'),
|
||||
('user-m06', 22, 32, 'preferred', 155, 170, 'preferred',
|
||||
'["321181","321100","320500"]', 'preferred', '["never_married"]', 'required', 'master', 'preferred');
|
||||
|
||||
-- ============================================================
|
||||
-- 6. 实名认证(user_identities)— mock
|
||||
-- ============================================================
|
||||
INSERT INTO user_identities (
|
||||
user_id, real_name_enc, id_number_enc, id_number_hash,
|
||||
gender, birth_date, verification_status, provider, verified_at
|
||||
) VALUES
|
||||
('user-f01', E'\\xencrypted_f01', E'\\xencrypted_f01_id', 'sha256_f01', 'female', '1995-06-15', 'verified', 'mock', '2026-03-16T10:00:00Z'),
|
||||
('user-f02', E'\\xencrypted_f02', E'\\xencrypted_f02_id', 'sha256_f02', 'female', '1993-09-20', 'verified', 'mock', '2026-03-21T14:30:00Z'),
|
||||
('user-f03', E'\\xencrypted_f03', E'\\xencrypted_f03_id', 'sha256_f03', 'female', '1998-02-10', 'verified', 'mock', '2026-04-02T09:15:00Z'),
|
||||
('user-f04', E'\\xencrypted_f04', E'\\xencrypted_f04_id', 'sha256_f04', 'female', '1990-11-05', 'verified', 'mock', '2026-04-11T16:00:00Z'),
|
||||
('user-f05', E'\\xencrypted_f05', E'\\xencrypted_f05_id', 'sha256_f05', 'female', '1996-07-22', 'verified', 'mock', '2026-05-02T11:20:00Z'),
|
||||
('user-f06', E'\\xencrypted_f06', E'\\xencrypted_f06_id', 'sha256_f06', 'female', '1992-04-18', 'verified', 'mock', '2026-05-16T08:45:00Z'),
|
||||
('user-m01', E'\\xencrypted_m01', E'\\xencrypted_m01_id', 'sha256_m01', 'male', '1992-01-10', 'verified', 'mock', '2026-03-11T09:00:00Z'),
|
||||
('user-m02', E'\\xencrypted_m02', E'\\xencrypted_m02_id', 'sha256_m02', 'male', '1990-08-25', 'verified', 'mock', '2026-03-26T13:00:00Z'),
|
||||
('user-m03', E'\\xencrypted_m03', E'\\xencrypted_m03_id', 'sha256_m03', 'male', '1997-12-03', 'verified', 'mock', '2026-04-06T15:30:00Z'),
|
||||
('user-m04', E'\\xencrypted_m04', E'\\xencrypted_m04_id', 'sha256_m04', 'male', '1988-05-30', 'verified', 'mock', '2026-04-21T10:00:00Z'),
|
||||
('user-m05', E'\\xencrypted_m05', E'\\xencrypted_m05_id', 'sha256_m05', 'male', '1994-03-14', 'verified', 'mock', '2026-05-02T14:00:00Z'),
|
||||
('user-m06', E'\\xencrypted_m06', E'\\xencrypted_m06_id', 'sha256_m06', 'male', '1999-08-08', 'verified', 'mock', '2026-05-11T16:30:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 7. 兴趣标签(user_interests)
|
||||
-- ============================================================
|
||||
INSERT INTO user_interests (user_id, interest_code) VALUES
|
||||
('user-f01', 'reading'), ('user-f01', 'cooking'), ('user-f01', 'travel'),
|
||||
('user-f02', 'sports'), ('user-f02', 'music'), ('user-f02', 'outdoor'),
|
||||
('user-f03', 'photography'), ('user-f03', 'dance'), ('user-f03', 'movie'),
|
||||
('user-f04', 'pets'), ('user-f04', 'cooking'),
|
||||
('user-f05', 'reading'), ('user-f05', 'fitness'), ('user-f05', 'charity'),
|
||||
('user-f06', 'gardening'), ('user-f06', 'cooking'),
|
||||
('user-m01', 'sports'), ('user-m01', 'gaming'), ('user-m01', 'travel'),
|
||||
('user-m02', 'reading'), ('user-m02', 'investment'), ('user-m02', 'hiking'),
|
||||
('user-m03', 'gaming'), ('user-m03', 'music'), ('user-m03', 'coding'),
|
||||
('user-m04', 'cars'), ('user-m04', 'cooking'),
|
||||
('user-m05', 'running'), ('user-m05', 'reading'), ('user-m05', 'charity'),
|
||||
('user-m06', 'research'), ('user-m06', 'travel'), ('user-m06', 'photography');
|
||||
|
||||
-- ============================================================
|
||||
-- 8. 隐私设置(user_privacy_settings)
|
||||
-- ============================================================
|
||||
INSERT INTO user_privacy_settings (
|
||||
user_id, visible_in_recommendations, visible_in_search,
|
||||
show_occupation, show_lifestyle_photos,
|
||||
receive_activity_recommendations, accept_matchmaker_recommendations
|
||||
) VALUES
|
||||
('user-f01', true, true, true, true, true, true),
|
||||
('user-f02', true, true, true, false, true, true),
|
||||
('user-f03', true, false, true, true, true, false),
|
||||
('user-f04', true, true, false, true, true, true),
|
||||
('user-f05', true, true, true, true, false,true),
|
||||
('user-f06', true, false, true, true, true, true),
|
||||
('user-m01', true, true, true, true, true, true),
|
||||
('user-m02', true, true, true, false, true, true),
|
||||
('user-m03', true, true, true, true, true, false),
|
||||
('user-m04', true, false, true, true, true, true),
|
||||
('user-m05', true, true, true, true, true, true),
|
||||
('user-m06', true, true, true, true, true, true);
|
||||
|
||||
-- ============================================================
|
||||
-- 9. 照片(user_photos)
|
||||
-- ============================================================
|
||||
INSERT INTO user_photos (id, user_id, file_key, photo_type, sort_order, review_status) VALUES
|
||||
('photo-f01-a', 'user-f01', 'photos/user-f01/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-f01-l1','user-f01', 'photos/user-f01/lifestyle/001.jpg','lifestyle',1, 'approved'),
|
||||
('photo-f01-l2','user-f01', 'photos/user-f01/lifestyle/002.jpg','lifestyle',2, 'approved'),
|
||||
('photo-f02-a', 'user-f02', 'photos/user-f02/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-f02-l1','user-f02', 'photos/user-f02/lifestyle/001.jpg','lifestyle',1, 'approved'),
|
||||
('photo-f03-a', 'user-f03', 'photos/user-f03/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-f03-l1','user-f03', 'photos/user-f03/lifestyle/001.jpg','lifestyle',1, 'approved'),
|
||||
('photo-f03-l2','user-f03', 'photos/user-f03/lifestyle/002.jpg','lifestyle',2, 'approved'),
|
||||
('photo-f04-a', 'user-f04', 'photos/user-f04/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-f05-a', 'user-f05', 'photos/user-f05/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-f05-l1','user-f05', 'photos/user-f05/lifestyle/001.jpg','lifestyle',1, 'approved'),
|
||||
('photo-f06-a', 'user-f06', 'photos/user-f06/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-m01-a', 'user-m01', 'photos/user-m01/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-m01-l1','user-m01', 'photos/user-m01/lifestyle/001.jpg','lifestyle',1, 'approved'),
|
||||
('photo-m01-l2','user-m01', 'photos/user-m01/lifestyle/002.jpg','lifestyle',2, 'approved'),
|
||||
('photo-m02-a', 'user-m02', 'photos/user-m02/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-m02-l1','user-m02', 'photos/user-m02/lifestyle/001.jpg','lifestyle',1, 'approved'),
|
||||
('photo-m03-a', 'user-m03', 'photos/user-m03/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-m03-l1','user-m03', 'photos/user-m03/lifestyle/001.jpg','lifestyle',1, 'approved'),
|
||||
('photo-m04-a', 'user-m04', 'photos/user-m04/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-m05-a', 'user-m05', 'photos/user-m05/avatar/001.jpg', 'avatar', 0, 'approved'),
|
||||
('photo-m05-l1','user-m05', 'photos/user-m05/lifestyle/001.jpg','lifestyle',1, 'approved'),
|
||||
('photo-m05-l2','user-m05', 'photos/user-m05/lifestyle/002.jpg','lifestyle',2, 'approved'),
|
||||
('photo-m06-a', 'user-m06', 'photos/user-m06/avatar/001.jpg', 'avatar', 0, 'approved');
|
||||
|
||||
-- ============================================================
|
||||
-- 10. 审核任务(review_tasks)
|
||||
-- ============================================================
|
||||
INSERT INTO review_tasks (id, user_id, review_type, status, assigned_operator_id, submitted_at, started_at, completed_at, final_comment, version) VALUES
|
||||
('rt-f01', 'user-f01', 'initial_profile', 'approved', 'op-rv001', '2026-03-15T11:00:00Z', '2026-03-15T11:30:00Z', '2026-03-15T12:00:00Z', '资料完整,信息真实', 1),
|
||||
('rt-f02', 'user-f02', 'initial_profile', 'approved', 'op-rv001', '2026-03-20T15:00:00Z', '2026-03-20T15:30:00Z', '2026-03-20T16:00:00Z', '资料完整', 1),
|
||||
('rt-f03', 'user-f03', 'initial_profile', 'approved', 'op-rv001', '2026-04-01T10:00:00Z', '2026-04-01T10:30:00Z', '2026-04-01T11:00:00Z', '资料完整', 1),
|
||||
('rt-m01', 'user-m01', 'initial_profile', 'approved', 'op-rv001', '2026-03-10T10:00:00Z', '2026-03-10T10:30:00Z', '2026-03-10T11:00:00Z', '资料完整', 1),
|
||||
('rt-m02', 'user-m02', 'initial_profile', 'approved', 'op-rv001', '2026-03-25T14:00:00Z', '2026-03-25T14:30:00Z', '2026-03-25T15:00:00Z', '资料完整', 1),
|
||||
('rt-m03', 'user-m03', 'initial_profile', 'approved', 'op-rv001', '2026-04-05T16:00:00Z', '2026-04-05T16:30:00Z', '2026-04-05T17:00:00Z', '资料完整', 1),
|
||||
('rt-m05', 'user-m05', 'initial_profile', 'approved', 'op-rv001', '2026-05-01T15:00:00Z', '2026-05-01T15:30:00Z', '2026-05-01T16:00:00Z', '资料完整', 1);
|
||||
|
||||
-- ============================================================
|
||||
-- 11. 用户关系(user_relations)
|
||||
-- ============================================================
|
||||
INSERT INTO user_relations (id, user_id, target_user_id, relation_type, created_at) VALUES
|
||||
('rel-f01-m01-a', 'user-f01', 'user-m01', 'liked', '2026-06-01T10:00:00Z'),
|
||||
('rel-f01-m01-b', 'user-m01', 'user-f01', 'liked', '2026-06-01T10:05:00Z'),
|
||||
('rel-f02-m02', 'user-f02', 'user-m02', 'liked', '2026-06-02T14:00:00Z'),
|
||||
('rel-f03-m03', 'user-f03', 'user-m03', 'liked', '2026-06-03T09:00:00Z'),
|
||||
('rel-m03-f03', 'user-m03', 'user-f03', 'liked', '2026-06-03T09:30:00Z'),
|
||||
('rel-m04-f02', 'user-m04', 'user-f02', 'liked', '2026-06-04T11:00:00Z'),
|
||||
('rel-f04-m04', 'user-f04', 'user-m04', 'passed', '2026-06-04T12:00:00Z'),
|
||||
('rel-f05-m05', 'user-f05', 'user-m05', 'liked', '2026-06-05T10:00:00Z'),
|
||||
('rel-f05-m05-b', 'user-m05', 'user-f05', 'liked', '2026-06-05T10:05:00Z'),
|
||||
('rel-m06-f01', 'user-m06', 'user-f01', 'liked', '2026-06-06T14:00:00Z'),
|
||||
('rel-f04-m06', 'user-f04', 'user-m06', 'passed', '2026-06-06T15:00:00Z'),
|
||||
('rel-f06-m04', 'user-f06', 'user-m04', 'blocked', '2026-06-07T09:00:00Z'),
|
||||
('rel-m02-f03', 'user-m02', 'user-f03', 'passed', '2026-06-07T10:00:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 12. Match(双向匹配)
|
||||
-- ============================================================
|
||||
INSERT INTO matches (id, user_a_id, user_b_id, status, source, matched_at) VALUES
|
||||
('match-f01-m01', 'user-f01', 'user-m01', 'active', 'user_like', '2026-06-01T10:05:00Z'),
|
||||
('match-f03-m03', 'user-f03', 'user-m03', 'active', 'user_like', '2026-06-03T09:30:00Z'),
|
||||
('match-f05-m05', 'user-f05', 'user-m05', 'successful', 'user_like', '2026-06-05T10:05:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 13. 成功牵手请求(relationship_success_requests)
|
||||
-- ============================================================
|
||||
INSERT INTO relationship_success_requests (id, match_id, initiated_by, status, confirmed_by, created_at, resolved_at) VALUES
|
||||
('rsr-f05-m05', 'match-f05-m05', 'user-f05', 'confirmed', 'user-m05', '2026-07-01T10:00:00Z', '2026-07-01T10:30:00Z'),
|
||||
('rsr-f01-m01', 'match-f01-m01', 'user-f01', 'pending', NULL, '2026-07-15T14:00:00Z', NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 14. Conversations & Messages
|
||||
-- ============================================================
|
||||
INSERT INTO conversations (id, match_id, status, last_message_id, last_message_at) VALUES
|
||||
('conv-f01-m01', 'match-f01-m01', 'active', 'msg-f01-m01-3', '2026-07-10T16:00:00Z'),
|
||||
('conv-f03-m03', 'match-f03-m03', 'active', 'msg-f03-m03-2', '2026-07-08T20:00:00Z'),
|
||||
('conv-f05-m05', 'match-f05-m05', 'active', 'msg-f05-m05-1', '2026-07-01T18:00:00Z');
|
||||
|
||||
INSERT INTO conversation_members (conversation_id, user_id, last_read_message_id, unread_count, can_send, joined_at) VALUES
|
||||
('conv-f01-m01', 'user-f01', 'msg-f01-m01-3', 0, true, '2026-06-01T10:05:00Z'),
|
||||
('conv-f01-m01', 'user-m01', 'msg-f01-m01-3', 0, true, '2026-06-01T10:05:00Z'),
|
||||
('conv-f03-m03', 'user-f03', 'msg-f03-m03-2', 1, true, '2026-06-03T09:30:00Z'),
|
||||
('conv-f03-m03', 'user-m03', 'msg-f03-m03-2', 0, true, '2026-06-03T09:30:00Z'),
|
||||
('conv-f05-m05', 'user-f05', 'msg-f05-m05-1', 0, true, '2026-06-05T10:05:00Z'),
|
||||
('conv-f05-m05', 'user-m05', 'msg-f05-m05-1', 0, true, '2026-06-05T10:05:00Z');
|
||||
|
||||
INSERT INTO messages (id, conversation_id, sender_id, message_type, content, status, risk_level, created_at) VALUES
|
||||
('msg-f01-m01-1', 'conv-f01-m01', 'user-f01', 'text', '你好!看到你的资料觉得挺合适的~', 'sent', 'normal', '2026-06-15T14:00:00Z'),
|
||||
('msg-f01-m01-2', 'conv-f01-m01', 'user-m01', 'text', '你好!谢谢你的喜欢,我也觉得挺有缘的', 'sent', 'normal', '2026-06-15T14:05:00Z'),
|
||||
('msg-f01-m01-3', 'conv-f01-m01', 'user-f01', 'text', '你也在丹阳工作吗?平时喜欢做些什么?', 'sent', 'normal', '2026-06-15T14:10:00Z'),
|
||||
('msg-f03-m03-1', 'conv-f03-m03', 'user-m03', 'text', '嗨,你好!很高兴认识你', 'sent', 'normal', '2026-07-05T19:30:00Z'),
|
||||
('msg-f03-m03-2', 'conv-f03-m03', 'user-f03', 'text', '你好呀!我平时喜欢拍照和跳舞,你呢?', 'sent', 'normal', '2026-07-05T19:35:00Z'),
|
||||
('msg-f05-m05-1', 'conv-f05-m05', 'user-m05', 'text', '你好,很高兴认识你!', 'sent', 'normal', '2026-06-10T10:00:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 15. 推荐记录(recommendation_records)
|
||||
-- ============================================================
|
||||
INSERT INTO recommendation_records (id, user_id, target_user_id, source, score, level, shown_at, action, action_at, rule_version) VALUES
|
||||
('rec-f01-m01', 'user-f01', 'user-m01', 'daily', 82.50, 'high', '2026-05-28T10:00:00Z', 'liked', '2026-06-01T10:00:00Z', 1),
|
||||
('rec-f01-m03', 'user-f01', 'user-m03', 'daily', 70.00, 'medium', '2026-05-28T10:00:00Z', 'passed','2026-05-28T10:01:00Z', 1),
|
||||
('rec-f01-m02', 'user-f01', 'user-m02', 'daily', 65.00, 'medium', '2026-05-28T10:00:00Z', 'passed','2026-05-28T10:02:00Z', 1),
|
||||
('rec-m01-f01', 'user-m01', 'user-f01', 'daily', 85.00, 'high', '2026-05-28T11:00:00Z', 'liked', '2026-06-01T10:05:00Z', 1),
|
||||
('rec-m01-f03', 'user-m01', 'user-f03', 'daily', 60.00, 'normal','2026-05-28T11:00:00Z', 'passed','2026-05-28T11:01:00Z', 1),
|
||||
('rec-f03-m03', 'user-f03', 'user-m03', 'daily', 78.00, 'high', '2026-06-01T09:00:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
('rec-m03-f03', 'user-m03', 'user-f03', 'daily', 75.00, 'high', '2026-06-01T09:30:00Z', 'liked', '2026-06-03T09:30:00Z', 1),
|
||||
('rec-f05-m05', 'user-f05', 'user-m05', 'daily', 88.00, 'high', '2026-06-01T10:00:00Z', 'liked', '2026-06-05T10:00:00Z', 1),
|
||||
('rec-m05-f05', 'user-m05', 'user-f05', 'daily', 86.00, 'high', '2026-06-01T10:30:00Z', 'liked', '2026-06-05T10:05:00Z', 1),
|
||||
('rec-m06-f01', 'user-m06', 'user-f01', 'daily', 62.00, 'medium','2026-06-06T14:00:00Z', 'liked', '2026-06-06T14:00:00Z', 1);
|
||||
|
||||
-- ============================================================
|
||||
-- 16. 相亲活动(activities)
|
||||
-- ============================================================
|
||||
INSERT INTO activities (
|
||||
id, title, description, organizer_org_id, coorganizer_text,
|
||||
start_at, end_at, location_name, location_address,
|
||||
male_limit, female_limit, total_limit,
|
||||
min_age, max_age,
|
||||
registration_start_at, registration_end_at,
|
||||
need_review, status, created_by
|
||||
) VALUES
|
||||
('act-001',
|
||||
'丹阳公益单身联谊会(夏季场)',
|
||||
'面向丹阳市区及周边乡镇的单身青年,由妇联、工会联合主办,提供安全、真实的交友平台。现场设有互动游戏、自由交流环节,红娘全程辅助。',
|
||||
'org-danyang-women',
|
||||
'丹阳市总工会、丹阳市慈善基金会',
|
||||
'2026-08-15T14:00:00Z', '2026-08-15T17:30:00Z',
|
||||
'丹阳市文化馆多功能厅', '丹阳市丹北路168号',
|
||||
15, 15, 30, 22, 40,
|
||||
'2026-07-01T00:00:00Z', '2026-08-10T23:59:59Z',
|
||||
true, 'registration_open', 'op-admin-001'),
|
||||
|
||||
('act-002',
|
||||
'七夕特别活动·丹阳缘来是你',
|
||||
'七夕节特别策划,浪漫主题相亲活动。适合寻找认真关系的单身人士。',
|
||||
'org-danyang-trade',
|
||||
'丹阳市新时代文明实践中心',
|
||||
'2026-08-29T15:00:00Z', '2026-08-29T18:00:00Z',
|
||||
'丹阳大剧院报告厅', '丹阳市书院路28号',
|
||||
20, 20, 40, 25, 45,
|
||||
'2026-08-01T00:00:00Z', '2026-08-25T23:59:59Z',
|
||||
true, 'draft', 'op-act01');
|
||||
|
||||
-- ============================================================
|
||||
-- 17. 活动报名(activity_registrations)
|
||||
-- ============================================================
|
||||
INSERT INTO activity_registrations (id, activity_id, user_id, status, registered_at, reviewed_by, reviewed_at, checkin_status) VALUES
|
||||
('reg-001-f01', 'act-001', 'user-f01', 'approved', '2026-07-05T10:00:00Z', 'op-act01', '2026-07-05T10:30:00Z', 'not_checked_in'),
|
||||
('reg-001-f03', 'act-001', 'user-f03', 'approved', '2026-07-06T14:00:00Z', 'op-act01', '2026-07-06T14:15:00Z', 'not_checked_in'),
|
||||
('reg-001-f05', 'act-001', 'user-f05', 'approved', '2026-07-07T09:00:00Z', 'op-act01', '2026-07-07T09:20:00Z', 'not_checked_in'),
|
||||
('reg-001-m01', 'act-001', 'user-m01', 'approved', '2026-07-08T11:00:00Z', 'op-act01', '2026-07-08T11:10:00Z', 'not_checked_in'),
|
||||
('reg-001-m03', 'act-001', 'user-m03', 'approved', '2026-07-09T15:00:00Z', 'op-act01', '2026-07-09T15:20:00Z', 'not_checked_in'),
|
||||
('reg-001-m05', 'act-001', 'user-m05', 'approved', '2026-07-10T08:30:00Z', 'op-act01', '2026-07-10T08:45:00Z', 'not_checked_in'),
|
||||
('reg-001-f02', 'act-001', 'user-f02', 'pending', '2026-07-12T10:00:00Z', NULL, NULL, 'not_checked_in'),
|
||||
('reg-001-m02', 'act-001', 'user-m02', 'approved', '2026-07-11T16:00:00Z', 'op-act01', '2026-07-11T16:30:00Z', 'not_checked_in'),
|
||||
('reg-001-f04', 'act-001', 'user-f04', 'rejected', '2026-07-13T09:00:00Z', 'op-act01', '2026-07-13T09:15:00Z', 'not_checked_in');
|
||||
|
||||
-- ============================================================
|
||||
-- 18. 活动互选意向(activity_interests)
|
||||
-- ============================================================
|
||||
INSERT INTO activity_interests (id, source_user_id, target_user_id, activity_id, status, confirmed_at, created_at) VALUES
|
||||
('ai-f01-m01', 'user-f01', 'user-m01', 'act-001', 'mutual', '2026-08-15T17:00:00Z', '2026-08-15T17:00:00Z'),
|
||||
('ai-f03-m03', 'user-f03', 'user-m03', 'act-001', 'mutual', '2026-08-15T17:05:00Z', '2026-08-15T17:05:00Z'),
|
||||
('ai-f05-m05', 'user-f05', 'user-m05', 'act-001', 'expressed','2026-08-15T17:10:00Z', '2026-08-15T17:10:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 19. 红娘服务(matchmaker_services)
|
||||
-- ============================================================
|
||||
INSERT INTO matchmaker_services (id, user_id, service_type, description, status, organization_id, assigned_operator_id, assigned_at, completed_at) VALUES
|
||||
('ms-f02', 'user-f02', 'recommend_partner', '离异用户希望找到合适的伴侣,需要红娘协助筛选',
|
||||
'in_service', 'org-danyang-women', 'op-mh001', '2026-06-20T10:00:00Z', NULL),
|
||||
('ms-f06', 'user-f06', 'no_match_help', '丧偶用户希望重新融入社交,找到新伴侣',
|
||||
'waiting_user', 'org-danyang-charity', 'op-mh001', '2026-06-25T14:00:00Z', NULL),
|
||||
('ms-f04', 'user-f04', 'review_preference', '用户希望调整择偶条件,请红娘帮助评估',
|
||||
'completed', 'org-danyang-women', 'op-mh001', '2026-06-15T09:00:00Z', '2026-06-20T11:00:00Z');
|
||||
|
||||
-- 红娘推荐记录
|
||||
INSERT INTO matchmaker_recommendations (id, service_id, user_id, target_user_id, operator_id, reason, status, created_at, viewed_at, responded_at) VALUES
|
||||
('mr-f02-m02', 'ms-f02', 'user-f02', 'user-m02', 'op-mh001',
|
||||
'两人同在丹阳工作,年龄相仿,都离过婚有共同语言',
|
||||
'viewed', '2026-06-21T10:00:00Z', '2026-06-22T09:00:00Z', NULL);
|
||||
|
||||
-- 红娘跟进记录
|
||||
INSERT INTO matchmaker_followups (id, service_id, operator_id, followup_type, content, result_code, next_followup_at, created_at) VALUES
|
||||
('mf-f02-1', 'ms-f02', 'op-mh001', 'phone_call', '电话沟通用户情况,了解离异原因及择偶期望', '正常', '2026-07-01T10:00:00Z', '2026-06-22T10:00:00Z'),
|
||||
('mf-f04-1', 'ms-f04', 'op-mh001', 'face_to_face', '面对面交流,帮助用户调整身高要求从170改为168', '已调整', NULL, '2026-06-18T15:00:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 20. 系统通知(notifications)
|
||||
-- ============================================================
|
||||
INSERT INTO notifications (id, user_id, type, title, content, business_type, business_id, read_status, created_at) VALUES
|
||||
('notif-match-f01', 'user-f01', 'match', '你们互相喜欢!', '张伟也喜欢了你,可以开始聊天啦~', 'match', 'match-f01-m01', 'read', '2026-06-01T10:05:00Z'),
|
||||
('notif-match-m01', 'user-m01', 'match', '你们互相喜欢!', '小芳也喜欢了你,可以开始聊天啦~', 'match', 'match-f01-m01', 'read', '2026-06-01T10:05:00Z'),
|
||||
('notif-match-f03', 'user-f03', 'match', '你们互相喜欢!', '王磊也喜欢了你,可以开始聊天啦~', 'match', 'match-f03-m03', 'read', '2026-06-03T09:30:00Z'),
|
||||
('notif-match-m03', 'user-m03', 'match', '你们互相喜欢!', '婷婷也喜欢了你,可以开始聊天啦~', 'match', 'match-f03-m03', 'unread','2026-06-03T09:30:00Z'),
|
||||
('notif-match-f05', 'user-f05', 'match', '你们互相喜欢!', '孙浩也喜欢了你,可以开始聊天啦~', 'match', 'match-f05-m05', 'read', '2026-06-05T10:05:00Z'),
|
||||
('notif-match-m05', 'user-m05', 'match', '你们互相喜欢!', '慧琴也喜欢了你,可以开始聊天啦~', 'match', 'match-f05-m05', 'read', '2026-06-05T10:05:00Z'),
|
||||
('notif-success-f05','user-f05', 'system', '恭喜牵手成功!', '您与孙浩已成功牵手,祝你们幸福!', 'match', 'match-f05-m05', 'read', '2026-07-01T10:30:00Z'),
|
||||
('notif-success-m05','user-m05', 'system', '恭喜牵手成功!', '您与慧琴已成功牵手,祝你们幸福!', 'match', 'match-f05-m05', 'read', '2026-07-01T10:30:00Z'),
|
||||
('notif-act-001-f01','user-f01', 'activity', '活动报名已确认', '您已成功报名「丹阳公益单身联谊会」,活动时间:2026-08-15 14:00', 'activity', 'act-001', 'read', '2026-07-05T10:30:00Z'),
|
||||
('notif-act-001-f05','user-f05', 'activity', '活动报名已确认', '您已成功报名「丹阳公益单身联谊会」,活动时间:2026-08-15 14:00', 'activity', 'act-001', 'unread','2026-07-07T09:20:00Z'),
|
||||
('notif-mh-f02', 'user-f02', 'matchmaker','红娘已为您服务', '您的红娘服务申请已被分配,红娘小王将在24小时内与您联系', 'matchmaker', 'ms-f02', 'read', '2026-06-20T10:30:00Z');
|
||||
|
||||
-- ============================================================
|
||||
-- 21. 同意记录(consent_records)
|
||||
-- ============================================================
|
||||
INSERT INTO consent_records (id, user_id, type, version, agreed_at, ip_address, user_agent) VALUES
|
||||
('cr-f01', 'user-f01', 'terms_of_service', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
('cr-f01', 'user-f01', 'privacy_policy', '1.0', '2026-03-15T10:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
('cr-m01', 'user-m01', 'terms_of_service', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0'),
|
||||
('cr-m01', 'user-m01', 'privacy_policy', '1.0', '2026-03-10T09:00:00Z', '127.0.0.1', 'WeChat/8.0');
|
||||
|
||||
-- ============================================================
|
||||
-- 22. 审核原因字典(review_reasons)
|
||||
-- ============================================================
|
||||
INSERT INTO review_reasons (code, name, category, enabled, sort_order) VALUES
|
||||
('profile_incomplete', '资料不完整', 'quality', true, 1),
|
||||
('photo_unclear', '照片不清晰', 'quality', true, 2),
|
||||
('fake_info', '信息疑似虚假', 'trust', true, 3),
|
||||
('inappropriate_photo', '照片内容不当', 'safety', true, 4),
|
||||
('duplicate_identity', '重复注册', 'duplicate', true, 5),
|
||||
('suspicious_behavior', '行为异常', 'risk', true, 6),
|
||||
('manual_review_needed', '需人工复核', 'quality', true, 7);
|
||||
|
||||
-- 启用 replication
|
||||
SET session_replication_role = 'origin';
|
||||
|
||||
-- ============================================================
|
||||
-- 验证数据量
|
||||
-- ============================================================
|
||||
DO $$
|
||||
DECLARE
|
||||
u_cnt INTEGER; o_cnt INTEGER; op_cnt INTEGER; m_cnt INTEGER;
|
||||
a_cnt INTEGER; r_cnt INTEGER; n_cnt INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO u_cnt FROM users WHERE deleted_at IS NULL;
|
||||
SELECT COUNT(*) INTO o_cnt FROM organizations;
|
||||
SELECT COUNT(*) INTO op_cnt FROM operators;
|
||||
SELECT COUNT(*) INTO m_cnt FROM matches;
|
||||
SELECT COUNT(*) INTO a_cnt FROM activities WHERE deleted_at IS NULL;
|
||||
SELECT COUNT(*) INTO r_cnt FROM user_relations;
|
||||
SELECT COUNT(*) INTO n_cnt FROM notifications;
|
||||
RAISE NOTICE '📊 Demo 数据已生成:';
|
||||
RAISE NOTICE ' 用户: %人 | 组织: %个 | 操作员: %人', u_cnt, o_cnt, op_cnt;
|
||||
RAISE NOTICE ' Match: %对 | 关系: %条 | 活动: %个 | 通知: %条', m_cnt, r_cnt, a_cnt, n_cnt;
|
||||
END $$;
|
||||
@@ -0,0 +1,222 @@
|
||||
-- V001__init_base_tables.sql
|
||||
-- 第一阶段迁移:基础用户表与组织架构表
|
||||
|
||||
-- 用户账号表
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id UUID PRIMARY KEY,
|
||||
wechat_openid VARCHAR(128) NOT NULL,
|
||||
wechat_unionid VARCHAR(128),
|
||||
phone VARCHAR(32),
|
||||
account_status VARCHAR(32) NOT NULL DEFAULT 'normal',
|
||||
relationship_status VARCHAR(32) NOT NULL DEFAULT 'searching',
|
||||
recommendation_enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
last_login_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uk_users_openid ON users(wechat_openid) WHERE deleted_at IS NULL;
|
||||
CREATE UNIQUE INDEX uk_users_phone ON users(phone) WHERE phone IS NOT NULL AND deleted_at IS NULL;
|
||||
CREATE UNIQUE INDEX uk_users_unionid ON users(wechat_unionid) WHERE wechat_unionid IS NOT NULL AND deleted_at IS NULL;
|
||||
|
||||
ALTER TABLE users ADD CONSTRAINT chk_user_account_status CHECK (account_status IN (
|
||||
'normal', 'reviewing_risk', 'limited', 'suspended', 'banned', 'closed'
|
||||
));
|
||||
ALTER TABLE users ADD CONSTRAINT chk_user_relationship_status CHECK (relationship_status IN (
|
||||
'searching', 'getting_to_know', 'paused', 'matched_successfully', 'service_exited'
|
||||
));
|
||||
|
||||
-- 组织表
|
||||
CREATE TABLE IF NOT EXISTS organizations (
|
||||
id UUID PRIMARY KEY,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
type VARCHAR(32) NOT NULL,
|
||||
contact_name VARCHAR(100),
|
||||
contact_phone_enc TEXT,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
ALTER TABLE organizations ADD CONSTRAINT chk_org_type CHECK (type IN (
|
||||
'women_federation', 'trade_union', 'charity_center', 'volunteer_team', 'civil_affairs_partner', 'other'
|
||||
));
|
||||
ALTER TABLE organizations ADD CONSTRAINT chk_org_status CHECK (status IN ('active', 'inactive'));
|
||||
|
||||
-- 工作人员表
|
||||
CREATE TABLE IF NOT EXISTS operators (
|
||||
id UUID PRIMARY KEY,
|
||||
organization_id UUID REFERENCES organizations(id),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
phone_enc TEXT,
|
||||
phone_hash VARCHAR(128),
|
||||
username VARCHAR(100) NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'active',
|
||||
last_login_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uk_operator_username ON operators(username);
|
||||
|
||||
-- 角色表
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
id UUID PRIMARY KEY,
|
||||
code VARCHAR(64) NOT NULL UNIQUE,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
description VARCHAR(500),
|
||||
system_role BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 权限表
|
||||
CREATE TABLE IF NOT EXISTS permissions (
|
||||
id UUID PRIMARY KEY,
|
||||
code VARCHAR(128) NOT NULL UNIQUE,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
module VARCHAR(64) NOT NULL,
|
||||
description VARCHAR(500)
|
||||
);
|
||||
|
||||
-- 角色权限关联
|
||||
CREATE TABLE IF NOT EXISTS role_permissions (
|
||||
role_id UUID NOT NULL REFERENCES roles(id),
|
||||
permission_id UUID NOT NULL REFERENCES permissions(id),
|
||||
PRIMARY KEY (role_id, permission_id)
|
||||
);
|
||||
|
||||
-- 操作员角色关联
|
||||
CREATE TABLE IF NOT EXISTS operator_roles (
|
||||
operator_id UUID NOT NULL REFERENCES operators(id),
|
||||
role_id UUID NOT NULL REFERENCES roles(id),
|
||||
PRIMARY KEY (operator_id, role_id)
|
||||
);
|
||||
|
||||
-- 审计日志表
|
||||
CREATE TABLE IF NOT EXISTS audit_logs (
|
||||
id UUID PRIMARY KEY,
|
||||
operator_id UUID REFERENCES operators(id),
|
||||
organization_id UUID REFERENCES organizations(id),
|
||||
action VARCHAR(128) NOT NULL,
|
||||
resource_type VARCHAR(64) NOT NULL,
|
||||
resource_id VARCHAR(128),
|
||||
before_data JSONB,
|
||||
after_data JSONB,
|
||||
ip VARCHAR(64),
|
||||
user_agent VARCHAR(500),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_audit_logs_operator ON audit_logs(operator_id, created_at DESC);
|
||||
CREATE INDEX idx_audit_logs_resource ON audit_logs(resource_type, resource_id);
|
||||
CREATE INDEX idx_audit_logs_created ON audit_logs(created_at DESC);
|
||||
|
||||
-- 敏感访问日志表
|
||||
CREATE TABLE IF NOT EXISTS sensitive_access_logs (
|
||||
id UUID PRIMARY KEY,
|
||||
operator_id UUID NOT NULL REFERENCES operators(id),
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
data_type VARCHAR(64) NOT NULL,
|
||||
reason VARCHAR(500),
|
||||
ip VARCHAR(64),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_sensitive_access_operator ON sensitive_access_logs(operator_id, created_at DESC);
|
||||
CREATE INDEX idx_sensitive_access_user ON sensitive_access_logs(user_id, created_at DESC);
|
||||
|
||||
-- 系统配置表
|
||||
CREATE TABLE IF NOT EXISTS system_configs (
|
||||
config_key VARCHAR(128) PRIMARY KEY,
|
||||
config_value JSONB NOT NULL,
|
||||
description VARCHAR(500),
|
||||
updated_by UUID REFERENCES operators(id),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 初始化默认角色
|
||||
INSERT INTO roles (id, code, name, description, system_role) VALUES
|
||||
('00000000-0000-0000-0000-000000000001', 'super_admin', '超级管理员', '系统超级管理员,拥有全部权限', TRUE),
|
||||
('00000000-0000-0000-0000-000000000002', 'platform_admin', '平台管理员', '平台运营管理员', TRUE),
|
||||
('00000000-0000-0000-0000-000000000003', 'organization_admin', '机构管理员', '机构级别管理员', TRUE),
|
||||
('00000000-0000-0000-0000-000000000004', 'reviewer', '审核员', '负责用户资料审核', TRUE),
|
||||
('00000000-0000-0000-0000-000000000005', 'matchmaker', '公益红娘', '提供人工婚恋服务', TRUE),
|
||||
('00000000-0000-0000-0000-000000000006', 'activity_manager', '活动管理员', '负责相亲活动管理', TRUE),
|
||||
('00000000-0000-0000-0000-000000000007', 'risk_operator', '风控人员', '负责举报处理与风控', TRUE),
|
||||
('00000000-0000-0000-0000-000000000008', 'volunteer', '志愿者', '活动现场辅助人员', TRUE),
|
||||
('00000000-0000-0000-0000-000000000009', 'data_viewer', '数据查看者', '仅查看统计数据', TRUE);
|
||||
|
||||
-- 初始化基础权限
|
||||
INSERT INTO permissions (id, code, name, module, description) VALUES
|
||||
-- 用户管理权限
|
||||
('10000000-0000-0000-0000-000000000001', 'user.view', '查看用户', 'user', '查看用户基本信息'),
|
||||
('10000000-0000-0000-0000-000000000002', 'user.sensitive.view', '查看敏感信息', 'user', '查看身份证等敏感信息(需特殊授权)'),
|
||||
('10000000-0000-0000-0000-000000000003', 'user.status.change', '修改用户状态', 'user', '修改账号状态'),
|
||||
-- 审核权限
|
||||
('10000000-0000-0000-0000-000000000010', 'review.view', '查看审核任务', 'review', '查看待审核用户资料'),
|
||||
('10000000-0000-0000-0000-000000000011', 'review.process', '处理审核任务', 'review', '审核通过/退回/需修改'),
|
||||
-- 红娘权限
|
||||
('10000000-0000-0000-0000-000000000020', 'matchmaker.view', '查看红娘服务', 'matchmaker', '查看服务申请列表'),
|
||||
('10000000-0000-0000-0000-000000000021', 'matchmaker.assign', '分配红娘服务', 'matchmaker', '分配服务任务给红娘'),
|
||||
('10000000-0000-0000-0000-000000000022', 'matchmaker.service', '执行红娘服务', 'matchmaker', '处理红娘服务'),
|
||||
-- 活动权限
|
||||
('10000000-0000-0000-0000-000000000030', 'activity.view', '查看活动', 'activity', '查看活动列表'),
|
||||
('10000000-0000-0000-0000-000000000031', 'activity.create', '创建活动', 'activity', '创建新的相亲活动'),
|
||||
('10000000-0000-0000-0000-000000000032', 'activity.review_registration', '审核活动报名', 'activity', '审核用户活动报名'),
|
||||
-- 风控权限
|
||||
('10000000-0000-0000-0000-000000000040', 'risk.report.view', '查看举报', 'risk', '查看举报列表'),
|
||||
('10000000-0000-0000-0000-000000000041', 'risk.report.process', '处理举报', 'risk', '处理举报并处置'),
|
||||
('10000000-0000-0000-0000-000000000042', 'risk.user.ban', '封禁用户', 'risk', '对用户进行封禁处置'),
|
||||
-- 权限管理
|
||||
('10000000-0000-0000-0000-000000000050', 'organization.manage', '管理组织', 'organization', '管理公益组织'),
|
||||
('10000000-0000-0000-0000-000000000051', 'permission.manage', '管理权限', 'permission', '管理角色与权限'),
|
||||
-- 统计权限
|
||||
('10000000-0000-0000-0000-000000000060', 'analytics.view', '查看统计', 'analytics', '查看数据统计'),
|
||||
-- 数据导出
|
||||
('10000000-0000-0000-0000-000000000070', 'data.export', '导出数据', 'data', '导出用户数据(需脱敏+审计)');
|
||||
|
||||
-- 为 super_admin 分配全部权限
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT '00000000-0000-0000-0000-000000000001', id FROM permissions;
|
||||
|
||||
-- 初始化兴趣字典
|
||||
CREATE TABLE IF NOT EXISTS interest_dictionary (
|
||||
code VARCHAR(32) PRIMARY KEY,
|
||||
name VARCHAR(64) NOT NULL,
|
||||
sort_order INT NOT NULL DEFAULT 0,
|
||||
enabled BOOLEAN NOT NULL DEFAULT TRUE
|
||||
);
|
||||
|
||||
INSERT INTO interest_dictionary (code, name, sort_order) VALUES
|
||||
('travel', '旅行', 1),
|
||||
('reading', '阅读', 2),
|
||||
('sports', '运动', 3),
|
||||
('fitness', '健身', 4),
|
||||
('photography', '摄影', 5),
|
||||
('movie', '电影', 6),
|
||||
('music', '音乐', 7),
|
||||
('food', '美食', 8),
|
||||
('cooking', '烹饪', 9),
|
||||
('outdoor', '户外', 10),
|
||||
('pets', '宠物', 11),
|
||||
('games', '游戏', 12),
|
||||
('culture', '文化', 13),
|
||||
('charity', '公益', 14),
|
||||
('shopping', '购物', 15),
|
||||
('painting', '绘画', 16),
|
||||
('dance', '舞蹈', 17),
|
||||
('hiking', '徒步', 18);
|
||||
|
||||
-- 初始化默认匹配规则配置
|
||||
INSERT INTO system_configs (config_key, config_value, description) VALUES
|
||||
('match_rule_version', '1', '当前生效的匹配规则版本'),
|
||||
('daily_recommendation_limit', '6', '每日推荐人数上限'),
|
||||
('match_score_threshold', '60', '推荐最低阈值分数'),
|
||||
('recommendation_cooldown_days', '180', 'Pass冷却天数'),
|
||||
('max_profile_photos', '6', '最大照片数量'),
|
||||
('max_interest_tags', '8', '最大兴趣标签数量'),
|
||||
('activity_default_need_review', 'true', '活动报名默认需要审核'),
|
||||
('activity_mutual_max_selection', '3', '活动互选最大人数'),
|
||||
('activity_mutual_deadline_hours', '48', '活动互选截止时间(小时)');
|
||||
@@ -0,0 +1,151 @@
|
||||
-- V002__add_user_and_verification_tables.sql
|
||||
-- 用户账号、实名认证、Profile、偏好表
|
||||
|
||||
-- user_identities 实名认证表
|
||||
CREATE TABLE IF NOT EXISTS user_identities (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL UNIQUE,
|
||||
real_name_enc TEXT NOT NULL,
|
||||
id_number_enc TEXT NOT NULL,
|
||||
id_number_hash VARCHAR(128) NOT NULL,
|
||||
gender VARCHAR(16),
|
||||
birth_date DATE,
|
||||
verification_status VARCHAR(32) NOT NULL DEFAULT 'not_verified',
|
||||
provider VARCHAR(64),
|
||||
provider_request_id VARCHAR(128),
|
||||
verified_at TIMESTAMPTZ,
|
||||
failed_reason_code VARCHAR(64),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT fk_identity_user FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uk_identity_user ON user_identities(user_id);
|
||||
CREATE UNIQUE INDEX uk_identity_hash ON user_identities(id_number_hash)
|
||||
WHERE verification_status = 'verified';
|
||||
|
||||
ALTER TABLE user_identities ADD CONSTRAINT chk_identity_status
|
||||
CHECK (verification_status IN ('not_verified', 'verifying', 'verified', 'failed', 'manual_review'));
|
||||
|
||||
-- user_profiles 婚恋资料表
|
||||
CREATE TABLE IF NOT EXISTS user_profiles (
|
||||
user_id UUID PRIMARY KEY,
|
||||
display_name VARCHAR(64),
|
||||
gender VARCHAR(16) NOT NULL,
|
||||
birth_date DATE NOT NULL,
|
||||
height_cm SMALLINT,
|
||||
region_code VARCHAR(32),
|
||||
region_name VARCHAR(128),
|
||||
marital_status VARCHAR(32),
|
||||
children_status VARCHAR(32),
|
||||
education_code VARCHAR(32),
|
||||
occupation_code VARCHAR(32),
|
||||
work_region_code VARCHAR(32),
|
||||
smoking_status VARCHAR(32),
|
||||
drinking_status VARCHAR(32),
|
||||
long_term_danyang VARCHAR(32),
|
||||
future_danyang VARCHAR(32),
|
||||
relationship_goal VARCHAR(64),
|
||||
marriage_plan VARCHAR(32),
|
||||
self_intro TEXT,
|
||||
profile_completion SMALLINT NOT NULL DEFAULT 0,
|
||||
profile_status VARCHAR(32) NOT NULL DEFAULT 'in_progress',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT fk_profile_user FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
ALTER TABLE user_profiles ADD CONSTRAINT chk_profile_gender CHECK (gender IN ('male', 'female', 'other'));
|
||||
ALTER TABLE user_profiles ADD CONSTRAINT chk_profile_marital CHECK (marital_status IN ('never_married', 'divorced', 'widowed'));
|
||||
ALTER TABLE user_profiles ADD CONSTRAINT chk_profile_children CHECK (children_status IN ('none', 'yes'));
|
||||
ALTER TABLE user_profiles ADD CONSTRAINT chk_profile_edu CHECK (education_code IN ('primary', 'junior_high', 'senior_high', 'vocational', 'college', 'bachelor', 'master', 'doctor'));
|
||||
ALTER TABLE user_profiles ADD CONSTRAINT chk_profile_smoking CHECK (smoking_status IN ('never', 'sometimes', 'often'));
|
||||
ALTER TABLE user_profiles ADD CONSTRAINT chk_profile_drinking CHECK (drinking_status IN ('never', 'sometimes', 'often'));
|
||||
ALTER TABLE user_profiles ADD CONSTRAINT chk_profile_completion CHECK (profile_completion >= 0 AND profile_completion <= 100);
|
||||
ALTER TABLE user_profiles ADD CONSTRAINT chk_profile_status CHECK (profile_status IN ('in_progress', 'completed', 'pending_review', 'approved', 'need_edit', 'rejected'));
|
||||
|
||||
-- user_preferences 择偶条件表
|
||||
CREATE TABLE IF NOT EXISTS user_preferences (
|
||||
user_id UUID PRIMARY KEY,
|
||||
min_age SMALLINT,
|
||||
max_age SMALLINT,
|
||||
age_priority VARCHAR(16),
|
||||
min_height_cm SMALLINT,
|
||||
max_height_cm SMALLINT,
|
||||
height_priority VARCHAR(16),
|
||||
region_scope JSONB,
|
||||
region_priority VARCHAR(16),
|
||||
marital_statuses JSONB,
|
||||
marital_priority VARCHAR(16),
|
||||
min_education_code VARCHAR(32),
|
||||
education_priority VARCHAR(16),
|
||||
children_acceptance VARCHAR(32),
|
||||
children_priority VARCHAR(16),
|
||||
smoking_preference VARCHAR(32),
|
||||
drinking_preference VARCHAR(32),
|
||||
settlement_preference VARCHAR(32),
|
||||
marriage_plan_preference VARCHAR(32),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT fk_pref_user FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
ALTER TABLE user_preferences ADD CONSTRAINT chk_pref_priority CHECK (age_priority IN ('required', 'preferred'));
|
||||
|
||||
-- user_interests 兴趣关系表
|
||||
CREATE TABLE IF NOT EXISTS user_interests (
|
||||
user_id UUID NOT NULL,
|
||||
interest_code VARCHAR(32) NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (user_id, interest_code),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- user_photos 用户照片表
|
||||
CREATE TABLE IF NOT EXISTS user_photos (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
file_key VARCHAR(512) NOT NULL,
|
||||
photo_type VARCHAR(32) NOT NULL DEFAULT 'lifestyle',
|
||||
sort_order SMALLINT NOT NULL DEFAULT 0,
|
||||
review_status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
review_reason VARCHAR(256),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uk_user_avatar ON user_photos(user_id)
|
||||
WHERE photo_type = 'avatar' AND deleted_at IS NULL;
|
||||
|
||||
ALTER TABLE user_photos ADD CONSTRAINT chk_photo_type CHECK (photo_type IN ('avatar', 'lifestyle'));
|
||||
ALTER TABLE user_photos ADD CONSTRAINT chk_photo_review_status CHECK (review_status IN ('pending', 'approved', 'need_edit', 'rejected'));
|
||||
|
||||
-- user_privacy_settings 隐私设置表
|
||||
CREATE TABLE IF NOT EXISTS user_privacy_settings (
|
||||
user_id UUID PRIMARY KEY,
|
||||
visible_in_recommendations BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
visible_in_search BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
show_occupation BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
show_lifestyle_photos BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
receive_activity_recommendations BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
accept_matchmaker_recommendations BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- consent_records 用户同意记录表
|
||||
CREATE TABLE IF NOT EXISTS consent_records (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
type VARCHAR(64) NOT NULL,
|
||||
version VARCHAR(32) NOT NULL,
|
||||
agreed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
ip_address VARCHAR(64),
|
||||
user_agent VARCHAR(500),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_consent_user ON consent_records(user_id, agreed_at DESC);
|
||||
@@ -0,0 +1,109 @@
|
||||
-- V003__add_review_and_relation_tables.sql
|
||||
-- 审核、关系、匹配表
|
||||
|
||||
-- review_tasks 审核任务
|
||||
CREATE TABLE IF NOT EXISTS review_tasks (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
review_type VARCHAR(32) NOT NULL DEFAULT 'initial_profile',
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
assigned_operator_id UUID,
|
||||
submitted_at TIMESTAMPTZ NOT NULL,
|
||||
started_at TIMESTAMPTZ,
|
||||
completed_at TIMESTAMPTZ,
|
||||
final_comment VARCHAR(1000),
|
||||
version INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (assigned_operator_id) REFERENCES operators(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_review_tasks_status_time ON review_tasks(status, submitted_at);
|
||||
CREATE INDEX idx_review_tasks_operator ON review_tasks(assigned_operator_id, status);
|
||||
|
||||
ALTER TABLE review_tasks ADD CONSTRAINT chk_review_type CHECK (review_type IN ('initial_profile', 'profile_change', 'photo_change', 'marital_status_change', 'risk_recheck'));
|
||||
ALTER TABLE review_tasks ADD CONSTRAINT chk_review_status CHECK (status IN ('pending', 'processing', 'approved', 'need_edit', 'rejected'));
|
||||
|
||||
-- review_items 审核明细
|
||||
CREATE TABLE IF NOT EXISTS review_items (
|
||||
id UUID PRIMARY KEY,
|
||||
review_task_id UUID NOT NULL,
|
||||
item_type VARCHAR(32) NOT NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
reason_code VARCHAR(64),
|
||||
comment VARCHAR(500),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (review_task_id) REFERENCES review_tasks(id)
|
||||
);
|
||||
|
||||
ALTER TABLE review_items ADD CONSTRAINT chk_item_type CHECK (item_type IN ('avatar', 'lifestyle_photos', 'basic_profile', 'self_intro', 'relationship_profile'));
|
||||
ALTER TABLE review_items ADD CONSTRAINT chk_item_status CHECK (status IN ('pending', 'approved', 'need_edit', 'abnormal'));
|
||||
|
||||
-- review_reasons 审核原因字典
|
||||
CREATE TABLE IF NOT EXISTS review_reasons (
|
||||
code VARCHAR(64) PRIMARY KEY,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
category VARCHAR(32),
|
||||
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
sort_order INT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
-- user_relations 用户单向关系
|
||||
CREATE TABLE IF NOT EXISTS user_relations (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
target_user_id UUID NOT NULL,
|
||||
relation_type VARCHAR(32) NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (target_user_id) REFERENCES users(id),
|
||||
CONSTRAINT chk_not_self_relation CHECK (user_id <> target_user_id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uk_user_relation ON user_relations(user_id, target_user_id, relation_type);
|
||||
|
||||
ALTER TABLE user_relations ADD CONSTRAINT chk_relation_type CHECK (relation_type IN ('liked', 'passed', 'blocked'));
|
||||
|
||||
-- matches 双向匹配表
|
||||
CREATE TABLE IF NOT EXISTS matches (
|
||||
id UUID PRIMARY KEY,
|
||||
user_a_id UUID NOT NULL,
|
||||
user_b_id UUID NOT NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'active',
|
||||
source VARCHAR(32) NOT NULL DEFAULT 'user_like',
|
||||
matched_at TIMESTAMPTZ NOT NULL,
|
||||
unmatched_at TIMESTAMPTZ,
|
||||
successful_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (user_a_id) REFERENCES users(id),
|
||||
FOREIGN KEY (user_b_id) REFERENCES users(id),
|
||||
CONSTRAINT chk_match_users CHECK (user_a_id <> user_b_id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uk_match_pair ON matches(user_a_id, user_b_id);
|
||||
CREATE INDEX idx_match_status ON matches(status, matched_at DESC);
|
||||
|
||||
ALTER TABLE matches ADD CONSTRAINT chk_match_status CHECK (status IN ('active', 'getting_to_know', 'unmatched', 'successful'));
|
||||
ALTER TABLE matches ADD CONSTRAINT chk_match_source CHECK (source IN ('user_like', 'activity_mutual', 'matchmaker'));
|
||||
|
||||
-- relationship_success_requests 成功牵手请求
|
||||
CREATE TABLE IF NOT EXISTS relationship_success_requests (
|
||||
id UUID PRIMARY KEY,
|
||||
match_id UUID NOT NULL,
|
||||
initiated_by UUID NOT NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
confirmed_by UUID,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
resolved_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (match_id) REFERENCES matches(id),
|
||||
FOREIGN KEY (initiated_by) REFERENCES users(id),
|
||||
FOREIGN KEY (confirmed_by) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_success_request_match ON relationship_success_requests(match_id, status);
|
||||
|
||||
ALTER TABLE relationship_success_requests ADD CONSTRAINT chk_success_status CHECK (status IN ('pending', 'confirmed', 'declined'));
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
-- V004__add_messaging_and_recommendation_tables.sql
|
||||
-- 推荐、聊天消息表
|
||||
|
||||
-- recommendation_records 推荐记录
|
||||
CREATE TABLE IF NOT EXISTS recommendation_records (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
target_user_id UUID NOT NULL,
|
||||
source VARCHAR(32) NOT NULL DEFAULT 'daily',
|
||||
score NUMERIC(5,2),
|
||||
level VARCHAR(16),
|
||||
reasons JSONB,
|
||||
shown_at TIMESTAMPTZ NOT NULL,
|
||||
action VARCHAR(32),
|
||||
action_at TIMESTAMPTZ,
|
||||
rule_version INT NOT NULL DEFAULT 1,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (target_user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_recommend_user_time ON recommendation_records(user_id, shown_at DESC);
|
||||
CREATE INDEX idx_recommend_pair ON recommendation_records(user_id, target_user_id);
|
||||
|
||||
ALTER TABLE recommendation_records ADD CONSTRAINT chk_rec_source CHECK (source IN ('daily', 'discover', 'matchmaker', 'activity'));
|
||||
ALTER TABLE recommendation_records ADD CONSTRAINT chk_rec_level CHECK (level IN ('high', 'medium', 'normal'));
|
||||
ALTER TABLE recommendation_records ADD CONSTRAINT chk_rec_action CHECK (action IN ('liked', 'passed', 'blocked', 'matched', NULL));
|
||||
|
||||
-- conversations 会话表
|
||||
CREATE TABLE IF NOT EXISTS conversations (
|
||||
id UUID PRIMARY KEY,
|
||||
match_id UUID NOT NULL UNIQUE,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'active',
|
||||
last_message_id UUID,
|
||||
last_message_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (match_id) REFERENCES matches(id)
|
||||
);
|
||||
|
||||
ALTER TABLE conversations ADD CONSTRAINT chk_conversation_status CHECK (status IN ('active', 'unmatched', 'blocked'));
|
||||
|
||||
-- conversation_members 会话成员表
|
||||
CREATE TABLE IF NOT EXISTS conversation_members (
|
||||
conversation_id UUID NOT NULL,
|
||||
user_id UUID NOT NULL,
|
||||
last_read_message_id UUID,
|
||||
unread_count INT NOT NULL DEFAULT 0,
|
||||
can_send BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
joined_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (conversation_id, user_id),
|
||||
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- messages 消息表
|
||||
CREATE TABLE IF NOT EXISTS messages (
|
||||
id UUID PRIMARY KEY,
|
||||
conversation_id UUID NOT NULL,
|
||||
sender_id UUID,
|
||||
client_message_id VARCHAR(128),
|
||||
message_type VARCHAR(32) NOT NULL,
|
||||
content TEXT,
|
||||
file_id UUID,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'sent',
|
||||
risk_level VARCHAR(16),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
||||
FOREIGN KEY (sender_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uk_message_client_id ON messages(sender_id, client_message_id)
|
||||
WHERE client_message_id IS NOT NULL;
|
||||
CREATE INDEX idx_messages_conversation_time ON messages(conversation_id, created_at DESC);
|
||||
|
||||
ALTER TABLE messages ADD CONSTRAINT chk_msg_type CHECK (message_type IN ('text', 'image', 'system', 'risk_notice'));
|
||||
ALTER TABLE messages ADD CONSTRAINT chk_msg_status CHECK (status IN ('sent', 'delivered', 'failed'));
|
||||
ALTER TABLE messages ADD CONSTRAINT chk_msg_risk_level CHECK (risk_level IN (NULL, 'normal', 'warning', 'high'));
|
||||
|
||||
-- notifications 系统通知表
|
||||
CREATE TABLE IF NOT EXISTS notifications (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
type VARCHAR(32) NOT NULL,
|
||||
title VARCHAR(200) NOT NULL,
|
||||
content VARCHAR(2000),
|
||||
business_type VARCHAR(32),
|
||||
business_id UUID,
|
||||
read_status VARCHAR(16) NOT NULL DEFAULT 'unread',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
read_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_notifications_user ON notifications(user_id, read_status, created_at DESC);
|
||||
|
||||
ALTER TABLE notifications ADD CONSTRAINT chk_notification_type CHECK (type IN ('review', 'match', 'matchmaker', 'activity', 'risk', 'account', 'system'));
|
||||
ALTER TABLE notifications ADD CONSTRAINT chk_read_status CHECK (read_status IN ('unread', 'read'));
|
||||
@@ -0,0 +1,4 @@
|
||||
-- V005__add_review_tables.sql
|
||||
-- 为 review_tasks 补充用户查询索引(review_tasks 表已在 V003 中创建)
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_review_tasks_user ON review_tasks(user_id, created_at DESC);
|
||||
@@ -0,0 +1,38 @@
|
||||
-- V006__add_match_tables.sql
|
||||
-- 推荐与匹配相关表补充(仅添加 V004 未创建的补充内容)
|
||||
|
||||
-- match_rule_configs 匹配规则配置表
|
||||
CREATE TABLE IF NOT EXISTS match_rule_configs (
|
||||
id UUID PRIMARY KEY,
|
||||
version INT NOT NULL,
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'draft',
|
||||
age_weight INT NOT NULL DEFAULT 15,
|
||||
region_weight INT NOT NULL DEFAULT 15,
|
||||
marital_weight INT NOT NULL DEFAULT 10,
|
||||
children_weight INT NOT NULL DEFAULT 10,
|
||||
education_weight INT NOT NULL DEFAULT 5,
|
||||
height_weight INT NOT NULL DEFAULT 5,
|
||||
marriage_plan_weight INT NOT NULL DEFAULT 15,
|
||||
settlement_weight INT NOT NULL DEFAULT 10,
|
||||
lifestyle_weight INT NOT NULL DEFAULT 10,
|
||||
interest_weight INT NOT NULL DEFAULT 5,
|
||||
minimum_score INT NOT NULL DEFAULT 60,
|
||||
created_by UUID,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
activated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_match_rule_version ON match_rule_configs(version DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_match_rule_status ON match_rule_configs(status) WHERE status = 'active';
|
||||
|
||||
-- 初始化默认匹配规则(version=1, status=active)
|
||||
INSERT INTO match_rule_configs (id, version, status, age_weight, region_weight, marital_weight,
|
||||
children_weight, education_weight, height_weight, marriage_plan_weight, settlement_weight,
|
||||
lifestyle_weight, interest_weight, minimum_score)
|
||||
VALUES (
|
||||
'00000000-0000-0000-0000-000000000100',
|
||||
1, 'active',
|
||||
15, 15, 10, 10, 5, 5, 15, 10, 10, 5,
|
||||
60
|
||||
)
|
||||
ON CONFLICT DO NOTHING;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- V007__add_relationship_tables.sql
|
||||
-- 用户关系与匹配表(已在 V003 中创建,本文件保留为占位)
|
||||
@@ -0,0 +1,65 @@
|
||||
-- V008__add_messaging_tables.sql
|
||||
-- 聊天消息表补充(如V004未完整创建则执行)
|
||||
|
||||
-- conversations 会话表
|
||||
CREATE TABLE IF NOT EXISTS conversations (
|
||||
id UUID PRIMARY KEY,
|
||||
match_id UUID NOT NULL UNIQUE,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'active',
|
||||
last_message_id UUID,
|
||||
last_message_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (match_id) REFERENCES matches(id)
|
||||
);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'chk_conversation_status') THEN
|
||||
ALTER TABLE conversations ADD CONSTRAINT chk_conversation_status CHECK (status IN ('active', 'unmatched', 'blocked'));
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- conversation_members 会话成员表
|
||||
CREATE TABLE IF NOT EXISTS conversation_members (
|
||||
conversation_id UUID NOT NULL,
|
||||
user_id UUID NOT NULL,
|
||||
last_read_message_id UUID,
|
||||
unread_count INT NOT NULL DEFAULT 0,
|
||||
can_send BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
joined_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (conversation_id, user_id),
|
||||
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- messages 消息表
|
||||
CREATE TABLE IF NOT EXISTS messages (
|
||||
id UUID PRIMARY KEY,
|
||||
conversation_id UUID NOT NULL,
|
||||
sender_id UUID,
|
||||
client_message_id VARCHAR(128),
|
||||
message_type VARCHAR(32) NOT NULL,
|
||||
content TEXT,
|
||||
file_id UUID,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'sent',
|
||||
risk_level VARCHAR(16),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
||||
FOREIGN KEY (sender_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_conversation_time ON messages(conversation_id, created_at DESC);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'chk_msg_type') THEN
|
||||
ALTER TABLE messages ADD CONSTRAINT chk_msg_type CHECK (message_type IN ('text', 'image', 'system', 'risk_notice'));
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'chk_msg_status') THEN
|
||||
ALTER TABLE messages ADD CONSTRAINT chk_msg_status CHECK (status IN ('sent', 'delivered', 'failed'));
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'chk_msg_risk_level') THEN
|
||||
ALTER TABLE messages ADD CONSTRAINT chk_msg_risk_level CHECK (risk_level IN (NULL, 'normal', 'warning', 'high'));
|
||||
END IF;
|
||||
END $$;
|
||||
@@ -0,0 +1,74 @@
|
||||
-- V009__add_matchmaker_tables.sql
|
||||
-- 公益红娘服务表
|
||||
|
||||
-- matchmaker_services 红娘服务表
|
||||
CREATE TABLE IF NOT EXISTS matchmaker_services (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
service_type VARCHAR(32) NOT NULL,
|
||||
description VARCHAR(1000),
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'submitted',
|
||||
organization_id UUID,
|
||||
assigned_operator_id UUID,
|
||||
assigned_at TIMESTAMPTZ,
|
||||
completed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id),
|
||||
FOREIGN KEY (assigned_operator_id) REFERENCES operators(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_matchmaker_status ON matchmaker_services(status, created_at);
|
||||
CREATE INDEX idx_matchmaker_operator ON matchmaker_services(assigned_operator_id, status);
|
||||
CREATE INDEX idx_matchmaker_user ON matchmaker_services(user_id, created_at DESC);
|
||||
|
||||
ALTER TABLE matchmaker_services ADD CONSTRAINT chk_matchmaker_service_type CHECK (service_type IN (
|
||||
'recommend_partner', 'review_preference', 'contact_intention',
|
||||
'join_activity', 'no_match_help', 'chat_help', 'other'
|
||||
));
|
||||
ALTER TABLE matchmaker_services ADD CONSTRAINT chk_matchmaker_status CHECK (status IN (
|
||||
'submitted', 'assigned', 'in_service', 'waiting_user', 'completed', 'cancelled'
|
||||
));
|
||||
|
||||
-- matchmaker_recommendations 红娘推荐表
|
||||
CREATE TABLE IF NOT EXISTS matchmaker_recommendations (
|
||||
id UUID PRIMARY KEY,
|
||||
service_id UUID NOT NULL,
|
||||
user_id UUID NOT NULL,
|
||||
target_user_id UUID NOT NULL,
|
||||
operator_id UUID NOT NULL,
|
||||
reason VARCHAR(1000),
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending_view',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
viewed_at TIMESTAMPTZ,
|
||||
responded_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (service_id) REFERENCES matchmaker_services(id),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (target_user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (operator_id) REFERENCES operators(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_matchmaker_rec_service ON matchmaker_recommendations(service_id);
|
||||
CREATE INDEX idx_matchmaker_rec_user ON matchmaker_recommendations(user_id);
|
||||
|
||||
ALTER TABLE matchmaker_recommendations ADD CONSTRAINT chk_rec_status CHECK (status IN (
|
||||
'pending_view', 'viewed', 'responded'
|
||||
));
|
||||
|
||||
-- matchmaker_followups 红娘跟进表
|
||||
CREATE TABLE IF NOT EXISTS matchmaker_followups (
|
||||
id UUID PRIMARY KEY,
|
||||
service_id UUID NOT NULL,
|
||||
operator_id UUID NOT NULL,
|
||||
followup_type VARCHAR(32),
|
||||
content VARCHAR(2000) NOT NULL,
|
||||
result_code VARCHAR(64),
|
||||
next_followup_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
FOREIGN KEY (service_id) REFERENCES matchmaker_services(id),
|
||||
FOREIGN KEY (operator_id) REFERENCES operators(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_matchmaker_fu_service ON matchmaker_followups(service_id);
|
||||
CREATE INDEX idx_matchmaker_fu_operator ON matchmaker_followups(operator_id, created_at DESC);
|
||||
@@ -0,0 +1,70 @@
|
||||
-- V010__add_activity_tables.sql
|
||||
-- 公益活动表(如V004未完整创建则执行)
|
||||
|
||||
-- activities 活动表
|
||||
CREATE TABLE IF NOT EXISTS activities (
|
||||
id UUID PRIMARY KEY,
|
||||
title VARCHAR(200) NOT NULL,
|
||||
cover_file_id UUID,
|
||||
description TEXT,
|
||||
organizer_org_id UUID NOT NULL,
|
||||
coorganizer_text VARCHAR(500),
|
||||
start_at TIMESTAMPTZ NOT NULL,
|
||||
end_at TIMESTAMPTZ NOT NULL,
|
||||
location_name VARCHAR(200),
|
||||
location_address VARCHAR(500),
|
||||
male_limit INT,
|
||||
female_limit INT,
|
||||
total_limit INT,
|
||||
min_age SMALLINT,
|
||||
max_age SMALLINT,
|
||||
registration_start_at TIMESTAMPTZ,
|
||||
registration_end_at TIMESTAMPTZ,
|
||||
need_review BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'draft',
|
||||
created_by UUID NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (organizer_org_id) REFERENCES organizations(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_activities_status ON activities(status, start_at);
|
||||
CREATE INDEX idx_activities_organizer ON activities(organizer_org_id, status);
|
||||
|
||||
ALTER TABLE activities ADD CONSTRAINT chk_activity_status CHECK (status IN (
|
||||
'draft', 'registration_open', 'registration_closed', 'ongoing', 'ended', 'cancelled'
|
||||
));
|
||||
|
||||
-- activity_registrations 活动报名表
|
||||
CREATE TABLE IF NOT EXISTS activity_registrations (
|
||||
id UUID PRIMARY KEY,
|
||||
activity_id UUID NOT NULL,
|
||||
user_id UUID NOT NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
registered_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
reviewed_by UUID,
|
||||
reviewed_at TIMESTAMPTZ,
|
||||
reject_reason VARCHAR(500),
|
||||
checkin_status VARCHAR(32) NOT NULL DEFAULT 'not_checked_in',
|
||||
checkin_at TIMESTAMPTZ,
|
||||
emergency_contact_name VARCHAR(100),
|
||||
emergency_contact_phone_enc TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (activity_id) REFERENCES activities(id),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (reviewed_by) REFERENCES operators(id),
|
||||
UNIQUE(activity_id, user_id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_activity_reg_activity ON activity_registrations(activity_id, status);
|
||||
CREATE INDEX idx_activity_reg_user ON activity_registrations(user_id, status);
|
||||
|
||||
ALTER TABLE activity_registrations ADD CONSTRAINT chk_reg_status CHECK (status IN (
|
||||
'pending', 'approved', 'rejected', 'cancelled'
|
||||
));
|
||||
ALTER TABLE activity_registrations ADD CONSTRAINT chk_checkin_status CHECK (checkin_status IN (
|
||||
'not_checked_in', 'checked_in'
|
||||
));
|
||||
@@ -0,0 +1,28 @@
|
||||
-- V011__add_activity_interests.sql
|
||||
-- 活动互选表:活动结束后,用户可对其他参与者表达进一步了解意愿
|
||||
|
||||
CREATE TABLE IF NOT EXISTS activity_interests (
|
||||
id UUID PRIMARY KEY,
|
||||
source_user_id UUID NOT NULL,
|
||||
target_user_id UUID NOT NULL,
|
||||
activity_id UUID NOT NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'expressed',
|
||||
-- 'expressed' = 单方面表达意向(保密)
|
||||
-- 'mutual' = 双方均表达,已建立活动互选关系
|
||||
confirmed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (source_user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (target_user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (activity_id) REFERENCES activities(id),
|
||||
UNIQUE(activity_id, source_user_id, target_user_id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_activity_interest_source ON activity_interests(source_user_id, status);
|
||||
CREATE INDEX idx_activity_interest_target ON activity_interests(target_user_id, status);
|
||||
CREATE INDEX idx_activity_interest_activity ON activity_interests(activity_id, status);
|
||||
|
||||
ALTER TABLE activity_interests ADD CONSTRAINT chk_ai_status CHECK (
|
||||
status IN ('expressed', 'mutual')
|
||||
);
|
||||
@@ -0,0 +1,76 @@
|
||||
-- V012__add_risk_and_report_tables.sql
|
||||
-- 举报与风控表
|
||||
|
||||
-- reports 举报表
|
||||
CREATE TABLE IF NOT EXISTS reports (
|
||||
id UUID PRIMARY KEY,
|
||||
reporter_user_id UUID NOT NULL,
|
||||
reported_user_id UUID,
|
||||
reason_type VARCHAR(64) NOT NULL,
|
||||
description TEXT,
|
||||
evidence_file_ids TEXT,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
process_result VARCHAR(64),
|
||||
processed_by UUID,
|
||||
processed_at TIMESTAMPTZ,
|
||||
process_note TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (reporter_user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (reported_user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (processed_by) REFERENCES operators(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_reports_reporter ON reports(reporter_user_id, status);
|
||||
CREATE INDEX idx_reports_reported ON reports(reported_user_id, status);
|
||||
CREATE INDEX idx_reports_status_priority ON reports(status, reason_type, created_at);
|
||||
|
||||
ALTER TABLE reports ADD CONSTRAINT chk_report_status CHECK (
|
||||
status IN ('pending', 'processing', 'resolved', 'rejected', 'dismissed')
|
||||
);
|
||||
|
||||
-- risk_events 风险事件表
|
||||
CREATE TABLE IF NOT EXISTS risk_events (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
event_type VARCHAR(64) NOT NULL,
|
||||
score INT NOT NULL DEFAULT 0,
|
||||
source VARCHAR(32) NOT NULL DEFAULT 'auto',
|
||||
source_id VARCHAR(128),
|
||||
note TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_risk_events_user ON risk_events(user_id, created_at DESC);
|
||||
CREATE INDEX idx_risk_events_type ON risk_events(event_type, created_at DESC);
|
||||
|
||||
-- risk_actions 风险处置记录表
|
||||
CREATE TABLE IF NOT EXISTS risk_actions (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
action_type VARCHAR(64) NOT NULL,
|
||||
reason VARCHAR(256) NOT NULL,
|
||||
reason_detail TEXT,
|
||||
created_by UUID NOT NULL,
|
||||
effective_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
expires_at TIMESTAMPTZ,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (created_by) REFERENCES operators(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_risk_actions_user ON risk_actions(user_id, status);
|
||||
CREATE INDEX idx_risk_actions_active ON risk_actions(status, effective_at) WHERE status = 'active';
|
||||
|
||||
ALTER TABLE risk_actions ADD CONSTRAINT chk_risk_action_type CHECK (
|
||||
action_type IN ('warning', 'feature_limit', 'temporary_suspend', 'ban')
|
||||
);
|
||||
ALTER TABLE risk_actions ADD CONSTRAINT chk_risk_action_status CHECK (
|
||||
status IN ('active', 'resolved', 'expired')
|
||||
);
|
||||
@@ -0,0 +1,33 @@
|
||||
-- V013__add_appeals_table.sql
|
||||
-- 申诉表
|
||||
|
||||
CREATE TABLE IF NOT EXISTS appeals (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL,
|
||||
appeal_type VARCHAR(64) NOT NULL,
|
||||
related_action_id UUID,
|
||||
reason TEXT NOT NULL,
|
||||
evidence TEXT,
|
||||
contact_method VARCHAR(256),
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
decision_note TEXT,
|
||||
reviewed_by UUID,
|
||||
reviewed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (related_action_id) REFERENCES risk_actions(id),
|
||||
FOREIGN KEY (reviewed_by) REFERENCES operators(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_appeals_user ON appeals(user_id, status);
|
||||
CREATE INDEX idx_appeals_status ON appeals(status, created_at);
|
||||
CREATE INDEX idx_appeals_action ON appeals(related_action_id, status);
|
||||
|
||||
ALTER TABLE appeals ADD CONSTRAINT chk_appeal_status CHECK (
|
||||
status IN ('pending', 'reviewing', 'approved', 'rejected', 'escalated')
|
||||
);
|
||||
ALTER TABLE appeals ADD CONSTRAINT chk_appeal_type CHECK (
|
||||
appeal_type IN ('ban_appeal', 'suspend_appeal')
|
||||
);
|
||||
@@ -0,0 +1,26 @@
|
||||
-- V014__add_consent_and_privacy_tables.sql
|
||||
-- 补充 consent_records 和 user_privacy_settings 的缺失字段与索引
|
||||
|
||||
-- 为 consent_records 添加 V002 中未包含的新字段
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'consent_records' AND column_name = 'consent_type') THEN
|
||||
ALTER TABLE consent_records ADD COLUMN consent_type VARCHAR(64);
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'consent_records' AND column_name = 'agreed') THEN
|
||||
ALTER TABLE consent_records ADD COLUMN agreed BOOLEAN NOT NULL DEFAULT TRUE;
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'consent_records' AND column_name = 'deleted_at') THEN
|
||||
ALTER TABLE consent_records ADD COLUMN deleted_at TIMESTAMPTZ;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_consent_user_type ON consent_records(user_id, consent_type, deleted_at);
|
||||
|
||||
-- 为 user_privacy_settings 添加缺失字段
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_privacy_settings' AND column_name = 'deleted_at') THEN
|
||||
ALTER TABLE user_privacy_settings ADD COLUMN deleted_at TIMESTAMPTZ;
|
||||
END IF;
|
||||
END $$;
|
||||
@@ -0,0 +1,87 @@
|
||||
-- ============================================================
|
||||
-- V015: V1.1 新增角色与权限域
|
||||
-- 新增4个角色 + 7个权限域(~30个权限)
|
||||
-- ============================================================
|
||||
|
||||
-- ========== 新增角色 ==========
|
||||
INSERT INTO roles (id, code, name, description, system_role) VALUES
|
||||
('00000000-0000-0000-0000-000000000010', 'service_station_operator', '服务站运营人员', '善缘服务站现场运营,处理预约和现场任务', TRUE),
|
||||
('00000000-0000-0000-0000-000000000011', 'counselor', '婚恋咨询人员', '公益婚恋咨询师,仅处理被分配的服务', TRUE),
|
||||
('00000000-0000-0000-0000-000000000012', 'counseling_manager', '咨询管理员', '管理咨询预约分配和服务流程', TRUE),
|
||||
('00000000-0000-0000-0000-000000000013', 'content_editor', '内容编辑员', '管理公益内容文章,无用户数据权限', TRUE);
|
||||
|
||||
-- ========== 新增权限:Banner 域 ==========
|
||||
INSERT INTO permissions (id, code, name, module, description) VALUES
|
||||
('20000000-0000-0000-0000-000000000100', 'banner.view', '查看Banner', 'banner', '查看首页Banner列表'),
|
||||
('20000000-0000-0000-0000-000000000101', 'banner.create', '创建Banner', 'banner', '创建新的首页Banner'),
|
||||
('20000000-0000-0000-0000-000000000102', 'banner.edit', '编辑Banner', 'banner', '编辑已有Banner'),
|
||||
('20000000-0000-0000-0000-000000000103', 'banner.publish', '发布Banner', 'banner', '上架/发布Banner'),
|
||||
('20000000-0000-0000-0000-000000000104', 'banner.disable', '禁用Banner', 'banner', '下架/禁用Banner'),
|
||||
('20000000-0000-0000-0000-000000000105', 'banner.reorder', '重排Banner', 'banner', '调整Banner排序');
|
||||
|
||||
-- ========== 新增权限:Counseling 域 ==========
|
||||
INSERT INTO permissions (id, code, name, module, description) VALUES
|
||||
('20000000-0000-0000-0000-000000000200', 'counseling.service.view', '查看咨询服务', 'counseling', '查看分配的咨询服务列表'),
|
||||
('20000000-0000-0000-0000-000000000201', 'counseling.service.assign', '分配咨询服务', 'counseling', '将咨询分配给咨询师'),
|
||||
('20000000-0000-0000-0000-000000000202', 'counseling.service.process', '处理咨询服务', 'counseling', '执行咨询服务(开始/完成/跟进)'),
|
||||
('20000000-0000-0000-0000-000000000203', 'counseling.note.view', '查看咨询备注', 'counseling', '查看咨询敏感备注(需特殊授权)'),
|
||||
('20000000-0000-0000-0000-000000000204', 'counseling.note.create', '创建咨询备注', 'counseling', '添加咨询服务摘要记录');
|
||||
|
||||
-- ========== 新增权限:Content 域 ==========
|
||||
INSERT INTO permissions (id, code, name, module, description) VALUES
|
||||
('20000000-0000-0000-0000-000000000300', 'content.view', '查看内容', 'content', '浏览公益文章内容'),
|
||||
('20000000-0000-0000-0000-000000000301', 'content.create', '创建内容', 'content', '创建公益文章'),
|
||||
('20000000-0000-0000-0000-000000000302', 'content.edit', '编辑内容', 'content', '编辑已有文章'),
|
||||
('20000000-0000-0000-0000-000000000303', 'content.publish', '发布内容', 'content', '发布/上架文章'),
|
||||
('20000000-0000-0000-0000-000000000304', 'content.offline', '下架内容', 'content', '下架/离线文章');
|
||||
|
||||
-- ========== 新增权限:Service Location 域 ==========
|
||||
INSERT INTO permissions (id, code, name, module, description) VALUES
|
||||
('20000000-0000-0000-0000-000000000400', 'service_location.view', '查看服务站', 'service_location', '查看善缘服务站信息'),
|
||||
('20000000-0000-0000-0000-000000000401', 'service_location.manage', '管理服务站', 'service_location', '维护服务站信息(地址/时间/状态)');
|
||||
|
||||
-- ========== 新增权限:Service Appointment 域 ==========
|
||||
INSERT INTO permissions (id, code, name, module, description) VALUES
|
||||
('20000000-0000-0000-0000-000000000500', 'service_appointment.view', '查看预约', 'service_appointment', '查看服务预约列表'),
|
||||
('20000000-0000-0000-0000-000000000501', 'service_appointment.assign', '分配预约', 'service_appointment', '将预约分配给工作人员'),
|
||||
('20000000-0000-0000-0000-000000000502', 'service_appointment.confirm', '确认预约', 'service_appointment', '确认用户服务预约'),
|
||||
('20000000-0000-0000-0000-000000000503', 'service_appointment.complete', '完成预约', 'service_appointment', '标记预约已完成'),
|
||||
('20000000-0000-0000-0000-000000000504', 'service_appointment.cancel', '取消预约', 'service_appointment', '取消服务预约');
|
||||
|
||||
-- ========== 新增权限:Local Eligibility 域 ==========
|
||||
INSERT INTO permissions (id, code, name, module, description) VALUES
|
||||
('20000000-0000-0000-0000-000000000600', 'local_eligibility.view', '查看本地资格', 'local_eligibility', '查看用户本地资格状态'),
|
||||
('20000000-0000-0000-0000-000000000601', 'local_eligibility.review', '审核本地资格', 'local_eligibility', '审核用户本地资格声明和佐证'),
|
||||
('20000000-0000-0000-0000-000000000602', 'local_eligibility.evidence.view', '查看资格佐证', 'local_eligibility', '查看本地资格原始佐证文件(需特殊授权+审计)');
|
||||
|
||||
-- ========== 新增权限:Service Program 域 ==========
|
||||
INSERT INTO permissions (id, code, name, module, description) VALUES
|
||||
('20000000-0000-0000-0000-000000000700', 'service_program.view', '查看服务项目', 'service_program', '查看专项公益服务项目'),
|
||||
('20000000-0000-0000-0000-000000000701', 'service_program.manage', '管理服务项目', 'service_program', '创建/编辑/管理专项服务项目');
|
||||
|
||||
-- ========== 角色 → 权限分配 ==========
|
||||
|
||||
-- service_station_operator: 仅处理现场预约和服务(不含身份证/用户全库)
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT '00000000-0000-0000-0000-000000000010', id FROM permissions
|
||||
WHERE code IN ('service_location.view', 'service_appointment.view', 'service_appointment.confirm', 'service_appointment.complete');
|
||||
|
||||
-- counselor: 仅查看和处理被分配的服务(无用户全库/身份证/聊天权限)
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT '00000000-0000-0000-0000-000000000011', id FROM permissions
|
||||
WHERE code IN ('counseling.service.view', 'counseling.service.process', 'counseling.note.create');
|
||||
|
||||
-- counseling_manager: 可分配、查看和管理咨询(含敏感备注查看权限)
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT '00000000-0000-0000-0000-000000000012', id FROM permissions
|
||||
WHERE code IN ('counseling.service.view', 'counseling.service.assign', 'counseling.service.process', 'counseling.note.view');
|
||||
|
||||
-- content_editor: 仅内容管理,明确无用户数据权限
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT '00000000-0000-0000-0000-000000000013', id FROM permissions
|
||||
WHERE code IN ('content.view', 'content.create', 'content.edit', 'content.publish', 'content.offline');
|
||||
|
||||
-- platform_admin: 扩展包含所有V1.1新增权限
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT '00000000-0000-0000-0000-000000000002', id FROM permissions
|
||||
WHERE id >= '20000000-0000-0000-0000-000000000100';
|
||||
@@ -0,0 +1,46 @@
|
||||
-- ============================================================
|
||||
-- V016: V1.1 实名认证扩展 — 人脸核验预留
|
||||
-- 增加 verification_level / liveness_verification_status / verification_provider 字段
|
||||
-- 同时新增 Feature Flag 系统配置
|
||||
-- ============================================================
|
||||
|
||||
-- ========== 1. user_identities 扩展字段 ==========
|
||||
ALTER TABLE user_identities ADD COLUMN IF NOT EXISTS verification_level VARCHAR(32) DEFAULT 'basic';
|
||||
ALTER TABLE user_identities ADD COLUMN IF NOT EXISTS liveness_verification_status VARCHAR(32) DEFAULT 'not_required';
|
||||
ALTER TABLE user_identities ADD COLUMN IF NOT EXISTS verification_provider VARCHAR(64);
|
||||
|
||||
-- verification_level 约束:basic / enhanced / facial
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_identity_verification_level'
|
||||
) THEN
|
||||
ALTER TABLE user_identities ADD CONSTRAINT chk_identity_verification_level
|
||||
CHECK (verification_level IN ('basic', 'enhanced', 'facial'));
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- liveness_verification_status 约束:not_required / not_started / in_progress / passed / failed
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_identity_liveness_status'
|
||||
) THEN
|
||||
ALTER TABLE user_identities ADD CONSTRAINT chk_identity_liveness_status
|
||||
CHECK (liveness_verification_status IN ('not_required', 'not_started', 'in_progress', 'passed', 'failed'));
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- ========== 2. 新增 Feature Flag 系统配置 ==========
|
||||
-- Note: Default values for V1.1 feature flags are configured in application.yml
|
||||
-- INSERT INTO system_configs (config_key, config_value, description) VALUES
|
||||
-- ('livenessVerification.enabled', to_jsonb(false), '人脸核验功能开关(V1.1预留,默认关闭)'),
|
||||
-- ('localEligibility.evidencePolicy', to_jsonb('need_based'), '本地资格佐证策略'),
|
||||
-- ('counseling.enabled', to_jsonb(true), '婚恋咨询功能开关'),
|
||||
-- ('premarital.enabled', to_jsonb(true), '婚前辅导功能开关'),
|
||||
-- ('serviceLocation.enabled', to_jsonb(true), '善缘服务站功能开关'),
|
||||
-- ('content.enabled', to_jsonb(true), '内容中心功能开关'),
|
||||
-- ('localEligibility.enabled', to_jsonb(true), '本地资格功能开关'),
|
||||
-- ('banner.maxActiveCount', to_jsonb(5), 'Banner最大活跃数量');
|
||||
@@ -0,0 +1,44 @@
|
||||
-- ============================================================
|
||||
-- V017: V1.1 本地资格 — user_local_eligibilities + local_eligibility_evidences
|
||||
-- ============================================================
|
||||
|
||||
-- 本地资格表:每个用户一条,声明丹阳户籍/工作/居住/其他
|
||||
CREATE TABLE IF NOT EXISTS user_local_eligibilities (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL UNIQUE REFERENCES users(id),
|
||||
eligibility_type VARCHAR(32) NOT NULL DEFAULT 'other',
|
||||
declared_region_code VARCHAR(32),
|
||||
verification_status VARCHAR(32) NOT NULL DEFAULT 'declared',
|
||||
review_task_id UUID REFERENCES review_tasks(id),
|
||||
verified_at TIMESTAMPTZ,
|
||||
verified_by UUID REFERENCES operators(id),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_local_elig_user ON user_local_eligibilities(user_id);
|
||||
CREATE INDEX idx_local_elig_status ON user_local_eligibilities(verification_status);
|
||||
|
||||
ALTER TABLE user_local_eligibilities ADD CONSTRAINT chk_elig_type
|
||||
CHECK (eligibility_type IN ('household_registration', 'residence', 'employment', 'other'));
|
||||
|
||||
ALTER TABLE user_local_eligibilities ADD CONSTRAINT chk_elig_verify_status
|
||||
CHECK (verification_status IN ('declared', 'needs_evidence', 'pending_review', 'verified', 'rejected'));
|
||||
|
||||
-- 本地资格佐证文件表
|
||||
CREATE TABLE IF NOT EXISTS local_eligibility_evidences (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
local_eligibility_id UUID NOT NULL REFERENCES user_local_eligibilities(id) ON DELETE CASCADE,
|
||||
file_key VARCHAR(256) NOT NULL,
|
||||
evidence_type VARCHAR(64) NOT NULL DEFAULT 'other',
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'uploaded',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_evidence_elig ON local_eligibility_evidences(local_eligibility_id);
|
||||
|
||||
ALTER TABLE local_eligibility_evidences ADD CONSTRAINT chk_evidence_type
|
||||
CHECK (evidence_type IN ('employment_proof', 'residence_proof', 'household_proof', 'other'));
|
||||
|
||||
ALTER TABLE local_eligibility_evidences ADD CONSTRAINT chk_evidence_status
|
||||
CHECK (status IN ('uploaded', 'reviewing', 'approved', 'rejected'));
|
||||
@@ -0,0 +1,24 @@
|
||||
-- ============================================================
|
||||
-- V018: V1.1 本地资格审核复用 — review_tasks 扩展
|
||||
-- 新增 review_type=local_eligibility + 本地资格审核索引
|
||||
-- 不含第二套审核引擎,完全复用现有 review_tasks/review_items
|
||||
-- ============================================================
|
||||
|
||||
-- 1. 扩展 review_type CHECK 约束,新增 local_eligibility
|
||||
ALTER TABLE review_tasks DROP CONSTRAINT IF EXISTS chk_review_type;
|
||||
|
||||
ALTER TABLE review_tasks ADD CONSTRAINT chk_review_type
|
||||
CHECK (review_type IN (
|
||||
'initial_profile', 'profile_change', 'photo_change',
|
||||
'marital_status_change', 'risk_recheck',
|
||||
'local_eligibility'
|
||||
));
|
||||
|
||||
-- 2. 本地资格审核队列索引(加速 pending + processing 查询)
|
||||
CREATE INDEX IF NOT EXISTS idx_review_tasks_local_elig
|
||||
ON review_tasks (status, submitted_at)
|
||||
WHERE review_type = 'local_eligibility';
|
||||
|
||||
-- 3. 佐证文件访问审计触发(通过敏感访问日志表记录)
|
||||
-- sensitive_access_logs 表已在 V001 创建,无需新建
|
||||
-- 业务层在访问 local_eligibility_evidences.file_id 时调用审计接口
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
-- ============================================================
|
||||
-- V019: V1.1 首页 Banner + 聚合首页 API 基础
|
||||
-- 创建 home_banners 表 + service_locations 表(单阵地)
|
||||
-- ============================================================
|
||||
|
||||
-- ========== home_banners 表 ==========
|
||||
CREATE TABLE IF NOT EXISTS home_banners (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
title VARCHAR(200) NOT NULL,
|
||||
subtitle VARCHAR(300),
|
||||
image_file_id UUID,
|
||||
button_text VARCHAR(64),
|
||||
target_type VARCHAR(64) NOT NULL DEFAULT 'none',
|
||||
target_value VARCHAR(200),
|
||||
audience_scope VARCHAR(64) NOT NULL DEFAULT 'all',
|
||||
sort_order INT NOT NULL DEFAULT 0,
|
||||
start_at TIMESTAMPTZ,
|
||||
end_at TIMESTAMPTZ,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'active',
|
||||
created_by UUID REFERENCES operators(id),
|
||||
updated_by UUID REFERENCES operators(id),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
ALTER TABLE home_banners ADD CONSTRAINT chk_banner_target_type
|
||||
CHECK (target_type IN ('activity', 'matchmaker', 'counseling', 'premarital', 'service_location', 'article', 'internal_page', 'none'));
|
||||
|
||||
ALTER TABLE home_banners ADD CONSTRAINT chk_banner_audience_scope
|
||||
CHECK (audience_scope IN ('all', 'onboarding', 'searching', 'getting_to_know', 'successful'));
|
||||
|
||||
ALTER TABLE home_banners ADD CONSTRAINT chk_banner_status
|
||||
CHECK (status IN ('draft', 'scheduled', 'active', 'inactive', 'expired'));
|
||||
|
||||
CREATE INDEX idx_home_banners_display ON home_banners(status, start_at, end_at, sort_order)
|
||||
WHERE status IN ('active', 'scheduled');
|
||||
|
||||
-- ========== service_locations 表(万善公园婚姻登记处作为首个阵地) ==========
|
||||
CREATE TABLE IF NOT EXISTS service_locations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(128) NOT NULL,
|
||||
short_name VARCHAR(64),
|
||||
address TEXT NOT NULL,
|
||||
latitude DECIMAL(10, 7),
|
||||
longitude DECIMAL(10, 7),
|
||||
contact_phone_enc TEXT,
|
||||
contact_phone_display VARCHAR(32),
|
||||
opening_hours_text TEXT,
|
||||
service_description TEXT,
|
||||
cover_file_id UUID,
|
||||
primary_organization_id UUID REFERENCES organizations(id),
|
||||
notice_text TEXT,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
ALTER TABLE service_locations ADD CONSTRAINT chk_service_location_status
|
||||
CHECK (status IN ('active', 'inactive', 'closed'));
|
||||
@@ -0,0 +1,13 @@
|
||||
-- ============================================================
|
||||
-- V020: V1.1 通知类型扩展
|
||||
-- 新增 appointment/counseling/premarital/local_eligibility/service_location
|
||||
-- ============================================================
|
||||
|
||||
-- 扩展 notifications.type 约束
|
||||
ALTER TABLE notifications DROP CONSTRAINT IF EXISTS chk_notification_type;
|
||||
|
||||
ALTER TABLE notifications ADD CONSTRAINT chk_notification_type
|
||||
CHECK (type IN (
|
||||
'review', 'match', 'matchmaker', 'activity', 'risk', 'account', 'system',
|
||||
'appointment', 'counseling', 'premarital', 'local_eligibility', 'service_location'
|
||||
));
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
-- ============================================================
|
||||
-- V021: V1.1 Phase 13 - 服务预约表 + 转介追踪字段扩展
|
||||
-- ============================================================
|
||||
|
||||
-- ========== service_appointments 表 ==========
|
||||
CREATE TABLE IF NOT EXISTS service_appointments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL,
|
||||
service_location_id UUID REFERENCES service_locations(id),
|
||||
service_type VARCHAR(64) NOT NULL,
|
||||
preferred_date DATE,
|
||||
preferred_time_slot VARCHAR(32),
|
||||
user_note TEXT,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'submitted',
|
||||
assigned_operator_id UUID REFERENCES operators(id),
|
||||
confirmed_start_at TIMESTAMPTZ,
|
||||
confirmed_end_at TIMESTAMPTZ,
|
||||
cancelled_by UUID REFERENCES operators(id),
|
||||
cancel_reason VARCHAR(500),
|
||||
source VARCHAR(64) NOT NULL DEFAULT 'user_self',
|
||||
request_source VARCHAR(64) NOT NULL DEFAULT 'user_self',
|
||||
created_by_operator_id UUID REFERENCES operators(id),
|
||||
user_confirmed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
ALTER TABLE service_appointments ADD CONSTRAINT chk_appointment_status
|
||||
CHECK (status IN ('submitted', 'pending_confirmation', 'confirmed', 'completed', 'cancelled'));
|
||||
|
||||
ALTER TABLE service_appointments ADD CONSTRAINT chk_source_type
|
||||
CHECK (source IN ('user_self', 'matchmaker_referral', 'activity_followup', 'service_station', 'operator_assisted'));
|
||||
|
||||
CREATE INDEX idx_appointments_user ON service_appointments(user_id, status) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX idx_appointments_location_date ON service_appointments(service_location_id, preferred_date, status) WHERE deleted_at IS NULL;
|
||||
|
||||
-- ========== 为 activity_registrations 添加转介追踪字段 ==========
|
||||
ALTER TABLE activity_registrations ADD COLUMN IF NOT EXISTS source VARCHAR(64) NOT NULL DEFAULT 'user_self';
|
||||
ALTER TABLE activity_registrations ADD COLUMN IF NOT EXISTS request_source VARCHAR(64) NOT NULL DEFAULT 'user_self';
|
||||
ALTER TABLE activity_registrations ADD COLUMN IF NOT EXISTS created_by_operator_id UUID REFERENCES operators(id);
|
||||
ALTER TABLE activity_registrations ADD COLUMN IF NOT EXISTS user_confirmed_at TIMESTAMPTZ;
|
||||
|
||||
ALTER TABLE activity_registrations ADD CONSTRAINT chk_reg_source CHECK (
|
||||
source IN ('user_self', 'matchmaker_referral', 'activity_followup', 'service_station', 'operator_assisted')
|
||||
);
|
||||
|
||||
-- ========== 为 matchmaker services 添加转介目标字段 ==========
|
||||
ALTER TABLE matchmaker_services ADD COLUMN IF NOT EXISTS referral_target_type VARCHAR(64);
|
||||
ALTER TABLE matchmaker_services ADD COLUMN IF NOT EXISTS referral_target_id VARCHAR(128);
|
||||
ALTER TABLE matchmaker_services ADD COLUMN IF NOT EXISTS referral_source_type VARCHAR(64) NOT NULL DEFAULT 'manual';
|
||||
@@ -0,0 +1,67 @@
|
||||
-- ============================================================
|
||||
-- V022: V1.1 Phase 13A - 婚恋咨询 + 婚前辅导 表结构
|
||||
-- ============================================================
|
||||
|
||||
-- ========== counseling_services 表 ==========
|
||||
CREATE TABLE IF NOT EXISTS counseling_services (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL,
|
||||
service_type VARCHAR(64) NOT NULL,
|
||||
request_source VARCHAR(64) NOT NULL DEFAULT 'user_self',
|
||||
user_request_summary TEXT,
|
||||
organization_id UUID REFERENCES organizations(id),
|
||||
assigned_operator_id UUID REFERENCES operators(id),
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
preferred_service_mode VARCHAR(32), -- online / offline
|
||||
preferred_time VARCHAR(128),
|
||||
scheduled_start_at TIMESTAMPTZ,
|
||||
scheduled_end_at TIMESTAMPTZ,
|
||||
consent_version VARCHAR(32),
|
||||
consented_at TIMESTAMPTZ,
|
||||
completed_at TIMESTAMPTZ,
|
||||
closed_reason VARCHAR(500),
|
||||
companion_user_id UUID REFERENCES users(id),
|
||||
created_by_operator_id UUID REFERENCES operators(id),
|
||||
user_confirmed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
ALTER TABLE counseling_services ADD CONSTRAINT chk_counseling_service_type
|
||||
CHECK (service_type IN (
|
||||
'relationship_guidance', 'emotional_support',
|
||||
'premarital_guidance', 'anti_fraud_guidance'
|
||||
));
|
||||
|
||||
ALTER TABLE counseling_services ADD CONSTRAINT chk_counseling_status
|
||||
CHECK (status IN (
|
||||
'pending', 'assigned', 'scheduled', 'in_progress',
|
||||
'completed', 'cancelled', 'closed'
|
||||
));
|
||||
|
||||
ALTER TABLE counseling_services ADD CONSTRAINT chk_request_source
|
||||
CHECK (request_source IN (
|
||||
'user_self', 'matchmaker_referral', 'activity_followup',
|
||||
'service_station', 'operator_assisted'
|
||||
));
|
||||
|
||||
CREATE INDEX idx_counseling_user ON counseling_services(user_id, status) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX idx_counseling_assigned ON counseling_services(assigned_operator_id, status) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX idx_counseling_scheduled ON counseling_services(scheduled_start_at) WHERE deleted_at IS NULL;
|
||||
|
||||
-- ========== counseling_followups 表 ==========
|
||||
CREATE TABLE IF NOT EXISTS counseling_followups (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
counseling_id UUID NOT NULL REFERENCES counseling_services(id),
|
||||
operator_id UUID NOT NULL REFERENCES operators(id),
|
||||
followup_type VARCHAR(32),
|
||||
content TEXT NOT NULL,
|
||||
result_code VARCHAR(64),
|
||||
next_followup_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_followups_counseling ON counseling_followups(counseling_id);
|
||||
CREATE INDEX idx_followups_operator ON counseling_followups(operator_id, created_at DESC);
|
||||
@@ -0,0 +1,48 @@
|
||||
-- ============================================================
|
||||
-- V023: V1.1 Phase 14 - 多类型公益活动扩展
|
||||
-- ============================================================
|
||||
|
||||
-- ========== activities 新增字段 ==========
|
||||
ALTER TABLE activities ADD COLUMN IF NOT EXISTS activity_type VARCHAR(64) NOT NULL DEFAULT 'matchmaking';
|
||||
ALTER TABLE activities ADD COLUMN IF NOT EXISTS registration_policy TEXT;
|
||||
ALTER TABLE activities ADD COLUMN IF NOT EXISTS target_group VARCHAR(200);
|
||||
ALTER TABLE activities ADD COLUMN IF NOT EXISTS industry_scope VARCHAR(200);
|
||||
ALTER TABLE activities ADD COLUMN IF NOT EXISTS post_event_interest_enabled BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
|
||||
ALTER TABLE activities ADD CONSTRAINT chk_activity_type
|
||||
CHECK (activity_type IN (
|
||||
'matchmaking', 'interest_social', 'relationship_education',
|
||||
'premarital_guidance', 'marriage_custom_culture', 'anti_fraud'
|
||||
));
|
||||
|
||||
-- ========== activity_organizations 多组织关联表 ==========
|
||||
CREATE TABLE IF NOT EXISTS activity_organizations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
activity_id UUID NOT NULL REFERENCES activities(id),
|
||||
organization_id UUID NOT NULL REFERENCES organizations(id),
|
||||
role VARCHAR(32) NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(activity_id, organization_id)
|
||||
);
|
||||
|
||||
ALTER TABLE activity_organizations ADD CONSTRAINT chk_org_role
|
||||
CHECK (role IN ('host', 'organizer', 'co_organizer', 'partner', 'venue_partner'));
|
||||
|
||||
CREATE INDEX idx_activity_org_activity ON activity_organizations(activity_id);
|
||||
CREATE INDEX idx_activity_org_org ON activity_organizations(organization_id);
|
||||
|
||||
-- ========== activity_capacity_groups 容量分组表 ==========
|
||||
CREATE TABLE IF NOT EXISTS activity_capacity_groups (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
activity_id UUID NOT NULL REFERENCES activities(id),
|
||||
group_code VARCHAR(32) NOT NULL,
|
||||
rule_definition TEXT,
|
||||
capacity INT NOT NULL DEFAULT 0,
|
||||
approved_count INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(activity_id, group_code)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_capacity_group_activity ON activity_capacity_groups(activity_id);
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
-- ============================================================
|
||||
-- V024: V1.1 Phase 16 - 活动互选二阶段同意重构
|
||||
-- ============================================================
|
||||
|
||||
-- ========== activity_mutual_connection_consents 表 ==========
|
||||
-- 记录每对用户在活动中各自的同意状态(二阶段确认)
|
||||
CREATE TABLE IF NOT EXISTS activity_mutual_connection_consents (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
activity_id UUID NOT NULL REFERENCES activities(id),
|
||||
user_a_id UUID NOT NULL,
|
||||
user_b_id UUID NOT NULL,
|
||||
user_a_status VARCHAR(32) NOT NULL DEFAULT 'pending', -- pending / accepted / declined
|
||||
user_b_status VARCHAR(32) NOT NULL DEFAULT 'pending', -- pending / accepted / declined
|
||||
both_confirmed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(activity_id, user_a_id, user_b_id)
|
||||
);
|
||||
|
||||
ALTER TABLE activity_mutual_connection_consents ADD CONSTRAINT chk_consent_status
|
||||
CHECK (user_a_status IN ('pending', 'accepted', 'declined')
|
||||
AND user_b_status IN ('pending', 'accepted', 'declined'));
|
||||
|
||||
-- 唯一约束:同一对用户在同一个活动中只能有一个活跃同意记录
|
||||
--(通过 activity_id + LEAST(user_a_id, user_b_id) + GREATEST 实现)
|
||||
CREATE UNIQUE INDEX idx_mutual_consents_pair_unique
|
||||
ON activity_mutual_connection_consents(activity_id,
|
||||
LEAST(user_a_id, user_b_id),
|
||||
GREATEST(user_a_id, user_b_id));
|
||||
|
||||
CREATE INDEX idx_mutual_consents_user_a ON activity_mutual_connection_consents(user_a_id, user_a_status);
|
||||
CREATE INDEX idx_mutual_consents_user_b ON activity_mutual_connection_consents(user_b_id, user_b_status);
|
||||
CREATE INDEX idx_mutual_consents_both ON activity_mutual_connection_consents(activity_id, user_a_status, user_b_status)
|
||||
WHERE user_a_status = 'accepted' AND user_b_status = 'accepted';
|
||||
@@ -0,0 +1,17 @@
|
||||
-- ============================================================
|
||||
-- V025: V1.1 Phase 17 - 风险来源扩展(咨询/服务站/活动)
|
||||
-- ============================================================
|
||||
|
||||
-- 扩展 risk_events.event_type CHECK 约束
|
||||
ALTER TABLE risk_events DROP CONSTRAINT IF EXISTS chk_risk_event_type;
|
||||
ALTER TABLE risk_events ADD CONSTRAINT chk_risk_event_type
|
||||
CHECK (event_type IN (
|
||||
'abuse_report', 'high_risk_message', 'manual_flag',
|
||||
'fake_marital_status_report', 'counseling_risk',
|
||||
'appointment_risk', 'activity_risk'
|
||||
));
|
||||
|
||||
-- 扩展 risk_actions.action_type CHECK 约束,支持人工风险标记
|
||||
ALTER TABLE risk_actions DROP CONSTRAINT IF EXISTS chk_risk_action_type;
|
||||
ALTER TABLE risk_actions ADD CONSTRAINT chk_risk_action_type
|
||||
CHECK (action_type IN ('warning', 'feature_limit', 'temporary_suspend', 'ban', 'manual_flag'));
|
||||
@@ -0,0 +1,106 @@
|
||||
-- ============================================================
|
||||
-- V026: V1.1 Phase 19 - 内容管理 + 专项公益服务项目 + 组织关系
|
||||
-- ============================================================
|
||||
|
||||
-- ========== content_categories 表 ==========
|
||||
CREATE TABLE IF NOT EXISTS content_categories (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(128) NOT NULL,
|
||||
code VARCHAR(64) NOT NULL,
|
||||
description TEXT,
|
||||
sort_order INT NOT NULL DEFAULT 0,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(code)
|
||||
);
|
||||
|
||||
ALTER TABLE content_categories ADD CONSTRAINT chk_category_status
|
||||
CHECK (status IN ('active', 'inactive'));
|
||||
|
||||
-- ========== content_articles 表 ==========
|
||||
CREATE TABLE IF NOT EXISTS content_articles (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
category_id UUID REFERENCES content_categories(id),
|
||||
title VARCHAR(200) NOT NULL,
|
||||
summary VARCHAR(500),
|
||||
content TEXT,
|
||||
cover_file_id UUID,
|
||||
author_operator_id UUID REFERENCES operators(id),
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'draft',
|
||||
publish_at TIMESTAMPTZ,
|
||||
view_count INT NOT NULL DEFAULT 0,
|
||||
sort_order INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
ALTER TABLE content_articles ADD CONSTRAINT chk_article_status
|
||||
CHECK (status IN ('draft', 'scheduled', 'published', 'offline'));
|
||||
|
||||
CREATE INDEX idx_articles_category ON content_articles(category_id, status) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX idx_articles_publish ON content_articles(status, publish_at) WHERE deleted_at IS NULL;
|
||||
|
||||
-- ========== service_programs 表 ==========
|
||||
CREATE TABLE IF NOT EXISTS service_programs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(128) NOT NULL,
|
||||
description TEXT,
|
||||
cover_file_id UUID,
|
||||
organizer_org_id UUID REFERENCES organizations(id),
|
||||
start_at TIMESTAMPTZ,
|
||||
end_at TIMESTAMPTZ,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'draft',
|
||||
created_by UUID REFERENCES operators(id),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
ALTER TABLE service_programs ADD CONSTRAINT chk_program_status
|
||||
CHECK (status IN ('draft', 'active', 'ended', 'cancelled'));
|
||||
|
||||
CREATE INDEX idx_programs_status ON service_programs(status, start_at) WHERE deleted_at IS NULL;
|
||||
|
||||
-- ========== service_program_members 表 ==========
|
||||
CREATE TABLE IF NOT EXISTS service_program_members (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
program_id UUID NOT NULL REFERENCES service_programs(id),
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
approved_at TIMESTAMPTZ,
|
||||
approved_by UUID REFERENCES operators(id),
|
||||
rejected_reason VARCHAR(500),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(program_id, user_id)
|
||||
);
|
||||
|
||||
ALTER TABLE service_program_members ADD CONSTRAINT chk_program_member_status
|
||||
CHECK (status IN ('pending', 'approved', 'rejected', 'withdrawn'));
|
||||
|
||||
CREATE INDEX idx_program_members_program ON service_program_members(program_id, status);
|
||||
CREATE INDEX idx_program_members_user ON service_program_members(user_id, status);
|
||||
|
||||
-- ========== organization_relationships 表 ==========
|
||||
CREATE TABLE IF NOT EXISTS organization_relationships (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
org_a_id UUID NOT NULL REFERENCES organizations(id),
|
||||
org_b_id UUID NOT NULL REFERENCES organizations(id),
|
||||
relationship_type VARCHAR(64) NOT NULL,
|
||||
description TEXT,
|
||||
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
ended_at TIMESTAMPTZ,
|
||||
created_by UUID REFERENCES operators(id),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(org_a_id, org_b_id, relationship_type)
|
||||
);
|
||||
|
||||
ALTER TABLE organization_relationships ADD CONSTRAINT chk_rel_type
|
||||
CHECK (relationship_type IN ('partner', 'venue_partner', 'referral_partner', 'sponsor', 'collaborator'));
|
||||
|
||||
CREATE INDEX idx_org_rel_a ON organization_relationships(org_a_id, relationship_type);
|
||||
CREATE INDEX idx_org_rel_b ON organization_relationships(org_b_id, relationship_type);
|
||||
@@ -0,0 +1,41 @@
|
||||
-- ============================================================
|
||||
-- V027: V1.1 Production 初始化种子数据
|
||||
-- Phase 26: Production Initialization
|
||||
-- ============================================================
|
||||
|
||||
-- ========== T01: Seed Content Categories ==========
|
||||
INSERT INTO content_categories (id, name, code, description, sort_order, status, created_at) VALUES
|
||||
(gen_random_uuid(), '婚恋课堂', 'marriage_class', '婚恋 relationship 知识和技巧', 1, 'active', NOW()),
|
||||
(gen_random_uuid(), '婚恋反诈', 'anti_fraud', '婚恋诈骗识别与防范知识', 2, 'active', NOW()),
|
||||
(gen_random_uuid(), '婚前辅导', 'premarital_edu', '婚前准备与关系建立指导', 3, 'active', NOW()),
|
||||
(gen_random_uuid(), '婚俗新风', 'custom_culture', '传统婚俗与文明新风尚', 4, 'active', NOW());
|
||||
|
||||
-- ========== T02: Seed Activity Types (already in CHECK constraint, no DB seed needed) ==========
|
||||
-- Activity types are validated by CHECK constraint: matchmaking, interest_social, relationship_education, premarital_guidance, marriage_custom_culture, anti_fraud
|
||||
|
||||
-- ========== T03: Seed Service Types ==========
|
||||
-- Service types are validated by CHECK constraints in respective tables
|
||||
|
||||
-- ========== T04: Initialize 万善公园服务站 ==========
|
||||
INSERT INTO service_locations (id, name, short_name, address, latitude, longitude, contact_phone_display, opening_hours_text, service_description, status, created_at) VALUES
|
||||
(gen_random_uuid(), '万善公园婚姻登记处善缘服务站', '万善公园站', '丹阳市云阳街道万善公园内', 31.9086, 119.5281, '0511-88888888',
|
||||
'周一至周五 9:00-17:00
|
||||
周六 9:00-12:00(法定节假日除外)',
|
||||
'提供公益红娘服务、婚恋咨询预约、婚前辅导、本地资格核验等综合婚姻服务',
|
||||
'active', NOW());
|
||||
|
||||
-- ========== T05: Initialize Banners ==========
|
||||
INSERT INTO home_banners (id, title, subtitle, button_text, target_type, target_value, audience_scope, sort_order, start_at, end_at, status, created_at) VALUES
|
||||
(gen_random_uuid(), '公益婚恋服务', '实名认证 · 本地资格 · 人工审核 · 双向匹配', '立即体验', 'internal_page', 'home', 'all', 1, NOW() - INTERVAL '30 days', NOW() + INTERVAL '365 days', 'active', NOW()),
|
||||
(gen_random_uuid(), '万善公园服务站', '每周三、五下午开设公益红娘服务', '查看服务站', 'service_location', NULL, 'all', 2, NOW() - INTERVAL '30 days', NOW() + INTERVAL '365 days', 'active', NOW()),
|
||||
(gen_random_uuid(), '公益活动报名中', '近期有多场交友活动,欢迎参加', '查看全部活动', 'activity', NULL, 'all', 3, NOW() - INTERVAL '30 days', NOW() + INTERVAL '90 days', 'active', NOW());
|
||||
|
||||
-- ========== T06: Initialize Feature Flags (if using DB-based feature flags) ==========
|
||||
-- Feature flags are configured via application.yml / application-dev.yml / application-docker.yml
|
||||
-- No DB seed needed for Phase 26
|
||||
|
||||
-- ========== T07: Seed Roles/Permissions ==========
|
||||
-- Roles and permissions were already seeded in V015__add_v11_roles_and_permissions.sql
|
||||
-- Verify they exist:
|
||||
SELECT COUNT(*) as role_count FROM roles WHERE id::text LIKE '30000000-%';
|
||||
SELECT COUNT(*) as permission_count FROM permissions WHERE id::text LIKE '20000000-%';
|
||||
Reference in New Issue
Block a user