Browse Source

项目代码

main
wanghao 5 days ago
parent
commit
16c94a81ba
  1. 109
      docs/20260908_case_risk_warning.sql
  2. 99
      docs/20260908_case_risk_warning_seed.sql
  3. 7
      docs/20260909_clear_risk_warning_submenu_icons.sql
  4. 7
      docs/20260909_fix_risk_warning_menu_component.sql
  5. 63
      docs/20260909_risk_warning_rule_submenus.sql
  6. 150
      docs/20260928_case_supervision.sql
  7. 58
      docs/20260928_case_supervision_seed.sql
  8. 107
      docs/20261015_alarm_audit_demo_accounts.sql
  9. 305
      docs/20261015_biz_demo_roles_accounts.sql
  10. 63
      docs/20261015_case_source_dict.sql
  11. 19
      docs/20261015_weekly_schedule_minutes.sql
  12. 40
      docs/Plan/prd-case-risk-warning.md
  13. 49
      docs/Plan/prd-case-supervision.md
  14. 0
      economic-crime-api/economic-crime-admin/logs/economic-crime/dev/tomcat-logs/logs/access_log.2026-09-09.log

109
docs/20260908_case_risk_warning.sql

@ -0,0 +1,109 @@
-- 案件三色预警:案件快照 + 法律文书抓取 + 活动日志 + 预警单
-- 红色通报一旦触发不可消除
-- 接报案来源:人民检察院通知立案;法院/检察院子项允许普通经侦
ALTER TABLE t_alarm_report DROP CONSTRAINT IF EXISTS t_alarm_report_case_source_check;
ALTER TABLE t_alarm_report ADD CONSTRAINT t_alarm_report_case_source_check
CHECK (case_source IS NULL OR case_source IN (
'party_report',
'admin_transfer',
'court_transfer',
'procuratorate_transfer',
'procuratorate_notify',
'superior_assign',
'work_discovery',
'other_unit_transfer'
));
ALTER TABLE t_alarm_report DROP CONSTRAINT IF EXISTS t_alarm_report_case_source_sub_check;
ALTER TABLE t_alarm_report ADD CONSTRAINT t_alarm_report_case_source_sub_check
CHECK (case_source_sub IS NULL OR case_source_sub IN ('false_litigation', 'other', 'normal'));
INSERT INTO t_dict_data (dict_id, data_value, data_label, remark, sort_order, disabled_flag, create_time, update_time)
SELECT d.dict_id, 'procuratorate_notify', '人民检察院通知立案', '案件来源', 5, false, NOW(), NOW()
FROM t_dict d
WHERE d.dict_code = 'CASE_SOURCE'
AND NOT EXISTS (
SELECT 1 FROM t_dict_data x
WHERE x.dict_id = d.dict_id AND x.data_value = 'procuratorate_notify'
);
UPDATE t_dict_data SET sort_order = 6 WHERE dict_id = (SELECT dict_id FROM t_dict WHERE dict_code = 'CASE_SOURCE') AND data_value = 'superior_assign';
UPDATE t_dict_data SET sort_order = 7 WHERE dict_id = (SELECT dict_id FROM t_dict WHERE dict_code = 'CASE_SOURCE') AND data_value = 'work_discovery';
UPDATE t_dict_data SET sort_order = 8 WHERE dict_id = (SELECT dict_id FROM t_dict WHERE dict_code = 'CASE_SOURCE') AND data_value = 'other_unit_transfer';
INSERT INTO t_dict_data (dict_id, data_value, data_label, remark, sort_order, disabled_flag, create_time, update_time)
SELECT d.dict_id, 'normal', '普通经侦案件', '案件来源子项', 0, false, NOW(), NOW()
FROM t_dict d
WHERE d.dict_code = 'CASE_SOURCE_SUB'
AND NOT EXISTS (
SELECT 1 FROM t_dict_data x
WHERE x.dict_id = d.dict_id AND x.data_value = 'normal'
);
CREATE TABLE IF NOT EXISTS t_case_file (
case_id BIGSERIAL PRIMARY KEY,
case_no VARCHAR(64) NOT NULL,
case_name VARCHAR(200) NOT NULL,
alarm_id BIGINT,
case_source VARCHAR(64),
case_source_sub VARCHAR(64),
handler_name VARCHAR(64),
review_decide_time TIMESTAMP,
accept_time TIMESTAMP,
filing_time TIMESTAMP,
detention_time TIMESTAMP,
arrest_time TIMESTAMP,
residential_time TIMESTAMP,
designated_time TIMESTAMP,
create_time TIMESTAMP DEFAULT NOW(),
update_time TIMESTAMP DEFAULT NOW(),
deleted_flag BOOLEAN DEFAULT FALSE
);
CREATE UNIQUE INDEX IF NOT EXISTS uk_t_case_file_no ON t_case_file(case_no) WHERE deleted_flag = FALSE;
CREATE TABLE IF NOT EXISTS t_case_legal_doc (
doc_id BIGSERIAL PRIMARY KEY,
case_id BIGINT NOT NULL,
doc_type VARCHAR(64) NOT NULL,
doc_name VARCHAR(200) NOT NULL,
issue_time TIMESTAMP NOT NULL,
approved_flag BOOLEAN DEFAULT TRUE,
interrogated BOOLEAN DEFAULT FALSE,
seq_no INTEGER DEFAULT 1,
create_time TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_t_case_legal_doc_case ON t_case_legal_doc(case_id, doc_type);
CREATE TABLE IF NOT EXISTS t_case_activity_log (
log_id BIGSERIAL PRIMARY KEY,
case_id BIGINT NOT NULL,
activity_time TIMESTAMP NOT NULL,
activity_title VARCHAR(200) NOT NULL,
operator_name VARCHAR(64),
create_time TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_t_case_activity_case ON t_case_activity_log(case_id, activity_time);
CREATE TABLE IF NOT EXISTS t_case_risk_warning (
warning_id BIGSERIAL PRIMARY KEY,
warning_no VARCHAR(64) NOT NULL,
case_id BIGINT NOT NULL,
rule_code VARCHAR(64) NOT NULL,
track_key VARCHAR(64) NOT NULL,
color VARCHAR(16) NOT NULL,
reason TEXT NOT NULL,
elapsed_days INTEGER,
sticky_red BOOLEAN DEFAULT FALSE,
status VARCHAR(32) NOT NULL DEFAULT 'open',
process_measure TEXT,
process_remark TEXT,
process_user VARCHAR(64),
process_time TIMESTAMP,
trigger_time TIMESTAMP NOT NULL DEFAULT NOW(),
update_time TIMESTAMP DEFAULT NOW()
);
CREATE UNIQUE INDEX IF NOT EXISTS uk_t_case_risk_warning_no ON t_case_risk_warning(warning_no);
CREATE INDEX IF NOT EXISTS idx_t_case_risk_warning_case ON t_case_risk_warning(case_id, rule_code, track_key);
COMMENT ON TABLE t_case_risk_warning IS '案件三色预警:红=问题通报 黄=问题预警 蓝=普通提醒;红色 sticky_red 后不可消除';

99
docs/20260908_case_risk_warning_seed.sql

@ -0,0 +1,99 @@
-- 案件三色预警演示数据(相对当前时间构造超期场景)
INSERT INTO t_case_file (
case_no, case_name, case_source, case_source_sub, handler_name,
review_decide_time, accept_time, filing_time,
detention_time, arrest_time, residential_time, designated_time
)
SELECT v.case_no, v.case_name, v.case_source, v.case_source_sub, v.handler_name,
v.review_decide_time, v.accept_time, v.filing_time,
v.detention_time, v.arrest_time, v.residential_time, v.designated_time
FROM (VALUES
('AJFX20260908001', '审议受案超24小时未受案', 'party_report', NULL, '张警官',
NOW() - INTERVAL '36 hour', NULL, NULL, NULL, NULL, NULL, NULL),
('AJFX20260908002', '普通经侦立案审查第6日', 'party_report', NULL, '李警官',
NOW() - INTERVAL '10 day', NOW() - INTERVAL '6 day', NULL, NULL, NULL, NULL, NULL),
('AJFX20260908003', '行政机关移送立案审查超期', 'admin_transfer', NULL, '王警官',
NOW() - INTERVAL '20 day', NOW() - INTERVAL '12 day', NULL, NULL, NULL, NULL, NULL),
('AJFX20260908004', '法院移送普通经侦审查', 'court_transfer', 'normal', '赵警官',
NOW() - INTERVAL '15 day', NOW() - INTERVAL '9 day', NULL, NULL, NULL, NULL, NULL),
('AJFX20260908005', '法院移送虚假诉讼审查', 'court_transfer', 'false_litigation', '孙警官',
NOW() - INTERVAL '40 day', NOW() - INTERVAL '26 day', NULL, NULL, NULL, NULL, NULL),
('AJFX20260908006', '检察院通知立案超期', 'procuratorate_notify', NULL, '钱警官',
NOW() - INTERVAL '20 day', NOW() - INTERVAL '16 day', NULL, NULL, NULL, NULL, NULL),
('AJFX20260908007', '普通经侦一延后审查', 'party_report', NULL, '周警官',
NOW() - INTERVAL '40 day', NOW() - INTERVAL '26 day', NULL, NULL, NULL, NULL, NULL),
('AJFX20260908008', '中止立案审查期限中', 'work_discovery', NULL, '吴警官',
NOW() - INTERVAL '30 day', NOW() - INTERVAL '28 day', NULL, NULL, NULL, NULL, NULL),
('AJFX20260908009', '取保候审传讯超期', 'party_report', NULL, '郑警官',
NOW() - INTERVAL '80 day', NOW() - INTERVAL '70 day', NOW() - INTERVAL '65 day', NULL, NULL, NULL, NULL),
('AJFX20260908010', '受案后长期无活动', 'superior_assign', NULL, '冯警官',
NOW() - INTERVAL '70 day', NOW() - INTERVAL '55 day', NULL, NULL, NULL, NULL, NULL),
('AJFX20260908011', '立案后长期无活动', 'party_report', NULL, '陈警官',
NOW() - INTERVAL '100 day', NOW() - INTERVAL '90 day', NOW() - INTERVAL '70 day', NULL, NULL, NULL, NULL),
('AJFX20260908012', '刑拘24小时未制作拘留通知书', 'party_report', NULL, '卫警官',
NOW() - INTERVAL '10 day', NOW() - INTERVAL '8 day', NOW() - INTERVAL '7 day',
NOW() - INTERVAL '30 hour', NULL, NULL, NULL),
('AJFX20260908013', '逮捕后羁押期限超两个月', 'party_report', NULL, '蒋警官',
NOW() - INTERVAL '90 day', NOW() - INTERVAL '85 day', NOW() - INTERVAL '80 day',
NOW() - INTERVAL '75 day', NOW() - INTERVAL '65 day', NULL, NULL),
('AJFX20260908014', '监视居住将满6个月', 'admin_transfer', NULL, '沈警官',
NOW() - INTERVAL '200 day', NOW() - INTERVAL '190 day', NOW() - INTERVAL '185 day',
NULL, NULL, NOW() - INTERVAL '185 day', NULL),
('AJFX20260908015', '指定居所监视居住未通知', 'party_report', NULL, '韩警官',
NOW() - INTERVAL '5 day', NOW() - INTERVAL '4 day', NOW() - INTERVAL '3 day',
NULL, NULL, NULL, NOW() - INTERVAL '30 hour')
) AS v(case_no, case_name, case_source, case_source_sub, handler_name,
review_decide_time, accept_time, filing_time,
detention_time, arrest_time, residential_time, designated_time)
WHERE NOT EXISTS (SELECT 1 FROM t_case_file c WHERE c.case_no = v.case_no AND c.deleted_flag = FALSE);
-- 一延呈请审批结束
INSERT INTO t_case_legal_doc (case_id, doc_type, doc_name, issue_time, approved_flag, seq_no)
SELECT c.case_id, 'extend_filing_deadline', '呈请延长立案期限报告书', NOW() - INTERVAL '20 day', TRUE, 1
FROM t_case_file c
WHERE c.case_no = 'AJFX20260908007'
AND NOT EXISTS (SELECT 1 FROM t_case_legal_doc d WHERE d.case_id = c.case_id AND d.doc_type = 'extend_filing_deadline');
-- 中止立案审查(第22日,应出蓝色)
INSERT INTO t_case_legal_doc (case_id, doc_type, doc_name, issue_time, approved_flag, seq_no)
SELECT c.case_id, 'suspend_filing', '中止立案审查期限通知书', NOW() - INTERVAL '22 day', TRUE, 1
FROM t_case_file c
WHERE c.case_no = 'AJFX20260908008'
AND NOT EXISTS (SELECT 1 FROM t_case_legal_doc d WHERE d.case_id = c.case_id AND d.doc_type = 'suspend_filing');
-- 取保候审决定书(约70日前),期间无传讯
INSERT INTO t_case_legal_doc (case_id, doc_type, doc_name, issue_time, approved_flag, interrogated, seq_no)
SELECT c.case_id, 'bail_decision', '取保候审决定书', NOW() - INTERVAL '70 day', TRUE, FALSE, 1
FROM t_case_file c
WHERE c.case_no = 'AJFX20260908009'
AND NOT EXISTS (SELECT 1 FROM t_case_legal_doc d WHERE d.case_id = c.case_id AND d.doc_type = 'bail_decision');
-- 监视居住决定书
INSERT INTO t_case_legal_doc (case_id, doc_type, doc_name, issue_time, approved_flag, seq_no)
SELECT c.case_id, 'residential_decision', '监视居住决定书', NOW() - INTERVAL '185 day', TRUE, 1
FROM t_case_file c
WHERE c.case_no = 'AJFX20260908014'
AND NOT EXISTS (SELECT 1 FROM t_case_legal_doc d WHERE d.case_id = c.case_id AND d.doc_type = 'residential_decision');
-- 指定居所决定书(无通知书)
INSERT INTO t_case_legal_doc (case_id, doc_type, doc_name, issue_time, approved_flag, seq_no)
SELECT c.case_id, 'designated_residence', '指定居所监视居住决定书', NOW() - INTERVAL '30 hour', TRUE, 1
FROM t_case_file c
WHERE c.case_no = 'AJFX20260908015'
AND NOT EXISTS (SELECT 1 FROM t_case_legal_doc d WHERE d.case_id = c.case_id AND d.doc_type = 'designated_residence');
-- 活动日志:有立案但长期无后续的案件仅保留立案当时日志
INSERT INTO t_case_activity_log (case_id, activity_time, activity_title, operator_name)
SELECT c.case_id, c.filing_time, '立案决定', c.handler_name
FROM t_case_file c
WHERE c.case_no = 'AJFX20260908011'
AND c.filing_time IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM t_case_activity_log l WHERE l.case_id = c.case_id);
INSERT INTO t_case_activity_log (case_id, activity_time, activity_title, operator_name)
SELECT c.case_id, c.accept_time, '受案登记', c.handler_name
FROM t_case_file c
WHERE c.case_no IN ('AJFX20260908002','AJFX20260908003','AJFX20260908004','AJFX20260908005','AJFX20260908006','AJFX20260908007','AJFX20260908008')
AND c.accept_time IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM t_case_activity_log l WHERE l.case_id = c.case_id);

