812 lines
26 KiB
Go
812 lines
26 KiB
Go
package controllers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"server/models"
|
|
|
|
beego "github.com/beego/beego/v2/server/web"
|
|
)
|
|
|
|
// =============================================================
|
|
// CRM 招投标管理 - 子表 CRUD(统一接口)
|
|
// =============================================================
|
|
//
|
|
// 每个子表控制器提供统一的接口:
|
|
// - List 按外键 bid_id / tender_id 列出
|
|
// - Create 新增(关联外键由请求体传入)
|
|
// - Delete 软删除
|
|
// - Update 更新(用于文件改名、任务进度等)
|
|
// =============================================================
|
|
|
|
// ------------------------------ 投标文件 ------------------------------
|
|
|
|
// BackendCrmBiddingBidFileController 投标文件
|
|
type BackendCrmBiddingBidFileController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
// bidFilePayload
|
|
type bidFilePayload struct {
|
|
BidID uint64 `json:"bid_id"`
|
|
FileType string `json:"file_type"`
|
|
FileName string `json:"file_name"`
|
|
FileURL string `json:"file_url"`
|
|
FileSize uint64 `json:"file_size"`
|
|
FileExt string `json:"file_ext"`
|
|
Version string `json:"version"`
|
|
UploadUserID string `json:"upload_user_id"`
|
|
UploadUserName string `json:"upload_user_name"`
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
// List GET /backend/crm/bidding/bid-file/list?bid_id=1
|
|
func (c *BackendCrmBiddingBidFileController) List() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
bidID, _ := c.GetInt64("bid_id")
|
|
if bidID == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "bid_id 必填")
|
|
return
|
|
}
|
|
var list []models.TenantCrmBiddingBidFile
|
|
_, _ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidFile)).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Filter("bid_id", bidID).
|
|
Filter("delete_time__isnull", true).
|
|
OrderBy("-id").All(&list)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"list": list})
|
|
}
|
|
|
|
// Create POST /backend/crm/bidding/bid-file
|
|
func (c *BackendCrmBiddingBidFileController) Create() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
|
var p bidFilePayload
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
pipelineErr(&c.Controller, 400, 400, "参数错误")
|
|
return
|
|
}
|
|
if p.BidID == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "bid_id 必填")
|
|
return
|
|
}
|
|
if strings.TrimSpace(p.FileName) == "" || strings.TrimSpace(p.FileURL) == "" {
|
|
pipelineErr(&c.Controller, 400, 400, "文件信息不完整")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
row := models.TenantCrmBiddingBidFile{
|
|
TenantID: pipelineTenantID(claims),
|
|
BidID: p.BidID,
|
|
FileType: firstNonEmpty(p.FileType, "1"),
|
|
FileName: strings.TrimSpace(p.FileName),
|
|
FileURL: strings.TrimSpace(p.FileURL),
|
|
FileSize: p.FileSize,
|
|
FileExt: strings.TrimSpace(p.FileExt),
|
|
Version: firstNonEmpty(p.Version, "1.0"),
|
|
UploadUserID: firstNonEmpty(p.UploadUserID, pipelineUID(claims)),
|
|
UploadUserName: firstNonEmpty(p.UploadUserName, resolveUserName(claims)),
|
|
Remark: p.Remark,
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}
|
|
id, err := models.Orm.Insert(&row)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "上传失败: "+err.Error())
|
|
return
|
|
}
|
|
crmWriteLog(pipelineTenantID(claims), 5, p.BidID, "create", "上传投标文件", claims)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"id": id})
|
|
}
|
|
|
|
// Delete DELETE /backend/crm/bidding/bid-file/:id
|
|
func (c *BackendCrmBiddingBidFileController) Delete() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
|
if id == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "无效的ID")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
_, err = models.Orm.QueryTable(new(models.TenantCrmBiddingBidFile)).
|
|
Filter("id", id).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Update(map[string]interface{}{"delete_time": now, "update_time": now})
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "删除失败: "+err.Error())
|
|
return
|
|
}
|
|
var delRow models.TenantCrmBiddingBidFile
|
|
_ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidFile)).Filter("id", id).One(&delRow)
|
|
crmWriteLog(pipelineTenantID(claims), 5, delRow.BidID, "delete", "删除投标文件", claims)
|
|
pipelineOk(&c.Controller, nil)
|
|
}
|
|
|
|
// ------------------------------ 投标任务 ------------------------------
|
|
|
|
// BackendCrmBiddingBidTaskController 投标任务
|
|
type BackendCrmBiddingBidTaskController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
type bidTaskPayload struct {
|
|
BidID uint64 `json:"bid_id"`
|
|
TaskName string `json:"task_name"`
|
|
TaskType string `json:"task_type"`
|
|
Content string `json:"content"`
|
|
OwnerUserID string `json:"owner_user_id"`
|
|
OwnerUserName string `json:"owner_user_name"`
|
|
StartDate string `json:"start_date"`
|
|
EndDate string `json:"end_date"`
|
|
Status int8 `json:"status"`
|
|
Progress int8 `json:"progress"`
|
|
Files string `json:"files"`
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
// List
|
|
func (c *BackendCrmBiddingBidTaskController) List() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
bidID, _ := c.GetInt64("bid_id")
|
|
if bidID == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "bid_id 必填")
|
|
return
|
|
}
|
|
var list []models.TenantCrmBiddingBidTask
|
|
_, _ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidTask)).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Filter("bid_id", bidID).
|
|
Filter("delete_time__isnull", true).
|
|
OrderBy("-id").All(&list)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"list": list})
|
|
}
|
|
|
|
// Create
|
|
func (c *BackendCrmBiddingBidTaskController) Create() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
|
var p bidTaskPayload
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
pipelineErr(&c.Controller, 400, 400, "参数错误")
|
|
return
|
|
}
|
|
if p.BidID == 0 || strings.TrimSpace(p.TaskName) == "" {
|
|
pipelineErr(&c.Controller, 400, 400, "任务信息不完整")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
row := models.TenantCrmBiddingBidTask{
|
|
TenantID: pipelineTenantID(claims),
|
|
BidID: p.BidID,
|
|
TaskName: strings.TrimSpace(p.TaskName),
|
|
TaskType: firstNonEmpty(p.TaskType, "1"),
|
|
Content: p.Content,
|
|
OwnerUserID: firstNonEmpty(p.OwnerUserID, pipelineUID(claims)),
|
|
OwnerUserName: firstNonEmpty(p.OwnerUserName, resolveUserName(claims)),
|
|
StartDate: parsePipelineDate(p.StartDate),
|
|
EndDate: parsePipelineDate(p.EndDate),
|
|
Status: p.Status,
|
|
Progress: p.Progress,
|
|
Files: p.Files,
|
|
Remark: p.Remark,
|
|
CreateUserID: pipelineUID(claims),
|
|
CreateUserName: resolveUserName(claims),
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}
|
|
id, err := models.Orm.Insert(&row)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "创建失败: "+err.Error())
|
|
return
|
|
}
|
|
crmWriteLog(pipelineTenantID(claims), 5, p.BidID, "create", "新建投标任务", claims)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"id": id})
|
|
}
|
|
|
|
// Update
|
|
func (c *BackendCrmBiddingBidTaskController) Update() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
|
if id == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "无效的ID")
|
|
return
|
|
}
|
|
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
|
var p bidTaskPayload
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
pipelineErr(&c.Controller, 400, 400, "参数错误")
|
|
return
|
|
}
|
|
var row models.TenantCrmBiddingBidTask
|
|
if err := models.Orm.QueryTable(new(models.TenantCrmBiddingBidTask)).
|
|
Filter("id", id).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Filter("delete_time__isnull", true).One(&row); err != nil {
|
|
pipelineErr(&c.Controller, 404, 404, "任务未找到")
|
|
return
|
|
}
|
|
if strings.TrimSpace(p.TaskName) != "" {
|
|
row.TaskName = strings.TrimSpace(p.TaskName)
|
|
}
|
|
if strings.TrimSpace(p.TaskType) != "" {
|
|
row.TaskType = p.TaskType
|
|
}
|
|
row.Content = p.Content
|
|
if strings.TrimSpace(p.OwnerUserID) != "" {
|
|
row.OwnerUserID = strings.TrimSpace(p.OwnerUserID)
|
|
row.OwnerUserName = strings.TrimSpace(p.OwnerUserName)
|
|
}
|
|
row.StartDate = parsePipelineDate(p.StartDate)
|
|
row.EndDate = parsePipelineDate(p.EndDate)
|
|
row.Status = p.Status
|
|
row.Progress = p.Progress
|
|
row.Files = p.Files
|
|
row.Remark = p.Remark
|
|
row.UpdateTime = time.Now()
|
|
if _, err := models.Orm.Update(&row); err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "更新失败: "+err.Error())
|
|
return
|
|
}
|
|
crmWriteLog(pipelineTenantID(claims), 5, row.BidID, "update", "更新投标任务", claims)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"id": row.ID})
|
|
}
|
|
|
|
// Delete
|
|
func (c *BackendCrmBiddingBidTaskController) Delete() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
|
if id == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "无效的ID")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
_, err = models.Orm.QueryTable(new(models.TenantCrmBiddingBidTask)).
|
|
Filter("id", id).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Update(map[string]interface{}{"delete_time": now, "update_time": now})
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "删除失败: "+err.Error())
|
|
return
|
|
}
|
|
var delRow models.TenantCrmBiddingBidTask
|
|
_ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidTask)).Filter("id", id).One(&delRow)
|
|
crmWriteLog(pipelineTenantID(claims), 5, delRow.BidID, "delete", "删除投标任务", claims)
|
|
pipelineOk(&c.Controller, nil)
|
|
}
|
|
|
|
// ------------------------------ 投标结果 ------------------------------
|
|
|
|
// BackendCrmBiddingBidResultController 投标结果
|
|
type BackendCrmBiddingBidResultController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
// List
|
|
func (c *BackendCrmBiddingBidResultController) List() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
bidID, _ := c.GetInt64("bid_id")
|
|
if bidID == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "bid_id 必填")
|
|
return
|
|
}
|
|
var list []models.TenantCrmBiddingBidResult
|
|
_, _ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidResult)).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Filter("bid_id", bidID).
|
|
Filter("delete_time__isnull", true).
|
|
OrderBy("-id").All(&list)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"list": list})
|
|
}
|
|
|
|
// Detail
|
|
func (c *BackendCrmBiddingBidResultController) Detail() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
|
if id == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "无效的ID")
|
|
return
|
|
}
|
|
var row models.TenantCrmBiddingBidResult
|
|
err = models.Orm.QueryTable(new(models.TenantCrmBiddingBidResult)).
|
|
Filter("id", id).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Filter("delete_time__isnull", true).One(&row)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 404, 404, "投标结果未找到")
|
|
return
|
|
}
|
|
pipelineOk(&c.Controller, row)
|
|
}
|
|
|
|
// ------------------------------ 投标报价 ------------------------------
|
|
|
|
// BackendCrmBiddingBidQuoteController 投标报价
|
|
type BackendCrmBiddingBidQuoteController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
type bidQuotePayload struct {
|
|
BidID uint64 `json:"bid_id"`
|
|
QuoteName string `json:"quote_name"`
|
|
TotalAmount float64 `json:"total_amount"`
|
|
Currency string `json:"currency"`
|
|
TaxRate float64 `json:"tax_rate"`
|
|
ValidDate string `json:"valid_date"`
|
|
Products string `json:"products"`
|
|
CostAnalysis string `json:"cost_analysis"`
|
|
ProfitRate float64 `json:"profit_rate"`
|
|
Status int8 `json:"status"`
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
// List
|
|
func (c *BackendCrmBiddingBidQuoteController) List() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
bidID, _ := c.GetInt64("bid_id")
|
|
if bidID == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "bid_id 必填")
|
|
return
|
|
}
|
|
var list []models.TenantCrmBiddingBidQuote
|
|
_, _ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidQuote)).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Filter("bid_id", bidID).
|
|
Filter("delete_time__isnull", true).
|
|
OrderBy("-id").All(&list)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"list": list})
|
|
}
|
|
|
|
// Create
|
|
func (c *BackendCrmBiddingBidQuoteController) Create() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
|
var p bidQuotePayload
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
pipelineErr(&c.Controller, 400, 400, "参数错误")
|
|
return
|
|
}
|
|
if p.BidID == 0 || strings.TrimSpace(p.QuoteName) == "" {
|
|
pipelineErr(&c.Controller, 400, 400, "报价信息不完整")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
row := models.TenantCrmBiddingBidQuote{
|
|
TenantID: pipelineTenantID(claims),
|
|
BidID: p.BidID,
|
|
QuoteName: strings.TrimSpace(p.QuoteName),
|
|
TotalAmount: p.TotalAmount,
|
|
Currency: firstNonEmpty(p.Currency, "CNY"),
|
|
TaxRate: p.TaxRate,
|
|
ValidDate: parsePipelineDate(p.ValidDate),
|
|
Products: p.Products,
|
|
CostAnalysis: p.CostAnalysis,
|
|
ProfitRate: p.ProfitRate,
|
|
Status: 1,
|
|
SubmitUserID: pipelineUID(claims),
|
|
SubmitUserName: resolveUserName(claims),
|
|
SubmitTime: &now,
|
|
Remark: p.Remark,
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}
|
|
id, err := models.Orm.Insert(&row)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "创建失败: "+err.Error())
|
|
return
|
|
}
|
|
crmWriteLog(pipelineTenantID(claims), 5, p.BidID, "create", "新建投标报价", claims)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"id": id})
|
|
}
|
|
|
|
// Delete
|
|
func (c *BackendCrmBiddingBidQuoteController) Delete() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
|
if id == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "无效的ID")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
_, err = models.Orm.QueryTable(new(models.TenantCrmBiddingBidQuote)).
|
|
Filter("id", id).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Update(map[string]interface{}{"delete_time": now, "update_time": now})
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "删除失败: "+err.Error())
|
|
return
|
|
}
|
|
var delRow models.TenantCrmBiddingBidQuote
|
|
_ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidQuote)).Filter("id", id).One(&delRow)
|
|
crmWriteLog(pipelineTenantID(claims), 5, delRow.BidID, "delete", "删除投标报价", claims)
|
|
pipelineOk(&c.Controller, nil)
|
|
}
|
|
|
|
// ------------------------------ 投标竞争对手 ------------------------------
|
|
|
|
// BackendCrmBiddingBidCompetitorController
|
|
type BackendCrmBiddingBidCompetitorController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
type bidCompetitorPayload struct {
|
|
BidID uint64 `json:"bid_id"`
|
|
CompetitorName string `json:"competitor_name"`
|
|
CompetitorType int8 `json:"competitor_type"`
|
|
QuoteAmount float64 `json:"quote_amount"`
|
|
Advantages string `json:"advantages"`
|
|
Weaknesses string `json:"weaknesses"`
|
|
Source string `json:"source"`
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
// List
|
|
func (c *BackendCrmBiddingBidCompetitorController) List() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
bidID, _ := c.GetInt64("bid_id")
|
|
if bidID == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "bid_id 必填")
|
|
return
|
|
}
|
|
var list []models.TenantCrmBiddingBidCompetitor
|
|
_, _ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidCompetitor)).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Filter("bid_id", bidID).
|
|
Filter("delete_time__isnull", true).
|
|
OrderBy("-id").All(&list)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"list": list})
|
|
}
|
|
|
|
// Create
|
|
func (c *BackendCrmBiddingBidCompetitorController) Create() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
|
var p bidCompetitorPayload
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
pipelineErr(&c.Controller, 400, 400, "参数错误")
|
|
return
|
|
}
|
|
if p.BidID == 0 || strings.TrimSpace(p.CompetitorName) == "" {
|
|
pipelineErr(&c.Controller, 400, 400, "竞争对手信息不完整")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
row := models.TenantCrmBiddingBidCompetitor{
|
|
TenantID: pipelineTenantID(claims),
|
|
BidID: p.BidID,
|
|
CompetitorName: strings.TrimSpace(p.CompetitorName),
|
|
CompetitorType: firstNonEmptyInt8(p.CompetitorType, 1),
|
|
QuoteAmount: p.QuoteAmount,
|
|
Advantages: p.Advantages,
|
|
Weaknesses: p.Weaknesses,
|
|
Source: strings.TrimSpace(p.Source),
|
|
Remark: p.Remark,
|
|
CreateUserID: pipelineUID(claims),
|
|
CreateUserName: resolveUserName(claims),
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}
|
|
id, err := models.Orm.Insert(&row)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "创建失败: "+err.Error())
|
|
return
|
|
}
|
|
crmWriteLog(pipelineTenantID(claims), 5, p.BidID, "create", "新增竞争对手", claims)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"id": id})
|
|
}
|
|
|
|
// Delete
|
|
func (c *BackendCrmBiddingBidCompetitorController) Delete() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
|
if id == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "无效的ID")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
_, err = models.Orm.QueryTable(new(models.TenantCrmBiddingBidCompetitor)).
|
|
Filter("id", id).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Update(map[string]interface{}{"delete_time": now, "update_time": now})
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "删除失败: "+err.Error())
|
|
return
|
|
}
|
|
var delRow models.TenantCrmBiddingBidCompetitor
|
|
_ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidCompetitor)).Filter("id", id).One(&delRow)
|
|
crmWriteLog(pipelineTenantID(claims), 5, delRow.BidID, "delete", "删除竞争对手", claims)
|
|
pipelineOk(&c.Controller, nil)
|
|
}
|
|
|
|
// ------------------------------ 投标费用 ------------------------------
|
|
|
|
// BackendCrmBiddingBidExpenseController
|
|
type BackendCrmBiddingBidExpenseController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
type bidExpensePayload struct {
|
|
BidID uint64 `json:"bid_id"`
|
|
ExpenseType int8 `json:"expense_type"`
|
|
ExpenseName string `json:"expense_name"`
|
|
Amount float64 `json:"amount"`
|
|
Currency string `json:"currency"`
|
|
PaymentStatus int8 `json:"payment_status"`
|
|
PaymentDate string `json:"payment_date"`
|
|
Description string `json:"description"`
|
|
VoucherURL string `json:"voucher_url"`
|
|
}
|
|
|
|
// List
|
|
func (c *BackendCrmBiddingBidExpenseController) List() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
bidID, _ := c.GetInt64("bid_id")
|
|
if bidID == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "bid_id 必填")
|
|
return
|
|
}
|
|
var list []models.TenantCrmBiddingBidExpense
|
|
_, _ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidExpense)).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Filter("bid_id", bidID).
|
|
Filter("delete_time__isnull", true).
|
|
OrderBy("-id").All(&list)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"list": list})
|
|
}
|
|
|
|
// Create
|
|
func (c *BackendCrmBiddingBidExpenseController) Create() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
|
var p bidExpensePayload
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
pipelineErr(&c.Controller, 400, 400, "参数错误")
|
|
return
|
|
}
|
|
if p.BidID == 0 || strings.TrimSpace(p.ExpenseName) == "" {
|
|
pipelineErr(&c.Controller, 400, 400, "费用信息不完整")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
row := models.TenantCrmBiddingBidExpense{
|
|
TenantID: pipelineTenantID(claims),
|
|
BidID: p.BidID,
|
|
ExpenseType: firstNonEmptyInt8(p.ExpenseType, 1),
|
|
ExpenseName: strings.TrimSpace(p.ExpenseName),
|
|
Amount: p.Amount,
|
|
Currency: firstNonEmpty(p.Currency, "CNY"),
|
|
PaymentStatus: p.PaymentStatus,
|
|
PaymentDate: parsePipelineDateTime(p.PaymentDate),
|
|
Description: p.Description,
|
|
VoucherURL: strings.TrimSpace(p.VoucherURL),
|
|
CreateUserID: pipelineUID(claims),
|
|
CreateUserName: resolveUserName(claims),
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}
|
|
id, err := models.Orm.Insert(&row)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "创建失败: "+err.Error())
|
|
return
|
|
}
|
|
crmWriteLog(pipelineTenantID(claims), 5, p.BidID, "create", "登记投标费用", claims)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"id": id})
|
|
}
|
|
|
|
// Delete
|
|
func (c *BackendCrmBiddingBidExpenseController) Delete() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
|
if id == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "无效的ID")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
_, err = models.Orm.QueryTable(new(models.TenantCrmBiddingBidExpense)).
|
|
Filter("id", id).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Update(map[string]interface{}{"delete_time": now, "update_time": now})
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "删除失败: "+err.Error())
|
|
return
|
|
}
|
|
var delRow models.TenantCrmBiddingBidExpense
|
|
_ = models.Orm.QueryTable(new(models.TenantCrmBiddingBidExpense)).Filter("id", id).One(&delRow)
|
|
crmWriteLog(pipelineTenantID(claims), 5, delRow.BidID, "delete", "删除投标费用", claims)
|
|
pipelineOk(&c.Controller, nil)
|
|
}
|
|
|
|
// ------------------------------ 招标文件 ------------------------------
|
|
|
|
// BackendCrmBiddingTenderFileController 招标文件
|
|
type BackendCrmBiddingTenderFileController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
type tenderFilePayload struct {
|
|
TenderID uint64 `json:"tender_id"`
|
|
FileType string `json:"file_type"`
|
|
FileName string `json:"file_name"`
|
|
FileURL string `json:"file_url"`
|
|
FileSize uint64 `json:"file_size"`
|
|
FileExt string `json:"file_ext"`
|
|
UploadUserID string `json:"upload_user_id"`
|
|
UploadUserName string `json:"upload_user_name"`
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
// List
|
|
func (c *BackendCrmBiddingTenderFileController) List() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
tenderID, _ := c.GetInt64("tender_id")
|
|
if tenderID == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "tender_id 必填")
|
|
return
|
|
}
|
|
var list []models.TenantCrmBiddingTenderFile
|
|
_, _ = models.Orm.QueryTable(new(models.TenantCrmBiddingTenderFile)).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Filter("tender_id", tenderID).
|
|
Filter("delete_time__isnull", true).
|
|
OrderBy("-id").All(&list)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"list": list})
|
|
}
|
|
|
|
// Create
|
|
func (c *BackendCrmBiddingTenderFileController) Create() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
|
var p tenderFilePayload
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
pipelineErr(&c.Controller, 400, 400, "参数错误")
|
|
return
|
|
}
|
|
if p.TenderID == 0 || strings.TrimSpace(p.FileName) == "" || strings.TrimSpace(p.FileURL) == "" {
|
|
pipelineErr(&c.Controller, 400, 400, "文件信息不完整")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
row := models.TenantCrmBiddingTenderFile{
|
|
TenantID: pipelineTenantID(claims),
|
|
TenderID: p.TenderID,
|
|
FileType: firstNonEmpty(p.FileType, "1"),
|
|
FileName: strings.TrimSpace(p.FileName),
|
|
FileURL: strings.TrimSpace(p.FileURL),
|
|
FileSize: p.FileSize,
|
|
FileExt: strings.TrimSpace(p.FileExt),
|
|
UploadUserID: firstNonEmpty(p.UploadUserID, pipelineUID(claims)),
|
|
UploadUserName: firstNonEmpty(p.UploadUserName, resolveUserName(claims)),
|
|
Remark: p.Remark,
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}
|
|
id, err := models.Orm.Insert(&row)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "上传失败: "+err.Error())
|
|
return
|
|
}
|
|
crmWriteLog(pipelineTenantID(claims), 5, p.TenderID, "create", "上传招标文件", claims)
|
|
pipelineOk(&c.Controller, map[string]interface{}{"id": id})
|
|
}
|
|
|
|
// Delete
|
|
func (c *BackendCrmBiddingTenderFileController) Delete() {
|
|
claims, err := pipelineClaims(&c.Controller)
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 401, 401, err.Error())
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
|
if id == 0 {
|
|
pipelineErr(&c.Controller, 400, 400, "无效的ID")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
_, err = models.Orm.QueryTable(new(models.TenantCrmBiddingTenderFile)).
|
|
Filter("id", id).
|
|
Filter("tenant_id", pipelineTenantID(claims)).
|
|
Update(map[string]interface{}{"delete_time": now, "update_time": now})
|
|
if err != nil {
|
|
pipelineErr(&c.Controller, 500, 500, "删除失败: "+err.Error())
|
|
return
|
|
}
|
|
var delRow models.TenantCrmBiddingTenderFile
|
|
_ = models.Orm.QueryTable(new(models.TenantCrmBiddingTenderFile)).Filter("id", id).One(&delRow)
|
|
crmWriteLog(pipelineTenantID(claims), 5, delRow.TenderID, "delete", "删除招标文件", claims)
|
|
pipelineOk(&c.Controller, nil)
|
|
}
|
|
|
|
// =====================================================================
|
|
// 工具函数
|
|
// =====================================================================
|
|
|
|
// firstNonEmptyInt8 返回第一个非零的 int8
|
|
func firstNonEmptyInt8(v, def int8) int8 {
|
|
if v == 0 {
|
|
return def
|
|
}
|
|
return v
|
|
} |