139 lines
8.3 KiB
Python
139 lines
8.3 KiB
Python
"""任务系统 v2:发布字段扩展 + 交付/里程碑/验收/发票表 + 标书扩展 + 评价唯一约束
|
|
|
|
Revision ID: 0056
|
|
Revises: 0055
|
|
"""
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
revision = "0056"
|
|
down_revision = "0055"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
# ── tasks 扩展字段(0056)──
|
|
op.add_column("tasks", sa.Column("resource_support_json", sa.Text(), nullable=False))
|
|
op.add_column("tasks", sa.Column("raw_materials_json", sa.Text(), nullable=False))
|
|
op.add_column("tasks", sa.Column("deliver_way", sa.String(length=20), nullable=False, server_default="online"))
|
|
op.add_column("tasks", sa.Column("deliver_items", sa.Text(), nullable=False))
|
|
op.add_column("tasks", sa.Column("accept_standard", sa.Text(), nullable=False))
|
|
op.add_column("tasks", sa.Column("price_type", sa.String(length=20), nullable=False, server_default="fixed"))
|
|
op.add_column("tasks", sa.Column("pay_type", sa.String(length=20), nullable=False, server_default="escrow"))
|
|
op.add_column("tasks", sa.Column("escrow_ratio", sa.Integer(), nullable=False, server_default="100"))
|
|
op.add_column("tasks", sa.Column("invoice_req", sa.Text(), nullable=False))
|
|
op.add_column("tasks", sa.Column("milestone_json", sa.Text(), nullable=False))
|
|
op.add_column("tasks", sa.Column("attachments_json", sa.Text(), nullable=False))
|
|
op.add_column("tasks", sa.Column("deliver_at", sa.String(length=40), nullable=False, server_default=""))
|
|
op.add_column("tasks", sa.Column("accepted_at", sa.String(length=40), nullable=False, server_default=""))
|
|
op.add_column("tasks", sa.Column("reject_count", sa.Integer(), nullable=False, server_default="0"))
|
|
op.add_column("tasks", sa.Column("settle_status", sa.String(length=20), nullable=False, server_default=""))
|
|
op.add_column("tasks", sa.Column("settled_at", sa.String(length=40), nullable=False, server_default=""))
|
|
op.add_column("tasks", sa.Column("on_time", sa.Boolean(), nullable=True))
|
|
op.add_column("tasks", sa.Column("contract_status", sa.String(length=20), nullable=False, server_default=""))
|
|
|
|
# ── bids 标书扩展 ──
|
|
op.add_column("bids", sa.Column("deliver_days", sa.Integer(), nullable=False, server_default="0"))
|
|
op.add_column("bids", sa.Column("team_json", sa.Text(), nullable=False))
|
|
op.add_column("bids", sa.Column("cases_json", sa.Text(), nullable=False))
|
|
op.add_column("bids", sa.Column("commit_json", sa.Text(), nullable=False))
|
|
op.add_column("bids", sa.Column("score_total", sa.Float(), nullable=False, server_default="0"))
|
|
op.add_column("bids", sa.Column("score_json", sa.Text(), nullable=False))
|
|
op.add_column("bids", sa.Column("review_note", sa.String(length=500), nullable=False, server_default=""))
|
|
|
|
# ── ratings:字段 + 唯一约束(先清理历史重复,保留最早一条)──
|
|
op.add_column("ratings", sa.Column("rating_type", sa.String(length=20), nullable=False, server_default="fulfill"))
|
|
op.add_column("ratings", sa.Column("dims_json", sa.Text(), nullable=False))
|
|
op.add_column("ratings", sa.Column("tags_json", sa.Text(), nullable=False))
|
|
op.execute(
|
|
"DELETE r1 FROM ratings r1 "
|
|
"INNER JOIN ratings r2 "
|
|
"ON r1.task_id = r2.task_id AND r1.from_id = r2.from_id AND r1.id > r2.id"
|
|
)
|
|
op.create_unique_constraint("uq_rating_task_from", "ratings", ["task_id", "from_id"])
|
|
|
|
# ── 新表:task_deliveries / task_milestones / task_acceptances / invoices ──
|
|
op.create_table(
|
|
"task_deliveries",
|
|
sa.Column("id", sa.String(length=64), primary_key=True),
|
|
sa.Column("task_id", sa.String(length=64), nullable=False, index=True),
|
|
sa.Column("milestone_id", sa.String(length=64), nullable=False, server_default=""),
|
|
sa.Column("version", sa.Integer(), nullable=False, server_default="1"),
|
|
sa.Column("attachments_json", sa.Text(), nullable=False),
|
|
sa.Column("note", sa.String(length=1000), nullable=False, server_default=""),
|
|
sa.Column("created_at", sa.String(length=40), nullable=False, server_default=""),
|
|
sa.ForeignKeyConstraint(["task_id"], ["tasks.id"], ondelete="CASCADE"),
|
|
)
|
|
op.create_table(
|
|
"task_milestones",
|
|
sa.Column("id", sa.String(length=64), primary_key=True),
|
|
sa.Column("task_id", sa.String(length=64), nullable=False, index=True),
|
|
sa.Column("index", sa.Integer(), nullable=False, server_default="1"),
|
|
sa.Column("name", sa.String(length=200), nullable=False, server_default=""),
|
|
sa.Column("desc", sa.String(length=1000), nullable=False, server_default=""),
|
|
sa.Column("days", sa.Integer(), nullable=False, server_default="0"),
|
|
sa.Column("deliverables_json", sa.Text(), nullable=False),
|
|
sa.Column("payment_ratio", sa.Float(), nullable=False, server_default="0"),
|
|
sa.Column("status", sa.String(length=20), nullable=False, server_default="pending"),
|
|
sa.Column("delivered_at", sa.String(length=40), nullable=False, server_default=""),
|
|
sa.Column("accepted_at", sa.String(length=40), nullable=False, server_default=""),
|
|
sa.Column("created_at", sa.String(length=40), nullable=False, server_default=""),
|
|
sa.ForeignKeyConstraint(["task_id"], ["tasks.id"], ondelete="CASCADE"),
|
|
)
|
|
op.create_table(
|
|
"task_acceptances",
|
|
sa.Column("id", sa.String(length=64), primary_key=True),
|
|
sa.Column("task_id", sa.String(length=64), nullable=False, index=True),
|
|
sa.Column("delivery_id", sa.String(length=64), nullable=False, server_default=""),
|
|
sa.Column("milestone_id", sa.String(length=64), nullable=False, server_default=""),
|
|
sa.Column("checklist_json", sa.Text(), nullable=False),
|
|
sa.Column("score_json", sa.Text(), nullable=False),
|
|
sa.Column("result", sa.String(length=20), nullable=False, server_default="pass"),
|
|
sa.Column("comment", sa.String(length=1000), nullable=False, server_default=""),
|
|
sa.Column("reviewer_id", sa.String(length=64), nullable=False, server_default=""),
|
|
sa.Column("created_at", sa.String(length=40), nullable=False, server_default=""),
|
|
sa.ForeignKeyConstraint(["task_id"], ["tasks.id"], ondelete="CASCADE"),
|
|
)
|
|
op.create_table(
|
|
"invoices",
|
|
sa.Column("id", sa.String(length=64), primary_key=True),
|
|
sa.Column("task_id", sa.String(length=64), nullable=False, index=True),
|
|
sa.Column("escrow_id", sa.String(length=64), nullable=False, server_default=""),
|
|
sa.Column("issuer_id", sa.String(length=64), nullable=False, server_default=""),
|
|
sa.Column("issuer_name", sa.String(length=200), nullable=False, server_default=""),
|
|
sa.Column("payer_name", sa.String(length=200), nullable=False, server_default=""),
|
|
sa.Column("amount", sa.Integer(), nullable=False, server_default="0"),
|
|
sa.Column("tax_rate", sa.Float(), nullable=False, server_default="0.01"),
|
|
sa.Column("invoice_type", sa.String(length=20), nullable=False, server_default="personal"),
|
|
sa.Column("status", sa.String(length=20), nullable=False, server_default="applied"),
|
|
sa.Column("invoice_no", sa.String(length=64), nullable=False, server_default=""),
|
|
sa.Column("created_at", sa.String(length=40), nullable=False, server_default=""),
|
|
sa.Column("issued_at", sa.String(length=40), nullable=False, server_default=""),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_table("invoices")
|
|
op.drop_table("task_acceptances")
|
|
op.drop_table("task_milestones")
|
|
op.drop_table("task_deliveries")
|
|
op.drop_constraint("uq_rating_task_from", "ratings", type_="unique")
|
|
op.drop_column("ratings", "tags_json")
|
|
op.drop_column("ratings", "dims_json")
|
|
op.drop_column("ratings", "rating_type")
|
|
op.drop_column("bids", "review_note")
|
|
op.drop_column("bids", "score_json")
|
|
op.drop_column("bids", "score_total")
|
|
op.drop_column("bids", "commit_json")
|
|
op.drop_column("bids", "cases_json")
|
|
op.drop_column("bids", "team_json")
|
|
op.drop_column("bids", "deliver_days")
|
|
for col in (
|
|
"contract_status", "on_time", "settled_at", "settle_status", "reject_count",
|
|
"accepted_at", "deliver_at", "attachments_json", "milestone_json",
|
|
"invoice_req", "escrow_ratio", "pay_type", "price_type", "accept_standard",
|
|
"deliver_items", "deliver_way", "raw_materials_json", "resource_support_json",
|
|
):
|
|
op.drop_column("tasks", col)
|