7
docs/20260909_clear_risk_warning_submenu_icons.sql

@ -0,0 +1,7 @@
-- 风险预警 13 条规则子菜单去掉图标
UPDATE t_menu
SET icon = NULL,
update_time = NOW()
WHERE deleted_flag = 0
AND menu_type = 2
AND path LIKE '/case-management/risk-warning/%';

7
docs/20260909_fix_risk_warning_menu_component.sql

@ -0,0 +1,7 @@
-- 风险预警菜单组件路径写错,页面无法加载(空白)
UPDATE t_menu
SET component = '/business/case-management/risk-warning.vue',
update_time = NOW()
WHERE path = '/case-management/risk-warning'
AND deleted_flag = 0
AND (component IS NULL OR component <> '/business/case-management/risk-warning.vue');

63
docs/20260909_risk_warning_rule_submenus.sql

@ -0,0 +1,63 @@
-- 风险预警保持二级(仍挂在案件管理下),改为目录后挂 13 条规则三级子菜单
-- 不改变 parent_id / sort,只把自身从页面改为目录
UPDATE t_menu
SET menu_type = 1,
component = NULL,
path = '/case-management/risk-warning',
update_time = NOW()
WHERE menu_name = '风险预警'
AND path = '/case-management/risk-warning'
AND deleted_flag = 0;
INSERT INTO t_menu (menu_name, menu_type, parent_id, sort, path, component,
frame_flag, cache_flag, visible_flag, disabled_flag,
perms_type, icon, deleted_flag, create_user_id, create_time, update_time)
SELECT v.menu_name, 2, p.menu_id, v.sort_num, v.path, '/business/case-management/risk-warning.vue',
false, false, true, false, 1, NULL, false, 1, NOW(), NOW()
FROM t_menu p
CROSS JOIN (VALUES
('审议受案超时', 1, '/case-management/risk-warning/accept-timeout', 'accept_timeout'),
('立案审查期限', 2, '/case-management/risk-warning/filing-deadline', 'filing_deadline'),
('取保候审传讯', 3, '/case-management/risk-warning/bail-summons', 'bail_summons'),
('取保候审期限', 4, '/case-management/risk-warning/bail-expire', 'bail_expire'),
('受案后无活动', 5, '/case-management/risk-warning/accept-inactivity', 'accept_inactivity'),
('立案后无活动', 6, '/case-management/risk-warning/filing-inactivity', 'filing_inactivity'),
('刑拘通知书', 7, '/case-management/risk-warning/detention-notice', 'detention_notice'),
('刑拘羁押期限', 8, '/case-management/risk-warning/detention-deadline', 'detention_deadline'),
('逮捕通知书', 9, '/case-management/risk-warning/arrest-notice', 'arrest_notice'),
('逮捕羁押期限', 10, '/case-management/risk-warning/arrest-deadline', 'arrest_deadline'),
('监视居住期限', 11, '/case-management/risk-warning/residential-expire', 'residential_expire'),
('监视居住传讯', 12, '/case-management/risk-warning/residential-summons', 'residential_summons'),
('指定居所通知', 13, '/case-management/risk-warning/designated-notice', 'designated_notice')
) AS v(menu_name, sort_num, path, rule_code)
WHERE p.menu_name = '风险预警'
AND p.path = '/case-management/risk-warning'
AND p.deleted_flag = 0
AND NOT EXISTS (SELECT 1 FROM t_menu x WHERE x.path = v.path AND x.deleted_flag = 0);
-- 原功能点仍挂在「风险预警」目录下
UPDATE t_menu f
SET parent_id = p.menu_id,
context_menu_id = p.menu_id,
update_time = NOW()
FROM t_menu p
WHERE p.menu_name = '风险预警'
AND p.path = '/case-management/risk-warning'
AND p.deleted_flag = 0
AND f.deleted_flag = 0
AND f.menu_type = 3
AND f.web_perms IN ('risk-warning:query', 'risk-warning:view', 'risk-warning:process', 'risk-warning:ignore');
-- 有「风险预警」权限的角色同步绑定全部规则子菜单
INSERT INTO t_role_menu (role_id, menu_id)
SELECT rm.role_id, c.menu_id
FROM t_role_menu rm
JOIN t_menu p ON p.menu_id = rm.menu_id
JOIN t_menu c ON c.parent_id = p.menu_id AND c.deleted_flag = 0 AND c.menu_type = 2
WHERE p.menu_name = '风险预警'
AND p.path = '/case-management/risk-warning'
AND p.deleted_flag = 0
AND NOT EXISTS (
SELECT 1 FROM t_role_menu x WHERE x.role_id = rm.role_id AND x.menu_id = c.menu_id
);

