Przeglądaj źródła

feat: 增加部分过滤模板页面的多语言

yanglzh 1 miesiąc temu
rodzic
commit
9372522022

+ 246 - 0
src/i18n/pages/projects/en.ts

@@ -6,6 +6,43 @@ export default {
       query: 'Search',
       reset: 'Reset'
     },
+    addOrEdit: {
+      form: {
+        name: 'Project Name',
+        addressCode: 'Region',
+        addressDetail: 'Address Detail',
+        channelMerchants: 'Channel Merchant',
+        customName: 'Key Customer',
+        repairCompany: 'Maintenance Company',
+        repairMobile: 'Maintenance Phone'
+      },
+      placeholders: {
+        select: 'Please select',
+        name: 'Enter project name',
+        addressDetail: 'Enter address detail',
+        channelMerchants: 'Enter channel merchant',
+        customName: 'Enter customer name',
+        repairCompany: 'Enter maintenance company',
+        repairMobile: 'Enter maintenance phone'
+      },
+      buttons: {
+        cancel: 'Cancel',
+        confirm: 'Confirm'
+      },
+      validation: {
+        name: 'Please enter project name',
+        addressCode: 'Please select region',
+        addressDetail: 'Please enter address detail',
+        channelMerchants: 'Please enter channel merchant',
+        customName: 'Please enter customer name',
+        repairCompany: 'Please enter maintenance company',
+        repairMobile: 'Please enter maintenance phone'
+      },
+      messages: {
+        addSuccess: 'Added successfully',
+        editSuccess: 'Edited successfully'
+      }
+    },
     status: {
       all: 'All status',
       enabled: 'Enabled',
@@ -51,4 +88,213 @@ export default {
       edit: 'Edit Project'
     }
   }
+  ,
+  detail: {
+    tabs: {
+      overview: 'Overview',
+      devices: 'Gateways & Devices',
+      scene: 'Scene Linkage',
+      topo: 'Topology Apps',
+      video: 'Video Surveillance'
+    },
+    device: {
+      actions: {
+        add: 'Add Device',
+        cancel: 'Cancel',
+        confirm: 'Confirm'
+      },
+      table: {
+        columns: {
+          key: 'Key',
+          name: 'Device Name',
+          deviceType: 'Device Type',
+          productName: 'Product',
+          status: 'Status',
+          lastOnlineTime: 'Last Online Time',
+          desc: 'Description',
+          actions: 'Actions'
+        },
+        actions: {
+          detail: 'Device Details',
+          unbind: 'Unbind'
+        },
+        statusTags: {
+          offline: 'Offline',
+          online: 'Online',
+          inactive: 'Inactive'
+        }
+      },
+      dialog: {
+        title: 'Add Device'
+      },
+      form: {
+        labels: {
+          product: 'Product',
+          device: 'Device'
+        },
+        placeholders: {
+          product: 'Select product',
+          device: 'Select device'
+        }
+      },
+      messages: {
+        selectDeviceFirst: 'Please select a device first',
+        addSuccess: 'Added successfully',
+        deleteConfirm: 'Are you sure to delete?',
+        tip: 'Prompt',
+        confirm: 'Confirm',
+        cancel: 'Cancel',
+        unbindSuccess: 'Unbound successfully'
+      }
+    }
+  },
+  filter: {
+    index: {
+      search: {
+        namePlaceholder: 'Search template name',
+        deviceKeyPlaceholder: 'Search device key',
+        statusPlaceholder: 'Select forward format',
+        query: 'Query',
+        reset: 'Reset'
+      },
+      status: {
+        all: 'All',
+        enabled: 'Enabled',
+        disabled: 'Disabled'
+      },
+      actions: {
+        add: 'Add',
+        delete: 'Delete'
+      },
+      table: {
+        columns: {
+          name: 'Template Name',
+          code: 'Template Code',
+          updatedAt: 'Updated At',
+          status: 'Status',
+          actions: 'Actions'
+        },
+        actions: {
+          detail: 'Details',
+          edit: 'Edit',
+          delete: 'Delete',
+          viewBind: 'View & Bind Devices'
+        }
+      },
+      switch: {
+        active: 'On',
+        inactive: 'Off'
+      },
+      messages: {
+        deleteConfirmSingle: 'This will delete template: “{name}”. Continue?',
+        deleteConfirmMultiple: 'This will delete {count} templates',
+        tip: 'Tip',
+        warn: 'Warning',
+        confirm: 'Confirm',
+        cancel: 'Cancel',
+        deleteSuccess: 'Deleted successfully',
+        enableActionText: 'Enable',
+        disableActionText: 'Disable',
+        statusChangeConfirm: 'Confirm to {action} template: 【{name}】?',
+        statusChangeSuccess: '{action} succeeded'
+      }
+    },
+    edit: {
+      form: {
+        name: 'Template Name'
+      },
+      placeholders: {
+        name: 'Enter template name'
+      },
+      actions: {
+        cancel: 'Cancel',
+        confirm: 'Confirm'
+      },
+      rules: {
+        required: 'Required'
+      },
+      messages: {
+        success: 'Operation succeeded'
+      }
+    },
+    editDialog: {
+      title: {
+        add: 'Add Template',
+        edit: 'Edit Template'
+      }
+    },
+    detail: {
+      dialog: {
+        title: 'Template Details'
+      },
+      sections: {
+        templateInfo: 'Device Data Filter Template Info',
+        customAttr: 'Custom Attributes'
+      },
+      descriptions: {
+        templateName: 'Template Name',
+        templateCode: 'Template Code',
+        updatedAt: 'Updated At'
+      },
+      actions: {
+        addCustomAttr: 'Add Custom Attribute'
+      },
+      table: {
+        columns: {
+          name: 'Attribute Name',
+          key: 'Attribute Code',
+          unit: 'Unit',
+          updatedAt: 'Updated At',
+          isVisible: 'Visible',
+          actions: 'Actions'
+        },
+        actions: {
+          edit: 'Edit',
+          delete: 'Delete'
+        }
+      },
+      switch: {
+        active: 'On',
+        inactive: 'Off'
+      },
+      messages: {
+        warn: 'Warning',
+        tip: 'Prompt',
+        confirm: 'Confirm',
+        cancel: 'Cancel',
+        deleteSuccess: 'Deleted successfully',
+        deleteConfirmSingle: 'This will delete attribute: “{name}”. Continue?',
+        deleteConfirmMultiple: 'This will delete {count} attributes',
+        confirmSetVisible: 'Confirm to set attribute "{name}" as visible?',
+        confirmSetInvisible: 'Confirm to set attribute "{name}" as invisible?',
+        setVisibleSuccess: 'Set visible successfully',
+        setInvisibleSuccess: 'Set invisible successfully'
+      }
+    }
+    ,
+    attrEdit: {
+      titleEdit: 'Edit Attribute',
+      titleAdd: 'Add Attribute',
+      labels: {
+        name: 'Attribute Name',
+        key: 'Attribute KEY',
+        unit: 'Unit'
+      },
+      placeholders: {
+        name: 'Enter attribute name',
+        key: 'Enter attribute code',
+        unit: 'Enter unit'
+      },
+      actions: {
+        cancel: 'Cancel',
+        confirm: 'Confirm'
+      },
+      rules: {
+        required: 'Required'
+      },
+      messages: {
+        success: 'Operation succeeded'
+      }
+    }
+  }
 };

