Переглянути джерело

feat: 完善数据源管理页面多语言处理

yanglzh 1 місяць тому
батько
коміт
145e0cd70e

+ 10 - 3
src/i18n/index.ts

@@ -42,6 +42,10 @@ import pagesPropertyZhcn from './pages/property/zh-cn';
 import pagesPropertyEn from './pages/property/en';
 import pagesPropertyZhtw from './pages/property/zh-tw';
 
+import pagesDateCenterZhcn from './pages/dateCenter/zh-cn';
+import pagesDateCenterEn from './pages/dateCenter/en';
+import pagesDateCenterZhtw from './pages/dateCenter/zh-tw';
+
 // 定义语言国际化内容
 /**
  * 说明:
@@ -59,7 +63,8 @@ const messages = {
 			...pagesIotmanagerZhcn,
 			iotCard: pagesIotcardZhcn,
 			projects: pagesProjectsZhcn,
-			property: pagesPropertyZhcn
+			property: pagesPropertyZhcn,
+			dateCenter: pagesDateCenterZhcn
 		}
 	},
 	[enLocale.name]: {
@@ -72,7 +77,8 @@ const messages = {
 			...pagesIotmanagerEn,
 			iotCard: pagesIotcardEn,
 			projects: pagesProjectsEn,
-			property: pagesPropertyEn
+			property: pagesPropertyEn,
+			dateCenter: pagesDateCenterEn
 		},	
 	},
 	[zhtwLocale.name]: {
@@ -85,7 +91,8 @@ const messages = {
 			...pagesIotmanagerZhtw,
 			iotCard: pagesIotcardZhtw,
 			projects: pagesProjectsZhtw,
-			property: pagesPropertyZhtw
+			property: pagesPropertyZhtw,
+			dateCenter: pagesDateCenterZhtw
 		},
 	},
 };

+ 2 - 0
src/i18n/pages/dateCenter/en.ts

@@ -72,6 +72,8 @@ export default {
     db: 'Database',
     file: 'File',
     device: 'Device',
+    yes: 'Yes',
+    no: 'No',
   },
   messages: {
     opSuccess: 'Operation succeeded',

+ 2 - 0
src/i18n/pages/dateCenter/zh-cn.ts

@@ -72,6 +72,8 @@ export default {
     db: '数据库',
     file: '文件',
     device: '设备',
+    yes: '是',
+    no: '否',
   },
   messages: {
     opSuccess: '操作成功',

+ 2 - 0
src/i18n/pages/dateCenter/zh-tw.ts

@@ -72,6 +72,8 @@ export default {
     db: '資料庫',
     file: '檔案',
     device: '設備',
+    yes: '是',
+    no: '否',
   },
   messages: {
     opSuccess: '操作成功',

+ 106 - 101
src/views/system/datahub/source/component/edit.vue

@@ -2,46 +2,46 @@
 	<el-dialog
 		class="api-edit"
 		v-model="showDialog"
-		:title="`${formData.sourceId ? '编辑数据源' : '新增数据源'}`"
+		:title="`${formData.sourceId ? t('message.dateCenter.actions.edit') : t('message.dateCenter.actions.createSource')}`"
 		width="800px"
 		:close-on-click-modal="false"
 		:close-on-press-escape="false"
 	>
-		<el-form class="inline-form" ref="formRef" :model="formData" :rules="ruleForm" label-width="120px">
-			<el-form-item label="数据源标识" prop="key">
-				<el-input v-model="formData.key" placeholder="请输入数据源名称" :disabled="formData.sourceId" />
+		<el-form class="inline-form" ref="formRef" :model="formData" :rules="ruleForm" label-width="140px">
+			<el-form-item :label="t('message.dateCenter.labels.sourceKey')" prop="key">
+				<el-input v-model="formData.key" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.sourceKey')}`" :disabled="formData.sourceId" />
 			</el-form-item>
-			<el-form-item label="数据源名称" prop="name">
-				<el-input v-model="formData.name" placeholder="请输入数据源名称" />
+			<el-form-item :label="t('message.dateCenter.labels.sourceName')" prop="name">
+				<el-input v-model="formData.name" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.sourceName')}`" />
 			</el-form-item>
-			<el-form-item label="描述" prop="desc">
-				<el-input v-model="formData.desc" type="textarea" placeholder="请输入内容"></el-input>
+			<el-form-item :label="t('message.dateCenter.labels.sourceDesc')" prop="desc">
+				<el-input v-model="formData.desc" type="textarea" :placeholder="t('message.dateCenter.placeholders.input')"></el-input>
 			</el-form-item>
 
-			<el-form-item label="数据来源" prop="from" v-if="!formData.sourceId">
+			<el-form-item :label="t('message.dateCenter.labels.sourceFrom')" prop="from" v-if="!formData.sourceId">
 				<el-radio-group v-model="formData.from">
-					<el-radio :label="1">api导入</el-radio>
-					<el-radio :label="4">设备或产品</el-radio>
-					<el-radio :label="2">数据库</el-radio>
+					<el-radio :label="1">{{ t('message.dateCenter.options.api') }}</el-radio>
+					<el-radio :label="4">{{ t('message.dateCenter.options.device') }}</el-radio>
+					<el-radio :label="2">{{ t('message.dateCenter.options.db') }}</el-radio>
 				</el-radio-group>
 			</el-form-item>
-			<el-divider content-position="left">数据源配置</el-divider>
+			<el-divider content-position="left">{{ t('message.dateCenter.tabs.sourceConfig') }}</el-divider>
 
 			<div v-if="formData.from == 1">
-				<el-form-item label="请求方法" prop="config.method">
-					<el-select v-model="formData.config.method" :rules="ruleForm['config.method']" placeholder="请选择请求方法">
+				<el-form-item :label="t('message.dateCenter.labels.method')" prop="config.method">
+					<el-select v-model="formData.config.method" :rules="ruleForm['config.method']" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.method')}`">
 						<el-option v-for="item in methodData" :key="item.value" :label="item.label" :value="item.value" />
 					</el-select>
 				</el-form-item>
 
-				<el-form-item label="请求地址" prop="config.url">
-					<el-input v-model="formData.config.url" placeholder="请输入请求地址" :rules="ruleForm['config.url']" />
+				<el-form-item :label="t('message.dateCenter.labels.url')" prop="config.url">
+					<el-input v-model="formData.config.url" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.url')}`" :rules="ruleForm['config.url']" />
 				</el-form-item>
 
-				<el-form-item label="定时请求" prop="config.cronExpression">
+				<el-form-item :label="t('message.dateCenter.labels.interval')" prop="config.cronExpression">
 					<div style="display: flex">
-						<el-input v-model="formData.config.cronExpression" placeholder="请输入cron表达式" :rules="ruleForm['config.cronExpression']" />
-						<el-button type="success" @click="showCron('config')" style="margin-left: 5px">设置</el-button>
+						<el-input v-model="formData.config.cronExpression" :placeholder="`${t('message.dateCenter.placeholders.input')} cron`" :rules="ruleForm['config.cronExpression']" />
+						<el-button type="success" @click="showCron('config')" style="margin-left: 5px">{{ t('message.dateCenter.actions.edit') }}</el-button>
 					</div>
 				</el-form-item>
 
@@ -59,42 +59,43 @@
 							</div>
 
 							<div style="display: flex">
-								<el-divider content-position="left">请求参数</el-divider>
+								<el-divider content-position="left">{{ t('message.dateCenter.tabs.reqParams') }}</el-divider>
 							</div>
 							<div class="content-f" v-for="(aaa, bbb) in item" :key="bbb">
-								<el-select v-model="aaa.type" placeholder="参数类型" style="width: 320px">
+								<el-select v-model="aaa.type" :placeholder="t('message.dateCenter.labels.paramType')" style="width: 320px">
 									<el-option v-for="item in paramData" :key="item.value" :label="item.label" :value="item.value" />
 								</el-select>
-								<el-input v-model="aaa.name" placeholder="请输入参数标题" style="width: 320px" />
-								<el-input v-model="aaa.key" placeholder="请输入参标识" style="width: 320px" />
-								<el-input v-model="aaa.value" placeholder="请输入参数值" style="width: 320px" />
+								<el-input v-model="aaa.name" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.paramTitle')}`" style="width: 320px" />
+								<el-input v-model="aaa.key" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.paramKey')}`" style="width: 320px" />
+								<el-input v-model="aaa.value" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.paramValue')}`" style="width: 320px" />
 								<div class="conicon">
 									<el-icon @click="delParamss(index, bbb)">
 										<Delete />
 									</el-icon>
 								</div>
 							</div>
-							<el-button type="primary" class="addbutton" @click="addParams(index)">增加</el-button>
+							<el-button type="primary" class="addbutton" @click="addParams(index)">{{ t('message.dateCenter.actions.add') }}</el-button>
 							<div style=""></div>
 						</div>
 					</div>
 				</div>
-				<el-button type="success" class="addbutton" @click="addParamss">增加分组</el-button>
+				<el-button type="success" class="addbutton" @click="addParamss">{{ t('message.dateCenter.actions.add') }}</el-button>
 			</div>
 			<div v-if="formData.from == 4">
-				<el-form-item label="设备或产品">
+				<el-form-item :label="t('message.dateCenter.labels.sourceFrom')">
 					<el-radio-group v-model="deviceOrProduct" @change=";(formData.devconfig.productKey = ''), (formData.devconfig.deviceKey = '')">
-						<el-radio label="device">设备</el-radio>
-						<el-radio label="product">产品</el-radio>
+						<el-radio label="device">{{ t('message.dateCenter.options.device') }}</el-radio>
+						<el-radio label="product">{{ t('message.dateCenter.labels.productKey') }}</el-radio>
 					</el-radio-group>
 				</el-form-item>
-				<el-form-item label="选择设备" v-if="deviceOrProduct == 'device'" prop="devconfig.deviceKey">
+				<el-form-item :label="t('message.dateCenter.labels.deviceKey')" v-if="deviceOrProduct == 'device'" prop="devconfig.deviceKey">
 					<el-select
 						v-model="formData.devconfig.deviceKey"
 						:rules="ruleForm['devconfig.deviceKey']"
 						filterable
-						placeholder="请选择设备"
+						:placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.deviceKey')}`"
 						@change="formData.devconfig.productKey = ''"
+						style="width: 100%"
 					>
 						<el-option v-for="item in sourceData" :key="item.key" :label="item.name" :value="item.key">
 							<span style="float: left">{{ item.name }}</span>
@@ -102,13 +103,14 @@
 						</el-option>
 					</el-select>
 				</el-form-item>
-				<el-form-item label="选择产品" v-if="deviceOrProduct == 'product'" prop="devconfig.productKey">
+				<el-form-item :label="t('message.dateCenter.labels.productKey')" v-if="deviceOrProduct == 'product'" prop="devconfig.productKey">
 					<el-select
 						v-model="formData.devconfig.productKey"
 						:rules="ruleForm['devconfig.productKey']"
 						filterable
-						placeholder="请选择产品"
+						:placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.productKey')}`"
 						@change="formData.devconfig.deviceKey = ''"
+						style="width: 100%"
 					>
 						<el-option v-for="item in producList" :key="item.key" :label="item.name" :value="item.key">
 							<span style="float: left">{{ item.name }}</span>
@@ -119,7 +121,7 @@
 			</div>
 
 			<div v-if="formData.from == 2">
-				<el-form-item label="数据来源" prop="tabconfig.type">
+				<el-form-item :label="t('message.dateCenter.labels.dbType')" prop="tabconfig.type">
 					<el-radio-group v-model="formData.tabconfig.type" :rules="ruleForm['tabconfig.type']">
 						<el-radio label="mysql">mysql</el-radio>
 						<el-radio label="mssql">mssql</el-radio>
@@ -127,31 +129,31 @@
 				</el-form-item>
 
 				<div class="inline">
-					<el-form-item label="主机地址" prop="tabconfig.host">
-						<el-input v-model="formData.tabconfig.host" placeholder="请输入主机地址" :rules="ruleForm['tabconfig.host']" />
+					<el-form-item :label="t('message.dateCenter.labels.host')" prop="tabconfig.host">
+						<el-input v-model="formData.tabconfig.host" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.host')}`" :rules="ruleForm['tabconfig.host']" />
 					</el-form-item>
 
-					<el-form-item label="端口号" prop="tabconfig.port">
-						<el-input v-model="formData.tabconfig.port" placeholder="请输入端口号" :rules="ruleForm['tabconfig.port']" />
+					<el-form-item :label="t('message.dateCenter.labels.port')" prop="tabconfig.port">
+						<el-input v-model="formData.tabconfig.port" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.port')}`" :rules="ruleForm['tabconfig.port']" />
 					</el-form-item>
 				</div>
 				<div class="inline">
-					<el-form-item label="用户名" prop="tabconfig.user">
-						<el-input v-model="formData.tabconfig.user" placeholder="请输入用户名" :rules="ruleForm['tabconfig.user']" />
+					<el-form-item :label="t('message.dateCenter.labels.user')" prop="tabconfig.user">
+						<el-input v-model="formData.tabconfig.user" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.user')}`" :rules="ruleForm['tabconfig.user']" />
 					</el-form-item>
 
-					<el-form-item label="密码" prop="tabconfig.passwd">
-						<el-input v-model="formData.tabconfig.passwd" placeholder="请输入密码" :rules="ruleForm['tabconfig.passwd']" />
+					<el-form-item :label="t('message.dateCenter.labels.password')" prop="tabconfig.passwd">
+						<el-input v-model="formData.tabconfig.passwd" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.password')}`" :rules="ruleForm['tabconfig.passwd']" />
 					</el-form-item>
 				</div>
 
-				<el-form-item label="数据库名称" prop="tabconfig.dbName">
-					<el-input v-model="formData.tabconfig.dbName" placeholder="请输入数据库名称" :rules="ruleForm['tabconfig.dbName']" />
+				<el-form-item :label="t('message.dateCenter.labels.dbName')" prop="tabconfig.dbName">
+					<el-input v-model="formData.tabconfig.dbName" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.dbName')}`" :rules="ruleForm['tabconfig.dbName']" />
 				</el-form-item>
 
-				<el-form-item label="执行方式" prop="tabconfig.queryType">
+				<el-form-item :label="t('message.dateCenter.labels.expression')" prop="tabconfig.queryType">
 					<el-radio-group v-model="formData.tabconfig.queryType" :rules="ruleForm['tabconfig.queryType']">
-						<el-radio label="tableName">数据表</el-radio>
+						<el-radio label="tableName">{{ t('message.dateCenter.columns.value') }}</el-radio>
 						<el-radio label="sql">Sql</el-radio>
 					</el-radio-group>
 				</el-form-item>
@@ -160,22 +162,22 @@
 					<el-input
 						v-model="formData.tabconfig.tableName"
 						type="textarea"
-						:placeholder="formData.tabconfig.queryType == 'sql' ? '请输入sql语句' : '请输入表名称'"
+						:placeholder="formData.tabconfig.queryType == 'sql' ? `${t('message.dateCenter.placeholders.input')} sql` : `${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.tableName')}`"
 					/>
 				</el-form-item>
 
-				<el-form-item label="主键字段" prop="tabconfig.pk">
-					<el-input v-model="formData.tabconfig.pk" placeholder="请输入主键字段" :rules="ruleForm['tabconfig.pk']" />
+				<el-form-item :label="t('message.dateCenter.labels.pk')" prop="tabconfig.pk">
+					<el-input v-model="formData.tabconfig.pk" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.pk')}`" :rules="ruleForm['tabconfig.pk']" />
 				</el-form-item>
 
-				<el-form-item label="每次获取数量" prop="tabconfig.num">
-					<el-input v-model="formData.tabconfig.num" placeholder="请输入每次获取数量" :rules="ruleForm['tabconfig.num']" />
+				<el-form-item :label="t('message.dateCenter.labels.num')" prop="tabconfig.num">
+					<el-input v-model="formData.tabconfig.num" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.num')}`" :rules="ruleForm['tabconfig.num']" />
 				</el-form-item>
 
-				<el-form-item label="任务表达式" prop="tabconfig.cronExpression">
+				<el-form-item :label="t('message.dateCenter.labels.cronExpression')" prop="tabconfig.cronExpression">
 					<div style="display: flex">
-						<el-input v-model="formData.tabconfig.cronExpression" placeholder="请输入cron任务表达式" :rules="ruleForm['tabconfig.cronExpression']" />
-						<el-button type="success" @click="showCron('tabconfig')" style="margin-left: 5px">设置</el-button>
+						<el-input v-model="formData.tabconfig.cronExpression" :placeholder="`${t('message.dateCenter.placeholders.input')} cron`" :rules="ruleForm['tabconfig.cronExpression']" />
+						<el-button type="success" @click="showCron('tabconfig')" style="margin-left: 5px">{{ t('message.dateCenter.actions.edit') }}</el-button>
 					</div>
 				</el-form-item>
 			</div>
@@ -183,30 +185,31 @@
 
 		<template #footer>
 			<div class="dialog-footer">
-				<el-button @click="onTest" type="warning" v-if="sourceId > 0">测试</el-button>
+				<el-button @click="onTest" type="warning" v-if="sourceId > 0">{{ t('message.dateCenter.actions.search') }}</el-button>
 
-				<el-button @click="showDialog = false">取消</el-button>
-				<el-button type="primary" @click="onSubmit">确定</el-button>
+				<el-button @click="showDialog = false">{{ t('message.dateCenter.messages.cancel') }}</el-button>
+				<el-button type="primary" @click="onSubmit">{{ t('message.dateCenter.messages.confirm') }}</el-button>
 			</div>
 		</template>
 	</el-dialog>
-	<el-dialog v-model="dialogVisible" title="返回Json数据" width="30%">
+	<el-dialog v-model="dialogVisible" :title="'Json'" width="30%">
 		<JsonViewer :value="jsonData" boxed sort theme="jv-dark" @click="onKeyclick" />
 
 		<template #footer>
 			<span class="dialog-footer">
-				<el-button @click="dialogVisible = false">关闭</el-button>
+				<el-button @click="dialogVisible = false">{{ t('message.dateCenter.messages.cancel') }}</el-button>
 			</span>
 		</template>
 	</el-dialog>
 
-	<el-dialog v-model="cronShow" title="选择Cron规则" width="60%">
+	<el-dialog v-model="cronShow" :title="'Cron'" width="60%">
 		<vue3cron @handlelisten="handlelisten" :type="crontype" @close="cronclose"></vue3cron>
 	</el-dialog>
 </template>
 
 <script lang="ts" setup>
-import { ref, reactive, nextTick } from 'vue'
+import { ref, reactive, nextTick, computed } from 'vue'
+import { useI18n } from 'vue-i18n'
 import api from '/@/api/datahub'
 import deviceApi from '/@/api/device'
 import { ruleRequired } from '/@/utils/validator'
@@ -219,14 +222,15 @@ import { Delete, CircleClose } from '@element-plus/icons-vue'
 const emit = defineEmits(['typeList'])
 
 const showDialog = ref(false)
+const { t } = useI18n()
 const deviceOrProduct = ref('device')
 const dialogVisible = ref(false)
 const cronShow = ref(false)
 const formRef = ref()
 const jsonData = ref()
 const crontype = ref()
-const sourceData = ref([])
-const producList = ref([])
+const sourceData = ref<Array<{ key: string; name: string }>>([])
+const producList = ref<Array<{ key: string; name: string }>>([])
 const sourceId = ref()
 const methodData = ref([
 	{
@@ -241,15 +245,15 @@ const methodData = ref([
 
 const paramData = ref([
 	{
-		lable: 'header',
+		label: 'header',
 		value: 'header',
 	},
 	{
-		lable: 'body',
+		label: 'body',
 		value: 'body',
 	},
 	{
-		lable: 'param',
+		label: 'param',
 		value: 'param',
 	},
 ])
@@ -354,40 +358,41 @@ const formData = reactive({
 	...baseForm,
 })
 
-const ruleForm = {
-	key: [ruleRequired('数据源标识不能为空')],
-	name: [ruleRequired('数据源名称不能为空')],
-	from: [ruleRequired('数据源类型不能为空')],
-
-	'config.method': [
-		{ required: true, message: '请求方法不能为空', trigger: 'change' },
-		{
-			validator: (rule: any, value: string, callback: any) => {
-				if (formData.from === 1 && !formData.config.method) {
-					callback(new Error('请求方法不能为空'))
-				} else {
-					callback()
-				}
+const ruleForm = computed(() => {
+	return {
+		key: [ruleRequired(`${t('message.dateCenter.labels.sourceKey')}${t('message.dateCenter.placeholders.input')}`)],
+		name: [ruleRequired(`${t('message.dateCenter.labels.sourceName')}${t('message.dateCenter.placeholders.input')}`)],
+		from: [ruleRequired(`${t('message.dateCenter.labels.sourceFrom')}${t('message.dateCenter.placeholders.input')}`)],
+		'config.method': [
+			{ required: true, message: `${t('message.dateCenter.labels.method')}${t('message.dateCenter.placeholders.input')}` , trigger: 'change' },
+			{
+				validator: (rule: any, value: string, callback: any) => {
+					if (formData.from === 1 && !formData.config.method) {
+						callback(new Error(`${t('message.dateCenter.labels.method')}${t('message.dateCenter.placeholders.input')}`))
+					} else {
+						callback()
+					}
+				},
+				trigger: 'change',
 			},
-			trigger: 'change',
-		},
-	],
-	'config.url': [ruleRequired('请求地址不能为空')],
-	'config.cronExpression': [ruleRequired('定时请求不能为空')],
-	'devconfig.deviceKey': [ruleRequired('请选择设备')],
-	'devconfig.productKey': [ruleRequired('请选择产品')],
-	'tabconfig.type': [ruleRequired('请选择数据来源')],
-	'tabconfig.host': [ruleRequired('请输入主机地址')],
-	'tabconfig.port': [ruleRequired('请输入端口号')],
-	'tabconfig.user': [ruleRequired('请输入用户名')],
-	'tabconfig.passwd': [ruleRequired('请输入密码')],
-	'tabconfig.dbName': [ruleRequired('请输入数据库名称')],
-	'tabconfig.queryType': [ruleRequired('请选择执行方式')],
-	'tabconfig.tableName': [ruleRequired('该项不能为空')],
-	'tabconfig.pk': [ruleRequired('请输入主键字段')],
-	'tabconfig.num': [ruleRequired('请输入每次获取数量')],
-	'tabconfig.cronExpression': [ruleRequired('请输入cron任务表达式')],
-}
+		],
+		'config.url': [ruleRequired(`${t('message.dateCenter.labels.url')}${t('message.dateCenter.placeholders.input')}`)],
+		'config.cronExpression': [ruleRequired(`${t('message.dateCenter.labels.interval')}${t('message.dateCenter.placeholders.input')}`)],
+		'devconfig.deviceKey': [ruleRequired(`${t('message.dateCenter.labels.deviceKey')}${t('message.dateCenter.placeholders.input')}`)],
+		'devconfig.productKey': [ruleRequired(`${t('message.dateCenter.labels.productKey')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.type': [ruleRequired(`${t('message.dateCenter.labels.dbType')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.host': [ruleRequired(`${t('message.dateCenter.labels.host')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.port': [ruleRequired(`${t('message.dateCenter.labels.port')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.user': [ruleRequired(`${t('message.dateCenter.labels.user')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.passwd': [ruleRequired(`${t('message.dateCenter.labels.password')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.dbName': [ruleRequired(`${t('message.dateCenter.labels.dbName')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.queryType': [ruleRequired(`${t('message.dateCenter.labels.expression')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.tableName': [ruleRequired(`${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.pk': [ruleRequired(`${t('message.dateCenter.labels.pk')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.num': [ruleRequired(`${t('message.dateCenter.labels.num')}${t('message.dateCenter.placeholders.input')}`)],
+		'tabconfig.cronExpression': [ruleRequired(`${t('message.dateCenter.labels.cronExpression')}${t('message.dateCenter.placeholders.input')}`)],
+	}
+})
 const getDevData = () => {
 	api.common.getdevList({}).then((res: any) => {
 		sourceData.value = res.device
@@ -414,7 +419,7 @@ const onSubmit = async () => {
 		}
 		const theApi = sourceId.value ? api.common.edit : api.common.add
 		await theApi(form)
-		ElMessage.success('操作成功')
+		ElMessage.success(t('message.dateCenter.messages.opSuccess'))
 		resetForm()
 		showDialog.value = false
 		emit('typeList')

+ 446 - 439
src/views/system/datahub/source/component/editNode.vue

@@ -1,96 +1,97 @@
 <template>
-	<div class="system-edit-dic-container">
-		<el-dialog :title="(ruleForm.nodeId !== 0 ? '修改' : '添加') + '数据节点'" v-model="isShowDialog" width="769px">
-			<el-form :model="ruleForm" ref="formRef" :rules="rules" label-width="110px">
-				<el-form-item label="数据节点标识" prop="key">
-					<el-input v-model="ruleForm.key" placeholder="请输入数据节点名称" :disabled="detail.lockKey == 1 && ruleForm.nodeId !== 0" />
-				</el-form-item>
-				<el-form-item label="数据节点名称" prop="name">
-					<el-input v-model="ruleForm.name" placeholder="请输入数据节点名称" />
-				</el-form-item>
-
-				<el-form-item label="是否主键" prop="isPk">
-					<el-radio-group v-model="ruleForm.isPk">
-						<el-radio :label="0">否</el-radio>
-						<el-radio :label="1">是</el-radio>
-					</el-radio-group>
-				</el-form-item>
-
-				<el-form-item label="数据类型" prop="dataType" v-if="detail.from == 1 || detail.from == 2">
-					<el-select v-model="ruleForm.dataType" filterable placeholder="请选择数据类型">
-						<el-option v-for="item in tabData" :key="item.value" :label="item.label" :value="item.value" />
-					</el-select>
-				</el-form-item>
-
-				<el-form-item label="取值项" prop="value" v-if="detail.from == 1">
-					<el-input v-model="ruleForm.value" placeholder="请输入取值项" class="w-35" /><el-button type="success" @click="onTest">选择值</el-button>
-				</el-form-item>
-
-
-				<el-form-item label="取值项" prop="value" v-if="detail.from == 4">
-					<el-select v-model="ruleForm.value" filterable placeholder="请选择数取值项" @change="getNodeList">
-						<el-option v-for="item in propertyData" :key="item.key" :label="item.name" :value="item.key">
-							<span style="float: left">{{ item.key }}</span>
-							<span style="float: right; font-size: 13px">{{ item.name }}</span>
-						</el-option>
-					</el-select>
-				</el-form-item>
-
-
-				<el-form-item label="取值项" prop="value" v-if="detail.from == 2">
-					<el-select v-model="ruleForm.value" filterable placeholder="请选择数取值项" @change="getDbList">
-						<el-option v-for="item in dbData" :key="item.Name" :label="item.Comment" :value="item.Name">
-							<span style="float: left">{{ item.Name }}</span>
-							<span style="float: right; font-size: 13px">{{ item.Comment }}</span>
-						</el-option>
-					</el-select>
-				</el-form-item>
-
-
-
-				<el-divider content-position="left">规则表达式</el-divider>
-
-				<div v-for="(item, index) in rule" :key="index">
-					<el-form-item label="正则表达式">
-						<el-input v-model="item.expression" placeholder="请输入规则表达式" />
-					</el-form-item>
-
-					<el-form-item label="替换内容">
-						<el-input v-model="item.replace" placeholder="请输入替换内容" class="w-35" />
-						<!-- <el-input v-model="rule[index].params.name" placeholder="请输入键值" class="w-35" />
-						<el-input v-model="rule[index].params.value" placeholder="请输入值" class="w-35" /> -->
-						<div class="conicon">
-							<el-icon @click="delRule(index)" v-if="index > 0">
-								<Delete />
-							</el-icon>
-						</div>
-					</el-form-item>
-				</div>
-				<div style="padding: 10px">
-					<el-button type="primary" class="addbutton" @click="addRule">增加</el-button>
-				</div>
-			</el-form>
-			<template #footer>
-				<span class="dialog-footer">
-					<el-button @click="onCancel">取 消</el-button>
-					<el-button type="primary" @click="onSubmit">{{ ruleForm.nodeId !== 0 ? '修 改' : '添 加' }}</el-button>
-				</span>
-			</template>
-		</el-dialog>
-
-		<el-dialog v-model="dialogVisible" title="点击蓝色key值进行选择" width="40%">
-			<jsontree :data="jsonPathData" @handlePath="handlePath"></jsontree>
-			<template #footer>
-				<span class="dialog-footer">
-					<el-button @click="dialogVisible = false">关闭</el-button>
-				</span>
-			</template>
-		</el-dialog>
-	</div>
+    <div class="system-edit-dic-container">
+        <el-dialog :title="(ruleForm.nodeId !== 0 ? t('message.dateCenter.actions.edit') : t('message.dateCenter.actions.add')) + ' ' + t('message.dateCenter.tabs.nodes')" v-model="isShowDialog" width="769px">
+            <el-form :model="ruleForm" ref="formRef" :rules="rules" label-width="110px">
+                <el-form-item :label="t('message.dateCenter.columns.key')" prop="key">
+                    <el-input v-model="ruleForm.key" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.columns.key')}`" :disabled="detail.lockKey == 1 && ruleForm.nodeId !== 0" />
+                </el-form-item>
+                <el-form-item :label="t('message.dateCenter.columns.name')" prop="name">
+                    <el-input v-model="ruleForm.name" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.columns.name')}`" />
+                </el-form-item>
+
+                <el-form-item :label="t('message.dateCenter.labels.pk')" prop="isPk">
+                    <el-radio-group v-model="ruleForm.isPk">
+                        <el-radio :label="0">{{ t('message.dateCenter.options.no') }}</el-radio>
+                        <el-radio :label="1">{{ t('message.dateCenter.options.yes') }}</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+
+                <el-form-item :label="t('message.dateCenter.columns.dataType')" prop="dataType" v-if="detail.from == 1 || detail.from == 2">
+                    <el-select v-model="ruleForm.dataType" filterable :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.columns.dataType')}`">
+                        <el-option v-for="item in tabData" :key="item.value" :label="item.label" :value="item.value" />
+                    </el-select>
+                </el-form-item>
+
+                <el-form-item :label="t('message.dateCenter.columns.value')" prop="value" v-if="detail.from == 1">
+                    <el-input v-model="ruleForm.value" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.columns.value')}`" class="w-35" /><el-button type="success" @click="onTest">{{ t('message.dateCenter.actions.search') }}</el-button>
+                </el-form-item>
+
+
+                <el-form-item :label="t('message.dateCenter.columns.value')" prop="value" v-if="detail.from == 4">
+                    <el-select v-model="ruleForm.value" filterable :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.columns.value')}`" @change="getNodeList">
+                        <el-option v-for="item in propertyData" :key="item.key" :label="item.name" :value="item.key">
+                            <span style="float: left">{{ item.key }}</span>
+                            <span style="float: right; font-size: 13px">{{ item.name }}</span>
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+
+
+                <el-form-item :label="t('message.dateCenter.columns.value')" prop="value" v-if="detail.from == 2">
+                    <el-select v-model="ruleForm.value" filterable :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.columns.value')}`" @change="getDbList">
+                        <el-option v-for="item in dbData" :key="item.Name" :label="item.Comment" :value="item.Name">
+                            <span style="float: left">{{ item.Name }}</span>
+                            <span style="float: right; font-size: 13px">{{ item.Comment }}</span>
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+
+
+
+                <el-divider content-position="left">{{ t('message.dateCenter.tabs.ruleExpr') }}</el-divider>
+
+                <div v-for="(item, index) in rule" :key="index">
+                    <el-form-item :label="t('message.dateCenter.labels.expression')">
+                        <el-input v-model="item.expression" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.expression')}`" />
+                    </el-form-item>
+
+                    <el-form-item label="">
+                        <el-input v-model="item.replace" :placeholder="t('message.dateCenter.placeholders.input')" class="w-35" />
+                        <!-- <el-input v-model="rule[index].params.name" placeholder="请输入键值" class="w-35" />
+                        <el-input v-model="rule[index].params.value" placeholder="请输入值" class="w-35" /> -->
+                        <div class="conicon">
+                            <el-icon @click="delRule(index)" v-if="index > 0">
+                                <Delete />
+                            </el-icon>
+                        </div>
+                    </el-form-item>
+                </div>
+                <div style="padding: 10px">
+                    <el-button type="primary" class="addbutton" @click="addRule">{{ t('message.dateCenter.actions.add') }}</el-button>
+                </div>
+            </el-form>
+            <template #footer>
+                <span class="dialog-footer">
+                    <el-button @click="onCancel">{{ t('message.dateCenter.messages.cancel') }}</el-button>
+                    <el-button type="primary" @click="onSubmit">{{ t('message.dateCenter.messages.confirm') }}</el-button>
+                </span>
+            </template>
+        </el-dialog>
+
+        <el-dialog v-model="dialogVisible" :title="t('message.dateCenter.actions.search')" width="40%">
+            <jsontree :data="jsonPathData" @handlePath="handlePath"></jsontree>
+            <template #footer>
+                <span class="dialog-footer">
+                    <el-button @click="dialogVisible = false">{{ t('message.dateCenter.messages.cancel') }}</el-button>
+                </span>
+            </template>
+        </el-dialog>
+    </div>
 </template>
 
 <script lang="ts">
 import { reactive, toRefs, defineComponent, ref, unref } from 'vue';
+import { useI18n } from 'vue-i18n';
 import api from '/@/api/datahub';
 import 'vue3-json-viewer/dist/index.css';
 import jsontree from '/@/components/jsontree/index.vue';
@@ -98,363 +99,369 @@ import jsontree from '/@/components/jsontree/index.vue';
 import { ElMessage } from 'element-plus';
 import { Delete, } from '@element-plus/icons-vue';
 
+interface RuleItem {
+    expression: string;
+    replace: string;
+}
 interface RuleFormState {
-	nodeId: number;
-	name: string;
-	from: number;
-	isPk: number;
-	key: string;
-	dataType: string;
-	value: string;
-	description: string;
-	status: number;
+    nodeId: number;
+    name: string;
+    from: number;
+    isPk: number;
+    key: string;
+    dataType: string;
+    value: string;
+    description: string;
+    status?: number;
+    rule: RuleItem[] | string;
+    sourceId?: number;
 }
 interface DicState {
-	isShowDialog: boolean;
-	ruleForm: RuleFormState;
-	rules: {};
+    isShowDialog: boolean;
+    dialogVisible: boolean;
+    jsonPathData: any[];
+    jsonData: any;
+    propertyData: any[];
+    dbData: any[];
+    config: Record<string, any>;
+    detail: Record<string, any>;
+    tabData: Array<{ label: string; value: string }>;
+    ruledata: RuleItem[];
+    rule: RuleItem[];
+    ruleForm: RuleFormState;
+    rules: Record<string, any>;
 }
 
 export default defineComponent({
-	name: 'Edit',
-	components: { Delete, jsontree },
-
-	setup(prop, { emit }) {
-		const formRef = ref<HTMLElement | null>(null);
-		const state = reactive<DicState>({
-			isShowDialog: false,
-			dialogVisible: false,
-			jsonPathData: [],
-			jsonData: '',
-			propertyData: [],
-			dbData: [],
-			config: {},
-			detail: {},
-			tabData: [
-				{
-					label: 'int',
-					value: 'int',
-				},
-				{
-					label: 'long',
-					value: 'long',
-				},
-				{
-					label: 'float',
-					value: 'float',
-				},
-				{
-					label: 'double',
-					value: 'double',
-				},
-				{
-					label: 'string',
-					value: 'string',
-				},
-				{
-					label: 'boolean',
-					value: 'boolean',
-				},
-				{
-					label: 'date',
-					value: 'date',
-				},
-			],
-			ruledata: [
-				{
-					expression: '',
-					replace: '',
-					// params: {
-					// 	name: '',
-					// 	value: '',
-					// },
-				},
-			],
-			rule: [
-				{
-					expression: '',
-					replace: '',
-					// params: {
-					// 	name: '',
-					// 	value: '',
-					// },
-				},
-			],
-
-			ruleForm: {
-				nodeId: 0,
-				isPk: 0,
-				name: '',
-				key: '',
-				dataType: '',
-				value: '',
-				rule: [],
-
-				description: '',
-			},
-			rules: {
-				key: [{ required: true, message: '数据节点标识不能为空', trigger: 'blur' }],
-				name: [{ required: true, message: '数据节点名称不能为空', trigger: 'blur' }],
-				isPk: [{ required: true, message: '请选择是否主键', trigger: 'blur' }],
-				dataType: [{ required: true, message: '数据节点类型不能为空', trigger: 'blur' }],
-				value: [{ required: true, message: '数据节点取值项不能为空', trigger: 'blur' }],
-			},
-		});
-
-		const onTest = () => {
-			if (state.detail.from == 1) {
-				api.common.api(state.detail.sourceId).then((res: any) => {
-					state.jsonData = JSON.parse(res.data);
-
-					var jsonstr = jsonPath([], state.jsonData, '');
-					state.jsonPathData = jsonstr;
-					state.dialogVisible = true;
-				});
-			} else if (state.detail.from == 4) {
-				api.common.devapi(state.detail.sourceId).then((res: any) => {
-					state.jsonData = JSON.parse(res.data);
-
-					var jsonstr = jsonPath([], state.jsonData, '');
-					state.jsonPathData = jsonstr;
-					state.dialogVisible = true;
-				});
-			}
-		};
-
-		const handlePath = (path) => {
-			let data = path.slice(1);
-
-			state.ruleForm.value = data;
-			state.dialogVisible = false;
-		};
-
-		const delRule = (index) => {
-			state.rule.splice(index, 1);
-		};
-
-		const addRule = () => {
-			state.rule.push({
-				expression: '',
-				replace: '',
-				// params: {
-				// 	name: '',
-				// 	value: '',
-				// },
-			});
-		};
-		// 打开弹窗
-		const openDialog = (row: RuleFormState | null) => {
-			resetForm();
-
-			if (row?.nodeId) {
-				state.ruleForm = row;
-
-				var data = JSON.parse(row.rule);
-				data.forEach((item, index) => {
-					state.rule[index].expression = item.expression;
-					state.rule[index].replace = item.replace;
-					// state.rule[index].params.name = Object.keys(item.params);
-					// state.rule[index].params.value = item.params[Object.keys(item.params)];
-				});
-			}
-
-			api.common.detail(row.sourceId).then((res: any) => {
-				state.detail = res.data;
-				if (res.data.from == 4) {
-					//propertyData
-					api.node.getpropertyList({ productKey: res.data.deviceConfig.productKey }).then((re: any) => {
-						state.propertyData = re;
-					});
-				}
-				if (res.data.from == 2) {
-					//propertyData
-					api.common.getfields(row.sourceId).then((re: any) => {
-						state.dbData = re.data;
-					});
-				}
-			});
-
-			state.ruleForm = row;
-			state.isShowDialog = true;
-		};
-		const resetForm = () => {
-			state.ruleForm = {
-				nodeId: 0,
-				name: '',
-				isPk: 0,
-				from: 1,
-				key: '',
-				rule: [],
-
-				description: '',
-			};
-		};
-		// 关闭弹窗
-		const closeDialog = () => {
-			state.isShowDialog = false;
-		};
-		// 取消
-		const onCancel = () => {
-			closeDialog();
-		};
-		// 新增
-		const onSubmit = () => {
-			const formWrap = unref(formRef) as any;
-			if (!formWrap) return;
-			formWrap.validate((valid: boolean) => {
-				if (valid) {
-					//修改rule数据
-					// state.rule.forEach((item, index) => {
-					// 	item.params[item.params.name] = item.params.value;
-					// 	delete item.params.name;
-					// 	delete item.params.value;
-					// });
-
-					state.ruleForm.rule = state.rule;
-
-					if (state.ruleForm.nodeId !== 0) {
-						//修改
-						api.node.edit(state.ruleForm).then(() => {
-							ElMessage.success('数据节点类型修改成功');
-							closeDialog(); // 关闭弹窗
-							emit('typeList');
-						});
-					} else {
-						//添加
-
-						api.node.add(state.ruleForm).then(() => {
-							ElMessage.success('数据节点类型添加成功');
-							closeDialog(); // 关闭弹窗
-							emit('typeList');
-						});
-					}
-				}
-			});
-		};
-
-		const getNodeList = (e) => {
-			state.propertyData.forEach((item) => {
-				if (item.key === e) {
-					state.ruleForm.dataType = item.valueType.type;
-				}
-			});
-		};
-
-		const getDbList = (e) => {
-			state.ruleForm.dataType = state.dbData[e].Type;
-		}
-
-		const onKeyclick = () => {
-		};
-
-		const jsonPath = (arr, json, basePath) => {
-			// 生成jsonpath
-			const type = validateType(json);
-
-			if (type === 'object') {
-				for (let key in json) {
-					const item = {
-						key,
-						path: `${basePath}.${key}`,
-					};
-					const childType = validateType(json[key]);
-					item.type = childType;
-					if (childType === 'object' || childType === 'array') {
-						item.leaf = true;
-						item.children = [];
-						jsonPath(item.children, json[key], item.path);
-					} else {
-						item.leaf = false;
-						item.value = json[key];
-					}
-					arr.push(item);
-				}
-			} else if (type === 'array') {
-				json.forEach((item, index) => {
-					const childType = validateType(item);
-					const obj = {
-						key: index,
-					};
-					obj.type = childType;
-					obj.path = `${basePath}.${index}`;
-					if (childType === 'object' || childType === 'array') {
-						(obj.leaf = true), (obj.children = []);
-						jsonPath(obj.children, item, obj.path);
-					} else {
-						obj.value = item;
-						obj.leaf = false;
-					}
-					arr.push(obj);
-				});
-			}
-
-			return arr;
-		};
-
-		// 校验JSON数据类型
-		const validateType = (val) => {
-			let type = typeof val;
-			if (type === 'object') {
-				if (Array.isArray(val)) {
-					return 'array';
-				} else if (val === null) {
-					return 'null';
-				} else {
-					return 'object';
-				}
-			} else {
-				switch (type) {
-					case 'boolean':
-						return 'boolean';
-					case 'string':
-						return 'string';
-					case 'number':
-						return 'number';
-					default:
-						return 'error';
-				}
-			}
-		};
-
-		const getOrgIdArr = (parents, childNode, treeData) => {
-			for (var key in treeData) {
-				// 父节点查询条件
-				if (key === childNode) {
-					// 如果找到结果,保存当前节点
-					parents.push(key);
-					break;
-				} else {
-					if (treeData[key] instanceof Object) {
-						parents.push(key);
-
-						//没找到,遍历该节点的子节点
-						getOrgIdArr(parents, childNode, treeData[key]);
-					}
-				}
-			}
-
-			return parents;
-		};
-
-		return {
-			jsonPath,
-			handlePath,
-			validateType,
-			getNodeList,
-			getDbList,
-			onKeyclick,
-			getOrgIdArr,
-			addRule,
-			onTest,
-			delRule,
-			openDialog,
-			closeDialog,
-			onCancel,
-			onSubmit,
-			formRef,
-			...toRefs(state),
-		};
-	},
+    name: 'Edit',
+    components: { Delete, jsontree },
+
+    setup(prop, { emit }) {
+        const { t } = useI18n();
+        const formRef = ref<HTMLElement | null>(null);
+        const state = reactive<DicState>({
+            isShowDialog: false,
+            dialogVisible: false,
+            jsonPathData: [],
+            jsonData: '',
+            propertyData: [],
+            dbData: [],
+            config: {},
+            detail: {},
+            tabData: [
+                {
+                    label: 'int',
+                    value: 'int',
+                },
+                {
+                    label: 'long',
+                    value: 'long',
+                },
+                {
+                    label: 'float',
+                    value: 'float',
+                },
+                {
+                    label: 'double',
+                    value: 'double',
+                },
+                {
+                    label: 'string',
+                    value: 'string',
+                },
+                {
+                    label: 'boolean',
+                    value: 'boolean',
+                },
+                {
+                    label: 'date',
+                    value: 'date',
+                },
+            ],
+            ruledata: [
+                {
+                    expression: '',
+                    replace: '',
+                },
+            ],
+            rule: [
+                {
+                    expression: '',
+                    replace: '',
+                },
+            ],
+
+            ruleForm: {
+                nodeId: 0,
+                isPk: 0,
+                name: '',
+                from: 1,
+                key: '',
+                dataType: '',
+                value: '',
+                rule: [],
+
+                description: '',
+            },
+            rules: {
+                key: [{ required: true, message: `${t('message.dateCenter.columns.key')}${t('message.dateCenter.placeholders.input')}`, trigger: 'blur' }],
+                name: [{ required: true, message: `${t('message.dateCenter.columns.name')}${t('message.dateCenter.placeholders.input')}`, trigger: 'blur' }],
+                isPk: [{ required: true, message: `${t('message.dateCenter.labels.pk')}${t('message.dateCenter.placeholders.input')}`, trigger: 'blur' }],
+                dataType: [{ required: true, message: `${t('message.dateCenter.columns.dataType')}${t('message.dateCenter.placeholders.input')}`, trigger: 'blur' }],
+                value: [{ required: true, message: `${t('message.dateCenter.columns.value')}${t('message.dateCenter.placeholders.input')}`, trigger: 'blur' }],
+            },
+        });
+
+        const onTest = () => {
+            if (state.detail.from == 1) {
+                api.common.api(state.detail.sourceId).then((res: any) => {
+                    state.jsonData = JSON.parse(res.data);
+
+                    var jsonstr = jsonPath([], state.jsonData, '');
+                    state.jsonPathData = jsonstr;
+                    state.dialogVisible = true;
+                });
+            } else if (state.detail.from == 4) {
+                api.common.devapi(state.detail.sourceId).then((res: any) => {
+                    state.jsonData = JSON.parse(res.data);
+
+                    var jsonstr = jsonPath([], state.jsonData, '');
+                    state.jsonPathData = jsonstr;
+                    state.dialogVisible = true;
+                });
+            }
+        };
+
+        const handlePath = (path: string) => {
+            let data = path.slice(1);
+
+            state.ruleForm.value = data;
+            state.dialogVisible = false;
+        };
+
+        const delRule = (index: number) => {
+            state.rule.splice(index, 1);
+        };
+
+        const addRule = () => {
+            state.rule.push({
+                expression: '',
+                replace: '',
+            });
+        };
+        // 打开弹窗
+        const openDialog = (row: any | null) => {
+            resetForm();
+
+            if (row && row.nodeId) {
+                state.ruleForm = row as RuleFormState;
+
+                const data = JSON.parse(row.rule);
+                data.forEach((item: any, index: number) => {
+                    state.rule[index].expression = item.expression;
+                    state.rule[index].replace = item.replace;
+                });
+            }
+
+            api.common.detail(row?.sourceId).then((res: any) => {
+                state.detail = res.data;
+                if (res.data.from == 4) {
+                    //propertyData
+                    api.node.getpropertyList({ productKey: res.data.deviceConfig.productKey }).then((re: any) => {
+                        state.propertyData = re;
+                    });
+                }
+                if (res.data.from == 2) {
+                    //propertyData
+                    api.common.getfields(row?.sourceId).then((re: any) => {
+                        state.dbData = re.data;
+                    });
+                }
+            });
+
+            state.ruleForm = (row || state.ruleForm) as RuleFormState;
+            state.isShowDialog = true;
+        };
+        const resetForm = () => {
+            state.ruleForm = {
+                nodeId: 0,
+                name: '',
+                isPk: 0,
+                from: 1,
+                key: '',
+                dataType: '',
+                value: '',
+                rule: [],
+                description: '',
+            };
+        };
+        // 关闭弹窗
+        const closeDialog = () => {
+            state.isShowDialog = false;
+        };
+        // 取消
+        const onCancel = () => {
+            closeDialog();
+        };
+        // 新增
+        const onSubmit = () => {
+            const formWrap = unref(formRef) as any;
+            if (!formWrap) return;
+            formWrap.validate((valid: boolean) => {
+                if (valid) {
+                    //修改rule数据
+                    // state.rule.forEach((item, index) => {
+                    // 	item.params[item.params.name] = item.params.value;
+                    // 	delete item.params.name;
+                    // 	delete item.params.value;
+                    // });
+
+                    state.ruleForm.rule = state.rule;
+
+                    if (state.ruleForm.nodeId !== 0) {
+                        //修改
+                        api.node.edit(state.ruleForm).then(() => {
+                            ElMessage.success(t('message.dateCenter.messages.opSuccess'));
+                            closeDialog(); // 关闭弹窗
+                            emit('typeList');
+                        });
+                    } else {
+                        //添加
+
+                        api.node.add(state.ruleForm).then(() => {
+                            ElMessage.success(t('message.dateCenter.messages.opSuccess'));
+                            closeDialog(); // 关闭弹窗
+                            emit('typeList');
+                        });
+                    }
+                }
+            });
+        };
+
+        const getNodeList = (e: any) => {
+            state.propertyData.forEach((item) => {
+                if (item.key === e) {
+                    state.ruleForm.dataType = item.valueType.type;
+                }
+            });
+        };
+
+        const getDbList = (e: any) => {
+            state.ruleForm.dataType = state.dbData[e].Type;
+        }
+
+        const onKeyclick = () => {
+        };
+
+        const jsonPath = (arr: any[], json: any, basePath: string) => {
+            // 生成jsonpath
+            const type = validateType(json);
+
+            if (type === 'object') {
+                for (let key in json) {
+                    const item: any = {
+                        key,
+                        path: `${basePath}.${key}`,
+                    };
+                    const childType = validateType(json[key]);
+                    item.type = childType;
+                    if (childType === 'object' || childType === 'array') {
+                        item.leaf = true;
+                        item.children = [];
+                        jsonPath(item.children, json[key], item.path);
+                    } else {
+                        item.leaf = false;
+                        item.value = json[key];
+                    }
+                    arr.push(item);
+                }
+            } else if (type === 'array') {
+                json.forEach((item: any, index: number) => {
+                    const childType = validateType(item);
+                    const obj: any = {
+                        key: index,
+                    };
+                    obj.type = childType;
+                    obj.path = `${basePath}.${index}`;
+                    if (childType === 'object' || childType === 'array') {
+                        (obj.leaf = true), (obj.children = []);
+                        jsonPath(obj.children, item, obj.path);
+                    } else {
+                        obj.value = item;
+                        obj.leaf = false;
+                    }
+                    arr.push(obj);
+                });
+            }
+
+            return arr;
+        };
+
+        // 校验JSON数据类型
+        const validateType = (val: any) => {
+            let type = typeof val;
+            if (type === 'object') {
+                if (Array.isArray(val)) {
+                    return 'array';
+                } else if (val === null) {
+                    return 'null';
+                } else {
+                    return 'object';
+                }
+            } else {
+                switch (type) {
+                    case 'boolean':
+                        return 'boolean';
+                    case 'string':
+                        return 'string';
+                    case 'number':
+                        return 'number';
+                    default:
+                        return 'error';
+                }
+            }
+        };
+
+        const getOrgIdArr = (parents: any[], childNode: any, treeData: Record<string, any>) => {
+            for (var key in treeData) {
+                // 父节点查询条件
+                if (key === childNode) {
+                    // 如果找到结果,保存当前节点
+                    parents.push(key);
+                    break;
+                } else {
+                    if (treeData[key] instanceof Object) {
+                        parents.push(key);
+
+                        //没找到,遍历该节点的子节点
+                        getOrgIdArr(parents, childNode, treeData[key]);
+                    }
+                }
+            }
+
+            return parents;
+        };
+
+        return {
+            jsonPath,
+            handlePath,
+            validateType,
+            getNodeList,
+            getDbList,
+            onKeyclick,
+            getOrgIdArr,
+            addRule,
+            onTest,
+            delRule,
+            openDialog,
+            closeDialog,
+            onCancel,
+            onSubmit,
+            formRef,
+            ...toRefs(state),
+            t,
+        };
+    },
 });
 </script>
 <style scoped>

+ 24 - 5
src/views/system/datahub/source/component/list.vue

@@ -3,7 +3,7 @@
 		<el-dialog v-model="isShowDialog" :show-close="false" width="75%" :fullscreen="dialogFullScreen">
 			<template #header="{ close, titleId, titleClass }">
 				<div class="my-header">
-					<h4 :id="titleId" :class="titleClass">数据记录</h4>
+					<h4 :id="titleId" :class="titleClass">{{ t('message.dateCenter.actions.records') }}</h4>
 					<div>
 						<i class="iconfont " :class="!dialogFullScreen ? 'icon-fullscreen' : 'icon-tuichuquanping'" @click="quanping" style="font-size: 22px;cursor: pointer;"></i>
 						<i class="el-icon" @click="close" style="font-size: 22px;cursor: pointer;    margin-left: 10px; position: relative; top: 3px;"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-029747aa="">
@@ -22,7 +22,7 @@
 							{{ item }}
 						</div>
 						<div>
-							<span v-if="item == 'created_at'">时间</span>
+							<span v-if="item == 'created_at'">{{ t('message.dateCenter.columns.createdAt') }}</span>
 							{{ titleData[item] }}
 						</div>
 					</template>
@@ -35,17 +35,35 @@
 
 <script lang="ts">
 import { reactive, toRefs, defineComponent, ref } from 'vue';
+import { useI18n } from 'vue-i18n';
 import { Close } from '@element-plus/icons-vue';
 
 import api from '/@/api/datahub';
 
+interface TableParam {
+    pageNum: number;
+    pageSize: number;
+    sourceId?: number;
+}
+interface TableData<T> {
+    data: T[];
+    total: number;
+    loading: boolean;
+    param: TableParam;
+}
 interface DicState {
-	isShowDialog: boolean;
+    isShowDialog: boolean;
+    dialogFullScreen: boolean;
+    titleData: Record<string, string>;
+    jsonsData: any[];
+    jData: string[];
+    tableData: TableData<Record<string, any>>;
 }
 
 export default defineComponent({
 	name: 'deviceEditPro',
 	setup() {
+		const { t } = useI18n();
 		const formRef = ref<HTMLElement | null>(null);
 		const state = reactive<DicState>({
 			isShowDialog: false,
@@ -81,7 +99,7 @@ export default defineComponent({
 				const jsonData = JSON.parse(res.data);
 				state.tableData.data = jsonData;
 				state.jData = Object.keys(jsonData[0]);
-				state.jData.forEach((item, index) => {
+				state.jData.forEach((item: string, index: number) => {
 					state.jsonsData[index] = jsonData[item];
 				});
 
@@ -89,7 +107,7 @@ export default defineComponent({
 			}).finally(() => (state.tableData.loading = false));
 
 			api.node.getList(state.tableData.param).then((res: any) => {
-				res.list.forEach((item) => {
+				res.list.forEach((item: { key: string; name: string }) => {
 					state.titleData[item.key] = item.name;
 				});
 			});
@@ -128,6 +146,7 @@ export default defineComponent({
 			onCancel,
 			formRef,
 			...toRefs(state),
+			t,
 		};
 	},
 });

+ 63 - 60
src/views/system/datahub/source/detail.vue

@@ -3,121 +3,121 @@
     <el-card shadow="never">
       <div class="content">
         <div class="cont_box">
-          <div class="title">数据源名称:{{ detail.name }}</div>
-          <div class="pro-status"><span :class="developer_status == 1 ? 'on' : 'off'"></span>{{ developer_status == 1 ? "已发布" : "未发布" }}</div>
-          <div class="pro-option" v-auth="'startOrStop'" @click="CkOption">{{ developer_status == 1 ? "停用" : "发布" }}</div>
+          <div class="title">{{ t('message.dateCenter.labels.sourceNameTitle') }}{{ detail.name }}</div>
+          <div class="pro-status"><span :class="developer_status == 1 ? 'on' : 'off'"></span>{{ t(developer_status == 1 ? 'message.dateCenter.status.published' : 'message.dateCenter.status.unpublished') }}</div>
+          <div class="pro-option" v-auth="'startOrStop'" @click="CkOption">{{ t(developer_status == 1 ? 'message.dateCenter.actions.disable' : 'message.dateCenter.actions.publish') }}</div>
         </div>
       </div>
       <!--  page-full page-full-part -->
       <div class="content-box">
         <el-tabs v-model="activeName" @tab-click="handleClick">
-          <el-tab-pane label="数据源信息" name="1">
+          <el-tab-pane :label="t('message.dateCenter.tabs.info')" name="1">
             <el-form label-width="110px" inline>
-              <el-divider content-position="left">基本信息</el-divider>
+              <el-divider content-position="left">{{ t('message.dateCenter.tabs.baseInfo') }}</el-divider>
 
-              <el-form-item label="数据源标识:">
+              <el-form-item :label="t('message.dateCenter.labels.sourceKey') + ':'">
                 {{ detail.key }}
               </el-form-item>
 
-              <el-form-item label="数据源名称:">
+              <el-form-item :label="t('message.dateCenter.labels.sourceName') + ':'">
                 {{ detail.name }}
               </el-form-item>
-              <el-form-item label="数据源描述:">
+              <el-form-item :label="t('message.dateCenter.labels.sourceDesc') + ':'">
                 {{ detail.desc }}
               </el-form-item>
-              <el-form-item label="数据来源:">
-                <span v-if="detail.from == 1">api导入</span>
-                <span v-if="detail.from == 2">数据库</span>
-                <span v-if="detail.from == 3">文件</span>
-                <span v-if="detail.from == 4">设备</span>
+              <el-form-item :label="t('message.dateCenter.labels.sourceFrom') + ':'">
+                <span v-if="detail.from == 1">{{ t('message.dateCenter.options.api') }}</span>
+                <span v-if="detail.from == 2">{{ t('message.dateCenter.options.db') }}</span>
+                <span v-if="detail.from == 3">{{ t('message.dateCenter.options.file') }}</span>
+                <span v-if="detail.from == 4">{{ t('message.dateCenter.options.device') }}</span>
               </el-form-item>
 
               <div v-if="detail.from == 4">
-                <el-divider content-position="left">数据源配置</el-divider>
-                <el-form-item label="设备key:" prop="deviceKey">
+                <el-divider content-position="left">{{ t('message.dateCenter.tabs.sourceConfig') }}</el-divider>
+                <el-form-item :label="t('message.dateCenter.labels.deviceKey') + ':'" prop="deviceKey">
                   {{ detail.deviceConfig.deviceKey }}
                 </el-form-item>
-                <el-form-item label="产品key:" prop="productKey">
+                <el-form-item :label="t('message.dateCenter.labels.productKey') + ':'" prop="productKey">
                   {{ detail.deviceConfig.productKey }}
                 </el-form-item>
               </div>
 
               <div v-if="detail.from == 2">
-                <el-divider content-position="left">数据源配置</el-divider>
-                <el-form-item label="数据来源:" prop="type">
+                <el-divider content-position="left">{{ t('message.dateCenter.tabs.sourceConfig') }}</el-divider>
+                <el-form-item :label="t('message.dateCenter.labels.dbType') + ':'" prop="type">
                   {{ detail.dbConfig.type }}
                 </el-form-item>
 
-                <el-form-item label="主机地址:" prop="host">
+                <el-form-item :label="t('message.dateCenter.labels.host') + ':'" prop="host">
                   {{ detail.dbConfig.host }}
                 </el-form-item>
 
-                <el-form-item label="端口号:" prop="port">
+                <el-form-item :label="t('message.dateCenter.labels.port') + ':'" prop="port">
                   {{ detail.dbConfig.port }}
                 </el-form-item>
 
-                <el-form-item label="用户名:" prop="user">
+                <el-form-item :label="t('message.dateCenter.labels.user') + ':'" prop="user">
                   {{ detail.dbConfig.user }}
                 </el-form-item>
-                <el-form-item label="密码:" prop="passwd">
+                <el-form-item :label="t('message.dateCenter.labels.password') + ':'" prop="passwd">
                   {{ detail.dbConfig.passwd }}
                 </el-form-item>
-                <el-form-item label="数据库名称:" prop="dbName">
+                <el-form-item :label="t('message.dateCenter.labels.dbName') + ':'" prop="dbName">
                   {{ detail.dbConfig.dbName }}
                 </el-form-item>
 
-                <el-form-item label="表名称:" prop="tableName">
+                <el-form-item :label="t('message.dateCenter.labels.tableName') + ':'" prop="tableName">
                   {{ detail.dbConfig.tableName }}
                 </el-form-item>
-                <el-form-item label="主键字段:" prop="pk">
+                <el-form-item :label="t('message.dateCenter.labels.pk') + ':'" prop="pk">
                   {{ detail.dbConfig.pk }}
                 </el-form-item>
 
-                <el-form-item label="每次获取数量:" prop="num">
+                <el-form-item :label="t('message.dateCenter.labels.num') + ':'" prop="num">
                   {{ detail.dbConfig.num }}
                 </el-form-item>
 
-                <el-form-item label="任务表达式:" prop="cronExpression">
+                <el-form-item :label="t('message.dateCenter.labels.cronExpression') + ':'" prop="cronExpression">
                   {{ detail.dbConfig.cronExpression }}
                 </el-form-item>
               </div>
               <div v-if="detail.from == 1">
-                <el-divider content-position="left">规则表达式</el-divider>
+                <el-divider content-position="left">{{ t('message.dateCenter.tabs.ruleExpr') }}</el-divider>
 
                 <div v-for="(item, index) in rule" :key="index">
-                  <el-form-item label="表达式:">
+                  <el-form-item :label="t('message.dateCenter.labels.expression') + ':'">
                     {{ item.expression }}
                   </el-form-item>
 
-                  <el-form-item label="参数:"> {{ item.params.name }}~ {{ item.params.value }} </el-form-item>
+                  <el-form-item :label="t('message.dateCenter.labels.param') + ':'"> {{ item.params.name }}~ {{ item.params.value }} </el-form-item>
 
-                  <el-divider content-position="left">数据源配置</el-divider>
+                  <el-divider content-position="left">{{ t('message.dateCenter.tabs.sourceConfig') }}</el-divider>
 
-                  <el-form-item label="请求方法:" prop="method">
+                  <el-form-item :label="t('message.dateCenter.labels.method') + ':'" prop="method">
                     {{ config.method }}
                   </el-form-item>
-                  <el-form-item label="请求地址:" prop="method">
+                  <el-form-item :label="t('message.dateCenter.labels.url') + ':'" prop="method">
                     {{ config.url }}
                   </el-form-item>
-                  <el-form-item label="更新时间:" prop="method">
+                  <el-form-item :label="t('message.dateCenter.labels.interval') + ':'" prop="method">
                     {{ config.interval }}
                     {{ config.intervalUnit }}
                   </el-form-item>
 
-                  <el-divider content-position="left">请求参数</el-divider>
+                  <el-divider content-position="left">{{ t('message.dateCenter.tabs.reqParams') }}</el-divider>
 
                   <div class="content-f" v-for="(item, index) in requestParams" :key="index" style="border: 1px solid #d9d9d9; padding: 10px; margin-bottom: 10px">
                     <div v-for="aa in item" :key="aa.type">
-                      <el-form-item label="参数类型:">
+                      <el-form-item :label="t('message.dateCenter.labels.paramType') + ':'">
                         {{ aa.type }}
                       </el-form-item>
-                      <el-form-item label="参数标题:">
+                      <el-form-item :label="t('message.dateCenter.labels.paramTitle') + ':'">
                         {{ aa.name }}
                       </el-form-item>
-                      <el-form-item label="参数名:">
+                      <el-form-item :label="t('message.dateCenter.labels.paramKey') + ':'">
                         {{ aa.key }}
                       </el-form-item>
-                      <el-form-item label="参数值:">
+                      <el-form-item :label="t('message.dateCenter.labels.paramValue') + ':'">
                         {{ aa.value }}
                       </el-form-item>
                     </div>
@@ -127,27 +127,27 @@
             </el-form>
           </el-tab-pane>
 
-          <el-tab-pane label="数据节点" name="2">
+          <el-tab-pane :label="t('message.dateCenter.tabs.nodes')" name="2">
             <div class="flex-row flex-end mb-4">
-              <el-button type="primary" size="small" @click="onOpenEdit()" v-if="developer_status == 0" v-auth="'add'">添加</el-button>
+              <el-button type="primary" size="small" @click="onOpenEdit()" v-if="developer_status == 0" v-auth="'add'">{{ t('message.dateCenter.actions.add') }}</el-button>
             </div>
             <el-table :data="tableData.data" style="width: 100%" v-loading="tableData.loading">
-              <el-table-column label="ID" align="center" prop="nodeId" width="100" v-col="'id'" />
-              <el-table-column label="数据标识" prop="key" show-overflow-tooltip v-col="'key'" />
-              <el-table-column label="数据名称" prop="name" show-overflow-tooltip v-col="'name'" />
-              <el-table-column label="数据类型" prop="dataType" show-overflow-tooltip v-col="'dataType'" />
-              <el-table-column label="数据取值项" prop="value" min-width="120" show-overflow-tooltip v-col="'value'" />
-              <el-table-column prop="createdAt" label="创建时间" min-width="160" align="center" v-col="'createdAt'" width="180"></el-table-column>
-              <el-table-column label="操作" width="200" align="center" fixed="right">
+              <el-table-column :label="t('message.dateCenter.columns.id')" align="center" prop="nodeId" width="100" v-col="'id'" />
+              <el-table-column :label="t('message.dateCenter.columns.key')" prop="key" show-overflow-tooltip v-col="'key'" />
+              <el-table-column :label="t('message.dateCenter.columns.name')" prop="name" show-overflow-tooltip v-col="'name'" />
+              <el-table-column :label="t('message.dateCenter.columns.dataType')" prop="dataType" show-overflow-tooltip v-col="'dataType'" />
+              <el-table-column :label="t('message.dateCenter.columns.value')" prop="value" min-width="120" show-overflow-tooltip v-col="'value'" />
+              <el-table-column prop="createdAt" :label="t('message.dateCenter.columns.createdAt')" min-width="160" align="center" v-col="'createdAt'" width="180"></el-table-column>
+              <el-table-column :label="t('message.dateCenter.columns.action')" width="200" align="center" fixed="right">
                 <template #default="scope">
-                  <el-button size="small" text type="warning" @click="onOpenEdit1(scope.row)" v-if="developer_status == 0" v-auth="'edit'">修改</el-button>
-                  <el-button size="small" text type="danger" @click="onRowDel(scope.row)" v-if="developer_status == 0" v-auth="'del'">删除</el-button>
+                  <el-button size="small" text type="warning" @click="onOpenEdit1(scope.row)" v-if="developer_status == 0" v-auth="'edit'">{{ t('message.dateCenter.actions.edit') }}</el-button>
+                  <el-button size="small" text type="danger" @click="onRowDel(scope.row)" v-if="developer_status == 0" v-auth="'del'">{{ t('message.dateCenter.actions.delete') }}</el-button>
                 </template>
               </el-table-column>
             </el-table>
             <pagination v-show="tableData.total > 0" :total="tableData.total" v-model:page="tableData.param.pageNum" @pagination="typeList" />
           </el-tab-pane>
-          <el-tab-pane label="查看数据" name="3">
+          <el-tab-pane :label="t('message.dateCenter.tabs.viewData')" name="3">
             <JsonViewer :value="jsonData" boxed sort theme="jv-dark" @click="onKeyclick" />
           </el-tab-pane>
         </el-tabs>
@@ -158,6 +158,7 @@
 </template>
 <script lang="ts">
 import { toRefs, reactive, onMounted, ref, defineComponent } from "vue";
+import { useI18n } from 'vue-i18n';
 import { Edit } from "@element-plus/icons-vue";
 import { ElMessageBox, ElMessage } from "element-plus";
 import { useRoute } from "vue-router";
@@ -186,6 +187,7 @@ export default defineComponent({
   name: "dataDetail",
   components: { EditDic },
   setup() {
+    const { t } = useI18n();
     const editDicRef = ref();
 
     const route = useRoute();
@@ -260,12 +262,12 @@ export default defineComponent({
     const CkOption = () => {
       if (state.developer_status == 1) {
         api.common.undeploy({ sourceId: route.params.sourceId }).then(() => {
-          ElMessage.success("操作成功");
+          ElMessage.success(t('message.dateCenter.messages.opSuccess'));
           state.developer_status = 0;
         });
       } else {
         api.common.deploy({ sourceId: route.params.sourceId }).then(() => {
-          ElMessage.success("操作成功");
+          ElMessage.success(t('message.dateCenter.messages.opSuccess'));
           state.developer_status = 1;
         });
       }
@@ -289,25 +291,25 @@ export default defineComponent({
     };
 
     const onRowDel = (row: any) => {
-      let msg = "你确定要删除所选数据?";
+      let msg = t('message.dateCenter.messages.deleteConfirmSelected');
       let ids: number[] = [];
       if (row) {
-        msg = `此操作将永久删除数据节点:“${row.name}”,是否继续?`;
+        msg = t('message.dateCenter.messages.deleteNodeConfirm', { name: row.name });
         ids = row.nodeId;
       } else {
         ids = state.ids;
       }
       if (ids.length === 0) {
-        ElMessage.error("请选择要删除的数据。");
+        ElMessage.error(t('message.dateCenter.messages.pleaseSelectToDelete'));
         return;
       }
-      ElMessageBox.confirm(msg, "提示", {
-        confirmButtonText: "确认",
-        cancelButtonText: "取消",
+      ElMessageBox.confirm(msg, t('message.dateCenter.messages.tip'), {
+        confirmButtonText: t('message.dateCenter.messages.confirm'),
+        cancelButtonText: t('message.dateCenter.messages.cancel'),
         type: "warning",
       }).then(() => {
         api.node.delete(ids).then(() => {
-          ElMessage.success("删除成功");
+          ElMessage.success(t('message.dateCenter.messages.deleteSuccess'));
           typeList();
         });
       });
@@ -323,6 +325,7 @@ export default defineComponent({
 
     return {
       Edit,
+      t,
       editDicRef,
       typeList,
       onRowDel,

+ 46 - 59
src/views/system/datahub/source/index.vue

@@ -2,14 +2,14 @@
 	<div class="page">
 		<el-card shadow="never">
 			<el-form inline ref="queryRef">
-				<el-form-item label="数据源标识" prop="name">
-					<el-input v-model="params.key" placeholder="请输入" clearable style="width: 140px" @keyup.enter.native="getList" />
+				<el-form-item :label="$t('message.dateCenter.labels.sourceKey')" prop="name">
+					<el-input v-model="params.key" :placeholder="$t('message.dateCenter.placeholders.input')" clearable style="width: 140px" @keyup.enter.native="getList" />
 				</el-form-item>
-				<el-form-item label="数据源名称" prop="name">
-					<el-input v-model="params.name" placeholder="请输入" clearable style="width: 140px" @keyup.enter.native="getList" />
+				<el-form-item :label="$t('message.dateCenter.labels.sourceName')" prop="name">
+					<el-input v-model="params.name" :placeholder="$t('message.dateCenter.placeholders.input')" clearable style="width: 140px" @keyup.enter.native="getList" />
 				</el-form-item>
 				<el-form-item label="" prop="from">
-					<el-select v-model="params.from" placeholder="数据源类型" @keyup.enter.native="getList" style="width: 120px;">
+					<el-select v-model="params.from" :placeholder="$t('message.dateCenter.placeholders.sourceType')" @keyup.enter.native="getList" style="width: 120px;">
 						<el-option v-for="item in typeData" :key="item.value" :label="item.label" :value="item.value" />
 					</el-select>
 				</el-form-item>
@@ -19,51 +19,51 @@
 						<el-icon>
 							<ele-Search />
 						</el-icon>
-						查询
+						{{ $t('message.dateCenter.actions.search') }}
 					</el-button>
 					<el-button v-auth="'add'" type="primary" class="ml10" @click="onOpenAdd">
 						<el-icon>
 							<ele-FolderAdd />
 						</el-icon>
-						新增数据源
+						{{ $t('message.dateCenter.actions.createSource') }}
 					</el-button>
 					<el-button type="info" class="ml10" @click="batchdel()" v-auth="'del'">
 						<el-icon>
 							<ele-Delete />
 						</el-icon>
-						批量删除
+						{{ $t('message.dateCenter.actions.batchDelete') }}
 					</el-button>
 				</el-form-item>
 			</el-form>
 			<el-table :data="tableData" style="width: 100%" @selection-change="handleSelectionChange" row-key="id" v-loading="loading">
 				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="ID" align="center" prop="sourceId" width="100" v-col="'sourceId'" />
-				<el-table-column label="数据源标识" prop="key" show-overflow-tooltip v-col="'key'" />
-				<el-table-column label="数据源名称" prop="name" show-overflow-tooltip v-col="'name'" />
-				<el-table-column prop="from" label="数据源类型" width="160" align="center" v-col="'from'">
+				<el-table-column :label="$t('message.dateCenter.columns.sourceId')" align="center" prop="sourceId" width="100" v-col="'sourceId'" />
+				<el-table-column :label="$t('message.dateCenter.labels.sourceKey')" prop="key" show-overflow-tooltip v-col="'key'" />
+				<el-table-column :label="$t('message.dateCenter.labels.sourceName')" prop="name" show-overflow-tooltip v-col="'name'" />
+				<el-table-column prop="from" :label="$t('message.dateCenter.columns.from')" width="160" align="center" v-col="'from'">
 					<template #default="scope">
-						<span v-if="scope.row.from == 1">api导入</span>
-						<span v-if="scope.row.from == 2">数据库</span>
-						<span v-if="scope.row.from == 3">文件</span>
-						<span v-if="scope.row.from == 4">设备</span>
+						<span v-if="scope.row.from == 1">{{ $t('message.dateCenter.options.api') }}</span>
+						<span v-if="scope.row.from == 2">{{ $t('message.dateCenter.options.db') }}</span>
+						<span v-if="scope.row.from == 3">{{ $t('message.dateCenter.options.file') }}</span>
+						<span v-if="scope.row.from == 4">{{ $t('message.dateCenter.options.device') }}</span>
 					</template>
 				</el-table-column>
-				<el-table-column prop="status" label="状态" width="100" align="center" v-col="'status'">
+				<el-table-column prop="status" :label="$t('message.dateCenter.labels.sourceStatus')" width="120" align="center" v-col="'status'">
 					<template #default="scope">
-						<el-tag type="success" size="small" v-if="scope.row.status == 1">已发布</el-tag>
-						<el-tag type="info" size="small" v-if="scope.row.status == 0">未发布</el-tag>
+						<el-tag type="success" size="small" v-if="scope.row.status == 1">{{ $t('message.dateCenter.status.published') }}</el-tag>
+						<el-tag type="info" size="small" v-if="scope.row.status == 0">{{ $t('message.dateCenter.status.unpublished') }}</el-tag>
 					</template>
 				</el-table-column>
 
-				<el-table-column label="操作" width="200" align="center" fixed="right">
+				<el-table-column :label="$t('message.dateCenter.columns.action')" width="200" align="center" fixed="right">
 					<template #default="scope">
 						<router-link :to="'/datahub/source/' + scope.row.sourceId" class="link-type" style="padding-right: 12px; font-size: 12px; color: #409eff" v-auth="'detail'">
-							<span>详情</span>
+							<span>{{ $t('message.dateCenter.actions.detail') }}</span>
 						</router-link>
-						<el-button size="small" text type="success" @click="onOpenList(scope.row)" v-if="scope.row.status == 1" v-auth="'detail'">数据记录</el-button>
-						<el-button size="small" text type="warning" @click="onOpenEdit(scope.row)" v-if="scope.row.status == 0" v-auth="'edit'">修改</el-button>
-						<el-button size="small" text type="info" @click="del(scope.row)" v-if="scope.row.status == 0" v-auth="'del'">删除</el-button>
-						<el-button size="small" text type="primary" @click="copy(scope.row)" v-auth="'copy'">复制</el-button>
+						<el-button size="small" text type="success" @click="onOpenList(scope.row)" v-if="scope.row.status == 1" v-auth="'detail'">{{ $t('message.dateCenter.actions.records') }}</el-button>
+						<el-button size="small" text type="warning" @click="onOpenEdit(scope.row)" v-if="scope.row.status == 0" v-auth="'edit'">{{ $t('message.dateCenter.actions.edit') }}</el-button>
+						<el-button size="small" text type="info" @click="del(scope.row)" v-if="scope.row.status == 0" v-auth="'del'">{{ $t('message.dateCenter.actions.delete') }}</el-button>
+						<el-button size="small" text type="primary" @click="copy(scope.row)" v-auth="'copy'">{{ $t('message.dateCenter.actions.copy') }}</el-button>
 					</template>
 				</el-table-column>
 			</el-table>
@@ -80,31 +80,18 @@ import { useSearch } from '/@/hooks/useCommon'
 import { ElMessageBox, ElMessage } from 'element-plus'
 import EditDic from './component/edit.vue'
 import ListDic from './component/list.vue'
-import { ref, onMounted } from 'vue'
+import { ref, onMounted, computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+const { t } = useI18n()
 const queryRef = ref()
 const editDicRef = ref()
 const listDicRef = ref()
-const typeData = ref([
-	{
-		label: '全部',
-		value: '-1',
-	},
-	{
-		label: 'api导入',
-		value: '1',
-	},
-	{
-		label: '数据库',
-		value: '2',
-	},
-	{
-		label: '文件',
-		value: '3',
-	},
-	{
-		label: '设备',
-		value: '4',
-	},
+const typeData = computed(() => [
+	{ label: t('message.dateCenter.options.all'), value: '-1' },
+	{ label: t('message.dateCenter.options.api'), value: '1' },
+	{ label: t('message.dateCenter.options.db'), value: '2' },
+	{ label: t('message.dateCenter.options.file'), value: '3' },
+	{ label: t('message.dateCenter.options.device'), value: '4' },
 ])
 const ids = ref()
 const { params, tableData, getList, loading } = useSearch<any[]>(api.common.getList, 'list', { keyWord: '' })
@@ -125,14 +112,14 @@ const onOpenEdit = async (row?: any) => {
 }
 //复制数据
 const copy = (row: any) => {
-	ElMessageBox.confirm('确定要复制该数据吗?', '提示', {
-		confirmButtonText: '确认',
-		cancelButtonText: '取消',
+	ElMessageBox.confirm(t('message.dateCenter.messages.copyConfirm'), t('message.dateCenter.messages.tip'), {
+		confirmButtonText: t('message.dateCenter.messages.confirm'),
+		cancelButtonText: t('message.dateCenter.messages.cancel'),
 		type: 'warning',
 	})
 		.then(() => {
 			api.common.copy({ sourceId: row.sourceId }).then(() => {
-				ElMessage.success('复制成功')
+				ElMessage.success(t('message.dateCenter.messages.copySuccess'))
 				getList()
 			})
 		})
@@ -142,24 +129,24 @@ const handleSelectionChange = (selection: any[]) => {
 	ids.value = selection.map((item) => item.sourceId)
 }
 const batchdel = () => {
-	ElMessageBox.confirm('是否确认要批量删除这些数据吗?', '提示', {
-		confirmButtonText: '确认',
-		cancelButtonText: '取消',
+	ElMessageBox.confirm(t('message.dateCenter.messages.batchDeleteConfirm'), t('message.dateCenter.messages.tip'), {
+		confirmButtonText: t('message.dateCenter.messages.confirm'),
+		cancelButtonText: t('message.dateCenter.messages.cancel'),
 		type: 'warning',
 	}).then(async () => {
 		await api.common.delete(ids.value)
-		ElMessage.success('删除成功')
+		ElMessage.success(t('message.dateCenter.messages.deleteSuccess'))
 		getList()
 	})
 }
 const del = (row: any) => {
-	ElMessageBox.confirm(`此操作将删除:“${row.name}”,是否继续?`, '提示', {
-		confirmButtonText: '确认',
-		cancelButtonText: '取消',
+	ElMessageBox.confirm(t('message.dateCenter.messages.deleteRowConfirm', { name: row.name }), t('message.dateCenter.messages.tip'), {
+		confirmButtonText: t('message.dateCenter.messages.confirm'),
+		cancelButtonText: t('message.dateCenter.messages.cancel'),
 		type: 'warning',
 	}).then(async () => {
 		await api.common.delete(row.sourceId)
-		ElMessage.success('删除成功')
+		ElMessage.success(t('message.dateCenter.messages.deleteSuccess'))
 		getList(1)
 	})
 }