优化合同个管理和产品管理相关功能
This commit is contained in:
@@ -84,6 +84,7 @@ func Init(_ string) {
|
||||
new(TenantCrmEntityContact),
|
||||
new(TenantCrmOperateLog),
|
||||
new(TenantCrmContract),
|
||||
new(TenantCrmPayback),
|
||||
new(ErpAccountSet),
|
||||
new(ErpNormalSetting),
|
||||
new(ErpCompanyContact),
|
||||
@@ -147,7 +148,49 @@ func Init(_ string) {
|
||||
EnsureCrmProjectDocColumn()
|
||||
EnsureCrmContractTable()
|
||||
EnsureCrmContractOurRoleColumn()
|
||||
EnsureCrmContractTechDateColumn()
|
||||
EnsureCrmProjectProductsColumn()
|
||||
EnsureCrmPaybackTable()
|
||||
EnsureCrmProductDevColumns()
|
||||
}
|
||||
|
||||
// EnsureCrmPaybackTable 回款计划表建表(CREATE TABLE IF NOT EXISTS,可重复执行;
|
||||
// 建表失败(如表已存在但结构不一致)时静默忽略,可用 sql/yz_backend_crm_payback.sql 手动修复)。
|
||||
func EnsureCrmPaybackTable() {
|
||||
sql := `CREATE TABLE IF NOT EXISTS yz_backend_crm_payback (
|
||||
id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',
|
||||
tenant_id varchar(64) NOT NULL COMMENT '租户ID',
|
||||
contract_id bigint(20) DEFAULT NULL COMMENT '关联合同ID(yz_backend_crm_contract.id)',
|
||||
contract_no varchar(50) NOT NULL DEFAULT '' COMMENT '合同编号',
|
||||
contract_name varchar(100) NOT NULL DEFAULT '' COMMENT '合同名称',
|
||||
customer_id bigint(20) DEFAULT NULL COMMENT '客户ID',
|
||||
customer_name varchar(128) NOT NULL DEFAULT '' COMMENT '客户名称',
|
||||
plan_type tinyint(4) NOT NULL DEFAULT '1' COMMENT '回款周期:1月度/2季度/3年度/4进度/5自定义',
|
||||
pay_method tinyint(4) NOT NULL DEFAULT '1' COMMENT '回款方式:1对公转账/2网银转账/3现金/4支票/5支付宝/6微信/7其他',
|
||||
remind_days int(11) NOT NULL DEFAULT '0' COMMENT '提前几天提醒',
|
||||
owner_user_id varchar(64) NOT NULL DEFAULT '' COMMENT '负责人用户ID',
|
||||
owner_user_name varchar(128) NOT NULL DEFAULT '' COMMENT '负责人姓名',
|
||||
contract_amount decimal(14,2) NOT NULL DEFAULT '0.00' COMMENT '合同总金额',
|
||||
total_amount decimal(14,2) NOT NULL DEFAULT '0.00' COMMENT '计划回款总额',
|
||||
received_amount decimal(14,2) NOT NULL DEFAULT '0.00' COMMENT '已回款金额',
|
||||
status tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态:1进行中/2已完成',
|
||||
items text COMMENT '计划明细JSON数组',
|
||||
remark text COMMENT '备注',
|
||||
create_user_id varchar(64) NOT NULL DEFAULT '' COMMENT '创建人用户ID',
|
||||
create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
delete_time datetime DEFAULT NULL COMMENT '删除时间(软删除)',
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_tenant_id (tenant_id),
|
||||
KEY idx_contract (tenant_id,contract_id),
|
||||
KEY idx_customer (tenant_id,customer_id),
|
||||
KEY idx_status (tenant_id,status),
|
||||
KEY idx_delete_time (delete_time)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户CRM回款计划表'`
|
||||
if _, err := Orm.Raw(sql).Exec(); err != nil {
|
||||
// 表已存在或执行失败时忽略(完整表结构见 sql/yz_backend_crm_payback.sql)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureCrmContractOurRoleColumn 补齐合同表的我方角色字段(存量表已建时新增;
|
||||
@@ -158,6 +201,14 @@ func EnsureCrmContractOurRoleColumn() {
|
||||
_, _ = Orm.Raw(sql).Exec()
|
||||
}
|
||||
|
||||
// EnsureCrmContractTechDateColumn 补齐合同表的技术日期字段(开发/交付完成日期;
|
||||
// 存量表已建时新增,表不存在或列已存在时忽略错误)。
|
||||
func EnsureCrmContractTechDateColumn() {
|
||||
sql := "ALTER TABLE " + new(TenantCrmContract).TableName() +
|
||||
" ADD COLUMN tech_date date DEFAULT NULL COMMENT '技术日期(开发/交付完成日期;到期且回款未满则自动转执行异常)'"
|
||||
_, _ = Orm.Raw(sql).Exec()
|
||||
}
|
||||
|
||||
// EnsureCrmProjectProductsColumn 补齐项目表的产品清单字段(存量表已建时新增;
|
||||
// 表不存在或列已存在时忽略错误,可用 docs/sql/alter_backend_crm_project_products_column.sql 手动修复)。
|
||||
func EnsureCrmProjectProductsColumn() {
|
||||
@@ -221,6 +272,24 @@ func EnsureCrmProjectDocColumn() {
|
||||
_, _ = Orm.Raw(sql).Exec()
|
||||
}
|
||||
|
||||
// EnsureCrmProductDevColumns 补齐产品表的软件开发字段(line_type / dev_unit_price / dev_tree);
|
||||
// 表不存在或列已存在时忽略错误,可用 docs/sql/alter_backend_crm_product_dev_columns.sql 手动修复。
|
||||
func EnsureCrmProductDevColumns() {
|
||||
table := new(TenantCrmProduct).TableName()
|
||||
cols := []string{
|
||||
"line_type varchar(20) NOT NULL DEFAULT 'product' COMMENT '行类型:product成品/dev软件开发'",
|
||||
"dev_unit_price decimal(14,2) NOT NULL DEFAULT '0.00' COMMENT '软件开发统一人天单价'",
|
||||
"dev_tree text COMMENT '软件开发模块树JSON(叶子人天×统一人天单价)'",
|
||||
}
|
||||
for _, col := range cols {
|
||||
sql := fmt.Sprintf("ALTER TABLE %s ADD COLUMN %s", table, col)
|
||||
if _, err := Orm.Raw(sql).Exec(); err != nil {
|
||||
// 列已存在或表不存在时忽略
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ 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"`
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// TenantCrmPayback 回款计划表: yz_backend_crm_payback
|
||||
//
|
||||
// 说明:
|
||||
// - 回款计划针对于合同创建,contract_id 为关联合同(yz_backend_crm_contract.id);
|
||||
// - plan_type 回款周期:1=月度 2=季度 3=年度 4=进度 5=自定义;
|
||||
// - pay_method 回款方式:1=对公转账 2=网银转账 3=现金 4=支票 5=支付宝 6=微信 7=其他;
|
||||
// - items 计划明细以 JSON 文本存储,结构随 plan_type 变化:
|
||||
// 月度/季度/年度:{seq, name, amount, plan_date} —— 期数 + 支付金额 + 计划回款日期
|
||||
// 进度: {seq, name, percent, amount, plan_date} —— 进度名称 + 进度百分比 + 进度金额 + 计划回款日期
|
||||
// 自定义: {seq, name, plan_date, amount} —— 名称 + 计划日期 + 金额
|
||||
// 每行另带 received_amount / received_date / status,用于「回款进度」登记实收。
|
||||
// - plan_date 计划回款日期随各 plan_type 的明细行一并存储于 items JSON,无需独立列。
|
||||
// - total_amount 计划回款总额;received_amount 已回款金额,均由 items 汇总。
|
||||
type TenantCrmPayback struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
|
||||
ContractID *uint64 `orm:"column(contract_id);null" json:"contract_id"` // 关联合同ID
|
||||
ContractNo string `orm:"column(contract_no);size(50)" json:"contract_no"`
|
||||
ContractName string `orm:"column(contract_name);size(100)" json:"contract_name"`
|
||||
CustomerID *uint64 `orm:"column(customer_id);null" json:"customer_id"`
|
||||
CustomerName string `orm:"column(customer_name);size(128)" json:"customer_name"`
|
||||
PlanType int8 `orm:"column(plan_type);default(1)" json:"plan_type"` // 回款周期:1月度/2季度/3年度/4进度/5自定义
|
||||
PayMethod int8 `orm:"column(pay_method);default(1)" json:"pay_method"` // 回款方式:1对公/2网银/3现金/4支票/5支付宝/6微信/7其他
|
||||
RemindDays int `orm:"column(remind_days);default(0)" json:"remind_days"` // 提前几天提醒
|
||||
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"`
|
||||
ContractAmount float64 `orm:"column(contract_amount);digits(14);decimals(2);default(0)" json:"contract_amount"` // 合同总金额
|
||||
TotalAmount float64 `orm:"column(total_amount);digits(14);decimals(2);default(0)" json:"total_amount"` // 计划回款总额
|
||||
ReceivedAmount float64 `orm:"column(received_amount);digits(14);decimals(2);default(0)" json:"received_amount"` // 已回款金额
|
||||
Status int8 `orm:"column(status);default(1)" json:"status"` // 1进行中/2已完成
|
||||
Items string `orm:"column(items);type(text);null" json:"-"` // 计划明细 JSON 数组
|
||||
Remark string `orm:"column(remark);type(text);null" json:"remark"`
|
||||
ReceiptURL string `orm:"column(receipt_url);size(512);null" json:"receipt_url"` // 流水回执文件地址(选填)
|
||||
ReceiptName string `orm:"column(receipt_name);size(255);null" json:"receipt_name"` // 流水回执文件名(选填)
|
||||
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 *TenantCrmPayback) TableName() string {
|
||||
return "yz_backend_crm_payback"
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// TenantCrmProduct CRM 产品管理(产品台账/目录): yz_backend_crm_product
|
||||
//
|
||||
@@ -19,6 +21,9 @@ type TenantCrmProduct struct {
|
||||
Price float64 `orm:"column(price);digits(14);decimals(2);default(0)" json:"price"` // 销售单价
|
||||
CostPrice float64 `orm:"column(cost_price);digits(14);decimals(2);default(0)" json:"cost_price"` // 成本单价
|
||||
TaxRate float64 `orm:"column(tax_rate);digits(6);decimals(2);default(0)" json:"tax_rate"` // 税率(%)
|
||||
LineType string `orm:"column(line_type);size(20);default(product)" json:"line_type"` // 行类型 product/dev
|
||||
DevUnitPrice float64 `orm:"column(dev_unit_price);digits(14);decimals(2);default(0)" json:"dev_unit_price"` // 软件开发统一人天单价
|
||||
DevTree string `orm:"column(dev_tree);type(text);null" json:"dev_tree"` // 软件开发模块树JSON文本
|
||||
Status int8 `orm:"column(status);default(1)" json:"status"` // 1启用/0停用
|
||||
ProjectID *uint64 `orm:"column(project_id);null" json:"project_id"` // 来源项目ID(由项目生成时填入)
|
||||
ProjectName string `orm:"column(project_name);size(100)" json:"project_name"` // 来源项目名称
|
||||
|
||||
Reference in New Issue
Block a user