品类管理: 新建 product_category 品类字典表(V25, 灌入 8 个预设品类并回填存量 product.category), 后端提供 ProductCategory 增删改查/启停/字典接口, 后台新增「品类管理」页面(设备管理组, 与产品管理同级), 产品管理的品类下拉改为读字典(失败回退内置枚举)。 孤儿设备根治: TuyaController.bindDevices 收口三道校验 —— 绑定门禁(本平台未绑定涂鸦账号直接拒绝)、归属白名单(上报设备须在该用户涂鸦账号真实清单内, 拉取失败降级放行)、owner 校验(他人名下设备不改写; 恢复已删设备时归属改到当前用户)。 兜底自愈: 新增 OrphanTuyaDeviceCleanupTask, 每天 04:30 回收无绑定记录用户的涂鸦设备与 AI 档案(逻辑删除, 可恢复)。 Android: 查看设备时的补同步先确认后端绑定状态, 未绑定不再写库; 同步被拒时记录原因而非静默失败。单测 TuyaControllerBindTest 5 用例覆盖门禁/白名单/owner/恢复归属。
126 lines
3.4 KiB
TypeScript
126 lines
3.4 KiB
TypeScript
import { defineConfig } from 'vite'
|
||
import vue from '@vitejs/plugin-vue'
|
||
import { resolve } from 'path'
|
||
import AutoImport from 'unplugin-auto-import/vite'
|
||
import Components from 'unplugin-vue-components/vite'
|
||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||
import ElementPlus from 'unplugin-element-plus/vite'
|
||
|
||
// https://vitejs.dev/config/
|
||
export default defineConfig({
|
||
plugins: [
|
||
vue(),
|
||
AutoImport({
|
||
resolvers: [ElementPlusResolver()],
|
||
imports: ['vue', 'vue-router', 'pinia'],
|
||
dts: 'src/auto-imports.d.ts'
|
||
}),
|
||
Components({
|
||
resolvers: [ElementPlusResolver()],
|
||
dts: 'src/components.d.ts'
|
||
}),
|
||
ElementPlus({})
|
||
],
|
||
resolve: {
|
||
alias: {
|
||
'@': resolve(__dirname, 'src')
|
||
}
|
||
},
|
||
optimizeDeps: {
|
||
// 依赖预优化缓存放到项目外(f:/work/iotsaas/.vite-cache),
|
||
// 避免 Vite 清理 node_modules/.vite 触发 CodeBuddy 文件删除防护导致 dev server 崩溃
|
||
cacheDir: resolve(__dirname, '../../.vite-cache')
|
||
},
|
||
server: {
|
||
port: 3000,
|
||
host: true,
|
||
proxy: {
|
||
// 设备服务 + 认证 + 系统管理 + 操作日志 (9081)
|
||
'/api/v1/devices': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/auth': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/device-groups': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/users': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/members': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/roles': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/logs': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/admin/platforms': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/admin/apps': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
// 产品管理 / 物模型 / 固件 OTA / 品类管理 (9081)
|
||
'/api/v1/products': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/product-categories': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/ota-tasks': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/firmwares': {
|
||
target: 'http://localhost:9081',
|
||
changeOrigin: true
|
||
},
|
||
// 数据服务 (9082)
|
||
'/api/v1/data': {
|
||
target: 'http://localhost:9082',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/device-data': {
|
||
target: 'http://localhost:9082',
|
||
changeOrigin: true
|
||
},
|
||
// 规则服务 (9083)
|
||
'/api/v1/rules': {
|
||
target: 'http://localhost:9083',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/linkage-rules': {
|
||
target: 'http://localhost:9083',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/scenes': {
|
||
target: 'http://localhost:9083',
|
||
changeOrigin: true
|
||
},
|
||
// 告警服务 (9084)
|
||
'/api/v1/alarms': {
|
||
target: 'http://localhost:9084',
|
||
changeOrigin: true
|
||
},
|
||
'/api/v1/alarm-rules': {
|
||
target: 'http://localhost:9084',
|
||
changeOrigin: true
|
||
}
|
||
}
|
||
}
|
||
})
|