150
docs/20260928_case_supervision.sql

@ -0,0 +1,150 @@
-- 案件监督:负面清单巡查 + 周调度
-- 1) t_case_file 补业务分类/创建单位/办案单位/案件状态
-- 2) 周调度主表 + 案件快照 + 参会人员
-- 3) 案件监督改为目录并挂两个子菜单及功能权限
-- ========== 案件快照补字段 ==========
ALTER TABLE t_case_file ADD COLUMN IF NOT EXISTS biz_category VARCHAR(32) DEFAULT '经侦';
ALTER TABLE t_case_file ADD COLUMN IF NOT EXISTS create_dept VARCHAR(128);
ALTER TABLE t_case_file ADD COLUMN IF NOT EXISTS handle_dept VARCHAR(128);
ALTER TABLE t_case_file ADD COLUMN IF NOT EXISTS case_status VARCHAR(32) DEFAULT 'investigating';
COMMENT ON COLUMN t_case_file.biz_category IS '业务系统分类:经侦/刑侦等';
COMMENT ON COLUMN t_case_file.create_dept IS '创建单位';
COMMENT ON COLUMN t_case_file.handle_dept IS '办案单位';
COMMENT ON COLUMN t_case_file.case_status IS '案件状态:pending_filing/investigating/closed/withdrawn';
UPDATE t_case_file
SET biz_category = COALESCE(NULLIF(biz_category, ''), '经侦'),
case_status = COALESCE(NULLIF(case_status, ''), 'investigating')
WHERE deleted_flag = FALSE;
-- ========== 周调度 ==========
CREATE TABLE IF NOT EXISTS t_case_weekly_schedule (
schedule_id BIGSERIAL PRIMARY KEY,
schedule_no VARCHAR(64) NOT NULL,
schedule_content TEXT,
status VARCHAR(32) NOT NULL DEFAULT 'draft',
create_user_id BIGINT,
create_user_name VARCHAR(64),
push_time TIMESTAMP,
lock_time TIMESTAMP,
create_time TIMESTAMP DEFAULT NOW(),
update_time TIMESTAMP DEFAULT NOW(),
deleted_flag BOOLEAN DEFAULT FALSE
);
CREATE UNIQUE INDEX IF NOT EXISTS uk_t_case_weekly_schedule_no
ON t_case_weekly_schedule(schedule_no) WHERE deleted_flag = FALSE;
CREATE INDEX IF NOT EXISTS idx_t_case_weekly_schedule_status
ON t_case_weekly_schedule(status) WHERE deleted_flag = FALSE;
COMMENT ON TABLE t_case_weekly_schedule IS '案件周调度:draft未推送 / pending_confirm待确认 / confirmed全员确认已锁定';
CREATE TABLE IF NOT EXISTS t_case_weekly_schedule_case (
item_id BIGSERIAL PRIMARY KEY,
schedule_id BIGINT NOT NULL,
case_id BIGINT NOT NULL,
case_no VARCHAR(64) NOT NULL,
case_name VARCHAR(200) NOT NULL,
create_dept VARCHAR(128),
handle_dept VARCHAR(128),
case_status VARCHAR(32),
accept_time TIMESTAMP,
sort_no INTEGER DEFAULT 0,
create_time TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_t_case_weekly_schedule_case_sid
ON t_case_weekly_schedule_case(schedule_id);
CREATE TABLE IF NOT EXISTS t_case_weekly_schedule_member (
member_id BIGSERIAL PRIMARY KEY,
schedule_id BIGINT NOT NULL,
employee_id BIGINT NOT NULL,
employee_name VARCHAR(64),
confirmed_flag BOOLEAN DEFAULT FALSE,
confirm_time TIMESTAMP,
create_time TIMESTAMP DEFAULT NOW()
);
CREATE UNIQUE INDEX IF NOT EXISTS uk_t_case_weekly_schedule_member
ON t_case_weekly_schedule_member(schedule_id, employee_id);
CREATE INDEX IF NOT EXISTS idx_t_case_weekly_schedule_member_emp
ON t_case_weekly_schedule_member(employee_id, confirmed_flag);
-- ========== 菜单:案件监督改为目录 ==========
UPDATE t_menu
SET menu_type = 1,
component = NULL,
path = '/case-management/supervision',
update_time = NOW()
WHERE menu_name = '案件监督'
AND path = '/case-management/supervision'
AND deleted_flag = 0;
-- 旧功能点挂在原页面上,改为目录后下线
UPDATE t_menu f
SET deleted_flag = TRUE,
update_time = NOW()
FROM t_menu p
WHERE p.menu_name = '案件监督'
AND p.path = '/case-management/supervision'
AND p.deleted_flag = 0
AND f.parent_id = p.menu_id
AND f.menu_type = 3
AND f.deleted_flag = 0
AND f.web_perms IN (
'case:query',
'case-supervision:query',
'case-supervision:add',
'case-supervision:view',
'case-supervision:supervise'
);
INSERT INTO t_menu (menu_name, menu_type, parent_id, sort, path, component,
frame_flag, cache_flag, visible_flag, disabled_flag,
perms_type, icon, deleted_flag, create_user_id, create_time, update_time)
SELECT v.menu_name, 2, p.menu_id, v.sort_num, v.path, v.component,
false, false, true, false, 1, NULL, false, 1, NOW(), NOW()
FROM t_menu p
CROSS JOIN (VALUES
('负面清单巡查', 1, '/case-management/supervision/negative-list',
'/business/case-management/negative-list.vue'),
('周调度', 2, '/case-management/supervision/weekly-schedule',
'/business/case-management/weekly-schedule.vue')
) AS v(menu_name, sort_num, path, component)
WHERE p.menu_name = '案件监督'
AND p.path = '/case-management/supervision'
AND p.deleted_flag = 0
AND NOT EXISTS (SELECT 1 FROM t_menu x WHERE x.path = v.path AND x.deleted_flag = 0);
-- 功能权限
INSERT INTO t_menu (menu_name, menu_type, parent_id, sort, frame_flag, cache_flag,
visible_flag, disabled_flag, perms_type, api_perms, web_perms,
context_menu_id, deleted_flag, create_user_id, create_time, update_time)
SELECT v.menu_name, 3, c.menu_id, v.sort_num, false, false, true, false, 1,
v.perms, v.perms, c.menu_id, false, 1, NOW(), NOW()
FROM t_menu c
CROSS JOIN (VALUES
('查询', 10, 'negative-list:query', '/case-management/supervision/negative-list'),
('查询', 10, 'weekly-schedule:query', '/case-management/supervision/weekly-schedule'),
('新增', 20, 'weekly-schedule:add', '/case-management/supervision/weekly-schedule'),
('查看', 30, 'weekly-schedule:view', '/case-management/supervision/weekly-schedule'),
('推送', 40, 'weekly-schedule:push', '/case-management/supervision/weekly-schedule'),
('确认', 50, 'weekly-schedule:confirm', '/case-management/supervision/weekly-schedule'),
('打印', 60, 'weekly-schedule:print', '/case-management/supervision/weekly-schedule')
) AS v(menu_name, sort_num, perms, child_path)
WHERE c.path = v.child_path
AND c.deleted_flag = 0
AND NOT EXISTS (SELECT 1 FROM t_menu x WHERE x.web_perms = v.perms AND x.deleted_flag = 0);
-- 原有「案件监督」权限的角色同步绑定子菜单及功能点
INSERT INTO t_role_menu (role_id, menu_id)
SELECT DISTINCT rm.role_id, c.menu_id
FROM t_role_menu rm
JOIN t_menu p ON p.menu_id = rm.menu_id
JOIN t_menu c ON c.parent_id = p.menu_id AND c.deleted_flag = 0 AND c.menu_type IN (2, 3)
WHERE p.menu_name = '案件监督'
AND p.path = '/case-management/supervision'
AND p.deleted_flag = 0
AND NOT EXISTS (
SELECT 1 FROM t_role_menu x WHERE x.role_id = rm.role_id AND x.menu_id = c.menu_id
);

58
docs/20260928_case_supervision_seed.sql

@ -0,0 +1,58 @@
-- 案件监督演示数据:补全现有案件单位字段,并插入派出所办案单位案件供负面清单标红
UPDATE t_case_file
SET biz_category = '经侦',
create_dept = COALESCE(create_dept, '铜陵市公安局经侦支队'),
handle_dept = CASE case_no
WHEN 'AJFX20260908001' THEN '市经侦支队一大队'
WHEN 'AJFX20260908002' THEN '铜官区分局经侦大队'
WHEN 'AJFX20260908003' THEN '义安区分局经侦大队'
WHEN 'AJFX20260908004' THEN '郊区分局经侦大队'
WHEN 'AJFX20260908005' THEN '市经侦支队二大队'
WHEN 'AJFX20260908006' THEN '枞阳县公安局经侦大队'
WHEN 'AJFX20260908007' THEN '市经侦支队一大队'
WHEN 'AJFX20260908008' THEN '铜官区分局西湖派出所'
WHEN 'AJFX20260908009' THEN '义安区分局五松派出所'
WHEN 'AJFX20260908010' THEN '市经侦支队三大队'
WHEN 'AJFX20260908011' THEN '郊区分局大通派出所'
WHEN 'AJFX20260908012' THEN '市经侦支队一大队'
WHEN 'AJFX20260908013' THEN '铜官区分局经侦大队'
WHEN 'AJFX20260908014' THEN '枞阳县公安局经侦大队'
WHEN 'AJFX20260908015' THEN '市经侦支队二大队'
ELSE COALESCE(handle_dept, '市经侦支队一大队')
END,
case_status = CASE case_no
WHEN 'AJFX20260908004' THEN 'closed'
WHEN 'AJFX20260908008' THEN 'pending_filing'
WHEN 'AJFX20260908014' THEN 'withdrawn'
ELSE COALESCE(NULLIF(case_status, ''), 'investigating')
END,
update_time = NOW()
WHERE deleted_flag = FALSE
AND case_no LIKE 'AJFX20260908%';
INSERT INTO t_case_file (
case_no, case_name, case_source, case_source_sub, handler_name,
review_decide_time, accept_time, filing_time,
biz_category, create_dept, handle_dept, case_status
)
SELECT v.case_no, v.case_name, v.case_source, v.case_source_sub, v.handler_name,
v.review_decide_time, v.accept_time, v.filing_time,
v.biz_category, v.create_dept, v.handle_dept, v.case_status
FROM (VALUES
('AJFX20260928001', '某商场合同诈骗案', 'party_report', NULL, '刘警官',
NOW() - INTERVAL '8 day', NOW() - INTERVAL '6 day', NOW() - INTERVAL '3 day',
'经侦', '铜陵市公安局经侦支队', '铜官区分局杨家山派出所', 'investigating'),
('AJFX20260928002', '王某非法吸收公众存款案', 'superior_assign', NULL, '黄警官',
NOW() - INTERVAL '20 day', NOW() - INTERVAL '18 day', NULL,
'经侦', '铜官区分局经侦大队', '铜官区分局阳光社区派出所', 'pending_filing'),
('AJFX20260928003', '李某虚开增值税发票案', 'work_discovery', NULL, '徐警官',
NOW() - INTERVAL '40 day', NOW() - INTERVAL '35 day', NOW() - INTERVAL '30 day',
'经侦', '义安区分局经侦大队', '义安区分局顺安派出所', 'investigating'),
('AJFX20260928004', '赵某职务侵占案', 'other_unit_transfer', NULL, '曹警官',
NOW() - INTERVAL '90 day', NOW() - INTERVAL '80 day', NOW() - INTERVAL '70 day',
'经侦', '郊区分局经侦大队', '郊区分局老洲派出所', 'closed')
) AS v(case_no, case_name, case_source, case_source_sub, handler_name,
review_decide_time, accept_time, filing_time,
biz_category, create_dept, handle_dept, case_status)
WHERE NOT EXISTS (SELECT 1 FROM t_case_file c WHERE c.case_no = v.case_no AND c.deleted_flag = FALSE);

107
docs/20261015_alarm_audit_demo_accounts.sql

@ -0,0 +1,107 @@
-- 审核监督三人组演示账号
-- 市局审核法制员 / 公职律师 新开六位警号;经侦支队审核员沿用已有账号章成(zhangcheng)
-- 密码 123456(Argon2id 与系统一致)
UPDATE t_role
SET role_name = '市局审核法制员',
remark = '审核监督-法制席位',
update_time = NOW()
WHERE role_code = 'alarm_audit_legal';
UPDATE t_role
SET role_name = '公职律师',
remark = '审核监督-公职律师席位',
update_time = NOW()
WHERE role_code = 'alarm_audit_lawyer';
UPDATE t_role
SET role_name = '经侦支队审核员',
remark = '审核监督-经侦席位(演示:章成)',
update_time = NOW()
WHERE role_code = 'alarm_audit_jz';
INSERT INTO t_role (role_name, role_code, remark, create_time, update_time)
SELECT '市局审核法制员', 'alarm_audit_legal', '审核监督-法制席位', NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM t_role WHERE role_code = 'alarm_audit_legal');
INSERT INTO t_role (role_name, role_code, remark, create_time, update_time)
SELECT '公职律师', 'alarm_audit_lawyer', '审核监督-公职律师席位', NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM t_role WHERE role_code = 'alarm_audit_lawyer');
INSERT INTO t_role (role_name, role_code, remark, create_time, update_time)
SELECT '经侦支队审核员', 'alarm_audit_jz', '审核监督-经侦席位(演示:章成)', NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM t_role WHERE role_code = 'alarm_audit_jz');
-- 审核组仅开「接报案中心 → 审核监督」及功能点
INSERT INTO t_role_menu (role_id, menu_id, create_time, update_time)
SELECT r.role_id, m.menu_id, NOW(), NOW()
FROM t_role r
CROSS JOIN t_menu m
WHERE r.role_code IN ('alarm_audit_legal', 'alarm_audit_lawyer', 'alarm_audit_jz')
AND m.deleted_flag = 0
AND (
(m.menu_name = '接报案中心' AND m.menu_type = 1)
OR m.path = '/business/alarm/audit-list'
OR m.menu_id IN (SELECT menu_id FROM t_menu WHERE path = '/business/alarm/audit-list' AND deleted_flag = 0)
OR m.parent_id IN (SELECT menu_id FROM t_menu WHERE path = '/business/alarm/audit-list' AND deleted_flag = 0)
)
AND NOT EXISTS (
SELECT 1 FROM t_role_menu x WHERE x.role_id = r.role_id AND x.menu_id = m.menu_id
);
INSERT INTO t_employee (
login_name, login_pwd, actual_name, gender, phone, department_id, email,
disabled_flag, deleted_flag, administrator_flag, remark, create_time, update_time
)
SELECT v.login_name,
'$argon2id$v=19$m=16384,t=2,p=1$e/hqRAZYCYHydMS3SPo7yA$5hdCxLG7q+Jtf6KLJHVg/yb0I8LZrPuKUF66jLq+Drc',
v.actual_name, v.gender, v.phone,
COALESCE((SELECT department_id FROM t_department d WHERE d.department_id = v.dept_id), 1),
CONCAT(v.login_name, '@tl-police.cn'),
0, 0, 0, v.remark, NOW(), NOW()
FROM (VALUES
('340704', '孙磊', 1, '13834070401', 118, '市局审核法制员'),
('340705', '林静', 0, '13834070501', 118, '公职律师')
) AS v(login_name, actual_name, gender, phone, dept_id, remark)
WHERE NOT EXISTS (
SELECT 1 FROM t_employee e WHERE e.login_name = v.login_name AND e.deleted_flag IN (0, FALSE)
);
-- 席位一人一岗:解绑旧岗号,避免同席位多人抢票
DELETE FROM t_role_employee re
USING t_role r, t_employee e
WHERE re.role_id = r.role_id
AND re.employee_id = e.employee_id
AND r.role_code IN ('alarm_audit_legal', 'alarm_audit_lawyer', 'alarm_audit_jz')
AND e.login_name IN ('sjjbazxfzg', 'sjjbazxgzlvg', 'sjjbazxjzg');
-- 章成去掉系统演示 cto,保留作废主任 + 经侦审核员
DELETE FROM t_role_employee re
USING t_role r, t_employee e
WHERE re.role_id = r.role_id
AND re.employee_id = e.employee_id
AND e.login_name = 'zhangcheng'
AND r.role_code = 'cto';
INSERT INTO t_role_employee (role_id, employee_id, create_time, update_time)
SELECT r.role_id, e.employee_id, NOW(), NOW()
FROM (VALUES
('340704', 'alarm_audit_legal'),
('340705', 'alarm_audit_lawyer'),
('zhangcheng', 'alarm_audit_jz')
) AS v(login_name, role_code)
JOIN t_employee e ON e.login_name = v.login_name AND e.deleted_flag IN (0, FALSE)
JOIN t_role r ON r.role_code = v.role_code
WHERE NOT EXISTS (
SELECT 1 FROM t_role_employee x WHERE x.role_id = r.role_id AND x.employee_id = e.employee_id
);
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM pg_class WHERE relkind = 'S' AND relname = 't_employee_employee_id_seq') THEN
PERFORM setval('t_employee_employee_id_seq', (SELECT COALESCE(MAX(employee_id), 1) FROM t_employee));
END IF;
IF EXISTS (SELECT 1 FROM pg_class WHERE relkind = 'S' AND relname = 't_role_role_id_seq') THEN
PERFORM setval('t_role_role_id_seq', (SELECT COALESCE(MAX(role_id), 1) FROM t_role));
END IF;
END $$;

