Procházet zdrojové kódy

Merge branch 'develop' into feature/1.5.3-file-manager

# Conflicts:
#	.gitignore
#	languages/en.js
#	languages/es.js
#	languages/ru-RU.js
#	languages/zh-CN.js
#	src/views/ncs-device/components/deviceManager.vue
wuyunfeng před 1 rokem
rodič
revize
877d33566e

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 1
dist/index.html


+ 40 - 2
languages/en.js

@@ -233,7 +233,8 @@ module.exports = {
     simulateSend: 'Simulate Send',
     justify: 'alignment',
     indent: 'indentation',
-    image: 'picture'
+    image: 'picture',
+    video: 'video'
   },
   member: {
     face: 'Avatar',
@@ -1594,12 +1595,49 @@ module.exports = {
   zy20240108: {
     nurseWatch: 'Nurse watch equipment',
     customerAgeHidden: 'Extension user age hidden',
-    customerAgeHiddenOnDoor: 'Door machine user age hidden',
+    customerAgeHiddenOnDoor: 'Door machine user age hidden'
   },
   wnn20240126: {
     MULTIFUNCTIONAL_BUTTON: 'Multi function button',
     S433_BJMD: 'Alarm door light'
   },
+  zy20240205: {
+    linuxPortraitDoor: 'Linux vertical screen doorstep machine',
+    ENABLE: 'Not turned on',
+    PANEL_BUTTON: 'Panel buttons',
+    S433_BUTTON: '433 button',
+    MULTIFUNCTIONAL_BUTTON: 'Multi function button',
+    SLEEP_MATTRESS: 'Sleep mattress',
+    NFC: 'NFC functionality',
+    linuxSerial1: 'Linux serial port 1',
+    linuxSerial2: 'Linux serial port 2',
+    linuxSerial3: 'Linux serial port 3',
+    androidSerial1: 'Android serial port 1',
+    androidSerial2: 'Android serial port 2',
+    androidSerial3: 'Android serial port 3',
+    choiceSerial: 'Select serial port',
+    dataBackup: 'Data backup',
+    newBackup: 'New backup',
+    flushed: 'flushed',
+    backupMsg: 'Note: 1. This function can only be used in the official environment, and there will be problems in other environments;2. The storage address is /opt/v70/api/upload by default, because of the mapping relationship, the backup file can be found in /mnt/ncs/upload on the physical machine;3. Because of the asynchronous relationship, the data needs to be manually refreshed after the operation is completed.',
+    database: 'database',
+    backupAddress: 'Backup address',
+    inputBackupAddress: 'Please enter a backup address',
+    operationsNumber: 'The number of operations',
+    recoveryTime: 'Recovery time',
+    backupTime: 'Backup time',
+    normal: 'normal',
+    fileError: 'The file does not exist',
+    restore: 'restore',
+    restoreMsg: 'restore....',
+    restoreMsg2: 'Are you sure you want to restore the restoration?',
+    inputDatabaseMsg: 'Please select or enter a database',
+    inputContainerName: 'Please enter a container name',
+    inputFileAddress: 'Please enter a file storage address',
+    inputMysqlAddress: 'Please enter the address of the MySQL server',
+    deleteSqlMsg: 'The data is not recoverable after the deletion operation, are you sure you want to delete this data?',
+
+  },
   wu20240322: {
     fileManager: 'File Manager'
   }

+ 40 - 2
languages/es.js

@@ -233,7 +233,8 @@ module.exports = {
     simulateSend: 'Simular envío',
     justify: 'Alinear',
     indent: 'Sangrado',
-    image: 'Imagen'
+    image: 'Imagen',
+    video: 'Vídeo'
   },
   member: {
     face: 'Avatar',
@@ -1594,12 +1595,49 @@ module.exports = {
   zy20240108: {
     nurseWatch: 'Reloj de enfermera',
     customerAgeHidden: 'Se oculta la edad de los usuarios de la extensión',
-    customerAgeHiddenOnDoor: 'La edad del usuario de la máquina de puerta está oculta',
+    customerAgeHiddenOnDoor: 'La edad del usuario de la máquina de puerta está oculta'
   },
   wnn20240126: {
     MULTIFUNCTIONAL_BUTTON: 'Botón multifuncional',
     S433_BJMD: 'Luz de la puerta de alarma'
   },
+
+  zy20240205: {
+    linuxPortraitDoor: 'Máquina de puerta de pantalla vertical de Linux',
+    ENABLE: 'No abrir',
+    PANEL_BUTTON: 'Botón del panel',
+    S433_BUTTON: 'Botón 433',
+    MULTIFUNCTIONAL_BUTTON: 'Botón multifuncional',
+    SLEEP_MATTRESS: 'Colchón para dormir',
+    NFC: 'Función NFC',
+    linuxSerial1: 'Puerto serie de Linux 1',
+    linuxSerial2: 'Puerto serie de Linux 2',
+    linuxSerial3: 'Puerto serie de Linux 3',
+    androidSerial1: 'Puerto serie Android 1',
+    androidSerial2: 'Puerto serie Android 2',
+    androidSerial3: 'Puerto serie Android 3',
+    choiceSerial: 'Seleccionar puerto serie',
+    dataBackup: 'Copia de seguridad de datos',
+    newBackup: 'Nueva copia de seguridad',
+    flushed: 'Enrojecida',
+    backupMsg: 'Nota: 1. Esta función solo se puede utilizar en el entorno oficial y habrá problemas en otros entornos;2. La dirección de almacenamiento es /opt/v70/api/upload De forma predeterminada, debido a la relación de asignación, el archivo de copia de seguridad se puede encontrar en /mnt/ncs/upload en la máquina física;3. Debido a la relación asincrónica, los datos deben actualizarse manualmente una vez completada la operación.',
+    database: 'base de datos',
+    backupAddress: 'Dirección de copia de seguridad',
+    inputBackupAddress: 'Introduzca una dirección de copia de seguridad',
+    operationsNumber: 'El número de operaciones',
+    recoveryTime: 'Tiempo de recuperación',
+    backupTime: 'Tiempo de copia de seguridad',
+    normal: 'normal',
+    fileError: 'El archivo no existe',
+    restore: 'restaurar',
+    restoreMsg: 'restaurar....',
+    restoreMsg2: '¿Estás seguro de que quieres restaurar la restauración?',
+    inputDatabaseMsg: 'Seleccione o ingrese a una base de datos',
+    inputContainerName: 'Introduzca un nombre de contenedor',
+    inputFileAddress: 'Introduzca una dirección de almacenamiento de archivos',
+    inputMysqlAddress: 'Introduzca la dirección del servidor MySQL',
+    deleteSqlMsg: 'Los datos no se pueden recuperar después de la operación de eliminación, ¿está seguro de que desea eliminar estos datos?',
+  },
   wu20240322: {
     fileManager: 'Administrador de Archivos'
   }

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 39 - 2
languages/ru-RU.js


+ 40 - 2
languages/zh-CN.js

@@ -233,7 +233,8 @@ module.exports = {
     simulateSend: '模拟发送',
     justify: '对齐',
     indent: '缩进',
-    image: '图片'
+    image: '图片',
+    video: '视频'
   },
   member: {
     face: '头像',
@@ -1594,12 +1595,49 @@ module.exports = {
   zy20240108: {
     nurseWatch: '护士腕表',
     customerAgeHidden: '分机用户年龄隐藏',
-    customerAgeHiddenOnDoor: '门口机用户年龄隐藏',
+    customerAgeHiddenOnDoor: '门口机用户年龄隐藏'
   },
   wnn20240126: {
     MULTIFUNCTIONAL_BUTTON: '多功能按钮',
     S433_BJMD: '报警门灯'
   },
+  zy20240205: {
+    linuxPortraitDoor: 'Linux竖屏门口机IMG',
+    ENABLE: '不开启',
+    PANEL_BUTTON: '面板按钮',
+    S433_BUTTON: '433按钮',
+    MULTIFUNCTIONAL_BUTTON: '多功能按钮',
+    SLEEP_MATTRESS: '睡眠床垫',
+    NFC: 'nfc功能',
+    linuxSerial1: 'linux串口1',
+    linuxSerial2: 'linux串口2',
+    linuxSerial3: 'linux串口3',
+    androidSerial1: '安卓串口1',
+    androidSerial2: '安卓串口2',
+    androidSerial3: '安卓串口3',
+    choiceSerial: '选择串口',
+    dataBackup: '数据备份',
+    newBackup: '新增备份',
+    flushed: '刷新',
+    backupMsg: '注意:1、该功能只能在正式环境中使用,其他环境会出现问题;2、存储地址默认是/opt/v70/api/upload,因为映射的关系,在物理机上/mnt/ncs/upload可以找到备份文件;3、因为异步的关系,操作完成需要手动刷新数据。',
+    database: '数据库',
+    backupAddress: '备份地址',
+    inputBackupAddress: '请输入备份地址',
+    operationsNumber: '操作次数',
+    recoveryTime: '恢复时间',
+    backupTime: '备份时间',
+    normal: '正常',
+    fileError: '文件不存在',
+    restore: '还原',
+    restoreMsg: '还原....',
+    restoreMsg2: '您确定要恢复还原吗?',
+    inputDatabaseMsg: '请选择或输入数据库',
+    inputContainerName: '请输入容器名称',
+    inputFileAddress: '请输入文件存储地址',
+    inputMysqlAddress: '请输入mysql服务器地址',
+    deleteSqlMsg: '删除操作后数据不可复原,您确定要删除此数据?',
+
+  },
   wu20240322: {
     fileManager: '文件管理器'
   }

+ 2 - 2
set-envs.sh

@@ -2,7 +2,7 @@ echo "const domain = {
   serverUrl: '${serverUrl}',
   DeviceUrl: '${DeviceUrl}',
   mediaUrl: '${mediaUrl}',
-  OnlineSystemUrl: '${API_MODEL}',
+  OnlineSystemUrl: '${OnlineSystemUrl}',
   apiMode: '${apiMode}',
   uiVersion: ${uiVersion}, // 1 医院版,2 月子中心版,3养老院版
   enableBroadcast: ${enableBroadcast}, //广播使能
@@ -13,4 +13,4 @@ echo "const domain = {
   enableSosDevice: ${enableSosDevice}, //报警设备
   enable485:${enable485},
   enableLinux:${enableLinux}
-}"  > /app/domain.js
+}"  > /app/domain.js

+ 9 - 9
src/components/WangEdiitor/wangEditorConfig.js

@@ -62,15 +62,15 @@ export const toolbarConfig = {
       menuKeys: ['uploadImage',
         'insertImage']
     },
-    // {
-    //   "key": "group-video",
-    //   "title": "视频",
-    //   "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M981.184 160.096C837.568 139.456 678.848 128 512 128S186.432 139.456 42.816 160.096C15.296 267.808 0 386.848 0 512s15.264 244.16 42.816 351.904C186.464 884.544 345.152 896 512 896s325.568-11.456 469.184-32.096C1008.704 756.192 1024 637.152 1024 512s-15.264-244.16-42.816-351.904zM384 704V320l320 192-320 192z\"></path></svg>",
-    //   "menuKeys": [
-    //     "insertVideo",
-    //     "uploadVideo"
-    //   ]
-    // },
+    {
+      'key': 'group-video',
+      'title': i18n.t('action.image'),
+      'iconSvg': '<svg viewBox="0 0 1024 1024"><path d="M981.184 160.096C837.568 139.456 678.848 128 512 128S186.432 139.456 42.816 160.096C15.296 267.808 0 386.848 0 512s15.264 244.16 42.816 351.904C186.464 884.544 345.152 896 512 896s325.568-11.456 469.184-32.096C1008.704 756.192 1024 637.152 1024 512s-15.264-244.16-42.816-351.904zM384 704V320l320 192-320 192z"></path></svg>',
+      'menuKeys': [
+        'insertVideo'
+        // "uploadVideo"
+      ]
+    },
     'insertTable',
     'codeBlock',
     'divider',

+ 1 - 1
src/router/index.js

@@ -855,7 +855,7 @@ export const adminRoutes = [
         path: 'index',
         component: () => import('@/views/mysql-backups/index'),
         name: 'mysql-backups-index',
-        meta: { title: '数据备份', icon: 'el-icon-refresh', noCache: true }
+        meta: { title: i18n.t('zy20240205.dataBackup'), icon: 'el-icon-refresh', noCache: true }
       }
     ]
   },

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 11 - 9
src/utils/domain.js


+ 13 - 0
src/utils/enum/SerialTypeEnum.js

@@ -0,0 +1,13 @@
+import createEnum from '@/utils/enum/createEnum'
+import i18n from '@/utils/i18n'
+
+export const SERIAL_TYPE = createEnum(
+  {
+    ENABLE: ['ENABLE', i18n.t('zy20240205.ENABLE')],
+    PANEL_BUTTON: ['PANEL_BUTTON', i18n.t('zy20240205.PANEL_BUTTON')],
+    S433_BUTTON: ['S433_BUTTON', i18n.t('zy20240205.S433_BUTTON')],
+    MULTIFUNCTIONAL_BUTTON: ['MULTIFUNCTIONAL_BUTTON', i18n.t('zy20240205.MULTIFUNCTIONAL_BUTTON')],
+    SLEEP_MATTRESS: ['SLEEP_MATTRESS', i18n.t('zy20240205.SLEEP_MATTRESS')],
+    NFC: ['NFC', i18n.t('zy20240205.NFC')]
+  }
+)

+ 38 - 38
src/views/mysql-backups/index.vue

@@ -4,33 +4,33 @@
       <el-select v-model="databaseName" @change="changeSearch" filterable allow-create default-first-option clearable>
         <el-option v-for="(item, index) in databaseOptions" :key="index" :label="item" :value="item" />
       </el-select>
-      <el-button style="margin-left: 20px" size="mini" type="primary" @click="addLog">新增备份</el-button>
-      <el-button style="margin-left: 20px" size="mini" type="" @click="clickSearch">刷新</el-button>
-      <span style="color: red; font-size: 12px;margin-left: 20px">注意:1、该功能只能在正式环境中使用,其他环境会出现问题;2、存储地址默认是/opt/v70/api/upload,因为映射的关系,在物理机上/mnt/ncs/upload可以找到备份文件;3、因为异步的关系,操作完成需要手动刷新数据。</span>
+      <el-button style="margin-left: 20px" size="mini" type="primary" @click="addLog">{{ this.$t('zy20240205.newBackup') }}</el-button>
+      <el-button style="margin-left: 20px" size="mini" type="" @click="clickSearch">{{ this.$t('zy20240205.flushed') }}</el-button>
+      <span style="color: red; font-size: 12px;margin-left: 20px">{{ this.$t('zy20240205.backupMsg') }}</span>
     </div>
     <div class="table-wrapper" style="padding-bottom: 10px;padding-left: 10px">
       <el-table :data="tableData.data" id="myTableId" stripe border style="width: 100%" ref="refTable" height="520">
 <!--        <el-table-column type="selection" width="55"></el-table-column>-->
-        <el-table-column prop="database_name" min-width="100" label="数据库" align="center" />
+        <el-table-column prop="database_name" min-width="100" :label="this.$t('zy20240205.database')" align="center" />
 <!--        <el-table-column prop="container_name" label="容器名称" min-width="100" align="center" />-->
-        <el-table-column prop="backups_path" label="备份地址" min-width="130" align="center" />
-        <el-table-column prop="backups_name" label="文件名" min-width="130" align="center" />
-        <el-table-column prop="operation" label="操作次数" width="100" align="center" />
-        <el-table-column prop="recovery_time" label="恢复时间" width="170" align="center" :formatter="fortDate"/>
-        <el-table-column prop="create_time" label="备份时间" width="170" align="center" :formatter="fortDate" />
-        <el-table-column prop="state" label="状态" width="100" align="center">
+        <el-table-column prop="backups_path" :label="this.$t('zy20240205.backupAddress')" min-width="130" align="center" />
+        <el-table-column prop="backups_name" :label="this.$t('action.uploadFileName')" min-width="130" align="center" />
+        <el-table-column prop="operation" :label="this.$t('zy20240205.operationsNumber')" width="100" align="center" />
+        <el-table-column prop="recovery_time" :label="this.$t('zy20240205.recoveryTime')" width="170" align="center" :formatter="fortDate"/>
+        <el-table-column prop="create_time" :label="this.$t('zy20240205.backupTime')" width="170" align="center" :formatter="fortDate" />
+        <el-table-column prop="state" :label="this.$t('action.state')" width="100" align="center">
           <template slot-scope="scope">
-            <el-tag v-if="scope.row.status === 0" type="success" disable-transitions>正常</el-tag>
-            <el-tag v-if="scope.row.status === 1" type="danger" disable-transitions>文件不存在</el-tag>
+            <el-tag v-if="scope.row.status === 0" type="success" disable-transitions>{{ this.$t('zy20240205.normal') }}</el-tag>
+            <el-tag v-if="scope.row.status === 1" type="danger" disable-transitions>{{ this.$t('zy20240205.fileError') }}</el-tag>
           </template>
         </el-table-column>
-        <el-table-column style="text-align: left;" label="操作" width="120" fixed="right">
+        <el-table-column style="text-align: left;" :label="this.$t('action.handle')" width="120" fixed="right">
           <template slot-scope="scope">
             <el-button v-if="scope.row.status === 0" type="success" size="mini" @click="handlerEdit(scope.row)">
-              还原
+              {{ this.$t('zy20240205.restore') }}
             </el-button>
             <el-button v-else type="info" size="mini" @click="handlerDel(scope.row.id)">
-              删除
+              {{ this.$t('action.delete') }}
             </el-button>
           </template>
         </el-table-column>
@@ -47,10 +47,10 @@
           :total="tableData.data_total">
       </el-pagination>
     </div>
-    <el-dialog title="新增备份" :visible.sync="fromDialog" width="700px" :close-on-click-modal="false" :close-on-press-escape="false">
+    <el-dialog :title="this.$t('zy20240205.newBackup')" :visible.sync="fromDialog" width="700px" :close-on-click-modal="false" :close-on-press-escape="false">
       <el-form :model="myForm" ref="myForm" :rules="formRules" label-width="140px">
-        <el-form-item label="数据库" prop="database_name">
-          <el-select v-model="myForm.database_name" filterable allow-create default-first-option placeholder="请选择或输入数据库">
+        <el-form-item :label="this.$t('zy20240205.database')" prop="database_name">
+          <el-select v-model="myForm.database_name" filterable allow-create default-first-option :placeholder="this.$t('zy20240205.inputDatabaseMsg')">
             <el-option v-for="(item, index) in databaseOptions" :key="index" :label="item" :value="item"></el-option>
           </el-select>
         </el-form-item>
@@ -63,8 +63,8 @@
 <!--        <el-form-item v-if="myForm.bool_docker" label="容器名称" prop="container_name">-->
 <!--          <el-input v-model="myForm.container_name" placeholder="默认mysql" />-->
 <!--        </el-form-item>-->
-        <el-form-item label="备份地址" prop="backups_path">
-          <el-input v-model="myForm.backups_path" placeholder="请输入备份地址" clearable />
+        <el-form-item :label="this.$t('zy20240205.backupAddress')" prop="backups_path">
+          <el-input v-model="myForm.backups_path" :placeholder="this.$t('zy20240205.inputBackupAddress')" clearable />
         </el-form-item>
 <!--        <el-form-item label="mysql服务器地址">-->
 <!--          <el-input v-model="myForm.mysql_ip" placeholder="mysql服务器地址" />-->
@@ -73,8 +73,8 @@
 
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button @click="fromDialog = false">取 消</el-button>
-        <el-button type="primary" @click="handleConfirm">确 定</el-button>
+        <el-button @click="fromDialog = false">{{ this.$t('action.cancel') }}</el-button>
+        <el-button type="primary" @click="handleConfirm">{{ this.$t('action.yes') }}</el-button>
       </div>
     </el-dialog>
   </div>
@@ -107,10 +107,10 @@ export default {
         bool_docker: false
       },
       formRules: {
-        database_name: [{ required: true, message: '请选择或输入数据库', trigger: 'change' }],
-        container_name: [{ required: true, message: '请输入容器名称', trigger: 'blur' }],
-        backups_path: [{ required: true, message: '请输入文件存储地址', trigger: 'blur' }],
-        mysql_ip: [{ required: true, message: '请输入mysql服务器地址', trigger: 'blur' }]
+        database_name: [{ required: true, message: this.$t('zy20240205.inputDatabaseMsg'), trigger: 'change' }],
+        container_name: [{ required: true, message: this.$t('zy20240205.inputContainerName'), trigger: 'blur' }],
+        backups_path: [{ required: true, message: this.$t('zy20240205.inputFileAddress'), trigger: 'blur' }],
+        mysql_ip: [{ required: true, message: this.$t('zy20240205.inputMysqlAddress'), trigger: 'blur' }]
       },
       databaseOptions:['wdkl_ncs', 'wdkl_nfc', 'kea'],
       databaseName: '',
@@ -146,14 +146,14 @@ export default {
     },
     /** 点击每页显示数量 **/
     fortDate(row, column, cellValue, index) {
-      if (!cellValue) return '暂无'
+      if (!cellValue) return this.$t('customerManage.null')
       return unix2Date(cellValue * 1000)
     },
     handlerEdit(row) {
-      console.log('还原....',row)
-      this.$confirm('您确定要恢复还原吗?', '警告', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
+      console.log(this.$t('zy20240205.restoreMsg'), row)
+      this.$confirm(this.$t('zy20240205.restoreMsg2'), this.$t('action.waring'), {
+        confirmButtonText: this.$t('action.yes'),
+        cancelButtonText: this.$t('action.cancel'),
         type: 'warning'
       }).then(() => {
         // if (row.mysql_ip === this.API_GetIP()) {
@@ -171,14 +171,14 @@ export default {
         //   })
         // }
       }).catch(() => {
-        console.log('取消删除')
+        console.log(this.$t('action.cancelDelete'))
       })
     },
     /** 单条数据删除处理 */
     handlerDel(ids) {
-      this.$confirm('删除操作后数据不可复原,您确定要删除此数据?', '警告', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
+      this.$confirm(this.$t('zy20240205.deleteSqlMsg'), this.$t('action.waring'), {
+        confirmButtonText: this.$t('action.yes'),
+        cancelButtonText: this.$t('action.cancel'),
         type: 'warning'
       }).then(() => {
         API_MysqlBackups.remove(ids).then(
@@ -186,12 +186,12 @@ export default {
               this.GET_List()
               this.$message({
                 type: 'success',
-                message: '删除成功!'
+                message: this.$t('action.cancel')
               })
             }
         )
       }).catch(() => {
-        console.log('取消删除')
+        console.log(this.$t('action.cancelDelete'))
       })
     },
     handleConfirm() {
@@ -205,7 +205,7 @@ export default {
             _this.$message.info(res.message)
           })
         } else {
-          this.$message.error('表单填写有误,请检查!')
+          this.$message.error(this.$t('action.fromError'))
         }
       })
     },

+ 1 - 1
src/views/ncs-advice/index.vue

@@ -85,7 +85,7 @@
                   value-format="timestamp"
                   :default-value="new Date()"
                   :placeholder="this.$t('customerManage.choiceDate')"
-                  :picker-options="{disabledDate(time) { return time.getTime() > Date.now() }}"
+                  :picker-options="{disabledDate(time) { return time.getTime() < addAdviceForm.start_time }}"
               />
             </el-form-item>
           </el-col>

+ 3 - 2
src/views/ncs-device/components/deviceManager.vue

@@ -224,7 +224,7 @@
                     <el-col :span="8">
                         <el-form-item :label="this.$t('deviceManage.controlLineNumber')" prop="control_line_number">
                             <el-input v-model="deviceModel.control_line_number" clearable
-                                      :placeholder="this.$t('deviceManage.controlLineNumber')" type="text"/>
+                                      :placeholder="this.$t('deviceManage.controlLineNumber')" type="number"/>
                         </el-form-item>
                     </el-col>
                 </el-row>
@@ -248,7 +248,7 @@
                     <el-col :span="8">
                         <el-form-item :label="this.$t('deviceManage.controlLineNumber')" prop="control_line_number">
                             <el-input v-model="deviceModel.control_line_number" clearable
-                                      :placeholder="this.$t('deviceManage.controlLineNumber')" />
+                                      :placeholder="this.$t('deviceManage.controlLineNumber')" type="text"/>
                         </el-form-item>
                     </el-col>
                 </el-row>
@@ -364,6 +364,7 @@
                 </el-row>
             </el-form>
             <div slot="footer" class="dialog-footer">
+
                 <el-button type="primary" @click="updateDevicesServerIp()">{{ this.$t('action.yes') }}</el-button>
             </div>
         </el-dialog>

+ 65 - 54
src/views/ncs-interaction/index.vue

@@ -61,63 +61,61 @@
         @current-change="handlePageCurrentChange"
       />
     </ag-grid-layout>
-      <el-dialog :v-loading="this.loading" :title="this.$t('interaction.recordPlay')" :visible.sync="dialogVisible" :before-close="stop" width="70%">
-        <template>
-          <el-row v-if="this.streamingType">
-            <el-col :span="12">
-              <video
+    <el-dialog :v-loading="this.loading" :title="this.$t('interaction.recordPlay')" :visible.sync="dialogVisible" :before-close="stop" :width="this.streaming2Show ? '70%' : '40%'">
+      <template>
+        <el-row v-if="this.streamingType">
+          <el-col :span="this.streaming2Show ? 12 : 24">
+            <video
+              :src="this.srcStreaming1"
+              autoplay="autoplay"
+              controls="controls"
+              ref="video1"
+              style="width: 98%"
+            >
+            </video>
+          </el-col>
+
+          <el-col :span="12" v-show="this.streaming2Show">
+            <video
+              :src="this.srcStreaming2"
+              autoplay="autoplay"
+              controls="controls"
+              ref="video2"
+              style="width: 98%"
+            >
+            </video>
+          </el-col>
+        </el-row>
+
+        <el-row v-else>
+          <el-col :span="this.streaming2Show ? 12 : 24">
+            <audio
                 :src="this.srcStreaming1"
                 autoplay="autoplay"
                 controls="controls"
-                ref="video1"
+                ref="audio1"
                 style="width: 98%"
-              >
-              </video>
-            </el-col>
+            >
+            </audio>
+          </el-col>
 
-            <el-col :span="12">
-              <video
+          <el-col :span="12" v-show="streaming2Show">
+            <audio
                 :src="this.srcStreaming2"
                 autoplay="autoplay"
                 controls="controls"
-                ref="video2"
+                ref="audio2"
                 style="width: 98%"
-              >
-              </video>
-            </el-col>
-          </el-row>
-
-          <el-row v-else>
-
-            <el-col :span="12">
-              <audio
-                  :src="this.srcStreaming1"
-                  autoplay="autoplay"
-                  controls="controls"
-                  ref="audio1"
-                  style="width: 98%"
-              >
-              </audio>
-            </el-col>
-
-            <el-col :span="12">
-              <audio
-                  :src="this.srcStreaming2"
-                  autoplay="autoplay"
-                  controls="controls"
-                  ref="audio2"
-                  style="width: 98%"
-              >
-              </audio>
-            </el-col>
-          </el-row>
-
-          <div slot="footer" class="dialog-footer" style="text-align: center">
-            <el-button ref="play" type="primary" @click="onclick('onclick')"> {{ this.buttonStr }} </el-button>
-          </div>
-        </template>
-      </el-dialog>
+            >
+            </audio>
+          </el-col>
+        </el-row>
 
+        <div slot="footer" class="dialog-footer" style="text-align: center">
+          <el-button ref="play" type="primary" @click="onclick('onclick')"> {{ this.buttonStr }} </el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -132,6 +130,7 @@ import RecordButtonCellRender from "@/components/AgGridCellRender/RecordButtonCe
 import RadioFilter from "@/components/AgGridCustomFilter/RadioFilter";
 import ListFilter from "@/components/AgGridCustomFilter/ListFilter";
 import * as API_Part from "@/api/ncs_partInfo";
+import * as API_ServiceInfo from "@/api/ncs_service_info";
 const DeviceUrl = domain.DeviceUrl
 
 export default {
@@ -198,8 +197,9 @@ export default {
       beginSeconds: 0,
       buttonStr: this.$t('action.play'),
       dialogVisible: false,
+      streaming2Show: false,
       streamingType: true,
-      recordDir: '',
+      recordDir: ''
     }
   },
   computed: {
@@ -611,13 +611,24 @@ export default {
             this.streamingType = true
           } else if (res[0].endsWith("opus")) {
             this.streamingType = false
+          } else if (res[0].endsWith("wav")) {
+            this.streamingType = false
           }
 
-          this.srcStreaming1 = DeviceUrl + res[0]
-          this.srcStreaming2 = DeviceUrl + res[1]
-          console.log(this.srcStreaming1)
-          console.log(this.srcStreaming2)
-          this.dialogVisible = true
+          if (res.length === 2) {
+            this.streaming2Show = true
+            this.srcStreaming1 = DeviceUrl + res[0]
+            this.srcStreaming2 = DeviceUrl + res[1]
+            console.log(this.srcStreaming1)
+            console.log(this.srcStreaming2)
+            this.dialogVisible = true
+          }
+          else {
+            this.streaming2Show = false
+            this.srcStreaming1 = DeviceUrl + res[0]
+            console.log(this.srcStreaming1)
+            this.dialogVisible = true
+          }
         } else {
           this.$message(this.$t('action.noFile'))
         }
@@ -664,7 +675,7 @@ export default {
         this.$refs.audio2.pause()
       }
       this.dialogVisible = false
-    },
+    }
   }
 }
 </script>

