增加商机线索管理修复若干bug

This commit is contained in:
2026-09-11 11:11:43 +08:00
parent b9cdabe045
commit 9c07af2b59
39 changed files with 6219 additions and 42 deletions
+3 -2
View File
@@ -2,7 +2,8 @@ package models
import "time"
// ErpCompanyContact 客户/供应商联系人表
// ErpCompanyContact 正式客户/供应商联系人通用表: yz_backend_contact_company
// 全模块共用的「公司联系人」正式库(客户/供应商对接人)。
type ErpCompanyContact struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
@@ -28,5 +29,5 @@ type ErpCompanyContact struct {
}
func (m *ErpCompanyContact) TableName() string {
return "yz_backend_erp_company_contact"
return "yz_backend_contact_company"
}
+7
View File
@@ -74,6 +74,13 @@ func Init(_ string) {
new(BackendUserNotifyConfig),
new(TenantCrmCustomer),
new(TenantCrmSupplier),
new(TenantCrmClue),
new(TenantCrmBusiness),
new(TenantCrmProject),
new(TenantCrmFollow),
new(TenantCrmAttach),
new(TenantCrmEntityContact),
new(TenantCrmOperateLog),
new(ErpAccountSet),
new(ErpNormalSetting),
new(ErpCompanyContact),
+25
View File
@@ -0,0 +1,25 @@
package models
import "time"
// TenantCrmAttach 附件表: yz_tenant_crm_attach
// related_type: 1线索 / 2商机 / 3项目
type TenantCrmAttach struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
RelatedType int8 `orm:"column(related_type)" json:"related_type"`
RelatedID uint64 `orm:"column(related_id)" json:"related_id"`
FileID *uint64 `orm:"column(file_id);null" json:"file_id"`
FileName string `orm:"column(file_name);size(255)" json:"file_name"`
FileURL string `orm:"column(file_url);size(500)" json:"file_url"`
FileSize int64 `orm:"column(file_size);default(0)" json:"file_size"`
UploaderID string `orm:"column(uploader_id);size(64)" json:"uploader_id"`
UploaderName string `orm:"column(uploader_name);size(128)" json:"uploader_name"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
}
func (m *TenantCrmAttach) TableName() string {
return "yz_tenant_crm_attach"
}
+41
View File
@@ -0,0 +1,41 @@
package models
import "time"
// TenantCrmBusiness 商机表: yz_tenant_crm_business
type TenantCrmBusiness struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
BusinessName string `orm:"column(business_name);size(100)" json:"business_name"` // 商机名称
ClueID *uint64 `orm:"column(clue_id);null" json:"clue_id"` // 来源线索ID
CustomerID *uint64 `orm:"column(customer_id);null" json:"customer_id"` // 正式客户ID
CustomerName string `orm:"column(customer_name);size(100)" json:"customer_name"`
Source string `orm:"column(source);size(50)" json:"source"`
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"`
Stage string `orm:"column(stage);size(20);default(1)" json:"stage"` // 商机阶段
Amount float64 `orm:"column(amount);digits(14);decimals(2);default(0)" json:"amount"`
ExpectDealDate *time.Time `orm:"column(expect_deal_date);type(date);null" json:"expect_deal_date"`
NextContactTime *time.Time `orm:"column(next_contact_time);type(datetime);null" json:"next_contact_time"`
Level string `orm:"column(level);size(20);default(2)" json:"level"`
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"`
ContactWechat string `orm:"column(contact_wechat);size(64)" json:"contact_wechat"`
ContactQQ string `orm:"column(contact_qq);size(20)" json:"contact_qq"`
Address string `orm:"column(address);size(255)" json:"address"`
Status int8 `orm:"column(status);default(1)" json:"status"` // 1跟进中/2已转化项目/3已关闭
Locked int8 `orm:"column(locked);default(0)" json:"locked"` // 转化项目后锁定
ProjectID *uint64 `orm:"column(project_id);null" json:"project_id"` // 转化后的项目ID
ConvertTime *time.Time `orm:"column(convert_time);type(datetime);null" json:"convert_time"`
Remark string `orm:"column(remark);type(text);null" json:"remark"`
CreateUserID string `orm:"column(create_user_id);size(64)" json:"create_user_id"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
}
func (m *TenantCrmBusiness) TableName() string {
return "yz_tenant_crm_business"
}
+37
View File
@@ -0,0 +1,37 @@
package models
import "time"
// TenantCrmClue 线索表: yz_tenant_crm_clue
// 线索阶段的「客户名称」不关联客户管理,转化商机时才落地为正式客户。
type TenantCrmClue struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
ClueName string `orm:"column(clue_name);size(100)" json:"clue_name"` // 线索名称
CustomerName string `orm:"column(customer_name);size(100)" json:"customer_name"` // 客户名称(暂不关联客户管理)
Source string `orm:"column(source);size(50)" json:"source"` // 客户来源
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"` // 客户行业
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"` // 客户对接人
ContactPosition string `orm:"column(contact_position);size(50)" json:"contact_position"` // 对接人职位
ContactPhone string `orm:"column(contact_phone);size(20)" json:"contact_phone"` // 对接人手机
ContactWechat string `orm:"column(contact_wechat);size(64)" json:"contact_wechat"` // 对接人微信
ContactQQ string `orm:"column(contact_qq);size(20)" json:"contact_qq"` // 对接人QQ
Address string `orm:"column(address);size(255)" json:"address"` // 公司地址
Status int8 `orm:"column(status);default(1)" json:"status"` // 1跟进中/2已转化/3已关闭
Locked int8 `orm:"column(locked);default(0)" json:"locked"` // 0否/1是(转化后锁定不可编辑)
BusinessID *uint64 `orm:"column(business_id);null" json:"business_id"` // 转化后的商机ID
ConvertTime *time.Time `orm:"column(convert_time);type(datetime);null" json:"convert_time"` // 转化时间
Remark string `orm:"column(remark);type(text);null" json:"remark"`
CreateUserID string `orm:"column(create_user_id);size(64)" json:"create_user_id"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
}
func (m *TenantCrmClue) TableName() string {
return "yz_tenant_crm_clue"
}
+27
View File
@@ -0,0 +1,27 @@
package models
import "time"
// TenantCrmEntityContact 联系人表: yz_tenant_crm_entity_contact
// related_type: 1线索 / 2商机 / 3项目
type TenantCrmEntityContact struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
RelatedType int8 `orm:"column(related_type)" json:"related_type"`
RelatedID uint64 `orm:"column(related_id)" json:"related_id"`
ContactName string `orm:"column(contact_name);size(50)" json:"contact_name"`
Position string `orm:"column(position);size(50)" json:"position"`
Mobile string `orm:"column(mobile);size(20)" json:"mobile"`
Wechat string `orm:"column(wechat);size(64)" json:"wechat"`
QQ string `orm:"column(qq);size(20)" json:"qq"`
Email string `orm:"column(email);size(100)" json:"email"`
IsPrimary int8 `orm:"column(is_primary);default(0)" json:"is_primary"`
Remark string `orm:"column(remark);size(500)" json:"remark"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
}
func (m *TenantCrmEntityContact) TableName() string {
return "yz_tenant_crm_entity_contact"
}
+26
View File
@@ -0,0 +1,26 @@
package models
import "time"
// TenantCrmFollow 回访/跟进记录表: yz_tenant_crm_follow
// related_type: 1线索 / 2商机 / 3项目
type TenantCrmFollow struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
RelatedType int8 `orm:"column(related_type)" json:"related_type"`
RelatedID uint64 `orm:"column(related_id)" json:"related_id"`
RelatedName string `orm:"column(related_name);size(100)" json:"related_name"`
FollowType string `orm:"column(follow_type);size(20);default(1)" json:"follow_type"` // 回访方式
FollowTime *time.Time `orm:"column(follow_time);type(datetime);null" json:"follow_time"`
Content string `orm:"column(content);type(text);null" json:"content"`
NextContactTime *time.Time `orm:"column(next_contact_time);type(datetime);null" json:"next_contact_time"`
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"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
}
func (m *TenantCrmFollow) TableName() string {
return "yz_tenant_crm_follow"
}
+21
View File
@@ -0,0 +1,21 @@
package models
import "time"
// TenantCrmOperateLog 操作日志表: yz_tenant_crm_operate_log
// related_type: 1线索 / 2商机 / 3项目
type TenantCrmOperateLog struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
RelatedType int8 `orm:"column(related_type)" json:"related_type"`
RelatedID uint64 `orm:"column(related_id)" json:"related_id"`
Action string `orm:"column(action);size(50)" json:"action"`
Content string `orm:"column(content);size(500)" json:"content"`
OperatorID string `orm:"column(operator_id);size(64)" json:"operator_id"`
OperatorName string `orm:"column(operator_name);size(128)" json:"operator_name"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
}
func (m *TenantCrmOperateLog) TableName() string {
return "yz_tenant_crm_operate_log"
}
+34
View File
@@ -0,0 +1,34 @@
package models
import "time"
// TenantCrmProject 项目表: yz_tenant_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
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"`
CreateUserID string `orm:"column(create_user_id);size(64)" json:"create_user_id"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
}
func (m *TenantCrmProject) TableName() string {
return "yz_tenant_crm_project"
}