305
docs/20261015_biz_demo_roles_accounts.sql

@ -0,0 +1,305 @@
-- 业务演示角色 + 六位警号账号(密码 123456,Argon2id 与系统一致)
-- 市局:案管员 / 财物保管员 / 接报案接待员
-- 义安分局:大队长 / 分局领导 / 办案民警 / 大队案管员 / 大队财物保管员 / 大队接报案接待员
-- 已知 123456 哈希(与 t_employee.admin 相同算法)
-- $argon2id$v=19$m=16384,t=2,p=1$e/hqRAZYCYHydMS3SPo7yA$5hdCxLG7q+Jtf6KLJHVg/yb0I8LZrPuKUF66jLq+Drc
INSERT INTO t_role (role_name, role_code, remark, create_time, update_time)
SELECT v.role_name, v.role_code, v.remark, NOW(), NOW()
FROM (VALUES
('市局案管员', 'city_case_manager', '市局案件监督、卷宗登记归档、借阅确认'),
('涉案财物保管员', 'city_property_keeper', '市局涉案财物入库保管、归还/出库确认'),
('接报案中心接待员', 'city_alarm_receptionist', '市局接报案中心登记、材料、发起作废'),
('义安区分局经侦大队大队长', 'yian_brigade_captain', '区县作废审核、财物调用审核、卷宗借阅/复印审核'),
('分局领导', 'bureau_leader', '分局业务总览、审议审批、领办包保、复印领导审'),
('大队办案民警', 'brigade_officer', '本大队办案:案件查询、财物录入/调用、本人卷宗借阅'),
('大队案管员', 'brigade_case_manager', '大队案件监督、卷宗登记、移交市局'),
('大队涉案财物保管员', 'brigade_property_keeper', '大队涉案财物入库保管、归还/出库确认'),
('大队接报案中心接待员', 'brigade_alarm_receptionist', '区县接报案分中心登记、材料、发起作废')
) AS v(role_name, role_code, remark)
WHERE NOT EXISTS (SELECT 1 FROM t_role x WHERE x.role_code = v.role_code);
-- 授权规则:dir=一级目录名;path=页面;children=页面及其功能点
CREATE TEMP TABLE IF NOT EXISTS tmp_role_menu_rule (
role_code VARCHAR(64) NOT NULL,
kind VARCHAR(16) NOT NULL,
val VARCHAR(256) NOT NULL
);
TRUNCATE tmp_role_menu_rule;
INSERT INTO tmp_role_menu_rule (role_code, kind, val) VALUES
-- 市局案管员
('city_case_manager', 'dir', '案件管理'),
('city_case_manager', 'dir', '案件监督'),
('city_case_manager', 'dir', '风险预警'),
('city_case_manager', 'dir', '卷宗管理'),
('city_case_manager', 'dir', '数据大屏'),
('city_case_manager', 'path_prefix', '/case-management'),
('city_case_manager', 'path_prefix', '/dossier'),
('city_case_manager', 'path', '/bigscreen/data-bigscreen'),
('city_case_manager', 'web_prefix', 'negative-list:'),
('city_case_manager', 'web_prefix', 'weekly-schedule:'),
('city_case_manager', 'web_prefix', 'risk-warning:'),
('city_case_manager', 'web_prefix', 'dossier:'),
-- 市局财物保管员
('city_property_keeper', 'dir', '涉案财物'),
('city_property_keeper', 'path_prefix', '/property'),
('city_property_keeper', 'web_prefix', 'property:management:'),
('city_property_keeper', 'web_prefix', 'property:unregistered:'),
('city_property_keeper', 'web_prefix', 'property:omission:'),
('city_property_keeper', 'web_prefix', 'property:return:'),
('city_property_keeper', 'web_prefix', 'property:checkout:'),
('city_property_keeper', 'web_prefix', 'property:transfer:query'),
('city_property_keeper', 'web_prefix', 'property:transfer:detail'),
-- 市局接报案接待员
('city_alarm_receptionist', 'dir', '接报案中心'),
('city_alarm_receptionist', 'path', '/business/alarm/alarm-reception-list'),
('city_alarm_receptionist', 'children', '/business/alarm/alarm-reception-list'),
('city_alarm_receptionist', 'path', '/business/alarm/material-view'),
('city_alarm_receptionist', 'children', '/business/alarm/material-view'),
('city_alarm_receptionist', 'path', '/business/alarm/center-monitor'),
('city_alarm_receptionist', 'children', '/business/alarm/center-monitor'),
('city_alarm_receptionist', 'path', '/business/alarm/no-accept-review-list'),
('city_alarm_receptionist', 'children', '/business/alarm/no-accept-review-list'),
('city_alarm_receptionist', 'web_prefix', 'alarm:void:apply'),
-- 义安大队长
('yian_brigade_captain', 'dir', '接报案中心'),
('yian_brigade_captain', 'dir', '案件管理'),
('yian_brigade_captain', 'dir', '案件监督'),
('yian_brigade_captain', 'dir', '风险预警'),
('yian_brigade_captain', 'dir', '涉案财物'),
('yian_brigade_captain', 'dir', '卷宗管理'),
('yian_brigade_captain', 'dir', '审议流程'),
('yian_brigade_captain', 'dir', '数据大屏'),
('yian_brigade_captain', 'path', '/business/alarm/alarm-reception-list'),
('yian_brigade_captain', 'children', '/business/alarm/alarm-reception-list'),
('yian_brigade_captain', 'path', '/business/alarm/void-audit-list'),
('yian_brigade_captain', 'children', '/business/alarm/void-audit-list'),
('yian_brigade_captain', 'path_prefix', '/case-management'),
('yian_brigade_captain', 'path_prefix', '/dossier'),
('yian_brigade_captain', 'path', '/property/transfer'),
('yian_brigade_captain', 'children', '/property/transfer'),
('yian_brigade_captain', 'path', '/property/management'),
('yian_brigade_captain', 'children', '/property/management'),
('yian_brigade_captain', 'path', '/bigscreen/data-bigscreen'),
('yian_brigade_captain', 'web_prefix', 'alarm:void:'),
('yian_brigade_captain', 'web_prefix', 'property:transfer:'),
('yian_brigade_captain', 'web_prefix', 'dossier:borrow:audit'),
('yian_brigade_captain', 'web_prefix', 'dossier:copy:audit'),
('yian_brigade_captain', 'web_prefix', 'weekly-schedule:'),
-- 分局领导
('bureau_leader', 'dir', '接报案中心'),
('bureau_leader', 'dir', '案件管理'),
('bureau_leader', 'dir', '案件监督'),
('bureau_leader', 'dir', '风险预警'),
('bureau_leader', 'dir', '涉案资金'),
('bureau_leader', 'dir', '涉案财物'),
('bureau_leader', 'dir', '卷宗管理'),
('bureau_leader', 'dir', '审议流程'),
('bureau_leader', 'dir', '数据大屏'),
('bureau_leader', 'path', '/business/alarm/alarm-reception-list'),
('bureau_leader', 'children', '/business/alarm/alarm-reception-list'),
('bureau_leader', 'path_prefix', '/case-management'),
('bureau_leader', 'path_prefix', '/fund'),
('bureau_leader', 'path', '/property/management'),
('bureau_leader', 'children', '/property/management'),
('bureau_leader', 'path_prefix', '/dossier'),
('bureau_leader', 'path', '/bigscreen/data-bigscreen'),
('bureau_leader', 'web_prefix', 'review:general:'),
('bureau_leader', 'web_prefix', 'leader-record:'),
('bureau_leader', 'web_prefix', 'dossier:copy:audit'),
('bureau_leader', 'web_prefix', 'risk-warning:query'),
('bureau_leader', 'web_prefix', 'risk-warning:view'),
-- 大队办案民警
('brigade_officer', 'dir', '案件管理'),
('brigade_officer', 'dir', '案件监督'),
('brigade_officer', 'dir', '风险预警'),
('brigade_officer', 'dir', '涉案财物'),
('brigade_officer', 'dir', '卷宗管理'),
('brigade_officer', 'path', '/case-management/supervision/weekly-schedule'),
('brigade_officer', 'children', '/case-management/supervision/weekly-schedule'),
('brigade_officer', 'path', '/case-management/risk-warning'),
('brigade_officer', 'path_prefix', '/case-management/risk-warning'),
('brigade_officer', 'path', '/property/management'),
('brigade_officer', 'children', '/property/management'),
('brigade_officer', 'path', '/property/transfer'),
('brigade_officer', 'children', '/property/transfer'),
('brigade_officer', 'path', '/dossier/register'),
('brigade_officer', 'children', '/dossier/register'),
('brigade_officer', 'path', '/dossier/borrow-self'),
('brigade_officer', 'children', '/dossier/borrow-self'),
('brigade_officer', 'path', '/dossier/copy-request'),
('brigade_officer', 'children', '/dossier/copy-request'),
('brigade_officer', 'web_prefix', 'weekly-schedule:confirm'),
('brigade_officer', 'web_prefix', 'weekly-schedule:query'),
('brigade_officer', 'web_prefix', 'weekly-schedule:view'),
('brigade_officer', 'web_prefix', 'risk-warning:query'),
('brigade_officer', 'web_prefix', 'risk-warning:view'),
('brigade_officer', 'web_prefix', 'property:management:query'),
('brigade_officer', 'web_prefix', 'property:management:add'),
('brigade_officer', 'web_prefix', 'property:management:detail'),
('brigade_officer', 'web_prefix', 'property:management:invoke'),
('brigade_officer', 'web_prefix', 'dossier:register:query'),
('brigade_officer', 'web_prefix', 'dossier:detail'),
('brigade_officer', 'web_prefix', 'dossier:borrow:apply'),
('brigade_officer', 'web_prefix', 'dossier:copy:apply'),
-- 大队案管员
('brigade_case_manager', 'dir', '案件管理'),
('brigade_case_manager', 'dir', '案件监督'),
('brigade_case_manager', 'dir', '风险预警'),
('brigade_case_manager', 'dir', '卷宗管理'),
('brigade_case_manager', 'path_prefix', '/case-management/supervision'),
('brigade_case_manager', 'path_prefix', '/case-management/risk-warning'),
('brigade_case_manager', 'path_prefix', '/dossier'),
('brigade_case_manager', 'web_prefix', 'negative-list:'),
('brigade_case_manager', 'web_prefix', 'weekly-schedule:'),
('brigade_case_manager', 'web_prefix', 'risk-warning:'),
('brigade_case_manager', 'web_prefix', 'dossier:'),
-- 大队财物保管员
('brigade_property_keeper', 'dir', '涉案财物'),
('brigade_property_keeper', 'path_prefix', '/property'),
('brigade_property_keeper', 'web_prefix', 'property:management:'),
('brigade_property_keeper', 'web_prefix', 'property:unregistered:'),
('brigade_property_keeper', 'web_prefix', 'property:omission:'),
('brigade_property_keeper', 'web_prefix', 'property:return:'),
('brigade_property_keeper', 'web_prefix', 'property:checkout:'),
('brigade_property_keeper', 'web_prefix', 'property:transfer:query'),
('brigade_property_keeper', 'web_prefix', 'property:transfer:detail'),
-- 大队接报案接待员
('brigade_alarm_receptionist', 'dir', '接报案中心'),
('brigade_alarm_receptionist', 'path', '/business/alarm/alarm-reception-list'),
('brigade_alarm_receptionist', 'children', '/business/alarm/alarm-reception-list'),
('brigade_alarm_receptionist', 'path', '/business/alarm/material-view'),
('brigade_alarm_receptionist', 'children', '/business/alarm/material-view'),
('brigade_alarm_receptionist', 'path', '/business/alarm/center-monitor'),
('brigade_alarm_receptionist', 'children', '/business/alarm/center-monitor'),
('brigade_alarm_receptionist', 'path', '/business/alarm/no-accept-review-list'),
('brigade_alarm_receptionist', 'children', '/business/alarm/no-accept-review-list'),
('brigade_alarm_receptionist', 'web_prefix', 'alarm:void:apply');
INSERT INTO t_role_menu (role_id, menu_id, create_time, update_time)
SELECT DISTINCT r.role_id, m.menu_id, NOW(), NOW()
FROM tmp_role_menu_rule g
JOIN t_role r ON r.role_code = g.role_code
JOIN t_menu m ON m.deleted_flag = 0
WHERE (
(g.kind = 'dir' AND m.menu_type = 1 AND m.menu_name = g.val)
OR (g.kind = 'path' AND m.path = g.val)
OR (g.kind = 'path_prefix' AND (m.path = g.val OR m.path LIKE CONCAT(g.val, '/%')))
OR (g.kind = 'web_prefix' AND m.web_perms LIKE CONCAT(g.val, '%'))
OR (g.kind = 'children' AND (
m.path = g.val
OR m.parent_id IN (SELECT menu_id FROM t_menu p WHERE p.path = g.val AND p.deleted_flag = 0)
))
)
AND NOT EXISTS (
SELECT 1 FROM t_role_menu x WHERE x.role_id = r.role_id AND x.menu_id = m.menu_id
);
-- 办案民警去掉财物调用审核、卷宗借阅他人审核等越权点
DELETE FROM t_role_menu rm
USING t_role r, t_menu m
WHERE rm.role_id = r.role_id
AND rm.menu_id = m.menu_id
AND r.role_code = 'brigade_officer'
AND m.web_perms IN (
'property:transfer:audit',
'dossier:borrow:audit',
'dossier:borrow:confirm',
'dossier:return:audit',
'dossier:copy:audit',
'dossier:transfer:submit',
'dossier:register:submit',
'dossier:sync',
'weekly-schedule:add',
'weekly-schedule:push',
'weekly-schedule:print',
'property:management:checkout'
);
-- 分局领导不作出库/入库操作与作废审批
DELETE FROM t_role_menu rm
USING t_role r, t_menu m
WHERE rm.role_id = r.role_id
AND rm.menu_id = m.menu_id
AND r.role_code = 'bureau_leader'
AND (
m.web_perms IN (
'property:management:add',
'property:management:checkout',
'property:management:invoke',
'property:transfer:audit',
'alarm:void:apply',
'alarm:void:audit',
'alarm:add',
'alarm:update'
)
OR m.path IN ('/business/alarm/void-audit-list', '/property/unregistered', '/property/omission')
OR m.web_perms IN ('weekly-schedule:add', 'weekly-schedule:push')
);
-- 财物保管员不审调用
DELETE FROM t_role_menu rm
USING t_role r, t_menu m
WHERE rm.role_id = r.role_id
AND rm.menu_id = m.menu_id
AND r.role_code IN ('city_property_keeper', 'brigade_property_keeper')
AND m.web_perms = 'property:transfer:audit';
INSERT INTO t_employee (
login_name, login_pwd, actual_name, gender, phone, department_id, email,
disabled_flag, deleted_flag, administrator_flag, remark, create_time, update_time
)
SELECT v.login_name,
'$argon2id$v=19$m=16384,t=2,p=1$e/hqRAZYCYHydMS3SPo7yA$5hdCxLG7q+Jtf6KLJHVg/yb0I8LZrPuKUF66jLq+Drc',
v.actual_name, v.gender, v.phone,
COALESCE((SELECT department_id FROM t_department d WHERE d.department_id = v.dept_id), 1),
v.login_name || '@tl-police.cn',
0, 0, 0, v.remark, NOW(), NOW()
FROM (VALUES
('340701', '陈立', 1, '13834070101', 118, '市局案管员'),
('340702', '刘仓', 1, '13834070201', 118, '涉案财物保管员'),
('340703', '王敏', 0, '13834070301', 123, '接报案中心接待员'),
('340711', '赵建军', 1, '13834071101', 3017, '义安区分局经侦大队大队长'),
('340712', '黄志强', 1, '13834071201', 301, '分局领导'),
('340713', '张伟', 1, '13834071301', 3017, '大队办案民警'),
('340714', '李芳', 0, '13834071401', 3017, '大队案管员'),
('340715', '周海', 1, '13834071501', 3017, '大队涉案财物保管员'),
('340716', '吴娟', 0, '13834071601', 3017, '大队接报案中心接待员')
) AS v(login_name, actual_name, gender, phone, dept_id, remark)
WHERE NOT EXISTS (
SELECT 1 FROM t_employee e WHERE e.login_name = v.login_name AND e.deleted_flag IN (0, FALSE)
);
INSERT INTO t_role_employee (role_id, employee_id, create_time, update_time)
SELECT r.role_id, e.employee_id, NOW(), NOW()
FROM (VALUES
('340701', 'city_case_manager'),
('340702', 'city_property_keeper'),
('340703', 'city_alarm_receptionist'),
('340703', 'alarm_city_receiver'),
('340711', 'yian_brigade_captain'),
('340711', 'alarm_district_captain'),
('340712', 'bureau_leader'),
('340713', 'brigade_officer'),
('340714', 'brigade_case_manager'),
('340715', 'brigade_property_keeper'),
('340716', 'brigade_alarm_receptionist'),
('340716', 'alarm_district_receiver')
) AS v(login_name, role_code)
JOIN t_employee e ON e.login_name = v.login_name AND e.deleted_flag IN (0, FALSE)
JOIN t_role r ON r.role_code = v.role_code
WHERE NOT EXISTS (
SELECT 1 FROM t_role_employee x WHERE x.role_id = r.role_id AND x.employee_id = e.employee_id
);
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM pg_class WHERE relkind = 'S' AND relname = 't_employee_employee_id_seq') THEN
PERFORM setval('t_employee_employee_id_seq', (SELECT COALESCE(MAX(employee_id), 1) FROM t_employee));
END IF;
IF EXISTS (SELECT 1 FROM pg_class WHERE relkind = 'S' AND relname = 't_role_role_id_seq') THEN
PERFORM setval('t_role_role_id_seq', (SELECT COALESCE(MAX(role_id), 1) FROM t_role));
END IF;
END $$;