+ 246 - 0
src/i18n/pages/projects/zh-cn.ts

@@ -6,6 +6,43 @@ export default {
       query: '查询',
       reset: '重置'
     },
+    addOrEdit: {
+      form: {
+        name: '项目名称',
+        addressCode: '地区',
+        addressDetail: '详细地址',
+        channelMerchants: '渠道商',
+        customName: '关键客户',
+        repairCompany: '维修公司',
+        repairMobile: '维修电话'
+      },
+      placeholders: {
+        select: '请选择',
+        name: '输入项目名称',
+        addressDetail: '输入详细地址',
+        channelMerchants: '输入渠道商',
+        customName: '输入客户名称',
+        repairCompany: '输入维修公司',
+        repairMobile: '输入维修电话'
+      },
+      buttons: {
+        cancel: '取消',
+        confirm: '确定'
+      },
+      validation: {
+        name: '请输入项目名称',
+        addressCode: '请选择地区',
+        addressDetail: '请输入详细地址',
+        channelMerchants: '请输入渠道商',
+        customName: '请输入客户名称',
+        repairCompany: '请输入维修公司',
+        repairMobile: '请输入维修电话'
+      },
+      messages: {
+        addSuccess: '新增成功',
+        editSuccess: '编辑成功'
+      }
+    },
     status: {
       all: '全部状态',
       enabled: '正常',
@@ -52,4 +89,213 @@ export default {
       edit: '编辑项目'
     }
   }
+  ,
+  detail: {
+    tabs: {
+      overview: '项目概况',
+      devices: '网关和设备',
+      scene: '场景联动',
+      topo: '组态应用',
+      video: '视频监控'
+    },
+    device: {
+      actions: {
+        add: '添加设备',
+        cancel: '取消',
+        confirm: '确定'
+      },
+      table: {
+        columns: {
+          key: '标识',
+          name: '设备名称',
+          deviceType: '设备类型',
+          productName: '所属产品',
+          status: '状态',
+          lastOnlineTime: '最后上线时间',
+          desc: '说明',
+          actions: '操作'
+        },
+        actions: {
+          detail: '设备详情',
+          unbind: '解绑'
+        },
+        statusTags: {
+          offline: '离线',
+          online: '在线',
+          inactive: '未启用'
+        }
+      },
+      dialog: {
+        title: '添加设备'
+      },
+      form: {
+        labels: {
+          product: '产品',
+          device: '设备'
+        },
+        placeholders: {
+          product: '选择产品',
+          device: '选择设备'
+        }
+      },
+      messages: {
+        selectDeviceFirst: '请先选择设备',
+        addSuccess: '添加成功',
+        deleteConfirm: '确定要删除?',
+        tip: '提示',
+        confirm: '确认',
+        cancel: '取消',
+        unbindSuccess: '解绑成功'
+      }
+    }
+  },
+  filter: {
+    index: {
+      search: {
+        namePlaceholder: '模板名称搜索',
+        deviceKeyPlaceholder: '设备key搜索',
+        statusPlaceholder: '请选择转发格式',
+        query: '查询',
+        reset: '重置'
+      },
+      status: {
+        all: '全部状态',
+        enabled: '正常',
+        disabled: '禁用'
+      },
+      actions: {
+        add: '新增',
+        delete: '删除'
+      },
+      table: {
+        columns: {
+          name: '模板名称',
+          code: '模板编码',
+          updatedAt: '更新时间',
+          status: '状态',
+          actions: '操作'
+        },
+        actions: {
+          detail: '详情',
+          edit: '编辑',
+          delete: '删除',
+          viewBind: '查看及绑定设备'
+        }
+      },
+      switch: {
+        active: '启',
+        inactive: '禁'
+      },
+      messages: {
+        deleteConfirmSingle: '此操作将模板:“{name}”,是否继续?',
+        deleteConfirmMultiple: '此操作将{count}个模板',
+        tip: '提示',
+        warn: '警告',
+        confirm: '确认',
+        cancel: '取消',
+        deleteSuccess: '删除成功',
+        enableActionText: '启用',
+        disableActionText: '停用',
+        statusChangeConfirm: '确认要{action}模板:【{name}】吗?',
+        statusChangeSuccess: '{action}成功'
+      }
+    },
+    edit: {
+      form: {
+        name: '模板名称'
+      },
+      placeholders: {
+        name: '输入模板名称'
+      },
+      actions: {
+        cancel: '取消',
+        confirm: '确定'
+      },
+      rules: {
+        required: '不能为空'
+      },
+      messages: {
+        success: '操作成功'
+      }
+    },
+    editDialog: {
+      title: {
+        add: '新增模板',
+        edit: '编辑模板'
+      }
+    },
+    detail: {
+      dialog: {
+        title: '模板详情'
+      },
+      sections: {
+        templateInfo: '设备数据过滤器模板信息',
+        customAttr: '自定义属性'
+      },
+      descriptions: {
+        templateName: '模板名称',
+        templateCode: '模板编码',
+        updatedAt: '更新时间'
+      },
+      actions: {
+        addCustomAttr: '添加自定义属性'
+      },
+      table: {
+        columns: {
+          name: '属性名称',
+          key: '属性编码',
+          unit: '单位',
+          updatedAt: '更新时间',
+          isVisible: '是否可见',
+          actions: '操作'
+        },
+        actions: {
+          edit: '编辑',
+          delete: '删除'
+        }
+      },
+      switch: {
+        active: '启',
+        inactive: '禁'
+      },
+      messages: {
+        warn: '警告',
+        tip: '提示',
+        confirm: '确认',
+        cancel: '取消',
+        deleteSuccess: '删除成功',
+        deleteConfirmSingle: '此操作将属性:“{name}”,是否继续?',
+        deleteConfirmMultiple: '此操作将{count}个属性',
+        confirmSetVisible: '确认要设置可见属性:【{name}】吗?',
+        confirmSetInvisible: '确认要设置不可见属性:【{name}】吗?',
+        setVisibleSuccess: '设置可见成功',
+        setInvisibleSuccess: '设置不可见成功'
+      }
+    }
+    ,
+    attrEdit: {
+      titleEdit: '编辑属性',
+      titleAdd: '新增属性',
+      labels: {
+        name: '属性名称',
+        key: '属性KEY',
+        unit: '单位'
+      },
+      placeholders: {
+        name: '输入属性名称',
+        key: '输入属性编码',
+        unit: '输入单位'
+      },
+      actions: {
+        cancel: '取消',
+        confirm: '确定'
+      },
+      rules: {
+        required: '不能为空'
+      },
+      messages: {
+        success: '操作成功'
+      }
+    }
+  }
 };

+ 246 - 0
src/i18n/pages/projects/zh-tw.ts

@@ -6,6 +6,43 @@ export default {
       query: '查詢',
       reset: '重置'
     },
