Browse Source

feat: 完善项目列表,项目详情页面的多语言

yanglzh 1 month ago
parent
commit
5c9675ab0c

+ 159 - 2
src/i18n/pages/projects/en.ts

@@ -87,8 +87,7 @@ export default {
       add: 'Add Project',
       edit: 'Edit Project'
     }
-  }
-  ,
+  },
   detail: {
     tabs: {
       overview: 'Overview',
@@ -146,6 +145,164 @@ export default {
         cancel: 'Cancel',
         unbindSuccess: 'Unbound successfully'
       }
+    },
+    info: {
+      actions: {
+        edit: 'Edit'
+      },
+      descriptions: {
+        name: 'Project Name',
+        customName: 'Key Customer',
+        address: 'Region',
+        channelMerchants: 'Channel Merchant',
+        repairCompany: 'Maintenance Company',
+        repairMobile: 'Maintenance Phone',
+        addressDetail: 'Address Detail'
+      }
+    },
+    scene: {
+      actions: {
+        add: 'Add Scene',
+        cancel: 'Cancel',
+        confirm: 'Confirm'
+      },
+      table: {
+        columns: {
+          id: 'ID',
+          name: 'Scene Name',
+          sceneType: 'Trigger Type',
+          status: 'Status',
+          description: 'Description',
+          createdAt: 'Created At',
+          actions: 'Actions'
+        },
+        actions: {
+          detail: 'Scene Details',
+          unbind: 'Unbind'
+        },
+        statusTags: {
+          enabled: 'Enabled',
+          disabled: 'Disabled'
+        },
+        sceneTypeTags: {
+          device: 'Device Trigger',
+          manual: 'Manual Trigger',
+          timer: 'Timer Trigger'
+        }
+      },
+      dialog: {
+        title: 'Add Scene'
+      },
+      form: {
+        labels: {
+          scene: 'Scene'
+        },
+        placeholders: {
+          scene: 'Select scene'
+        }
+      },
+      messages: {
+        selectSceneFirst: 'Please select a scene first',
+        addSuccess: 'Added successfully',
+        unbindConfirm: 'Are you sure to unbind this scene?',
+        tip: 'Prompt',
+        confirm: 'Confirm',
+        cancel: 'Cancel',
+        unbindSuccess: 'Unbound successfully'
+      }
+    },
+    topo: {
+      actions: {
+        add: 'Add Topology',
+        cancel: 'Cancel',
+        confirm: 'Confirm'
+      },
+      table: {
+        columns: {
+          id: 'ID',
+          name: 'Topology Name',
+          createdAt: 'Created At',
+          updatedAt: 'Updated At',
+          actions: 'Actions'
+        },
+        actions: {
+          preview: 'Preview',
+          edit: 'Edit Topology',
+          unbind: 'Unbind'
+        }
+      },
+      dialog: {
+        title: 'Add Topology'
+      },
+      form: {
+        labels: {
+          topo: 'Topology'
+        },
+        placeholders: {
+          topo: 'Select topology'
+        }
+      },
+      messages: {
+        selectTopoFirst: 'Please select a topology first',
+        addSuccess: 'Added successfully',
+        unbindConfirm: 'Are you sure to unbind this topology?',
+        tip: 'Prompt',
+        confirm: 'Confirm',
+        cancel: 'Cancel',
+        unbindSuccess: 'Unbound successfully'
+      }
+    },
+    video: {
+      actions: {
+        add: 'Add Video',
+        cancel: 'Cancel',
+        confirm: 'Confirm',
+        openInNewWindow: 'Open in new window'
+      },
+      table: {
+        columns: {
+          deviceName: 'Device Name',
+          deviceId: 'Device ID',
+          channelName: 'Channel Name',
+          model: 'Model',
+          manufacturer: 'Manufacturer',
+          liveStatus: 'Status',
+          keepAliveTime: 'Last Heartbeat',
+          registerTime: 'Register Time',
+          updateAt: 'Updated At',
+          actions: 'Actions'
+        },
+        actions: {
+          view: 'View Video',
+          unbind: 'Unbind'
+        }
+      },
+      dialog: {
+        addTitle: 'Add Video',
+        previewTitle: 'Preview Video'
+      },
+      form: {
+        labels: {
+          video: 'Video'
+        },
+        placeholders: {
+          video: 'Select video'
+        }
+      },
+      messages: {
+        selectVideoFirst: 'Please select a video first',
+        addSuccess: 'Added successfully',
+        unbindConfirm: 'Are you sure to unbind this video?',
+        tip: 'Prompt',
+        confirm: 'Confirm',
+        cancel: 'Cancel',
+        unbindSuccess: 'Unbound successfully'
+      },
+      liveStatusTags: {
+        idle: 'Idle',
+        inviting: 'Inviting',
+        streaming: 'Streaming'
+      }
     }
   },
   filter: {

+ 160 - 4
src/i18n/pages/projects/zh-cn.ts

@@ -81,15 +81,13 @@ export default {
       cancel: '取消',
       deleteSuccess: '删除成功'
     }
-  }
-  ,
+  },
   editDialog: {
     title: {
       add: '新增项目',
       edit: '编辑项目'
     }
-  }
-  ,
+  },
   detail: {
     tabs: {
       overview: '项目概况',
@@ -147,6 +145,164 @@ export default {
         cancel: '取消',
         unbindSuccess: '解绑成功'
       }
+    },
+    info: {
+      actions: {
+        edit: '编辑'
+      },
+      descriptions: {
+        name: '项目名称',
+        customName: '关键客户',
+        address: '地区',
+        channelMerchants: '渠道商',
+        repairCompany: '维修公司',
+        repairMobile: '维修电话',
+        addressDetail: '详细地址'
+      }
+    },
+    scene: {
+      actions: {
+        add: '添加场景',
+        cancel: '取消',
+        confirm: '确定'
+      },
+      table: {
+        columns: {
+          id: 'ID',
+          name: '场景名称',
+          sceneType: '触发方式',
+          status: '状态',
+          description: '场景描述',
+          createdAt: '创建时间',
+          actions: '操作'
+        },
+        actions: {
+          detail: '场景详情',
+          unbind: '解绑'
+        },
+        statusTags: {
+          enabled: '启用',
+          disabled: '禁用'
+        },
+        sceneTypeTags: {
+          device: '设备触发',
+          manual: '手动触发',
+          timer: '定时触发'
+        }
+      },
+      dialog: {
+        title: '添加场景'
+      },
+      form: {
+        labels: {
+          scene: '场景'
+        },
+        placeholders: {
+          scene: '选择场景'
+        }
+      },
+      messages: {
+        selectSceneFirst: '请先选择场景',
+        addSuccess: '添加成功',
+        unbindConfirm: '确定要解绑该场景?',
+        tip: '提示',
+        confirm: '确认',
+        cancel: '取消',
+        unbindSuccess: '解绑成功'
+      }
+    },
+    topo: {
+      actions: {
+        add: '添加组态',
+        cancel: '取消',
+        confirm: '确定'
+      },
+      table: {
+        columns: {
+          id: 'ID',
+          name: '组态图名称',
+          createdAt: '创建时间',
+          updatedAt: '更新时间',
+          actions: '操作'
+        },
+        actions: {
+          preview: '预览',
+          edit: '编辑组态图',
+          unbind: '解绑'
+        }
+      },
+      dialog: {
+        title: '添加组态'
+      },
+      form: {
+        labels: {
+          topo: '组态'
+        },
+        placeholders: {
+          topo: '选择组态'
+        }
+      },
+      messages: {
+        selectTopoFirst: '请先选择组态',
+        addSuccess: '添加成功',
+        unbindConfirm: '确定要解绑该组态?',
+        tip: '提示',
+        confirm: '确认',
+        cancel: '取消',
+        unbindSuccess: '解绑成功'
+      }
+    },
+    video: {
+      actions: {
+        add: '添加监控',
+        cancel: '取消',
+        confirm: '确定',
+        openInNewWindow: '新窗口预览'
+      },
+      table: {
+        columns: {
+          deviceName: '设备名称',
+          deviceId: '设备ID',
+          channelName: '通道名称',
+          model: '型号',
+          manufacturer: '厂商',
+          liveStatus: '状态',
+          keepAliveTime: '最后心跳时间',
+          registerTime: '注册时间',
+          updateAt: '更新时间',
+          actions: '操作'
+        },
+        actions: {
+          view: '查看监控',
+          unbind: '解绑'
+        }
+      },
+      dialog: {
+        addTitle: '添加监控',
+        previewTitle: '预览监控'
+      },
+      form: {
+        labels: {
+          video: '监控'
+        },
+        placeholders: {
+          video: '选择监控'
+        }
+      },
+      messages: {
+        selectVideoFirst: '请先选择监控',
+        addSuccess: '添加成功',
+        unbindConfirm: '确定要解绑该监控?',
+        tip: '提示',
+        confirm: '确认',
+        cancel: '取消',
+        unbindSuccess: '解绑成功'
+      },
+      liveStatusTags: {
+        idle: '空闲',
+        inviting: '调用中',
+        streaming: '拉流中'
+      }
     }
   },
   filter: {

+ 159 - 2
src/i18n/pages/projects/zh-tw.ts

@@ -87,8 +87,7 @@ export default {
       add: '新增項目',
       edit: '編輯項目'
     }
-  }
-  ,
+  },
   detail: {
     tabs: {
       overview: '項目概況',
@@ -146,6 +145,164 @@ export default {
         cancel: '取消',
         unbindSuccess: '解綁成功'
       }
+    },
+    info: {
+      actions: {
+        edit: '編輯'
+      },
+      descriptions: {
+        name: '項目名稱',
+        customName: '關鍵客戶',
+        address: '地區',
+        channelMerchants: '渠道商',
+        repairCompany: '維修公司',
+        repairMobile: '維修電話',
+        addressDetail: '詳細地址'
+      }
+    },
+    scene: {
+      actions: {
+        add: '添加場景',
+        cancel: '取消',
+        confirm: '確定'
+      },
+      table: {
+        columns: {
+          id: 'ID',
+          name: '場景名稱',
+          sceneType: '觸發方式',
+          status: '狀態',
+          description: '場景描述',
+          createdAt: '創建時間',
+          actions: '操作'
+        },
+        actions: {
+          detail: '場景詳情',
+          unbind: '解綁'
+        },
+        statusTags: {
+          enabled: '啟用',
+          disabled: '禁用'
+        },
+        sceneTypeTags: {
+          device: '設備觸發',
+          manual: '手動觸發',
+          timer: '定時觸發'
+        }
+      },
+      dialog: {
+        title: '添加場景'
+      },
+      form: {
+        labels: {
+          scene: '場景'
+        },
+        placeholders: {
+          scene: '選擇場景'
+        }
+      },
+      messages: {
+        selectSceneFirst: '請先選擇場景',
+        addSuccess: '添加成功',
+        unbindConfirm: '確定要解綁該場景?',
+        tip: '提示',
+        confirm: '確認',
+        cancel: '取消',
+        unbindSuccess: '解綁成功'
+      }
+    },
+    topo: {
+      actions: {
+        add: '添加組態',
+        cancel: '取消',
+        confirm: '確定'
+      },
+      table: {
+        columns: {
+          id: 'ID',
+          name: '組態圖名稱',
+          createdAt: '創建時間',
+          updatedAt: '更新時間',
+          actions: '操作'
+        },
+        actions: {
+          preview: '預覽',
+          edit: '編輯組態圖',
+          unbind: '解綁'
+        }
+      },
+      dialog: {
+        title: '添加組態'
+      },
+      form: {
+        labels: {
+          topo: '組態'
+        },
+        placeholders: {
+          topo: '選擇組態'
+        }
+      },
+      messages: {
+        selectTopoFirst: '請先選擇組態',
+        addSuccess: '添加成功',
+        unbindConfirm: '確定要解綁該組態?',
+        tip: '提示',
+        confirm: '確認',
+        cancel: '取消',
+        unbindSuccess: '解綁成功'
+      }
+    },
+    video: {
+      actions: {
+        add: '添加監控',
+        cancel: '取消',
+        confirm: '確定',
+        openInNewWindow: '新窗口預覽'
+      },
+      table: {
+        columns: {
+          deviceName: '設備名稱',
+          deviceId: '設備ID',
+          channelName: '通道名稱',
+          model: '型號',
+          manufacturer: '廠商',
+          liveStatus: '狀態',
+          keepAliveTime: '最後心跳時間',
+          registerTime: '註冊時間',
+          updateAt: '更新時間',
+          actions: '操作'
+        },
+        actions: {
+          view: '查看監控',
+          unbind: '解綁'
+        }
+      },
+      dialog: {
+        addTitle: '添加監控',
+        previewTitle: '預覽監控'
+      },
+      form: {
+        labels: {
+          video: '監控'
+        },
+        placeholders: {
+          video: '選擇監控'
+        }
+      },
+      messages: {
+        selectVideoFirst: '請先選擇監控',
+        addSuccess: '添加成功',
+        unbindConfirm: '確定要解綁該監控?',
+        tip: '提示',
+        confirm: '確認',
+        cancel: '取消',
+        unbindSuccess: '解綁成功'
+      },
+      liveStatusTags: {
+        idle: '空閒',
+        inviting: '調用中',
+        streaming: '拉流中'
+      }
     }
   },
   filter: {

+ 8 - 8
src/views/iot/projects/detail/device.vue

@@ -2,24 +2,24 @@
   <div class="tab-content h-full">
     <div class="subtitle"><span></span> <el-button type="primary" v-auth="'add'" size="small" @click="addDevice()">{{ $t('message.projects.detail.device.actions.add') }}</el-button></div>
     <el-table :data="tableData" style="width: 100%" v-loading="loading" max-height="calc(100vh - 280px)">
-      <el-table-column :label="$t('message.projects.detail.device.table.columns.key')" prop="key" min-width="150" show-overflow-tooltip v-col="'key'">
+      <el-table-column :label="$t('message.projects.detail.device.table.columns.key')" prop="key" min-width="150" show-overflow-tooltip>
         <template #default="{ row }">
           <copy :text="row.key"></copy>
         </template>
       </el-table-column>
-      <el-table-column :label="$t('message.projects.detail.device.table.columns.name')" prop="name" min-width="160" show-overflow-tooltip v-col="'name'" />
-      <el-table-column :label="$t('message.projects.detail.device.table.columns.deviceType')" prop="product.deviceType" min-width="100" align="center" show-overflow-tooltip v-col="'deviceType'" />
-      <el-table-column :label="$t('message.projects.detail.device.table.columns.productName')" prop="productName" min-width="120" align="center" show-overflow-tooltip v-col="'productName'" />
-      <el-table-column prop="status" :label="$t('message.projects.detail.device.table.columns.status')" min-width="80" align="center" v-col="'status'">
+      <el-table-column :label="$t('message.projects.detail.device.table.columns.name')" prop="name" min-width="160" show-overflow-tooltip />
+      <el-table-column :label="$t('message.projects.detail.device.table.columns.deviceType')" prop="product.deviceType" min-width="100" align="center" show-overflow-tooltip />
+      <el-table-column :label="$t('message.projects.detail.device.table.columns.productName')" prop="productName" min-width="120" align="center" show-overflow-tooltip />
+      <el-table-column prop="status" :label="$t('message.projects.detail.device.table.columns.status')" min-width="80" align="center">
         <template #default="scope">
           <el-tag type="info" size="small" v-if="scope.row.status == 1">{{ $t('message.projects.detail.device.table.statusTags.offline') }}</el-tag>
           <el-tag type="success" size="small" v-if="scope.row.status == 2">{{ $t('message.projects.detail.device.table.statusTags.online') }}</el-tag>
           <el-tag type="info" size="small" v-if="scope.row.status == 0">{{ $t('message.projects.detail.device.table.statusTags.inactive') }}</el-tag>
         </template>
       </el-table-column>
-      <el-table-column prop="lastOnlineTime" :label="$t('message.projects.detail.device.table.columns.lastOnlineTime')" align="center" width="160" v-col="'lastOnlineTime'"></el-table-column>
-      <el-table-column prop="desc" :label="$t('message.projects.detail.device.table.columns.desc')" show-overflow-tooltip v-col="'desc'"></el-table-column>
-      <el-table-column :label="$t('message.projects.detail.device.table.columns.actions')" width="120" align="center">
+      <el-table-column prop="lastOnlineTime" :label="$t('message.projects.detail.device.table.columns.lastOnlineTime')" align="center" width="160"></el-table-column>
+      <el-table-column prop="desc" :label="$t('message.projects.detail.device.table.columns.desc')" show-overflow-tooltip></el-table-column>
+      <el-table-column :label="$t('message.projects.detail.device.table.columns.actions')" width="170" align="center">
         <template #default="scope">
           <el-button size="small" text type="primary" v-auth="'detail'" @click="$router.push('/iotmanager/device/instance/' + scope.row.key)">{{ $t('message.projects.detail.device.table.actions.detail') }}</el-button>
           <el-button size="small" text type="warning" v-auth="'del'" @click="onDel(scope.row)">{{ $t('message.projects.detail.device.table.actions.unbind') }}</el-button>

+ 8 - 8
src/views/iot/projects/detail/info.vue

@@ -1,14 +1,14 @@
 <template>
   <div class="tab-content" v-loading="laoding">
-    <div class="subtitle"><span></span> <el-button type="primary" v-auth="'edit'" size="small" @click="edit()">编辑</el-button></div>
+    <div class="subtitle"><span></span> <el-button type="primary" v-auth="'edit'" size="small" @click="edit()">{{ $t('message.projects.detail.info.actions.edit') }}</el-button></div>
     <el-descriptions class="margin-top" :column="2" border>
-      <el-descriptions-item label="项目名称">{{ data.name }} </el-descriptions-item>
-      <el-descriptions-item label="关键客户">{{ data.customName }} </el-descriptions-item>
-      <el-descriptions-item label="地区">{{ data.address ? JSON.parse(data.address)?.name : '' }} </el-descriptions-item>
-      <el-descriptions-item label="渠道商">{{ data.channelMerchants }} </el-descriptions-item>
-      <el-descriptions-item label="维修公司">{{ data.repairCompany }} </el-descriptions-item>
-      <el-descriptions-item label="维修电话">{{ data.repairMobile }} </el-descriptions-item>
-      <el-descriptions-item label="详细地址">{{ data.addressDetail }} </el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.detail.info.descriptions.name')">{{ data.name }} </el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.detail.info.descriptions.customName')">{{ data.customName }} </el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.detail.info.descriptions.address')">{{ data.address ? JSON.parse(data.address)?.name : '' }} </el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.detail.info.descriptions.channelMerchants')">{{ data.channelMerchants }} </el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.detail.info.descriptions.repairCompany')">{{ data.repairCompany }} </el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.detail.info.descriptions.repairMobile')">{{ data.repairMobile }} </el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.detail.info.descriptions.addressDetail')">{{ data.addressDetail }} </el-descriptions-item>
     </el-descriptions>
     <EditForm ref="editFormRef" @getList="getInfo()"></EditForm>
   </div>

