You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
6.1 KiB
TypeScript
197 lines
6.1 KiB
TypeScript
import request from '@/config/axios'
|
|
|
|
export interface RecipeConfigVO {
|
|
id: number
|
|
recipeCode: string
|
|
recipeName?: string
|
|
name?: string
|
|
recipeType?: string | number
|
|
recipeTypeId?: string | number
|
|
productId?: number
|
|
productName?: string
|
|
machineName?: string
|
|
machineId?: number
|
|
deviceId?: number
|
|
deviceName?: string
|
|
recipeDesc?: string
|
|
remark?: string
|
|
isEnable?: string | number
|
|
dataUnit?: string
|
|
createTime?: string
|
|
}
|
|
|
|
export interface RecipePointDetailVO {
|
|
id: number
|
|
recipeId: string | number
|
|
attributeId?: number
|
|
pointName?: string
|
|
pointType?: string
|
|
dataType?: string
|
|
dataUnit?: string
|
|
attributeName?: string
|
|
attributeType?: string
|
|
}
|
|
|
|
export interface RecipePointCandidateVO {
|
|
id: number
|
|
pointName: string
|
|
pointType: string
|
|
dataType: string
|
|
dataUnit: string
|
|
}
|
|
|
|
type PageResult<T> = { list: T[]; total: number }
|
|
|
|
const STORAGE_KEYS = {
|
|
pointCandidates: 'mock:recipeConfig:pointCandidates',
|
|
recipePointRelation: 'mock:recipeConfig:recipePointRelation'
|
|
} as const
|
|
|
|
const safeParseJson = <T>(value: string | null): T | undefined => {
|
|
if (!value) return undefined
|
|
try {
|
|
return JSON.parse(value) as T
|
|
} catch {
|
|
return undefined
|
|
}
|
|
}
|
|
|
|
const loadFromStorage = <T>(key: string, fallback: T): T => {
|
|
const parsed = safeParseJson<T>(window.localStorage.getItem(key))
|
|
return parsed ?? fallback
|
|
}
|
|
|
|
const saveToStorage = (key: string, value: any) => {
|
|
window.localStorage.setItem(key, JSON.stringify(value))
|
|
}
|
|
|
|
const buildMockPointCandidates = (): RecipePointCandidateVO[] => {
|
|
const pointTypes = ['模拟量', '开关量', '计算量']
|
|
const dataTypes = ['int', 'float', 'string', 'bool']
|
|
const units = ['kg', 'm³', '℃', 'A', 'V', '']
|
|
return Array.from({ length: 60 }).map((_, idx) => {
|
|
const no = String(idx + 1).padStart(3, '0')
|
|
return {
|
|
id: idx + 1,
|
|
pointName: `点位-${no}`,
|
|
pointType: pointTypes[idx % pointTypes.length],
|
|
dataType: dataTypes[idx % dataTypes.length],
|
|
dataUnit: units[idx % units.length]
|
|
}
|
|
})
|
|
}
|
|
|
|
const ensureMockSeeded = () => {
|
|
const pointCandidates = loadFromStorage<RecipePointCandidateVO[]>(STORAGE_KEYS.pointCandidates, [])
|
|
if (!pointCandidates.length) saveToStorage(STORAGE_KEYS.pointCandidates, buildMockPointCandidates())
|
|
|
|
const relation = loadFromStorage<Record<string, number[]>>(STORAGE_KEYS.recipePointRelation, {})
|
|
if (!Object.keys(relation).length) saveToStorage(STORAGE_KEYS.recipePointRelation, {})
|
|
}
|
|
|
|
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
|
|
const paginate = <T>(items: T[], pageNo: number, pageSize: number): PageResult<T> => {
|
|
const safePageNo = Math.max(1, Number(pageNo) || 1)
|
|
const safePageSize = Math.max(1, Number(pageSize) || 10)
|
|
const start = (safePageNo - 1) * safePageSize
|
|
return {
|
|
total: items.length,
|
|
list: items.slice(start, start + safePageSize)
|
|
}
|
|
}
|
|
|
|
const contains = (value: string | undefined, keyword: string | undefined) => {
|
|
const v = (value ?? '').toLowerCase()
|
|
const k = (keyword ?? '').trim().toLowerCase()
|
|
if (!k) return true
|
|
return v.includes(k)
|
|
}
|
|
|
|
export const RecipeConfigApi = {
|
|
getRecipeConfigPage: async (params: any) => {
|
|
const finalParams = {
|
|
...(params ?? {}),
|
|
name: params?.name ?? params?.recipeName
|
|
}
|
|
return await request.get({ url: `/iot/recipe/page`, params: finalParams })
|
|
},
|
|
|
|
createRecipeConfig: async (data: Partial<RecipeConfigVO>) => {
|
|
const finalData = {
|
|
id: data.id,
|
|
name: data.name ?? data.recipeName,
|
|
recipeCode: data.recipeCode,
|
|
recipeTypeId: (data as any).recipeTypeId ?? data.recipeType,
|
|
productId: data.productId,
|
|
machineId: (data as any).machineId ?? data.deviceId,
|
|
recipeDesc: data.recipeDesc ?? data.remark,
|
|
isEnable: data.isEnable,
|
|
dataUnit: data.dataUnit
|
|
}
|
|
return await request.post({ url: `/iot/recipe/create`, data: finalData })
|
|
},
|
|
|
|
updateRecipeConfig: async (data: Partial<RecipeConfigVO>) => {
|
|
const finalData = {
|
|
id: data.id,
|
|
name: data.name ?? data.recipeName,
|
|
recipeCode: data.recipeCode,
|
|
recipeTypeId: (data as any).recipeTypeId ?? data.recipeType,
|
|
productId: data.productId,
|
|
machineId: (data as any).machineId ?? data.deviceId,
|
|
recipeDesc: data.recipeDesc ?? data.remark,
|
|
isEnable: data.isEnable,
|
|
dataUnit: data.dataUnit
|
|
}
|
|
return await request.put({ url: `/iot/recipe/update`, data: finalData })
|
|
},
|
|
|
|
deleteRecipeConfig: async (id: number) => {
|
|
return await request.delete({ url: `/iot/recipe/delete?id=` + id })
|
|
},
|
|
|
|
exportRecipeConfig: async (params: any) => {
|
|
const finalParams = {
|
|
...(params ?? {}),
|
|
name: params?.name ?? params?.recipeName
|
|
}
|
|
return await request.download({ url: `/iot/recipe/export-excel`, params: finalParams })
|
|
},
|
|
|
|
getPointCandidatePage: async (params: any): Promise<PageResult<RecipePointCandidateVO>> => {
|
|
ensureMockSeeded()
|
|
await sleep(80)
|
|
const keyword = params?.keyword
|
|
const pageNo = params?.pageNo
|
|
const pageSize = params?.pageSize
|
|
const list = loadFromStorage<RecipePointCandidateVO[]>(
|
|
STORAGE_KEYS.pointCandidates,
|
|
buildMockPointCandidates()
|
|
)
|
|
const filtered = keyword
|
|
? list.filter((item) => contains(item.pointName, keyword))
|
|
: list
|
|
return paginate(filtered, pageNo, pageSize)
|
|
},
|
|
|
|
getRecipePointDetailPage: async (params: any) => {
|
|
return await request.get({ url: `/iot/recipe-device-attribute/page`, params })
|
|
},
|
|
|
|
updateRecipeDeviceAttribute: async (data: { recipeId: string | number; ids: number[] }) => {
|
|
return await request.put({ url: `/iot/recipe-device-attribute/update`, data })
|
|
},
|
|
|
|
saveRecipePointConfig: async (data: { recipeId: string | number; attributeIds: number[] }) => {
|
|
ensureMockSeeded()
|
|
await sleep(120)
|
|
const relation = loadFromStorage<Record<string, number[]>>(STORAGE_KEYS.recipePointRelation, {})
|
|
relation[String(data.recipeId)] = Array.from(new Set(data.attributeIds ?? [])).filter((v) => {
|
|
return typeof v === 'number' && !Number.isNaN(v)
|
|
})
|
|
saveToStorage(STORAGE_KEYS.recipePointRelation, relation)
|
|
return true
|
|
}
|
|
}
|