+    addOrEdit: {
+      form: {
+        name: '項目名稱',
+        addressCode: '地區',
+        addressDetail: '詳細地址',
+        channelMerchants: '渠道商',
+        customName: '關鍵客戶',
+        repairCompany: '維修公司',
+        repairMobile: '維修電話'
+      },
+      placeholders: {
+        select: '請選擇',
+        name: '輸入項目名稱',
+        addressDetail: '輸入詳細地址',
+        channelMerchants: '輸入渠道商',
+        customName: '輸入客戶名稱',
+        repairCompany: '輸入維修公司',
+        repairMobile: '輸入維修電話'
+      },
+      buttons: {
+        cancel: '取消',
+        confirm: '確定'
+      },
+      validation: {
+        name: '請輸入項目名稱',
+        addressCode: '請選擇地區',
+        addressDetail: '請輸入詳細地址',
+        channelMerchants: '請輸入渠道商',
+        customName: '請輸入客戶名稱',
+        repairCompany: '請輸入維修公司',
+        repairMobile: '請輸入維修電話'
+      },
+      messages: {
+        addSuccess: '新增成功',
+        editSuccess: '編輯成功'
+      }
+    },
     status: {
       all: '全部狀態',
       enabled: '正常',
@@ -51,4 +88,213 @@ export default {
       edit: '編輯項目'
     }
   }
+  ,
+  detail: {
+    tabs: {
+      overview: '項目概況',
+      devices: '網關與設備',
+      scene: '場景聯動',
+      topo: '組態應用',
+      video: '視頻監控'
+    },
+    device: {
+      actions: {
+        add: '添加設備',
+        cancel: '取消',
+        confirm: '確定'
+      },
+      table: {
+        columns: {
+          key: '標識',
+          name: '設備名稱',
+          deviceType: '設備類型',
+          productName: '所屬產品',
+          status: '狀態',
+          lastOnlineTime: '最後上線時間',
+          desc: '說明',
+          actions: '操作'
+        },
+        actions: {
+          detail: '設備詳情',
+          unbind: '解綁'
+        },
+        statusTags: {
+          offline: '離線',
+          online: '在線',
+          inactive: '未啟用'
+        }
+      },
+      dialog: {
+        title: '添加設備'
+      },
+      form: {
+        labels: {
+          product: '產品',
+          device: '設備'
+        },
+        placeholders: {
+          product: '選擇產品',
+          device: '選擇設備'
+        }
+      },
+      messages: {
+        selectDeviceFirst: '請先選擇設備',
+        addSuccess: '添加成功',
+        deleteConfirm: '確定要刪除?',
+        tip: '提示',
+        confirm: '確認',
+        cancel: '取消',
+        unbindSuccess: '解綁成功'
+      }
+    }
+  },
+  filter: {
+    index: {
+      search: {
+        namePlaceholder: '模板名稱搜尋',
+        deviceKeyPlaceholder: '設備 key 搜尋',
+        statusPlaceholder: '請選擇轉發格式',
+        query: '查詢',
+        reset: '重置'
+      },
+      status: {
+        all: '全部狀態',
+        enabled: '正常',
+        disabled: '禁用'
+      },
+      actions: {
+        add: '新增',
+        delete: '刪除'
+      },
+      table: {
+        columns: {
+          name: '模板名稱',
+          code: '模板編碼',
+          updatedAt: '更新時間',
+          status: '狀態',
+          actions: '操作'
+        },
+        actions: {
+          detail: '詳情',
+          edit: '編輯',
+          delete: '刪除',
+          viewBind: '查看及綁定設備'
+        }
+      },
+      switch: {
+        active: '啟',
+        inactive: '禁'
+      },
+      messages: {
+        deleteConfirmSingle: '此操作將刪除模板:「{name}」,是否繼續?',
+        deleteConfirmMultiple: '此操作將刪除 {count} 個模板',
+        tip: '提示',
+        warn: '警告',
+        confirm: '確認',
+        cancel: '取消',
+        deleteSuccess: '刪除成功',
+        enableActionText: '啟用',
+        disableActionText: '停用',
+        statusChangeConfirm: '確認要{action}模板:【{name}】嗎?',
+        statusChangeSuccess: '{action}成功'
+      }
+    },
+    edit: {
+      form: {
+        name: '模板名稱'
+      },
+      placeholders: {
+        name: '輸入模板名稱'
+      },
+      actions: {
+        cancel: '取消',
+        confirm: '確定'
+      },
+      rules: {
+        required: '不能為空'
+      },
+      messages: {
+        success: '操作成功'
+      }
+    },
+    editDialog: {
+      title: {
+        add: '新增模板',
+        edit: '編輯模板'
+      }
+    },
+    detail: {
+      dialog: {
+        title: '模板詳情'
+      },
+      sections: {
+        templateInfo: '設備數據過濾器模板資訊',
+        customAttr: '自定義屬性'
+      },
+      descriptions: {
+        templateName: '模板名稱',
+        templateCode: '模板編碼',
+        updatedAt: '更新時間'
+      },
+      actions: {
+        addCustomAttr: '添加自定義屬性'
+      },
+      table: {
+        columns: {
+          name: '屬性名稱',
+          key: '屬性編碼',
+          unit: '單位',
+          updatedAt: '更新時間',
+          isVisible: '是否可見',
+          actions: '操作'
+        },
+        actions: {
+          edit: '編輯',
+          delete: '刪除'
+        }
+      },
+      switch: {
+        active: '啟',
+        inactive: '禁'
+      },
+      messages: {
+        warn: '警告',
+        tip: '提示',
+        confirm: '確認',
+        cancel: '取消',
+        deleteSuccess: '刪除成功',
+        deleteConfirmSingle: '此操作將屬性:「{name}」,是否繼續?',
+        deleteConfirmMultiple: '此操作將刪除 {count} 個屬性',
+        confirmSetVisible: '確認要設置可見屬性:【{name}】嗎?',
+        confirmSetInvisible: '確認要設置不可見屬性:【{name}】嗎?',
+        setVisibleSuccess: '設置可見成功',
+        setInvisibleSuccess: '設置不可見成功'
+      }
+    }
+    ,
+    attrEdit: {
+      titleEdit: '編輯屬性',
+      titleAdd: '新增屬性',
+      labels: {
+        name: '屬性名稱',
+        key: '屬性KEY',
+        unit: '單位'
+      },
+      placeholders: {
+        name: '輸入屬性名稱',
+        key: '輸入屬性編碼',
+        unit: '輸入單位'
+      },
+      actions: {
+        cancel: '取消',
+        confirm: '確定'
+      },
+      rules: {
+        required: '不能為空'
+      },
+      messages: {
+        success: '操作成功'
+      }
+    }
+  }
 };

+ 33 - 32
src/views/iot/projects/detail/device.vue

@@ -1,49 +1,49 @@
 <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.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="标识" 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 v-col="'key'">
         <template #default="{ row }">
           <copy :text="row.key"></copy>
         </template>
       </el-table-column>
-      <el-table-column label="设备名称" prop="name" min-width="160" show-overflow-tooltip v-col="'name'" />
-      <el-table-column label="设备类型" prop="product.deviceType" min-width="100" align="center" show-overflow-tooltip v-col="'deviceType'" />
-      <el-table-column label="所属产品" prop="productName" min-width="120" align="center" show-overflow-tooltip v-col="'productName'" />
-      <el-table-column prop="status" label="状态" 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 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'">
         <template #default="scope">
-          <el-tag type="info" size="small" v-if="scope.row.status == 1">离线</el-tag>
-          <el-tag type="success" size="small" v-if="scope.row.status == 2">在线</el-tag>
-          <el-tag type="info" size="small" v-if="scope.row.status == 0">未启用</el-tag>
+          <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="最后上线时间" align="center" width="160" v-col="'lastOnlineTime'"></el-table-column>
-      <el-table-column prop="desc" label="说明" show-overflow-tooltip v-col="'desc'"></el-table-column>
-      <el-table-column label="操作" width="120" align="center">
+      <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">
         <template #default="scope">