63
docs/20261015_case_source_dict.sql

@ -0,0 +1,63 @@
-- 报案类案件来源字典改为九项平铺(移交→移送;法院两类升主项)
ALTER TABLE t_alarm_report DROP CONSTRAINT IF EXISTS t_alarm_report_case_source_check;
-- 历史:人民法院移交 + 子项 → 平铺主项
UPDATE t_alarm_report
SET case_source = 'court_transfer_false'
WHERE case_source = 'court_transfer'
AND case_source_sub = 'false_litigation';
UPDATE t_alarm_report
SET case_source = 'court_transfer_normal'
WHERE case_source = 'court_transfer';
UPDATE t_case_file
SET case_source = 'court_transfer_false'
WHERE case_source = 'court_transfer'
AND case_source_sub = 'false_litigation';
UPDATE t_case_file
SET case_source = 'court_transfer_normal'
WHERE case_source = 'court_transfer';
ALTER TABLE t_alarm_report ADD CONSTRAINT t_alarm_report_case_source_check
CHECK (case_source IS NULL OR case_source IN (
'party_report',
'admin_transfer',
'court_transfer',
'court_transfer_normal',
'court_transfer_false',
'procuratorate_transfer',
'procuratorate_notify',
'superior_assign',
'work_discovery',
'other_unit_transfer'
));
COMMENT ON COLUMN t_alarm_report.case_source IS '案件来源:当事人报案/行政机关移送/人民法院移送普通案件/人民法院移送虚假诉讼类案件/人民检察院移送/人民检察院通知立案/上级交办/工作中发现/其他单位移送';
COMMENT ON COLUMN t_alarm_report.case_source_sub IS '历史子项(法院/检察院),新登记由主项派生,可空';
COMMENT ON COLUMN t_alarm_report.accepting_unit IS '受案单位:人民法院移送两类时填写';
DELETE FROM t_dict_data
WHERE dict_id = (SELECT dict_id FROM t_dict WHERE dict_code = 'CASE_SOURCE');
INSERT INTO t_dict (dict_name, dict_code, remark, disabled_flag, create_time, update_time)
SELECT '案件来源', 'CASE_SOURCE', '报案类警情登记-案件来源', false, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM t_dict WHERE dict_code = 'CASE_SOURCE');
INSERT INTO t_dict_data (dict_id, data_value, data_label, remark, sort_order, disabled_flag, create_time, update_time)
SELECT d.dict_id, v.data_value, v.data_label, '案件来源', v.sort_order, false, NOW(), NOW()
FROM t_dict d
CROSS JOIN (VALUES
('party_report', '当事人报案', 1),
('admin_transfer', '行政机关移送', 2),
('court_transfer_normal', '人民法院移送普通案件', 3),
('court_transfer_false', '人民法院移送虚假诉讼类案件', 4),
('procuratorate_transfer', '人民检察院移送', 5),
('procuratorate_notify', '人民检察院通知立案', 6),
('superior_assign', '上级交办', 7),
('work_discovery', '工作中发现', 8),
('other_unit_transfer', '其他单位移送', 9)
) AS v(data_value, data_label, sort_order)
WHERE d.dict_code = 'CASE_SOURCE';