+ 58 - 0
src/views/ncs-orginazition/components/partInfoEdit.vue

@@ -692,6 +692,62 @@
             </el-col>
           </el-row>
 
+          <el-row v-if="isShow">
+            <el-col :span="8">
+              <el-form-item :label="this.$t('zy20240205.linuxSerial1')" prop="linux_serial1">
+                <el-select v-model="formmodel.linux_serial1"
+                           :placeholder="this.$t('zy20240205.choiceSerial')">
+                  <el-option v-for="(item,index) in serialType" :key="index" :label="item.key" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="8">
+              <el-form-item :label="this.$t('zy20240205.linuxSerial2')" prop="linux_serial2">
+                <el-select v-model="formmodel.linux_serial2"
+                           :placeholder="this.$t('zy20240205.choiceSerial')">
+                  <el-option v-for="(item,index) in serialType" :key="index" :label="item.key" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="8">
+              <el-form-item :label="this.$t('zy20240205.linuxSerial3')" prop="linux_serial3">
+                <el-select v-model="formmodel.linux_serial3"
+                           :placeholder="this.$t('zy20240205.choiceSerial')">
+                  <el-option v-for="(item,index) in serialType" :key="index" :label="item.key" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="8">
+              <el-form-item :label="this.$t('zy20240205.androidSerial1')" prop="android_serial1">
+                <el-select v-model="formmodel.android_serial1"
+                           :placeholder="this.$t('zy20240205.choiceSerial')">
+                  <el-option v-for="(item,index) in serialType" :key="index" :label="item.key" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="8">
+              <el-form-item :label="this.$t('zy20240205.androidSerial2')" prop="android_serial2">
+                <el-select v-model="formmodel.android_serial2"
+                           :placeholder="this.$t('zy20240205.choiceSerial')">
+                  <el-option v-for="(item,index) in serialType" :key="index" :label="item.key" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="8">
+              <el-form-item :label="this.$t('zy20240205.androidSerial3')" prop="android_serial3">
+                <el-select v-model="formmodel.android_serial3"
+                           :placeholder="this.$t('zy20240205.choiceSerial')">
+                  <el-option v-for="(item,index) in serialType" :key="index" :label="item.key" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
           <el-row>
             <el-col :span="8">
               <el-form-item :label="this.$t('partInfo.iotProductId')">