-          <el-button size="small" text type="primary" v-auth="'detail'" @click="$router.push('/iotmanager/device/instance/' + scope.row.key)">设备详情</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/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>
         </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.device.dialog.title')" v-model="isShowDialog" width="400">
       <el-form v-if="isShowDialog">
-        <el-form-item label="产品">
-          <el-select v-model="form.productKey" @change="getDivices" filterable placeholder="选择产品" :clearable="false" style="width: 100%">
+        <el-form-item :label="$t('message.projects.detail.device.form.labels.product')">
+          <el-select v-model="form.productKey" @change="getDivices" filterable :placeholder="$t('message.projects.detail.device.form.placeholders.product')" :clearable="false" style="width: 100%">
             <el-option v-for="item in productList" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
-        <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.device.form.labels.device')" style="margin-bottom: 0;">
+          <el-select v-model="form.resourcesKey" filterable :placeholder="$t('message.projects.detail.device.form.placeholders.device')" :clearable="false" style="width: 100%">
             <el-option v-for="item in deviceList" :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.device.actions.cancel') }}</el-button>
+          <el-button type="primary" @click="onSubmit">{{ $t('message.projects.detail.device.actions.confirm') }}</el-button>
         </span>
       </template>
     </el-dialog>
@@ -57,20 +57,21 @@ 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 productList = ref<any[]>([])
 const deviceList = ref<any[]>([])