19
docs/20261015_weekly_schedule_minutes.sql

@ -0,0 +1,19 @@
-- 周调度记录改为「案件调度会议纪要」模板:会议信息 + 主办民警快照 + 逐案调度内容
ALTER TABLE t_case_weekly_schedule ADD COLUMN IF NOT EXISTS meeting_time TIMESTAMP;
ALTER TABLE t_case_weekly_schedule ADD COLUMN IF NOT EXISTS meeting_place VARCHAR(200);
ALTER TABLE t_case_weekly_schedule ADD COLUMN IF NOT EXISTS schedule_unit VARCHAR(128);
ALTER TABLE t_case_weekly_schedule ADD COLUMN IF NOT EXISTS host_name VARCHAR(64);
ALTER TABLE t_case_weekly_schedule ADD COLUMN IF NOT EXISTS recorder_name VARCHAR(64);
COMMENT ON COLUMN t_case_weekly_schedule.meeting_time IS '会议时间';
COMMENT ON COLUMN t_case_weekly_schedule.meeting_place IS '会议地点';
COMMENT ON COLUMN t_case_weekly_schedule.schedule_unit IS '调度单位(纪要标题红字)';
COMMENT ON COLUMN t_case_weekly_schedule.host_name IS '会议主持人';
COMMENT ON COLUMN t_case_weekly_schedule.recorder_name IS '会议记录人';
ALTER TABLE t_case_weekly_schedule_case ADD COLUMN IF NOT EXISTS handler_name VARCHAR(64);
ALTER TABLE t_case_weekly_schedule_case ADD COLUMN IF NOT EXISTS item_content TEXT;
COMMENT ON COLUMN t_case_weekly_schedule_case.handler_name IS '主办民警快照';
COMMENT ON COLUMN t_case_weekly_schedule_case.item_content IS '该案调度内容(手填)';