+ 32 - 31
src/views/iot/projects/detail/scene.vue

@@ -1,45 +1,45 @@
 <template>
   <div class="tab-content h-full">
-    <div class="subtitle"><span></span> <el-button type="primary" v-auth="'add'" size="small" @click="addDevice()">添加场景</el-button></div>
+    <div class="subtitle"><span></span> <el-button type="primary" v-auth="'add'" size="small" @click="addDevice()">{{ $t('message.projects.detail.scene.actions.add') }}</el-button></div>
     <el-table :data="tableData" style="width: 100%" v-loading="loading" max-height="calc(100vh - 280px)">
-      <el-table-column prop="id" label="ID" min-width="100" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="name" label="场景名称" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="sceneType" label="触发方式" align="center">
+      <el-table-column prop="id" :label="$t('message.projects.detail.scene.table.columns.id')" min-width="100" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="name" :label="$t('message.projects.detail.scene.table.columns.name')" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="sceneType" :label="$t('message.projects.detail.scene.table.columns.sceneType')" align="center">
         <template #default="scope">
-          <el-tag size="small" v-if="scope.row.sceneType == 'device'">设备触发</el-tag>
-          <el-tag size="small" v-if="scope.row.sceneType == 'manual'">手动触发</el-tag>
-          <el-tag size="small" v-if="scope.row.sceneType == 'timer'">定时触发</el-tag>
+          <el-tag size="small" v-if="scope.row.sceneType == 'device'">{{ $t('message.projects.detail.scene.table.sceneTypeTags.device') }}</el-tag>
+          <el-tag size="small" v-if="scope.row.sceneType == 'manual'">{{ $t('message.projects.detail.scene.table.sceneTypeTags.manual') }}</el-tag>
+          <el-tag size="small" v-if="scope.row.sceneType == 'timer'">{{ $t('message.projects.detail.scene.table.sceneTypeTags.timer') }}</el-tag>
         </template>
       </el-table-column>
 
