mock-device-types.ts 5.01 KB
import type { DeviceType, DeviceTypePayload } from '../../app/types/device-type'

interface MutationResult {
  success: boolean
  errorCode: string | null
  message: string
}

function now() {
  return new Date().toISOString()
}

let nextId = 1005

const mockDeviceTypes: DeviceType[] = [{
  id: 1001,
  name: '协作机械臂控制柜',
  model: 'RPS-CB-500',
  category: 'controller',
  lengthMm: 680,
  widthMm: 520,
  heightMm: 1480,
  weightKg: 92,
  hasBattery: true,
  batterySpec: '24V 15Ah 锂电',
  description: '用于协作机械臂整机控制与供电管理。',
  updatedAt: now()
}, {
  id: 1002,
  name: '末端视觉模组',
  model: 'RPS-VM-220',
  category: 'vision',
  lengthMm: 210,
  widthMm: 135,
  heightMm: 118,
  weightKg: 2.8,
  hasBattery: false,
  batterySpec: undefined,
  description: '安装于末端执行器位置,用于识别与定位。',
  updatedAt: now()
}, {
  id: 1003,
  name: '底盘驱动单元',
  model: 'RPS-CH-920',
  category: 'chassis',
  lengthMm: 1020,
  widthMm: 740,
  heightMm: 360,
  weightKg: 118,
  hasBattery: true,
  batterySpec: '48V 40Ah 磷酸铁锂',
  description: 'AGV 底盘驱动与转向一体化单元。',
  updatedAt: now()
}, {
  id: 1004,
  name: '工业网关',
  model: 'RPS-GW-110',
  category: 'communication',
  lengthMm: 280,
  widthMm: 180,
  heightMm: 86,
  weightKg: 3.2,
  hasBattery: false,
  batterySpec: undefined,
  description: '用于产线网络与设备数据转发。',
  updatedAt: now()
}]

function normalizeText(value: string | undefined) {
  if (!value) {
    return undefined
  }

  const trimmed = value.trim()
  return trimmed.length > 0 ? trimmed : undefined
}

function cloneDeviceType(item: DeviceType): DeviceType {
  return {
    ...item
  }
}

function byUpdatedAtDesc(a: DeviceType, b: DeviceType) {
  return b.updatedAt.localeCompare(a.updatedAt)
}

function hasDuplicateNameModel(payload: DeviceTypePayload, ignoreId?: number) {
  return mockDeviceTypes.some((item) => {
    if (typeof ignoreId === 'number' && item.id === ignoreId) {
      return false
    }

    return item.name.trim().toLowerCase() === payload.name.trim().toLowerCase()
      && item.model.trim().toLowerCase() === payload.model.trim().toLowerCase()
  })
}

function withMutation<T extends Record<string, unknown>>(base: MutationResult, extra?: T) {
  return {
    ...base,
    ...(extra || {})
  }
}

export function getMockDeviceTypes() {
  return mockDeviceTypes
    .slice()
    .sort(byUpdatedAtDesc)
    .map(item => cloneDeviceType(item))
}

export function createMockDeviceType(payload: DeviceTypePayload) {
  if (hasDuplicateNameModel(payload)) {
    return withMutation({
      success: false,
      errorCode: 'DEVICE_TYPE_EXISTS',
      message: '设备名称与型号组合已存在。'
    })
  }

  const created: DeviceType = {
    id: nextId++,
    name: payload.name.trim(),
    model: payload.model.trim(),
    category: payload.category,
    lengthMm: payload.lengthMm,
    widthMm: payload.widthMm,
    heightMm: payload.heightMm,
    weightKg: payload.weightKg,
    hasBattery: payload.hasBattery,
    batterySpec: payload.hasBattery ? normalizeText(payload.batterySpec) : undefined,
    description: normalizeText(payload.description),
    updatedAt: now()
  }

  mockDeviceTypes.unshift(created)

  return withMutation({
    success: true,
    errorCode: null,
    message: '设备类型已创建。'
  }, {
    item: cloneDeviceType(created)
  })
}

export function updateMockDeviceType(id: number, payload: DeviceTypePayload) {
  const index = mockDeviceTypes.findIndex(item => item.id === id)

  if (index < 0) {
    return withMutation({
      success: false,
      errorCode: 'DEVICE_TYPE_NOT_FOUND',
      message: '设备类型不存在。'
    })
  }

  if (hasDuplicateNameModel(payload, id)) {
    return withMutation({
      success: false,
      errorCode: 'DEVICE_TYPE_EXISTS',
      message: '设备名称与型号组合已存在。'
    })
  }

  const updated: DeviceType = {
    id,
    name: payload.name.trim(),
    model: payload.model.trim(),
    category: payload.category,
    lengthMm: payload.lengthMm,
    widthMm: payload.widthMm,
    heightMm: payload.heightMm,
    weightKg: payload.weightKg,
    hasBattery: payload.hasBattery,
    batterySpec: payload.hasBattery ? normalizeText(payload.batterySpec) : undefined,
    description: normalizeText(payload.description),
    updatedAt: now()
  }

  mockDeviceTypes[index] = updated

  return withMutation({
    success: true,
    errorCode: null,
    message: '设备类型已更新。'
  }, {
    item: cloneDeviceType(updated)
  })
}

export function removeMockDeviceType(id: number) {
  const index = mockDeviceTypes.findIndex(item => item.id === id)

  if (index < 0) {
    return withMutation({
      success: false,
      errorCode: 'DEVICE_TYPE_NOT_FOUND',
      message: '设备类型不存在。'
    })
  }

  const [removed] = mockDeviceTypes.splice(index, 1)

  return withMutation({
    success: true,
    errorCode: null,
    message: '设备类型已删除。'
  }, {
    item: removed ? cloneDeviceType(removed) : undefined
  })
}