You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
5.5 KiB
163 lines
5.5 KiB
package console
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"yunyan/pb"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// ============================ 芯片厂商域 (chip_vendor) ============================
|
|
//
|
|
// 芯片厂商原本是 db.proto 的 SolutionVendor 枚举,加一家要改三处代码再发版;现在是一张表,
|
|
// 后台可增删改。**本表 id 就是 CID**(手工指定的十六进制编码),方案商 vendor 列存的就是它。
|
|
// CID 唯一性由主键保证;改 CID 走 renameChipVendorId,会级联更新方案商的 vendor 引用。
|
|
|
|
// sortChipVendors 统一排序:sort 小的在前,相同再按 id。列表与下拉共用同一口径。
|
|
func sortChipVendors(list []*ChipVendor) {
|
|
sort.SliceStable(list, func(i, j int) bool {
|
|
if list[i].Sort != list[j].Sort {
|
|
return list[i].Sort < list[j].Sort
|
|
}
|
|
return list[i].Id < list[j].Id
|
|
})
|
|
}
|
|
|
|
func (this *serverComp) getChipVendors(c *gin.Context, sys *appConn) {
|
|
models, err := dvChipVendors(sys)
|
|
if err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, err.Error())
|
|
return
|
|
}
|
|
sortChipVendors(models)
|
|
writeOK(c, gin.H{"vendors": models})
|
|
}
|
|
|
|
func (this *serverComp) addChipVendor(c *gin.Context, sys *appConn) {
|
|
var req struct {
|
|
Vendor *ChipVendor `json:"vendor"`
|
|
}
|
|
_ = c.ShouldBindJSON(&req)
|
|
if req.Vendor == nil || strings.TrimSpace(req.Vendor.Name) == "" {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "芯片厂商名称必填")
|
|
return
|
|
}
|
|
req.Vendor.Name = strings.TrimSpace(req.Vendor.Name)
|
|
if msg := checkChipVendorNameUnique(sys, req.Vendor.Name, 0); msg != "" {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, msg)
|
|
return
|
|
}
|
|
// CID 就是主键,必须手填且不能与已有厂商重复(重复了设备在端侧分不开)。
|
|
if req.Vendor.Id == 0 {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "CID 必填(手工指定的十六进制编码,如 ABF4)")
|
|
return
|
|
}
|
|
if exist, _ := dvChipVendor(sys, req.Vendor.Id); exist != nil && exist.Id != 0 {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError,
|
|
fmt.Sprintf("CID 0x%X 已被芯片厂商「%s」占用", req.Vendor.Id, exist.Name))
|
|
return
|
|
}
|
|
now := time.Now().Unix()
|
|
req.Vendor.Createtime, req.Vendor.Updatetime = now, now
|
|
if err := dvAddChipVendor(sys, req.Vendor); err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, err.Error())
|
|
return
|
|
}
|
|
writeOK(c, gin.H{"vendor": req.Vendor})
|
|
}
|
|
|
|
func (this *serverComp) updateChipVendor(c *gin.Context, sys *appConn) {
|
|
// 多带一个 oldid:改 CID 时要同时知道新旧两个号(旧号定位记录,新号是目标)。
|
|
var req struct {
|
|
Vendor *ChipVendor `json:"vendor"`
|
|
Oldid uint32 `json:"oldid"` // 原 CID;0 或与 vendor.id 相同 = 不改号
|
|
}
|
|
_ = c.ShouldBindJSON(&req)
|
|
if req.Vendor == nil || req.Vendor.Id == 0 {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "CID 必填")
|
|
return
|
|
}
|
|
if strings.TrimSpace(req.Vendor.Name) == "" {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "芯片厂商名称必填")
|
|
return
|
|
}
|
|
req.Vendor.Name = strings.TrimSpace(req.Vendor.Name)
|
|
locateId := req.Oldid
|
|
if locateId == 0 {
|
|
locateId = req.Vendor.Id
|
|
}
|
|
old, err := dvChipVendor(sys, locateId)
|
|
if err != nil || old == nil || old.Id == 0 {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "芯片厂商不存在")
|
|
return
|
|
}
|
|
if msg := checkChipVendorNameUnique(sys, req.Vendor.Name, locateId); msg != "" {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, msg)
|
|
return
|
|
}
|
|
// 改 CID:校验新号未被占用后改主键,并级联把方案商的 vendor 引用一起搬过去。
|
|
if req.Vendor.Id != locateId {
|
|
if msg := checkChipVendorIdChange(sys, locateId, req.Vendor.Id); msg != "" {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, msg)
|
|
return
|
|
}
|
|
if err = renameChipVendorId(locateId, req.Vendor.Id); err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, "改 CID 失败: "+err.Error())
|
|
return
|
|
}
|
|
}
|
|
req.Vendor.Createtime = old.Createtime // 建档时间不可改
|
|
req.Vendor.Updatetime = time.Now().Unix()
|
|
if err := dvSaveChipVendor(sys, req.Vendor); err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, err.Error())
|
|
return
|
|
}
|
|
writeOK(c, gin.H{"vendor": req.Vendor})
|
|
}
|
|
|
|
func (this *serverComp) delChipVendor(c *gin.Context, sys *appConn) {
|
|
var req struct {
|
|
Id uint32 `json:"id"`
|
|
}
|
|
_ = c.ShouldBindJSON(&req)
|
|
if req.Id == 0 {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "id is required")
|
|
return
|
|
}
|
|
// 有方案商挂在它下面就不许删:vendor 是裸整数列、没有外键,删掉后那些方案商的芯片分组
|
|
// 会变成查不到名字的孤儿数值(列表显示「厂商#N」),且无法从界面上修回来。
|
|
n, err := dvCountProvidersByVendor(sys, req.Id)
|
|
if err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, err.Error())
|
|
return
|
|
}
|
|
if n > 0 {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError,
|
|
fmt.Sprintf("该芯片厂商下还有 %d 个方案商,请先把它们改到别的厂商下再删(也可以改成「停用」,停用后不再出现在新建方案商的下拉里)", n))
|
|
return
|
|
}
|
|
if err := dvDelChipVendor(sys, req.Id); err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, err.Error())
|
|
return
|
|
}
|
|
writeOK(c, gin.H{"id": req.Id})
|
|
}
|
|
|
|
// checkChipVendorNameUnique 同名校验(排除自己)。返回空串表示通过。
|
|
// 芯片厂商名字是运营在下拉里认人的唯一依据,重名会让「杰里」出现两条无法区分。
|
|
func checkChipVendorNameUnique(sys *appConn, name string, selfId uint32) string {
|
|
list, err := dvChipVendors(sys)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
for _, v := range list {
|
|
if v.Id != selfId && strings.EqualFold(strings.TrimSpace(v.Name), name) {
|
|
return fmt.Sprintf("芯片厂商「%s」已存在", name)
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|