-      <el-table-column prop="status" label="状态" align="center">
+      <el-table-column prop="status" :label="$t('message.projects.detail.scene.table.columns.status')" align="center">
         <template #default="scope">
-          <el-tag size="small" type="success" v-if="scope.row.status == 1">启用</el-tag>
-          <el-tag size="small" type="info" v-if="scope.row.status == 0">禁用</el-tag>
+          <el-tag size="small" type="success" v-if="scope.row.status == 1">{{ $t('message.projects.detail.scene.table.statusTags.enabled') }}</el-tag>
+          <el-tag size="small" type="info" v-if="scope.row.status == 0">{{ $t('message.projects.detail.scene.table.statusTags.disabled') }}</el-tag>
         </template>
       </el-table-column>
-      <el-table-column prop="description" label="场景描述" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="createdAt" label="创建时间" width="160" align="center"></el-table-column>
-      <el-table-column label="操作" width="120" align="center">
+      <el-table-column prop="description" :label="$t('message.projects.detail.scene.table.columns.description')" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="createdAt" :label="$t('message.projects.detail.scene.table.columns.createdAt')" width="160" align="center"></el-table-column>
+      <el-table-column :label="$t('message.projects.detail.scene.table.columns.actions')" width="150" align="center">
         <template #default="scope">