40
docs/Plan/prd-case-risk-warning.md

@ -0,0 +1,40 @@
# 案件三色预警 PRD
> 最后更新:2026-10-15
> 对应页面:`economic-crime-web/src/views/business/case-management/risk-warning.vue`(二级「风险预警」下 13 条规则子菜单共用)
> 后端:`/risk-warning/**`,包 `module/business/caserisk`
## 1. 级别
| 颜色 | 含义 | 消除规则 |
|------|------|----------|
| 红色 | 问题通报 | 一经触发锁定,任何操作不可重置、消除 |
| 黄色 | 问题预警 | 条件消失可清除;可处置/忽略 |
| 蓝色 | 普通提醒 | 条件消失可清除;可处置/忽略 |
## 2. 规则摘要
1. **审议受案超 24 小时未受案** → 红
2. **立案审查期限**(自受案日起算):按接报案案件来源分流;可抓取「呈请延长立案期限报告书」进入 20/25/31、40/50/61 轮次;法院两类与检察院通知立案不抓延长文书。中止立案审查(不含检察院通知立案)暂停原倒计时。
3. **取保候审**传讯 + 12 个月解除/起诉
4. **受案后无活动** 20/30/50
5. **立案后无活动** 30/60/90,有活动日志后重新检测
6. **刑拘**:24 小时拘留通知书;3/5/8;7 日内变更羁押 → 20/25/31;30 日内提捕 → 36 黄 / 38 红
7. **逮捕**:24 小时拘留通知书;40/50/两个月;延长侦查羁押后 3/5/7 个月档
8. **监视居住**:4/5/6 个月解除或起诉;传讯 1/2/3 月
9. **指定居所监视居住**:24 小时未制作指定监视居住通知书 → 红
## 3. 来源映射
| 预警分类 | 接报案 `case_source` |
|----------|----------------------|
| 普通经侦 | 当事人报案、上级交办、工作中发现、其他单位移送 |
| 行政机关移送 | `admin_transfer` |
| 法院普通 | `court_transfer_normal`(兼容历史 `court_transfer`+`normal`) |
| 法院虚假诉讼 | `court_transfer_false`(兼容历史 `court_transfer`+`false_litigation`) |
| 检察院移送 | `procuratorate_transfer`(同普通经侦期限) |
| 检察院通知立案 | `procuratorate_notify` |
## 4. 表
`t_case_file`、`t_case_legal_doc`、`t_case_activity_log`、`t_case_risk_warning`

