217 lines
7.4 KiB
Python
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
|