-          <el-button size="small" text type="primary" v-auth="'detail'" @click="$router.push('/iotmanager/scene/manage/' + scope.row.id)">场景详情</el-button>
-          <el-button size="small" text type="warning" v-auth="'del'" @click="onDel(scope.row)">解绑</el-button>
+          <el-button size="small" text type="primary" v-auth="'detail'" @click="$router.push('/iotmanager/scene/manage/' + scope.row.id)">{{ $t('message.projects.detail.scene.table.actions.detail') }}</el-button>
+          <el-button size="small" text type="warning" v-auth="'del'" @click="onDel(scope.row)">{{ $t('message.projects.detail.scene.table.actions.unbind') }}</el-button>
         </template>
       </el-table-column>
     </el-table>
     <pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum" v-model:limit="params.pageSize" @pagination="getList()" />
-    <el-dialog title="添加场景" v-model="isShowDialog" width="400">
+    <el-dialog :title="$t('message.projects.detail.scene.dialog.title')" v-model="isShowDialog" width="400">
       <el-form v-if="isShowDialog">
-        <el-form-item label="场景" style="margin-bottom: 0;">
-          <el-select v-model="form.resourcesKey" filterable placeholder="选择场景" :clearable="false" style="width: 100%">
+        <el-form-item :label="$t('message.projects.detail.scene.form.labels.scene')" style="margin-bottom: 0;">
+          <el-select v-model="form.resourcesKey" filterable :placeholder="$t('message.projects.detail.scene.form.placeholders.scene')" :clearable="false" style="width: 100%">
             <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
       </el-form>
       <template #footer>
         <span class="dialog-footer">