49
docs/Plan/prd-case-supervision.md

@ -0,0 +1,49 @@
# 案件监督:负面清单巡查 + 周调度 PRD
> 最后更新:2026-10-15
> 对应页面:`economic-crime-web/src/views/business/case-management/negative-list.vue`、`weekly-schedule.vue`
> 后端:`/negative-list/**`、`/weekly-schedule/**`,包 `module/business/casesupervision`
## 1. 菜单
「案件监督」由页面改为二级目录:
| 子菜单 | 路径 | 组件 |
|--------|------|------|
| 负面清单巡查 | `/case-management/supervision/negative-list` | `negative-list.vue` |
| 周调度 | `/case-management/supervision/weekly-schedule` | `weekly-schedule.vue` |
原 mock 督办页不再挂菜单。
权限:`negative-list:query`;`weekly-schedule:query/add/view/push/confirm/print`。
## 2. 负面清单巡查
自动查询系统内 `t_case_file` 且 `biz_category = 经侦` 的案件(非外网爬取)。
列表字段:案件名称、案件编号、创建单位、办案单位、案件状态、受案时间。
办案单位包含「派出所」:整行文字标红,办案单位加粗。
查询:编号、名称、办案单位、状态、受案时间范围。只读。
案件状态:`pending_filing` 待立案 / `investigating` 侦查中 / `closed` 已结案 / `withdrawn` 已撤销。
## 3. 周调度
状态机:`draft`(草稿,可推送)→ `pending_confirm`(已推送待确认,内容不再改)→ `confirmed`(全部参会人员确认后锁定,可打印不可改)。
新增:按案件名称(模糊)或案件编号搜索并勾选 → 按「铜陵市公安局 XX单位案件调度会议纪要」纸面模板填表:
- 会议时间、会议地点、调度单位、会议主持人、会议记录人(调度单位默认当前部门,标题红字)
- 调度内容区按勾选案件自动标红填入:一、XX案 / 案件编号 / 主办民警,手填该案「调度内容」
- 会议参与人员来自勾选人员;参会人员签名栏打印留空手签
- 页脚:注:此表交案管室存档,参会人员可自行复印留存。
勾选参加人员后推送站内信。参加人员在列表或详情中点「确认」。全部确认后记录锁定,打印与纸面模板一致,标红字段保持红色。
表:`t_case_weekly_schedule`(含会议信息)、`t_case_weekly_schedule_case`(含主办民警与逐案调度内容快照)、`t_case_weekly_schedule_member`。
## 4. 数据扩展
`t_case_file` 增加 `biz_category`、`create_dept`、`handle_dept`、`case_status`。

0
economic-crime-api/economic-crime-admin/logs/economic-crime/dev/tomcat-logs/logs/access_log.2026-09-09.log

Loading…
Cancel
Save