feat: 新增数据库迁移,重命名 device_no 为 virtual_no,新增 iot_card.virtual_no 和 package.virtual_ratio 字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m3s

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-03-14 18:27:28 +08:00
parent b5147d1acb
commit b9c3875c08
77 changed files with 5832 additions and 2393 deletions

View File

@@ -59,14 +59,14 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
// 查询所有设备
var devices []model.Device
if err := s.db.WithContext(ctx).Where("device_no IN ?", req.DeviceNos).Find(&devices).Error; err != nil {
if err := s.db.WithContext(ctx).Where("virtual_no IN ?", req.DeviceNos).Find(&devices).Error; err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备信息失败")
}
deviceMap := make(map[string]*model.Device)
deviceIDs := make([]uint, 0, len(devices))
for i := range devices {
deviceMap[devices[i].DeviceNo] = &devices[i]
deviceMap[devices[i].VirtualNo] = &devices[i]
deviceIDs = append(deviceIDs, devices[i].ID)
}
@@ -90,8 +90,8 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
device, exists := deviceMap[deviceNo]
if !exists {
resp.FailedItems = append(resp.FailedItems, dto.FailedDeviceItem{
DeviceNo: deviceNo,
Reason: "设备不存在",
VirtualNo: deviceNo,
Reason: "设备不存在",
})
continue
}
@@ -99,8 +99,8 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
// 验证设备状态(必须是"已分销"状态)
if device.Status != 2 {
resp.FailedItems = append(resp.FailedItems, dto.FailedDeviceItem{
DeviceNo: deviceNo,
Reason: "设备状态不正确,必须是已分销状态",
VirtualNo: deviceNo,
Reason: "设备状态不正确,必须是已分销状态",
})
continue
}
@@ -109,8 +109,8 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
if userType == constants.UserTypeAgent {
if device.ShopID == nil || *device.ShopID != currentShopID {
resp.FailedItems = append(resp.FailedItems, dto.FailedDeviceItem{
DeviceNo: deviceNo,
Reason: "无权操作此设备",
VirtualNo: deviceNo,
Reason: "无权操作此设备",
})
continue
}
@@ -119,8 +119,8 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
// 检查是否已授权
if existingAuths[device.ID] {
resp.FailedItems = append(resp.FailedItems, dto.FailedDeviceItem{
DeviceNo: deviceNo,
Reason: "设备已授权给此企业",
VirtualNo: deviceNo,
Reason: "设备已授权给此企业",
})
continue
}
@@ -199,7 +199,7 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
for _, device := range devicesToAllocate {
resp.AuthorizedDevices = append(resp.AuthorizedDevices, dto.AuthorizedDeviceItem{
DeviceID: device.ID,
DeviceNo: device.DeviceNo,
VirtualNo: device.VirtualNo,
CardCount: deviceCardCount[device.ID],
})
}
@@ -232,14 +232,14 @@ func (s *Service) RecallDevices(ctx context.Context, enterpriseID uint, req *dto
// 查询设备
var devices []model.Device
if err := s.db.WithContext(ctx).Where("device_no IN ?", req.DeviceNos).Find(&devices).Error; err != nil {
if err := s.db.WithContext(ctx).Where("virtual_no IN ?", req.DeviceNos).Find(&devices).Error; err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备信息失败")
}
deviceMap := make(map[string]*model.Device)
deviceIDs := make([]uint, 0, len(devices))
for i := range devices {
deviceMap[devices[i].DeviceNo] = &devices[i]
deviceMap[devices[i].VirtualNo] = &devices[i]
deviceIDs = append(deviceIDs, devices[i].ID)
}
@@ -258,16 +258,16 @@ func (s *Service) RecallDevices(ctx context.Context, enterpriseID uint, req *dto
device, exists := deviceMap[deviceNo]
if !exists {
resp.FailedItems = append(resp.FailedItems, dto.FailedDeviceItem{
DeviceNo: deviceNo,
Reason: "设备不存在",
VirtualNo: deviceNo,
Reason: "设备不存在",
})
continue
}
if !existingAuths[device.ID] {
resp.FailedItems = append(resp.FailedItems, dto.FailedDeviceItem{
DeviceNo: deviceNo,
Reason: "设备未授权给此企业",
VirtualNo: deviceNo,
Reason: "设备未授权给此企业",
})
continue
}
@@ -276,8 +276,8 @@ func (s *Service) RecallDevices(ctx context.Context, enterpriseID uint, req *dto
auth, err := s.enterpriseDeviceAuthStore.GetByDeviceID(ctx, device.ID)
if err != nil || auth.EnterpriseID != enterpriseID {
resp.FailedItems = append(resp.FailedItems, dto.FailedDeviceItem{
DeviceNo: deviceNo,
Reason: "授权记录不存在",
VirtualNo: deviceNo,
Reason: "授权记录不存在",
})
continue
}
@@ -352,8 +352,8 @@ func (s *Service) ListDevices(ctx context.Context, enterpriseID uint, req *dto.E
// 查询设备信息
var devices []model.Device
query := s.db.WithContext(ctx).Where("id IN ?", deviceIDs)
if req.DeviceNo != "" {
query = query.Where("device_no LIKE ?", "%"+req.DeviceNo+"%")
if req.VirtualNo != "" {
query = query.Where("virtual_no LIKE ?", "%"+req.VirtualNo+"%")
}
if err := query.Find(&devices).Error; err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备信息失败")
@@ -378,7 +378,7 @@ func (s *Service) ListDevices(ctx context.Context, enterpriseID uint, req *dto.E
auth := authMap[device.ID]
items = append(items, dto.EnterpriseDeviceItem{
DeviceID: device.ID,
DeviceNo: device.DeviceNo,
VirtualNo: device.VirtualNo,
DeviceName: device.DeviceName,
DeviceModel: device.DeviceModel,
CardCount: cardCountMap[device.ID],
@@ -427,8 +427,8 @@ func (s *Service) ListDevicesForEnterprise(ctx context.Context, req *dto.Enterpr
var devices []model.Device
query := s.db.WithContext(ctx).Where("id IN ?", deviceIDs)
if req.DeviceNo != "" {
query = query.Where("device_no LIKE ?", "%"+req.DeviceNo+"%")
if req.VirtualNo != "" {
query = query.Where("virtual_no LIKE ?", "%"+req.VirtualNo+"%")
}
if err := query.Find(&devices).Error; err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备信息失败")
@@ -451,7 +451,7 @@ func (s *Service) ListDevicesForEnterprise(ctx context.Context, req *dto.Enterpr
auth := authMap[device.ID]
items = append(items, dto.EnterpriseDeviceItem{
DeviceID: device.ID,
DeviceNo: device.DeviceNo,
VirtualNo: device.VirtualNo,
DeviceName: device.DeviceName,
DeviceModel: device.DeviceModel,
CardCount: cardCountMap[device.ID],
@@ -531,7 +531,7 @@ func (s *Service) GetDeviceDetail(ctx context.Context, deviceID uint) (*dto.Ente
return &dto.EnterpriseDeviceDetailResp{
Device: dto.EnterpriseDeviceInfo{
DeviceID: device.ID,
DeviceNo: device.DeviceNo,
VirtualNo: device.VirtualNo,
DeviceName: device.DeviceName,
DeviceModel: device.DeviceModel,
DeviceType: device.DeviceType,