Files
gsfdc/server/app/commands/seed_discipline_sample.py

217 lines
7.4 KiB
Python

"""写入行业自律演示数据:投诉说明、举报记录,以及警示案例、诚信档案、结果公示。
重复执行不会覆盖工作人员已填写的说明,也不会重复插入同标题的记录。
口令只从环境变量读取。
"""
from __future__ import annotations
import sys
from datetime import datetime, timedelta, timezone
from sqlalchemy import select
from app.db import Base, SessionLocal, get_engine
from app.models.discipline import (
DisciplineComplaint,
admin_notice,
create_complaint,
mark_processed,
save_notice,
)
from app.models.home import HomeArticle, create_article
from app.models.rbac import AdminUser
from app.services.storage import ensure_buckets
NOTICE = {
"phone": "0931-8126195",
"email": "gsrea2018@163.com",
"scopeHtml": (
"<p>受理会员机构、注册房地产估价师在估价执业中的下列情形:</p>"
"<ul>"
"<li>出具与现场查勘情况明显不符的估价报告;</li>"
"<li>比较案例选取明显不当,或遗漏影响价值的重要因素;</li>"
"<li>收费未按公示标准,或存在不正当竞争;</li>"
"<li>泄露委托人商业秘密或个人隐私。</li>"
"</ul>"
"<p>司法诉讼、已经行政机关立案的案件,以及与估价执业无关的消费纠纷,不由本会受理。</p>"
),
"processHtml": (
"<p>1. 登记。核对材料是否齐全,并生成内部查询码。</p>"
"<p>2. 核查。秘书处转相关专业委员会,必要时向被举报对象核实。</p>"
"<p>3. 处理。形成处理意见,按情节给予约谈、通报,或建议行政主管部门处理。</p>"
"<p>4. 反馈。在承诺时限内答复举报人,并将可公开的结果发布到结果公示。</p>"
),
}
EVIDENCE = (
"证据说明.txt",
"text/plain",
"演示材料:现场查勘记录与报告摘录对照说明,仅供界面查看。".encode(),
)
COMPLAINTS = [
{
"title": "比较案例选取明显不当",
"subject": "兰州示例房地产估价有限公司",
"body": "委托人对住宅估价报告提出异议,认为三宗比较案例均位于不同板块,且未说明修正理由。",
"contact_name": "周宁",
"mobile": "13800001001",
"email": "zhou.ning@example.com",
"days_ago": 6,
"processed": False,
},
{
"title": "收费未按公示标准执行",
"subject": "天水示例评估事务所",
"body": "机构公示收费标准与实际收取金额不一致,举报人已附收费单据说明。",
"contact_name": "李强",
"mobile": "13900002002",
"email": "",
"days_ago": 45,
"processed": False,
},
{
"title": "报告署名与现场查勘人不一致",
"subject": "嘉峪关示例估价有限公司",
"body": "报告签字估价师未参与现场查勘。协会已约谈机构并要求补正内部复核记录。",
"contact_name": "张华",
"mobile": "13700003003",
"email": "zhang.hua@example.com",
"days_ago": 20,
"processed": True,
},
]
ARTICLES = [
(
"warning_cases",
"比较案例选取不当的执业警示",
"2025-06-12T09:00:00",
"<p>某会员机构在住宅估价中选用跨板块案例,且未披露修正依据。本会予以通报,要求整改作业指引。</p>",
),
(
"warning_cases",
"现场查勘记录缺失的执业警示",
"2025-03-18T09:00:00",
"<p>报告未附现场查勘照片与记录。本会约谈签字估价师,并要求机构补齐内部复核。</p>",
),
(
"integrity_records",
"2024 年度会员机构诚信档案(摘录)",
"2025-02-20T09:00:00",
"<p>摘录会员机构年度执业情况、继续教育完成情况和受到的行业处理。正式名录由工作人员维护。</p>",
),
(
"integrity_records",
"注册房地产估价师执业记录说明",
"2024-12-06T09:00:00",
"<p>说明诚信档案公开的范围:执业登记、继续教育、行业处理。不公开身份证号和联系电话。</p>",
),
(
"discipline_results",
"关于对示例机构通报批评的处理结果",
"2025-07-08T09:00:00",
"<p>经核查,比较案例选取明显不当。决定对该机构通报批评,并责令一个月内提交整改报告。</p>",
),
(
"discipline_results",
"收费标准执行情况的核查结果",
"2025-04-02T09:00:00",
"<p>核查未发现与公示标准不符的收费。本案办结,不再另行处理。</p>",
),
]
def _seed_notice(db) -> str:
current = admin_notice(db)
if (current.get("phone") or "").strip() or (current.get("scopeHtml") or "").strip():
return "说明已有内容,未覆盖"
save_notice(db, NOTICE)
return "已写入投诉举报说明"
def _seed_complaints(db) -> int:
staff_id = db.scalar(select(AdminUser.id).order_by(AdminUser.id.asc()))
added = 0
for item in COMPLAINTS:
exists = db.scalar(
select(DisciplineComplaint.id).where(DisciplineComplaint.title == item["title"])
)
if exists is not None:
continue
create_complaint(
db,
title=item["title"],
subject=item["subject"],
body=item["body"],
contact_name=item["contact_name"],
mobile=item["mobile"],
email=item["email"],
files=[EVIDENCE],
)
row = db.scalar(
select(DisciplineComplaint).where(DisciplineComplaint.title == item["title"])
)
row.created_at = datetime.now(timezone.utc).replace(tzinfo=None) - timedelta(
days=item["days_ago"]
)
db.commit()
if item["processed"]:
mark_processed(db, row.id, staff_id=int(staff_id or 1))
added += 1
return added
def _seed_articles(db) -> int:
added = 0
for category, title, published_at, body in ARTICLES:
exists = db.scalar(
select(HomeArticle.id).where(
HomeArticle.category == category, HomeArticle.title == title
)
)
if exists is not None:
continue
create_article(
db,
{
"category": category,
"title": title,
"publishedAt": published_at,
"published": True,
"bodyHtml": body,
"attachmentFileIds": [],
},
)
added += 1
return added
def seed() -> None:
import app.models.content # noqa: F401
import app.models.discipline # noqa: F401
import app.models.home # noqa: F401
import app.models.rbac # noqa: F401
ensure_buckets()
engine = get_engine()
Base.metadata.create_all(bind=engine)
SessionLocal.configure(bind=engine)
db = SessionLocal()
try:
notice = _seed_notice(db)
complaints = _seed_complaints(db)
articles = _seed_articles(db)
print(f"行业自律演示数据:{notice};新增举报 {complaints} 条;新增文章 {articles} 条。")
finally:
db.close()
if __name__ == "__main__":
try:
seed()
except Exception as exc:
print(str(exc), file=sys.stderr)
raise