@@ -764,6 +820,7 @@ import * as API_SystemConfig from '@/api/ncs_systemconfig'
 import * as API_Device from '@/api/ncs_device'
 import * as API_Excel from "@/api/ncs_excel";
 import moment from  'moment'
+import {SERIAL_TYPE} from "@/utils/enum/SerialTypeEnum";
 const serverUrl = domain.serverUrl
 const DeviceUrl = domain.DeviceUrl
 export default {
@@ -798,6 +855,7 @@ export default {
       imageUrl: '',
       excelUploadUrl: DeviceUrl + '/ncs/excel/upload/' + this.partId,
       excelUploadDemo: serverUrl + '/upload/excel/demo/excel_demo.xlsx',
+      serialType: SERIAL_TYPE.getKeyValueList(),
     }
   },
   async mounted() {

+ 6 - 0
src/views/ncs-orginazition/partInfoSetting.vue

@@ -49,6 +49,12 @@
         </keep-alive>
       </el-tab-pane>
 
+      <el-tab-pane :label="this.$t('zy20240205.linuxPortraitDoor')" name="linuxPortraitDoor">
+        <keep-alive>
+          <app-version-manager :part-id="part_id" :device-type="403" />
+        </keep-alive>
+      </el-tab-pane>
+
       <el-tab-pane :label="this.$t('partInfo.sickbed')" name="sickbed">
         <keep-alive>
           <app-version-manager :part-id="part_id" :device-type="4" />