优化项目管理

This commit is contained in:
2026-09-13 22:31:42 +08:00
parent 2f6cdbb3cd
commit a8c09c1db5
30 changed files with 1654 additions and 346 deletions
+5 -5
View File
@@ -148,8 +148,8 @@ func Init(_ string) {
EnsureCrmCreateUserColumn()
EnsureCrmProjectDocColumn()
EnsureCrmContractTable()
EnsureCrmClueAmountColumn()
EnsureCrmContractOurRoleColumn()
EnsureCrmContractTechDateColumn()
EnsureCrmProjectProductsColumn()
EnsureCrmPaybackTable()
EnsureCrmPaybackRecordTable()
@@ -234,11 +234,11 @@ func EnsureCrmContractOurRoleColumn() {
_, _ = Orm.Raw(sql).Exec()
}
// EnsureCrmContractTechDateColumn 补齐合同表的技术日期字段(开发/交付完成日期;
// EnsureCrmClueAmountColumn 补齐线索表的预计金额字段(线索阶段预估金额;
// 存量表已建时新增,表不存在或列已存在时忽略错误)。
func EnsureCrmContractTechDateColumn() {
sql := "ALTER TABLE " + new(TenantCrmContract).TableName() +
" ADD COLUMN tech_date date DEFAULT NULL COMMENT '技术日期(开发/交付完成日期;到期且回款未满则自动转执行异常)'"
func EnsureCrmClueAmountColumn() {
sql := "ALTER TABLE " + new(TenantCrmClue).TableName() +
" ADD COLUMN amount decimal(14,2) NOT NULL DEFAULT '0.00' COMMENT '预计金额'"
_, _ = Orm.Raw(sql).Exec()
}
+1
View File
@@ -13,6 +13,7 @@ type TenantCrmClue struct {
OwnerUserID string `orm:"column(owner_user_id);size(64)" json:"owner_user_id"` // 负责人
OwnerUserName string `orm:"column(owner_user_name);size(128)" json:"owner_user_name"`
Industry string `orm:"column(industry);size(50)" json:"industry"` // 客户行业
Amount float64 `orm:"column(amount);digits(14);decimals(2);default(0)" json:"amount"` // 预计金额(线索阶段预估,用于仪表盘线索金额统计)
NextContactTime *time.Time `orm:"column(next_contact_time);type(datetime);null" json:"next_contact_time"` // 下次联系时间
ClueLevel string `orm:"column(clue_level);size(20);default(2)" json:"clue_level"` // 客户级别:1重点/2普通/3非优先
ContactPerson string `orm:"column(contact_person);size(50)" json:"contact_person"` // 客户对接人
-1
View File
@@ -25,7 +25,6 @@ type TenantCrmContract struct {
SignDate *time.Time `orm:"column(sign_date);type(date);null" json:"sign_date"`
EffectiveDate *time.Time `orm:"column(effective_date);type(date);null" json:"effective_date"`
ExpireDate *time.Time `orm:"column(expire_date);type(date);null" json:"expire_date"`
TechDate *time.Time `orm:"column(tech_date);type(date);null" json:"tech_date"` // 技术日期(开发/交付完成日期;到期且回款未满则自动转执行异常)
Parties string `orm:"column(parties);type(text);null" json:"-"` // 各方签约主体 JSON 数组
Products string `orm:"column(products);type(text);null" json:"-"` // 产品清单 JSON 数组
HardwareAmount float64 `orm:"column(hardware_amount);digits(14);decimals(2);default(0)" json:"hardware_amount"`
+41 -20
View File
@@ -4,26 +4,47 @@ import "time"
// TenantCrmProject 项目表: yz_backend_crm_project
type TenantCrmProject struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
ProjectName string `orm:"column(project_name);size(100)" json:"project_name"` // 项目名称
ProjectNo string `orm:"column(project_no);size(50)" json:"project_no"` // 项目编号
BusinessID *uint64 `orm:"column(business_id);null" json:"business_id"` // 来源商机ID
BusinessName string `orm:"-" json:"business_name"` // 来源商机名称(非表字段,查询时填充)
CustomerID *uint64 `orm:"column(customer_id);null" json:"customer_id"`
CustomerName string `orm:"column(customer_name);size(100)" json:"customer_name"`
OwnerUserID string `orm:"column(owner_user_id);size(64)" json:"owner_user_id"`
OwnerUserName string `orm:"column(owner_user_name);size(128)" json:"owner_user_name"`
Industry string `orm:"column(industry);size(50)" json:"industry"`
Amount float64 `orm:"column(amount);digits(14);decimals(2);default(0)" json:"amount"`
Status int8 `orm:"column(status);default(1)" json:"status"` // 1未开始/2进行中/3已完成/4已暂停
StartDate *time.Time `orm:"column(start_date);type(date);null" json:"start_date"`
EndDate *time.Time `orm:"column(end_date);type(date);null" json:"end_date"`
ContactPerson string `orm:"column(contact_person);size(50)" json:"contact_person"`
ContactPosition string `orm:"column(contact_position);size(50)" json:"contact_position"` // 对接人职位
ContactPhone string `orm:"column(contact_phone);size(20)" json:"contact_phone"`
Address string `orm:"column(address);size(255)" json:"address"`
Remark string `orm:"column(remark);type(text);null" json:"remark"`
ID uint64 `orm:"column(id);pk;auto" json:"id"`
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
ProjectName string `orm:"column(project_name);size(100)" json:"project_name"` // 项目名称
ProjectNo string `orm:"column(project_no);size(50)" json:"project_no"` // 项目编号
BusinessID *uint64 `orm:"column(business_id);null" json:"business_id"` // 来源商机ID
BusinessName string `orm:"-" json:"business_name"` // 来源商机名称(非表字段,查询时填充)
CustomerID *uint64 `orm:"column(customer_id);null" json:"customer_id"`
CustomerName string `orm:"column(customer_name);size(100)" json:"customer_name"`
OwnerUserID string `orm:"column(owner_user_id);size(64)" json:"owner_user_id"`
OwnerUserName string `orm:"column(owner_user_name);size(128)" json:"owner_user_name"`
Industry string `orm:"column(industry);size(50)" json:"industry"`
// 项目类型:1=单一项目(只有上游客户) 2=上下游项目(上游客户 + 下游供应商)
ProjectType int8 `orm:"column(project_type);default(1)" json:"project_type"`
// 下游主体:可从供应商库或客户库选择(supplier_ref_type + supplier_id 标明来源),也允许手工填写名称
SupplierID *uint64 `orm:"column(supplier_id);null" json:"supplier_id"`
SupplierRefType int8 `orm:"column(supplier_ref_type);default(0)" json:"supplier_ref_type"` // 0未关联 1客户 2供应商
SupplierName string `orm:"column(supplier_name);size(100)" json:"supplier_name"`
SupplierIndustry string `orm:"column(supplier_industry);size(50)" json:"supplier_industry"`
// 金额拆分为上下游:上游=对客户的收入,下游=对供应商的成本(上下游项目毛利 = 上游 - 下游)
UpstreamAmount float64 `orm:"column(upstream_amount);digits(14);decimals(2);default(0)" json:"upstream_amount"`
DownstreamAmount float64 `orm:"column(downstream_amount);digits(14);decimals(2);default(0)" json:"downstream_amount"`
// Amount 为旧「项目金额」列,已由 UpstreamAmount 取代;写入时始终同步为上游金额,仅作历史兼容
Amount float64 `orm:"column(amount);digits(14);decimals(2);default(0)" json:"amount"`
Status int8 `orm:"column(status);default(1)" json:"status"` // 1未开始/2进行中/3已完成/4已暂停
// StartDate / EndDate 为旧的手工维护列,已改由关联合同自动汇总,保留仅用于兼容历史数据
StartDate *time.Time `orm:"column(start_date);type(date);null" json:"start_date"`
EndDate *time.Time `orm:"column(end_date);type(date);null" json:"end_date"`
// 项目实际起止时间:按其下所有合同汇总(最早生效日期 / 最晚结束日期),只读不落库
ContractStartDate *time.Time `orm:"-" json:"contract_start_date"`
ContractEndDate *time.Time `orm:"-" json:"contract_end_date"`
// 上下游对接人:仅需姓名与电话
UpstreamContact string `orm:"column(upstream_contact);size(50)" json:"upstream_contact"`
UpstreamPhone string `orm:"column(upstream_phone);size(20)" json:"upstream_phone"`
DownstreamContact string `orm:"column(downstream_contact);size(50)" json:"downstream_contact"`
DownstreamPhone string `orm:"column(downstream_phone);size(20)" json:"downstream_phone"`
// 以下为旧版单一对接人信息,已被上下游对接人取代,仅保留列以兼容历史数据
ContactPerson string `orm:"column(contact_person);size(50)" json:"contact_person"`
ContactPosition string `orm:"column(contact_position);size(50)" json:"contact_position"` // 对接人职位(已废弃)
ContactPhone string `orm:"column(contact_phone);size(20)" json:"contact_phone"`
Address string `orm:"column(address);size(255)" json:"address"`
Remark string `orm:"column(remark);type(text);null" json:"remark"`
// DocCategoryID 项目在 OA 文档库的文件夹分类ID:
// 指向 yz_backend_oa_doc_category 中「共享文档 / 项目文档 / {项目名称}」这条记录(0 表示尚未建立)。
DocCategoryID uint64 `orm:"column(doc_category_id);default(0)" json:"doc_category_id"`