-const resourcesTypes = props.resourcesTypes
 const projectsCode = route.params.id
 
 const baseForm = {
   productKey: '',
   resourcesKey: '',
   projectsCode,
-  resourcesTypes
+  resourcesTypes: props.resourcesTypes
 }
 
 const form = reactive({
@@ -84,7 +85,7 @@ getSourceList();
 
 function getSourceList() {
   api.getProjectResourcesByCode({ projectsCode }).then((res: any) => {
-    params.keys = (res || []).filter((item: any) => item.resourcesTypes === resourcesTypes).map((item: any) => item.resourcesKey)
+    params.keys = (res || []).filter((item: any) => item.resourcesTypes === props.resourcesTypes).map((item: any) => item.resourcesKey)
     if (!params.keys.length) {
       params.pageNum = 1
       tableData.value = []
@@ -107,11 +108,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.device.messages.selectDeviceFirst'))
+  api.bindResources(form).then(() => {
     onCancel()
     getSourceList()
-    ElMessage.success('添加成功')
+    ElMessage.success(t('message.projects.detail.device.messages.addSuccess'))
   })
 }
 
@@ -120,18 +121,18 @@ function addDevice() {
 }
 
 function onDel(row: any) {
-  ElMessageBox.confirm(`确定要删除?`, '提示', {
-    confirmButtonText: '确认',
-    cancelButtonText: '取消',
+  ElMessageBox.confirm(t('message.projects.detail.device.messages.deleteConfirm'), t('message.projects.detail.device.messages.tip'), {
+    confirmButtonText: t('message.projects.detail.device.messages.confirm'),
+    cancelButtonText: t('message.projects.detail.device.messages.cancel'),
     type: 'warning',
   }).then(() => {
     api.unbindResources({
       projectsCode,
-      resourcesTypes,
+      resourcesTypes: props.resourcesTypes,
       resourcesKey: row.key
     }).then(() => {
       getSourceList()
-      ElMessage.success('解绑成功')
+      ElMessage.success(t('message.projects.detail.device.messages.unbindSuccess'))
     })
   });
 }

+ 5 - 5
src/views/iot/projects/detail/index.vue

@@ -2,19 +2,19 @@
   <div class="page">
     <el-card shadow="never" class="small-padding">
       <el-tabs :model-value="'0'" size="small" class="h-full">
-        <el-tab-pane label="项目概况" name="0" lazy>
+        <el-tab-pane :label="$t('message.projects.detail.tabs.overview')" name="0" lazy>
           <InfoVue></InfoVue>
         </el-tab-pane>
-        <el-tab-pane label="网关和设备" name="1" lazy>
+        <el-tab-pane :label="$t('message.projects.detail.tabs.devices')" name="1" lazy>
           <DeviceVue :resourcesTypes="1"></DeviceVue>
         </el-tab-pane>
-        <el-tab-pane label="场景联动" name="4" lazy>
+        <el-tab-pane :label="$t('message.projects.detail.tabs.scene')" name="4" lazy>
           <SceneVue :resourcesTypes="4"></SceneVue>
         </el-tab-pane>
-        <el-tab-pane label="组态应用" name="2" lazy>
+        <el-tab-pane :label="$t('message.projects.detail.tabs.topo')" name="2" lazy>
           <TopoVue :resourcesTypes="2"></TopoVue>
         </el-tab-pane>
-        <el-tab-pane label="视频监控" name="3" lazy>
+        <el-tab-pane :label="$t('message.projects.detail.tabs.video')" name="3" lazy>
           <VideoVue :resourcesTypes="3"></VideoVue>
         </el-tab-pane>
       </el-tabs>

+ 21 - 17
src/views/iot/projects/filter/attrEdit.vue

@@ -1,18 +1,18 @@
 <template>
-  <el-dialog class="api-edit" v-model="showDialog" :title="`${formData?.id ? '编辑属性' : '新增属性'}`" width="500px" :close-on-click-modal="false" :close-on-press-escape="false">
-    <el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="80px">
-      <el-form-item label="属性名称" prop="name">
-        <el-input v-model.trim="formData.name" placeholder="输入属性名称" />
+  <el-dialog class="api-edit" v-model="showDialog" :title="formData?.id ? $t('message.projects.filter.attrEdit.titleEdit') : $t('message.projects.filter.attrEdit.titleAdd')" width="500px" :close-on-click-modal="false" :close-on-press-escape="false">
+    <el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="120px">
+      <el-form-item :label="$t('message.projects.filter.attrEdit.labels.name')" prop="name">
+        <el-input v-model.trim="formData.name" :placeholder="$t('message.projects.filter.attrEdit.placeholders.name')" />
       </el-form-item>
-      <el-form-item label="属性KEY" prop="key">
-        <el-input v-model.trim="formData.key" placeholder="输入属性名称" />
+      <el-form-item :label="$t('message.projects.filter.attrEdit.labels.key')" prop="key">
+        <el-input v-model.trim="formData.key" :placeholder="$t('message.projects.filter.attrEdit.placeholders.key')" />
       </el-form-item>
-      <el-form-item label="单位" prop="unit">
-        <el-input v-model.trim="formData.unit" placeholder="输入属性名称" />
+      <el-form-item :label="$t('message.projects.filter.attrEdit.labels.unit')" prop="unit">
+        <el-input v-model.trim="formData.unit" :placeholder="$t('message.projects.filter.attrEdit.placeholders.unit')" />
       </el-form-item>
       <el-form-item label="" prop="">
-        <el-button @click="cancel">取消</el-button>
-        <el-button type="primary" @click="onSubmit">确定</el-button>
+        <el-button @click="cancel">{{ $t('message.projects.filter.attrEdit.actions.cancel') }}</el-button>
+        <el-button type="primary" @click="onSubmit">{{ $t('message.projects.filter.attrEdit.actions.confirm') }}</el-button>
       </el-form-item>
     </el-form>
   </el-dialog>
@@ -20,14 +20,16 @@
 
 <script lang="ts" setup>
 import api from '/@/api/projects';
-import { ref, reactive } from 'vue';
+import { ref, reactive, computed } from 'vue';
 import { ruleRequired } from '/@/utils/validator';
 import { ElMessage } from 'element-plus';
+import { useI18n } from 'vue-i18n';
 
 const emit = defineEmits(['getList']);
 
 const showDialog = ref(false);
 const formRef = ref();
+const { t } = useI18n();
 
 const baseForm = {
   id: undefined,
@@ -41,11 +43,13 @@ const formData = reactive({
   ...baseForm,
 });
 
-const ruleForm = {
-  name: [ruleRequired('不能为空')],
-  key: [ruleRequired('不能为空')],
-  unit: [ruleRequired('不能为空')],
-};
+const ruleForm = computed(() => {
+  return {
+    name: [ruleRequired(t('message.projects.filter.attrEdit.rules.required'))],
+    key: [ruleRequired(t('message.projects.filter.attrEdit.rules.required'))],
+    unit: [ruleRequired(t('message.projects.filter.attrEdit.rules.required'))],
+  };
+});
 
 const onSubmit = async () => {
   await formRef.value.validate();
@@ -54,7 +58,7 @@ const onSubmit = async () => {
 
   await theApi(formData);
 
-  ElMessage.success('操作成功');
+  ElMessage.success(t('message.projects.filter.attrEdit.messages.success'));
   // resetForm();
   showDialog.value = false;
   emit('getList');

+ 39 - 25
src/views/iot/projects/filter/detail.vue

@@ -1,28 +1,28 @@
 <template>
-  <el-dialog title="模板详情" v-model="isShowDialog" width="1200">
-    <el-divider content-position="left" style="margin-top: 0;">设备数据过滤器模板信息</el-divider>
+  <el-dialog :title="$t('message.projects.filter.detail.dialog.title')" v-model="isShowDialog" width="1200">
+    <el-divider content-position="left" style="margin-top: 0;">{{ $t('message.projects.filter.detail.sections.templateInfo') }}</el-divider>
     <el-descriptions :column="3" border>
-      <el-descriptions-item label="模板名称">{{ data.name }}</el-descriptions-item>
-      <el-descriptions-item label="模板编码">{{ data.code }}</el-descriptions-item>
-      <el-descriptions-item label="更新时间">{{ data.updatedAt }}</el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.filter.detail.descriptions.templateName')">{{ data.name }}</el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.filter.detail.descriptions.templateCode')">{{ data.code }}</el-descriptions-item>
+      <el-descriptions-item :label="$t('message.projects.filter.detail.descriptions.updatedAt')">{{ data.updatedAt }}</el-descriptions-item>
     </el-descriptions>
-    <el-divider content-position="left" style="margin-top: 30px;">自定义属性</el-divider>
-    <div class="flex-row"><span></span> <el-button type="primary" size="small" v-auth="'add'" @click="addOrEdit(data.code)">添加自定义属性</el-button></div>
+    <el-divider content-position="left" style="margin-top: 30px;">{{ $t('message.projects.filter.detail.sections.customAttr') }}</el-divider>
+    <div class="flex-row"><span></span> <el-button type="primary" size="small" v-auth="'add'" @click="addOrEdit(data.code)">{{ $t('message.projects.filter.detail.actions.addCustomAttr') }}</el-button></div>
     <el-table :data="tableData" style="width: 100%;margin-top: 20px;" v-loading="loading">
-      <el-table-column prop="name" label="属性名称" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="key" label="属性编码" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="unit" label="单位" align="center" show-overflow-tooltip></el-table-column>
-      <el-table-column prop="updatedAt" label="更新时间" align="center"></el-table-column>
-      <el-table-column prop="isVisible" label="是否可见" align="center">
+      <el-table-column prop="name" :label="$t('message.projects.filter.detail.table.columns.name')" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="key" :label="$t('message.projects.filter.detail.table.columns.key')" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="unit" :label="$t('message.projects.filter.detail.table.columns.unit')" align="center" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="updatedAt" :label="$t('message.projects.filter.detail.table.columns.updatedAt')" align="center"></el-table-column>
+      <el-table-column prop="isVisible" :label="$t('message.projects.filter.detail.table.columns.isVisible')" align="center">
         <template #default="scope">
-          <el-switch v-model="scope.row.isVisible" inline-prompt :active-value="1" :inactive-value="0" active-text="启" inactive-text="禁" @change="handleStatusChange(scope.row)">
+          <el-switch v-model="scope.row.isVisible" inline-prompt :active-value="1" :inactive-value="0" :active-text="$t('message.projects.filter.detail.switch.active')" :inactive-text="$t('message.projects.filter.detail.switch.inactive')" @change="handleStatusChange(scope.row)">
           </el-switch>
         </template>
       </el-table-column>
-      <el-table-column label="操作" width="120" align="center" fixed="right">
+      <el-table-column :label="$t('message.projects.filter.detail.table.columns.actions')" width="120" align="center" fixed="right">
         <template #default="{ row }">
-          <el-button size="small" text type="warning" v-auth="'edit'" @click="addOrEdit(data.code, row)">编辑</el-button>
-          <el-button size="small" text type="danger" v-auth="'del'" @click="del(row)">删除</el-button>
+          <el-button size="small" text type="warning" v-auth="'edit'" @click="addOrEdit(data.code, row)">{{ $t('message.projects.filter.detail.table.actions.edit') }}</el-button>
+          <el-button size="small" text type="danger" v-auth="'del'" @click="del(row)">{{ $t('message.projects.filter.detail.table.actions.delete') }}</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -37,6 +37,7 @@ import api from '/@/api/projects';
 import attrEdit from './attrEdit.vue';
 import { useSearch } from '/@/hooks/useCommon';
 import { ElMessageBox, ElMessage } from 'element-plus';
+import { useI18n } from 'vue-i18n';
 
 const { params, tableData, getList, loading } = useSearch<any[]>(api.template.attr.list, 'Data', { keyWord: '', templateseCode: '' });
 
@@ -44,6 +45,7 @@ const isShowDialog = ref(false);
 const editFormRef = ref();
 const ids = ref([]);
 const data = ref<any>({});
+const { t } = useI18n();
 
 function show(row: any) {
   data.value = { ...row }
@@ -57,17 +59,25 @@ const addOrEdit = (code: string, row?: any) => {
 };
 
 const handleStatusChange = (row: any) => {
-  let text = row.isVisible === 1 ? '设置可见' : '设置不可见';
-  ElMessageBox.confirm('确认要' + text + '属性:【' + row.name + '】吗?', '警告', {
-    confirmButtonText: '确定',
-    cancelButtonText: '取消',
+  const isOn = row.isVisible === 1;
+  const title = t('message.projects.filter.detail.messages.warn');
+  const confirmText = isOn
+    ? t('message.projects.filter.detail.messages.confirmSetVisible', { name: row.name })
+    : t('message.projects.filter.detail.messages.confirmSetInvisible', { name: row.name });
+  ElMessageBox.confirm(confirmText, title, {
+    confirmButtonText: t('message.projects.filter.detail.messages.confirm'),
+    cancelButtonText: t('message.projects.filter.detail.messages.cancel'),
     type: 'warning',
   })
     .then(function () {
       return api.template.attr.editIsVisible({ id: row.id, isVisible: row.isVisible });
     })
     .then(() => {
-      ElMessage.success(text + '成功');
+      ElMessage.success(
+        isOn
+          ? t('message.projects.filter.detail.messages.setVisibleSuccess')
+          : t('message.projects.filter.detail.messages.setInvisibleSuccess')
+      );
     })
     .catch(function () {
       row.isVisible = row.isVisible === 0 ? 1 : 0;
@@ -75,13 +85,17 @@ const handleStatusChange = (row: any) => {
 };
 
 const del = (row?: any) => {
-  ElMessageBox.confirm(row ? `此操作将属性:“${row.name}”,是否继续?` : `此操作将${ids.value.length}个属性`, '提示', {
-    confirmButtonText: '确认',
-    cancelButtonText: '取消',
+  const title = t('message.projects.filter.detail.messages.tip');
+  const message = row
+    ? t('message.projects.filter.detail.messages.deleteConfirmSingle', { name: row.name })
+    : t('message.projects.filter.detail.messages.deleteConfirmMultiple', { count: ids.value.length });
+  ElMessageBox.confirm(message, title, {
+    confirmButtonText: t('message.projects.filter.detail.messages.confirm'),
+    cancelButtonText: t('message.projects.filter.detail.messages.cancel'),
     type: 'warning',
   }).then(async () => {
     await api.template.attr.del(row ? [row.id] : ids.value);
-    ElMessage.success('删除成功');
+    ElMessage.success(t('message.projects.filter.detail.messages.deleteSuccess'));
     getList(1);
   });
 };

+ 8 - 1
src/views/iot/projects/filter/edit-dialog.vue

@@ -1,5 +1,12 @@
 <template>
-  <el-dialog class="api-edit" v-model="showDialog" :title="`${formData?.id ? '编辑模板' : '新增模板'}`" width="500px" :close-on-click-modal="false" :close-on-press-escape="false">
+  <el-dialog
+    class="api-edit"
+    v-model="showDialog"
+    :title="formData?.id ? $t('message.projects.filter.editDialog.title.edit') : $t('message.projects.filter.editDialog.title.add')"
+    width="500px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+  >
     <EditVue ref="editRef" v-if="showDialog" @getList="getList" @cancel="cancel"></EditVue>
   </el-dialog>
 </template>

+ 14 - 11
src/views/iot/projects/filter/edit.vue

@@ -1,25 +1,27 @@
 <template>
-  <el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="80px">
-    <el-form-item label="模板名称" prop="name">
-      <el-input v-model.trim="formData.name" placeholder="输入模板名称" />
+  <el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="120px">
+    <el-form-item :label="$t('message.projects.filter.edit.form.name')" prop="name">
+      <el-input v-model.trim="formData.name" :placeholder="$t('message.projects.filter.edit.placeholders.name')" />
     </el-form-item>
     <el-form-item label="" prop="">
-      <el-button @click="cancel">取消</el-button>
-      <el-button type="primary" @click="onSubmit">确定</el-button>
+      <el-button @click="cancel">{{ $t('message.projects.filter.edit.actions.cancel') }}</el-button>
+      <el-button type="primary" @click="onSubmit">{{ $t('message.projects.filter.edit.actions.confirm') }}</el-button>
     </el-form-item>
   </el-form>
 </template>
 
 <script lang="ts" setup>
-import { ref, reactive, nextTick } from 'vue';
+import { ref, reactive, computed } from 'vue';
 import api from '/@/api/projects';
 import { ruleRequired } from '/@/utils/validator';
 import { ElMessage } from 'element-plus';
+import { useI18n } from 'vue-i18n';
 
 const emit = defineEmits(['getList', 'cancel']);
 
 const showDialog = ref(false);
 const formRef = ref();
+const { t } = useI18n();
 
 const baseForm = {
   id: undefined,
@@ -30,9 +32,11 @@ const formData = reactive({
   ...baseForm,
 });
 
-const ruleForm = {
-  name: [ruleRequired('不能为空')],
-};
+const ruleForm = computed(() => {
+  return {
+    name: [ruleRequired(t('message.projects.filter.edit.rules.required'))],
+  };
+});
 
 const onSubmit = async () => {
   await formRef.value.validate();
@@ -41,7 +45,7 @@ const onSubmit = async () => {
 
   await theApi(formData);
 
-  ElMessage.success('操作成功');
+  ElMessage.success(t('message.projects.filter.edit.messages.success'));
   // resetForm();
   showDialog.value = false;
   emit('getList');
@@ -60,7 +64,6 @@ const open = async (row?: any) => {
   resetForm();
   showDialog.value = true;
   if (row) {
-    console.log(row)
     Object.assign(formData, { ...row });
   }
 };

+ 35 - 32
src/views/iot/projects/filter/index.vue

@@ -4,16 +4,16 @@
       <div class="search">
         <el-form inline>
           <el-form-item>
-            <el-input v-model="params.keyWord" style="width: 200px" placeholder="模板名称搜索" @keyup.enter.native="getList(1)" clearable> </el-input>
+            <el-input v-model="params.keyWord" style="width: 200px" :placeholder="$t('message.projects.filter.index.search.namePlaceholder')" @keyup.enter.native="getList(1)" clearable> </el-input>
           </el-form-item>
           <el-form-item>
-            <el-input v-model="params.deviceKey" style="width: 200px" placeholder="设备key搜索" @keyup.enter.native="getList(1)" clearable> </el-input>
+            <el-input v-model="params.deviceKey" style="width: 200px" :placeholder="$t('message.projects.filter.index.search.deviceKeyPlaceholder')" @keyup.enter.native="getList(1)" clearable> </el-input>
           </el-form-item>
           <el-form-item>
-            <el-select v-model="params.status" placeholder="请选择转发格式" style="width: 100px">
-              <el-option label="全部状态" :value="-1"> </el-option>
-              <el-option label="正常" :value="1"> </el-option>
-              <el-option label="禁用" :value="0"> </el-option>
+            <el-select v-model="params.status" :placeholder="$t('message.projects.filter.index.search.statusPlaceholder')" style="width: 100px">
+              <el-option :label="$t('message.projects.filter.index.status.all')" :value="-1"> </el-option>
+              <el-option :label="$t('message.projects.filter.index.status.enabled')" :value="1"> </el-option>
+              <el-option :label="$t('message.projects.filter.index.status.disabled')" :value="0"> </el-option>
             </el-select>
           </el-form-item>
           <el-form-item>
@@ -21,13 +21,13 @@
               <el-icon>
                 <ele-Search />
               </el-icon>
-              查询
+              {{ $t('message.projects.filter.index.search.query') }}
             </el-button>
             <el-button @click="resetQuery()">
               <el-icon>
                 <ele-Refresh />
               </el-icon>
-              重置
+              {{ $t('message.projects.filter.index.search.reset') }}
             </el-button>
           </el-form-item>
           <el-form-item>
@@ -35,33 +35,33 @@
               <el-icon>
                 <ele-FolderAdd />
               </el-icon>
-              新增
+              {{ $t('message.projects.filter.index.actions.add') }}
             </el-button>
             <el-button type="danger" v-auth="'del'" :disabled="!ids.length" @click="del()">
               <el-icon>
                 <ele-Delete />
               </el-icon>
-              删除
+              {{ $t('message.projects.filter.index.actions.delete') }}
             </el-button>
           </el-form-item>
         </el-form>
       </div>
       <el-table :data="tableData" style="width: 100%" @selection-change="handleSelectionChange" row-key="id" v-loading="loading">
         <el-table-column type="selection" v-col="'selection'" width="55" align="center" />
-        <el-table-column prop="name" v-col="'name'" label="模板名称" show-overflow-tooltip></el-table-column>
-        <el-table-column prop="code" v-col="'code'" label="模板编码" align="center" show-overflow-tooltip></el-table-column>
-        <el-table-column prop="updatedAt" v-col="'updatedAt'" label="更新时间" align="center"></el-table-column>
-        <el-table-column prop="status" v-col="'status'" label="状态" align="center">
+        <el-table-column prop="name" v-col="'name'" :label="$t('message.projects.filter.index.table.columns.name')" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="code" v-col="'code'" :label="$t('message.projects.filter.index.table.columns.code')" align="center" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="updatedAt" v-col="'updatedAt'" :label="$t('message.projects.filter.index.table.columns.updatedAt')" align="center"></el-table-column>
+        <el-table-column prop="status" v-col="'status'" :label="$t('message.projects.filter.index.table.columns.status')" align="center">
           <template #default="scope">
-            <el-switch v-model="scope.row.status" inline-prompt :active-value="1" :inactive-value="0" active-text="启" inactive-text="禁" @change="handleStatusChange(scope.row)"> </el-switch>
+            <el-switch v-model="scope.row.status" inline-prompt :active-value="1" :inactive-value="0" :active-text="$t('message.projects.filter.index.switch.active')" :inactive-text="$t('message.projects.filter.index.switch.inactive')" @change="handleStatusChange(scope.row)"> </el-switch>
           </template>
         </el-table-column>
-        <el-table-column label="操作" width="220" align="center" fixed="right" v-col="'handle'">
+        <el-table-column :label="$t('message.projects.filter.index.table.columns.actions')" width="220" align="center" fixed="right" v-col="'handle'">
           <template #default="{ row }">
-            <el-button size="small" text type="primary" v-auth="'detail'" @click="$refs.detailRef?.show(row)">详情</el-button>
-            <el-button size="small" text type="warning" v-auth="'edit'" @click="addOrEdit(row)">编辑</el-button>
-            <el-button size="small" text type="danger" v-auth="'del'" @click="del(row)">删除</el-button>
-            <el-button size="small" text type="primary" v-auth="'viewbind'" @click="$refs.bindDeviceRef?.show(row)">查看及绑定设备</el-button>
+            <el-button size="small" text type="primary" v-auth="'detail'" @click="detailRef?.show(row)">{{ $t('message.projects.filter.index.table.actions.detail') }}</el-button>
+            <el-button size="small" text type="warning" v-auth="'edit'" @click="addOrEdit(row)">{{ $t('message.projects.filter.index.table.actions.edit') }}</el-button>
+            <el-button size="small" text type="danger" v-auth="'del'" @click="del(row)">{{ $t('message.projects.filter.index.table.actions.delete') }}</el-button>
+            <el-button size="small" text type="primary" v-auth="'viewbind'" @click="bindDeviceRef?.show(row)">{{ $t('message.projects.filter.index.table.actions.viewBind') }}</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -81,10 +81,13 @@ import EditForm from "./edit-dialog.vue";
 import detailVue from "./detail.vue";
 import bindDevice from "./bindDevice.vue";
 import { ref } from "vue";
+import { useI18n } from 'vue-i18n';
 
-const editFormRef = ref();
-const bindDeviceRef = ref();
-const detailRef = ref();
+const { t } = useI18n();
+
+const editFormRef = ref<any>();
+const bindDeviceRef = ref<any>();
+const detailRef = ref<any>();
 const ids = ref<number[]>([]);
 
 const { params, tableData, getList, loading, resetQuery } = useSearch<any[]>(api.template.list, "Data", { keyWord: "", deviceKey: "" });
@@ -106,29 +109,29 @@ const handleSelectionChange = (selections: any[]) => {
 };
 
 const del = (row?: any) => {
-  ElMessageBox.confirm(row ? `此操作将模板:“${row.name}”,是否继续?` : `此操作将${ids.value.length}个模板`, "提示", {
-    confirmButtonText: "确认",
-    cancelButtonText: "取消",
+  ElMessageBox.confirm(row ? t('message.projects.filter.index.messages.deleteConfirmSingle', { name: row.name }) : t('message.projects.filter.index.messages.deleteConfirmMultiple', { count: ids.value.length }), t('message.projects.filter.index.messages.tip'), {
+    confirmButtonText: t('message.projects.filter.index.messages.confirm'),
+    cancelButtonText: t('message.projects.filter.index.messages.cancel'),
     type: "warning",
   }).then(async () => {
     await api.template.del(row ? [row.id] : ids.value);
-    ElMessage.success("删除成功");
+    ElMessage.success(t('message.projects.filter.index.messages.deleteSuccess'));
     getList(1);
   });
 };
 
 const handleStatusChange = (row: any) => {
-  let text = row.status === 1 ? "启用" : "停用";
-  ElMessageBox.confirm("确认要" + text + "模板:【" + row.name + "】吗?", "警告", {
-    confirmButtonText: "确定",
-    cancelButtonText: "取消",
+  const text = row.status === 1 ? t('message.projects.filter.index.messages.enableActionText') : t('message.projects.filter.index.messages.disableActionText');
+  ElMessageBox.confirm(t('message.projects.filter.index.messages.statusChangeConfirm', { action: text, name: row.name }), t('message.projects.filter.index.messages.warn'), {
+    confirmButtonText: t('message.projects.filter.index.messages.confirm'),
+    cancelButtonText: t('message.projects.filter.index.messages.cancel'),
     type: "warning",
   })
     .then(function () {
       return api.template.editStatus({ id: row.id, status: row.status });
     })
     .then(() => {
-      ElMessage.success(text + "成功");
+      ElMessage.success(t('message.projects.filter.index.messages.statusChangeSuccess', { action: text }));
     })
     .catch(function () {
       row.status = row.status === 0 ? 1 : 0;

+ 61 - 56
src/views/iot/projects/list/edit.vue

@@ -1,90 +1,95 @@
 <template>
-  <el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="80px">
-    <el-form-item label="项目名称" prop="name">
-      <el-input v-model.trim="formData.name" placeholder="输入项目名称" />
+  <el-form ref="formRef" :model="formData" :rules="ruleForm" :label-width="store.state.themeConfig.themeConfig.globalI18n === 'en' ? '170px' : '100px'">
+    <el-form-item :label="$t('message.projects.list.addOrEdit.form.name')" prop="name">
+      <el-input v-model.trim="formData.name" :placeholder="$t('message.projects.list.addOrEdit.placeholders.name')" />
     </el-form-item>
-    <el-form-item label="地区" prop="addressCode">
-      <el-cascader :options="data" :props="{ emitPath: true, value: 'code', label: 'name' }" placeholder="请选择" clearable class="w100" v-model="formData.addressCode">
-      </el-cascader>
+    <el-form-item :label="$t('message.projects.list.addOrEdit.form.addressCode')" prop="addressCode">
+      <el-cascader :options="data" :props="{ emitPath: true, value: 'code', label: 'name' }" :placeholder="$t('message.projects.list.addOrEdit.placeholders.select')" clearable class="w100" v-model="formData.addressCode"> </el-cascader>
     </el-form-item>
-    <el-form-item label="详细地址" prop="addressDetail">
-      <el-input v-model.trim="formData.addressDetail" placeholder="输入详细地址" />
+    <el-form-item :label="$t('message.projects.list.addOrEdit.form.addressDetail')" prop="addressDetail">
+      <el-input v-model.trim="formData.addressDetail" :placeholder="$t('message.projects.list.addOrEdit.placeholders.addressDetail')" />
     </el-form-item>
-    <el-form-item label="渠道商" prop="channelMerchants">
-      <el-input v-model.trim="formData.channelMerchants" placeholder="输入渠道商" />
+    <el-form-item :label="$t('message.projects.list.addOrEdit.form.channelMerchants')" prop="channelMerchants">
+      <el-input v-model.trim="formData.channelMerchants" :placeholder="$t('message.projects.list.addOrEdit.placeholders.channelMerchants')" />
     </el-form-item>
-    <el-form-item label="关键客户" prop="customName">
-      <el-input v-model.trim="formData.customName" placeholder="输入客户名称" />
+    <el-form-item :label="$t('message.projects.list.addOrEdit.form.customName')" prop="customName">
+      <el-input v-model.trim="formData.customName" :placeholder="$t('message.projects.list.addOrEdit.placeholders.customName')" />
     </el-form-item>
-    <el-form-item label="维修公司" prop="repairCompany">
-      <el-input v-model.trim="formData.repairCompany" placeholder="输入维修公司" />
+    <el-form-item :label="$t('message.projects.list.addOrEdit.form.repairCompany')" prop="repairCompany">
+      <el-input v-model.trim="formData.repairCompany" :placeholder="$t('message.projects.list.addOrEdit.placeholders.repairCompany')" />
     </el-form-item>
-    <el-form-item label="维修电话" prop="repairMobile">
-      <el-input v-model.trim="formData.repairMobile" placeholder="输入维修电话" />
+    <el-form-item :label="$t('message.projects.list.addOrEdit.form.repairMobile')" prop="repairMobile">
+      <el-input v-model.trim="formData.repairMobile" :placeholder="$t('message.projects.list.addOrEdit.placeholders.repairMobile')" />
     </el-form-item>
     <el-form-item label="" prop="">
-      <el-button @click="cancel">取消</el-button>
-      <el-button type="primary" @click="onSubmit">确定</el-button>
+      <el-button @click="cancel">{{ $t("message.projects.list.addOrEdit.buttons.cancel") }}</el-button>
+      <el-button type="primary" @click="onSubmit">{{ $t("message.projects.list.addOrEdit.buttons.confirm") }}</el-button>
     </el-form-item>
   </el-form>
 </template>
 
 <script lang="ts" setup>
-import { ref, reactive, nextTick } from 'vue';
-import api from '/@/api/projects';
-import { ruleRequired } from '/@/utils/validator';
-import { ElMessage } from 'element-plus';
-import data from 'province-city-china/dist/level.json'
+import { ref, reactive, nextTick, computed } from "vue";
+import api from "/@/api/projects";
+import { ruleRequired } from "/@/utils/validator";
+import { ElMessage } from "element-plus";
+import data from "province-city-china/dist/level.json";
+import { useI18n } from "vue-i18n";
+import { useStore } from "/@/store/index";
 
-const emit = defineEmits(['getList', 'cancel']);
+const store = useStore();
+
+const emit = defineEmits(["getList", "cancel"]);
 
 const showDialog = ref(false);
 const formRef = ref();
+const { t } = useI18n();
 
 // 从省市区的的树形结构中获取省市区名称
 function getNames(code: string) {
-  const provinceItem = data.find((item: any) => item.province === code.substring(0, 2))
-  const provinceName = provinceItem.name
-  const cityItem = provinceItem.children.find((item: any) => item.city === code.substring(2, 4))
-  const cityName = cityItem.name
+  const provinceItem = data.find((item: any) => item.province === code.substring(0, 2));
+  const provinceName = provinceItem.name;
+  const cityItem = provinceItem.children.find((item: any) => item.city === code.substring(2, 4));
+  const cityName = cityItem.name;
 
   if (!cityItem.children) {
-    const areaItem = provinceItem.children.find((item: any) => item.area === code.substring(4, 6))
-    const areaName = areaItem.name
-    return `${provinceName}/${areaName}`
-
+    const areaItem = provinceItem.children.find((item: any) => item.area === code.substring(4, 6));
+    const areaName = areaItem.name;
+    return `${provinceName}/${areaName}`;
   } else {
-    const areaItem = cityItem.children.find((item: any) => item.area === code.substring(4, 6))
-    const areaName = areaItem.name
-    return `${provinceName}/${cityName}/${areaName}`
+    const areaItem = cityItem.children.find((item: any) => item.area === code.substring(4, 6));
+    const areaName = areaItem.name;
+    return `${provinceName}/${cityName}/${areaName}`;
   }
 }
 
 const baseForm = {
   id: undefined,
-  address: '',
+  address: "",
   addressCode: [],
-  name: '',
-  addressDetail: '',
-  channelMerchants: '',
-  customName: '',
-  repairCompany: '',
-  repairMobile: '',
+  name: "",
+  addressDetail: "",
+  channelMerchants: "",
+  customName: "",
+  repairCompany: "",
+  repairMobile: "",
 };
 
 const formData = reactive({
   ...baseForm,
 });
 
-const ruleForm = {
-  name: [ruleRequired('不能为空')],
-  addressCode: [ruleRequired('不能为空')],
-  addressDetail: [ruleRequired('不能为空')],
-  channelMerchants: [ruleRequired('不能为空')],
-  customName: [ruleRequired('不能为空')],
-  repairCompany: [ruleRequired('不能为空')],
-  repairMobile: [ruleRequired('不能为空')],
-};
+const ruleForm = computed(() => {
+  return {
+    name: [ruleRequired(t("message.projects.list.addOrEdit.validation.name"))],
+    addressCode: [ruleRequired(t("message.projects.list.addOrEdit.validation.addressCode"))],
+    addressDetail: [ruleRequired(t("message.projects.list.addOrEdit.validation.addressDetail"))],
+    channelMerchants: [ruleRequired(t("message.projects.list.addOrEdit.validation.channelMerchants"))],
+    customName: [ruleRequired(t("message.projects.list.addOrEdit.validation.customName"))],
+    repairCompany: [ruleRequired(t("message.projects.list.addOrEdit.validation.repairCompany"))],
+    repairMobile: [ruleRequired(t("message.projects.list.addOrEdit.validation.repairMobile"))],
+  };
+});
 
 const onSubmit = async () => {
   await formRef.value.validate();
@@ -92,17 +97,17 @@ const onSubmit = async () => {
   const { addressCode } = formData;
   formData.address = JSON.stringify({
     name: getNames(addressCode[2] || addressCode[1]),
-    code: addressCode
-  })
+    code: addressCode,
+  });
 
   const theApi = formData.id ? api.edit : api.add;
 
   await theApi(formData);
 
-  ElMessage.success('操作成功');
+  ElMessage.success(t(`message.projects.list.addOrEdit.messages.${formData.id ? "editSuccess" : "addSuccess"}`));
   // resetForm();
   showDialog.value = false;
-  emit('getList');
+  emit("getList");
 };
 
 const resetForm = async () => {
@@ -111,7 +116,7 @@ const resetForm = async () => {
 };
 
 const cancel = () => {
-  emit('cancel');
+  emit("cancel");
 };
 
 const open = async (row?: any) => {