-          <el-button @click="onCancel">取 消</el-button>
-          <el-button type="primary" @click="onSubmit">确 定</el-button>
+          <el-button @click="onCancel">{{ $t('message.projects.detail.scene.actions.cancel') }}</el-button>
+          <el-button type="primary" @click="onSubmit">{{ $t('message.projects.detail.scene.actions.confirm') }}</el-button>
         </span>
       </template>
     </el-dialog>
@@ -53,18 +53,19 @@ import api from '/@/api/projects';
 import { useSearch } from '/@/hooks/useCommon';
 import { useRoute } from 'vue-router';
 import { ElMessage, ElMessageBox } from 'element-plus';
+import { useI18n } from 'vue-i18n';
 const route = useRoute();
+const { t } = useI18n();
 
 const props = defineProps({ resourcesTypes: Number })
 const isShowDialog = ref(false)
 const options = ref<any[]>([])
-const resourcesTypes = props.resourcesTypes
 const projectsCode = route.params.id
 
 const baseForm = {
   resourcesKey: '',
   projectsCode,
-  resourcesTypes
+  resourcesTypes: props.resourcesTypes
 }
 
 const form = reactive({
@@ -78,7 +79,7 @@ getSourceList();
 
 function getSourceList() {
   api.getProjectResourcesByCode({ projectsCode }).then((res: any) => {
-    params.ids = (res || []).filter((item: any) => item.resourcesTypes === resourcesTypes).map((item: any) => item.resourcesKey)
+    params.ids = (res || []).filter((item: any) => item.resourcesTypes === props.resourcesTypes).map((item: any) => item.resourcesKey)
     if (!params.ids.length) {
       params.pageNum = 1
       tableData.value = []
@@ -101,11 +102,11 @@ function onCancel() {
 }
 
 function onSubmit() {
-  if (!form.resourcesKey) return ElMessage('请先选择场景')
-  api.bindResources(form).then((res: any) => {
+  if (!form.resourcesKey) return ElMessage(t('message.projects.detail.scene.messages.selectSceneFirst'))
+  api.bindResources(form).then(() => {
     onCancel()
     getSourceList()
-    ElMessage.success('添加成功')
+    ElMessage.success(t('message.projects.detail.scene.messages.addSuccess'))
   })
 }
 
@@ -114,18 +115,18 @@ function addDevice() {
 }
 
 function onDel(row: any) {
-  ElMessageBox.confirm(`确定要解绑该场景?`, '提示', {
-    confirmButtonText: '确认',
-    cancelButtonText: '取消',
+  ElMessageBox.confirm(t('message.projects.detail.scene.messages.unbindConfirm'), t('message.projects.detail.scene.messages.tip'), {
+    confirmButtonText: t('message.projects.detail.scene.messages.confirm'),
+    cancelButtonText: t('message.projects.detail.scene.messages.cancel'),
     type: 'warning',
   }).then(() => {
     api.unbindResources({
       projectsCode,
-      resourcesTypes,
+      resourcesTypes: props.resourcesTypes,
       resourcesKey: row.id
     }).then(() => {
       getSourceList()
-      ElMessage.success('解绑成功')
+      ElMessage.success(t('message.projects.detail.scene.messages.unbindSuccess'))
     })
   });
 }

+ 28 - 26
src/views/iot/projects/detail/topo.vue

@@ -1,32 +1,32 @@
 <template>
   <div class="tab-content h-full">
-    <div class="subtitle"><span></span> <el-button type="primary" v-auth="'add'" size="small" @click="addDevice()">添加组态</el-button></div>
+    <div class="subtitle"><span></span> <el-button type="primary" v-auth="'add'" size="small" @click="addDevice()">{{ $t('message.projects.detail.topo.actions.add') }}</el-button></div>
     <el-table :data="tableData" style="width: 100%" v-loading="loading" max-height="calc(100vh - 280px)">
-      <el-table-column prop="id" label="ID" width="100" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="name" label="组态图名称" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="createdAt" label="创建时间" min-width="100" align="center"></el-table-column>
-      <el-table-column prop="updatedAt" label="更新时间" min-width="100" align="center"></el-table-column>
-      <el-table-column label="操作" width="170" align="center">
+      <el-table-column prop="id" :label="$t('message.projects.detail.topo.table.columns.id')" width="100" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="name" :label="$t('message.projects.detail.topo.table.columns.name')" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="createdAt" :label="$t('message.projects.detail.topo.table.columns.createdAt')" min-width="100" align="center"></el-table-column>
+      <el-table-column prop="updatedAt" :label="$t('message.projects.detail.topo.table.columns.updatedAt')" min-width="100" align="center"></el-table-column>
+      <el-table-column :label="$t('message.projects.detail.topo.table.columns.actions')" width="210" align="center">
         <template #default="scope">
-          <el-button size="small" text type="primary" v-auth="'detail'" v-if="!scope.row.folderName" @click="view(scope.row)">预览</el-button>
-          <el-button size="small" text type="primary" v-auth="'edit'" @click="edit(scope.row)">编辑组态图</el-button>
-          <el-button size="small" text type="warning" v-auth="'del'" @click="onDel(scope.row)">解绑</el-button>
+          <el-button size="small" text type="primary" v-auth="'detail'" v-if="!scope.row.folderName" @click="view(scope.row)">{{ $t('message.projects.detail.topo.table.actions.preview') }}</el-button>
+          <el-button size="small" text type="primary" v-auth="'edit'" @click="edit(scope.row)">{{ $t('message.projects.detail.topo.table.actions.edit') }}</el-button>
+          <el-button size="small" text type="warning" v-auth="'del'" @click="onDel(scope.row)">{{ $t('message.projects.detail.topo.table.actions.unbind') }}</el-button>
         </template>
       </el-table-column>
     </el-table>
     <pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum" v-model:limit="params.pageSize" @pagination="getList()" />
-    <el-dialog title="添加组态" v-model="isShowDialog" width="400">
+    <el-dialog :title="$t('message.projects.detail.topo.dialog.title')" v-model="isShowDialog" width="400">
       <el-form v-if="isShowDialog">
-        <el-form-item label="组态" style="margin-bottom: 0;">
-          <el-select v-model="form.resourcesKey" filterable placeholder="选择组态" :clearable="false" style="width: 100%">
+        <el-form-item :label="$t('message.projects.detail.topo.form.labels.topo')" style="margin-bottom: 0;">
+          <el-select v-model="form.resourcesKey" filterable :placeholder="$t('message.projects.detail.topo.form.placeholders.topo')" :clearable="false" style="width: 100%">
             <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
       </el-form>
       <template #footer>
         <span class="dialog-footer">
-          <el-button @click="onCancel">取 消</el-button>
-          <el-button type="primary" @click="onSubmit">确 定</el-button>
+          <el-button @click="onCancel">{{ $t('message.projects.detail.topo.actions.cancel') }}</el-button>
+          <el-button type="primary" @click="onSubmit">{{ $t('message.projects.detail.topo.actions.confirm') }}</el-button>
         </span>
       </template>
     </el-dialog>
@@ -34,25 +34,27 @@
 </template>
 
 <script lang="ts" setup>
-import { reactive, ref } from 'vue';
+import { reactive, ref, toRef } from 'vue';
 import topoApi from '/@/api/configuration';
 import api from '/@/api/projects';
 import { useSearch } from '/@/hooks/useCommon';
 import { useRoute } from 'vue-router';
 import { ElMessage, ElMessageBox } from 'element-plus';
+import { useI18n } from 'vue-i18n';
 import getOrigin from '/@/utils/origin'
 const route = useRoute();
+const { t } = useI18n();
 
 const props = defineProps({ resourcesTypes: Number })
 const isShowDialog = ref(false)
 const options = ref<any[]>([])
-const resourcesTypes = props.resourcesTypes
+const resourcesTypes = toRef(props, 'resourcesTypes')
 const projectsCode = route.params.id
 
 const baseForm = {
   resourcesKey: '',
   projectsCode,
-  resourcesTypes
+  resourcesTypes: resourcesTypes.value
 }
 
 const form = reactive({
@@ -66,7 +68,7 @@ getSourceList();
 
 function getSourceList() {
   api.getProjectResourcesByCode({ projectsCode }).then((res: any) => {
-    params.ids = (res || []).filter((item: any) => item.resourcesTypes === resourcesTypes).map((item: any) => item.resourcesKey)
+    params.ids = (res || []).filter((item: any) => item.resourcesTypes === resourcesTypes.value).map((item: any) => item.resourcesKey)
     if (!params.ids.length) {
       params.pageNum = 1
       tableData.value = []
@@ -88,11 +90,11 @@ function onCancel() {
 }
 
 function onSubmit() {
-  if (!form.resourcesKey) return ElMessage('请先选择组态')
-  api.bindResources(form).then((res: any) => {
+  if (!form.resourcesKey) return ElMessage(t('message.projects.detail.topo.messages.selectTopoFirst'))
+  api.bindResources(form).then(() => {
     onCancel()
     getSourceList()
-    ElMessage.success('添加成功')
+    ElMessage.success(t('message.projects.detail.topo.messages.addSuccess'))
   })
 }
 
@@ -116,18 +118,18 @@ const edit = (row: any) => {
 };
 
 function onDel(row: any) {
-  ElMessageBox.confirm(`确定要解绑该组态?`, '提示', {
-    confirmButtonText: '确认',
-    cancelButtonText: '取消',
+  ElMessageBox.confirm(t('message.projects.detail.topo.messages.unbindConfirm'), t('message.projects.detail.topo.messages.tip'), {
+    confirmButtonText: t('message.projects.detail.topo.messages.confirm'),
+    cancelButtonText: t('message.projects.detail.topo.messages.cancel'),
     type: 'warning',
   }).then(() => {
     api.unbindResources({
       projectsCode,
-      resourcesTypes,
+      resourcesTypes: resourcesTypes.value,
       resourcesKey: row.id
     }).then(() => {
       getSourceList()
-      ElMessage.success('解绑成功')
+      ElMessage.success(t('message.projects.detail.topo.messages.unbindSuccess'))
     })
   });
 }

+ 34 - 32
src/views/iot/projects/detail/video.vue

@@ -1,42 +1,42 @@
 <template>
   <div class="tab-content h-full">
-    <div class="subtitle"><span></span> <el-button type="primary" v-auth="'add'" size="small" @click="addDevice()">添加监控</el-button></div>
+    <div class="subtitle"><span></span> <el-button type="primary" v-auth="'add'" size="small" @click="addDevice()">{{ $t('message.projects.detail.video.actions.add') }}</el-button></div>
     <el-table :data="tableData" style="width: 100%" v-loading="loading" max-height="calc(100vh - 280px)">
-      <el-table-column prop="name" label="设备名称" min-width="130" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="deviceId" label="设备ID" min-width="210" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="name" label="通道名称" min-width="140" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="model" label="型号" width="100" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="manufacturer" label="厂商" width="100" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="liveStatus" label="状态" width="100" align="center" :formatter="formatLiveStatus" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="keepAliveTime" label="最后心跳时间" :formatter="formatTime" width="170" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="registerTime" label="注册时间" :formatter="formatTime" width="170" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="updateAt" label="更新时间" :formatter="formatTime" width="170" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column label="操作" width="120" align="center" fixed="right">
+      <el-table-column prop="name" :label="$t('message.projects.detail.video.table.columns.deviceName')" min-width="130" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="deviceId" :label="$t('message.projects.detail.video.table.columns.deviceId')" min-width="210" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="name" :label="$t('message.projects.detail.video.table.columns.channelName')" min-width="140" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="model" :label="$t('message.projects.detail.video.table.columns.model')" width="100" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="manufacturer" :label="$t('message.projects.detail.video.table.columns.manufacturer')" width="100" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="liveStatus" :label="$t('message.projects.detail.video.table.columns.liveStatus')" width="100" align="center" :formatter="formatLiveStatus" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="keepAliveTime" :label="$t('message.projects.detail.video.table.columns.keepAliveTime')" :formatter="formatTime" width="170" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="registerTime" :label="$t('message.projects.detail.video.table.columns.registerTime')" :formatter="formatTime" width="170" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="updateAt" :label="$t('message.projects.detail.video.table.columns.updateAt')" :formatter="formatTime" width="170" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column :label="$t('message.projects.detail.video.table.columns.actions')" width="120" align="center" fixed="right">
         <template #default="scope">
-          <el-button size="small" text type="primary" v-auth="'detail'" @click="view(scope.row)">查看监控</el-button>
-          <el-button size="small" text type="warning" v-auth="'del'" @click="onDel(scope.row)">解绑</el-button>
+          <el-button size="small" text type="primary" v-auth="'detail'" @click="view(scope.row)">{{ $t('message.projects.detail.video.table.actions.view') }}</el-button>
+          <el-button size="small" text type="warning" v-auth="'del'" @click="onDel(scope.row)">{{ $t('message.projects.detail.video.table.actions.unbind') }}</el-button>
         </template>
       </el-table-column>
     </el-table>
-    <el-dialog title="添加监控" v-model="isShowDialog" width="400">
+    <el-dialog :title="$t('message.projects.detail.video.dialog.addTitle')" v-model="isShowDialog" width="400">
       <el-form v-if="isShowDialog">
-        <el-form-item label="监控" style="margin-bottom: 0">
-          <el-select v-model="form.resourcesKey" filterable placeholder="选择监控" :clearable="false" style="width: 100%">
+        <el-form-item :label="$t('message.projects.detail.video.form.labels.video')" style="margin-bottom: 0">
+          <el-select v-model="form.resourcesKey" filterable :placeholder="$t('message.projects.detail.video.form.placeholders.video')" :clearable="false" style="width: 100%">
             <el-option v-for="item in options" :disabled="item.disabled" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
       </el-form>
       <template #footer>
         <span class="dialog-footer">
-          <el-button @click="onCancel">取 消</el-button>
-          <el-button type="primary" @click="onSubmit">确 定</el-button>
+          <el-button @click="onCancel">{{ $t('message.projects.detail.video.actions.cancel') }}</el-button>
+          <el-button type="primary" @click="onSubmit">{{ $t('message.projects.detail.video.actions.confirm') }}</el-button>
         </span>
       </template>
     </el-dialog>
-    <el-dialog title="预览监控" v-model="isShowPreviewDialog" width="90vh">
+    <el-dialog :title="$t('message.projects.detail.video.dialog.previewTitle')" v-model="isShowPreviewDialog" width="90vh">
       <template #header>
         <span class="dialog-footer">
-          <el-button type="primary" size="small" @click="openToNewWindow">新窗口预览</el-button>
+          <el-button type="primary" size="small" @click="openToNewWindow">{{ $t('message.projects.detail.video.actions.openInNewWindow') }}</el-button>
         </span>
       </template>
       <iframe v-if="isShowPreviewDialog" :src="previewUrl" style="width: 100%; height: 50vh"></iframe>
@@ -45,13 +45,15 @@
 </template>
 
 <script lang="ts" setup>
-import { reactive, ref } from "vue";
+import { reactive, ref, toRef } from "vue";
 import api from "/@/api/projects";
 import { useRoute } from "vue-router";
 import { dayjs, ElMessage, ElMessageBox } from "element-plus";
 import axios from "axios";
 import { getMediaOrigin } from "/@/utils/origin";
+import { useI18n } from 'vue-i18n';
 const route = useRoute();
+const { t } = useI18n();
 
 const props = defineProps({ resourcesTypes: Number });
 const isShowDialog = ref(false);
@@ -61,13 +63,13 @@ const previewUrl = ref("");
 const options = ref<any[]>([]);
 const tableData = ref<any[]>([]);
 const channels = ref<any[]>([]);
-const resourcesTypes = props.resourcesTypes!;
+const resourcesTypes = toRef(props, 'resourcesTypes');
 const projectsCode = route.params.id;
 
 const baseForm = {
   resourcesKey: "",
   projectsCode,
-  resourcesTypes,
+  resourcesTypes: resourcesTypes.value,
 };
 
 const form = reactive({
@@ -78,7 +80,7 @@ getOptions();
 
 function getSourceList() {
   api.getProjectResourcesByCode({ projectsCode }).then((res: any) => {
-    const ids = (res || []).filter((item: any) => item.resourcesTypes === resourcesTypes).map((item: any) => item.resourcesKey);
+    const ids = (res || []).filter((item: any) => item.resourcesTypes === resourcesTypes.value).map((item: any) => item.resourcesKey);
 
     const tableDataList: any[] = [];
 
@@ -126,11 +128,11 @@ function onCancel() {
 }
 
 function onSubmit() {
-  if (!form.resourcesKey) return ElMessage("请先选择监控");
+  if (!form.resourcesKey) return ElMessage(t('message.projects.detail.video.messages.selectVideoFirst'));
   api.bindResources(form).then(() => {
     onCancel();
     getSourceList();
-    ElMessage.success("添加成功");
+    ElMessage.success(t('message.projects.detail.video.messages.addSuccess'));
   });
 }
 
@@ -149,20 +151,20 @@ function openToNewWindow() {
 }
 
 function onDel(row: any) {
-  ElMessageBox.confirm(`确定要解绑该监控?`, "提示", {
-    confirmButtonText: "确认",
-    cancelButtonText: "取消",
+  ElMessageBox.confirm(t('message.projects.detail.video.messages.unbindConfirm'), t('message.projects.detail.video.messages.tip'), {
+    confirmButtonText: t('message.projects.detail.video.messages.confirm'),
+    cancelButtonText: t('message.projects.detail.video.messages.cancel'),
     type: "warning",
   }).then(() => {
     api
       .unbindResources({
         projectsCode,
-        resourcesTypes,
+        resourcesTypes: resourcesTypes.value,
         resourcesKey: row.deviceId + "-" + row.channelId,
       })
       .then(() => {
         getSourceList();
-        ElMessage.success("解绑成功");
+        ElMessage.success(t('message.projects.detail.video.messages.unbindSuccess'));
       });
   });
 }
@@ -173,6 +175,6 @@ function formatTime(row: any, column: any) {
 
 function formatLiveStatus(row: any, column: any) {
   // 0 代表空闲,1 代表正在调用 invite,2 代表正在拉流
-  return row[column.property] === 0 ? "空闲" : row[column.property] === 1 ? "调用中" : "拉流中";
+  return row[column.property] === 0 ? t('message.projects.detail.video.liveStatusTags.idle') : row[column.property] === 1 ? t('message.projects.detail.video.liveStatusTags.inviting') : t('message.projects.detail.video.liveStatusTags.streaming');
 }
 </script>