fix(列表页面): 样式优化

This commit is contained in:
Zhunianya
2026-03-26 16:29:32 +08:00
parent 153d643aff
commit 0143280742
25 changed files with 1151 additions and 1131 deletions

View File

@@ -1,6 +1,6 @@
<template>
<div class="category_wrap">
<el-card v-show="showSearch" style="margin-bottom: 10px">
<el-card shadow="never" v-show="showSearch" style="margin-bottom: 10px">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom: -20px">
<el-form-item :label="$t('product.category.142342-0')" prop="categoryName">
<el-input v-model="queryParams.categoryName" :placeholder="$t('product.index.091251-3')" clearable size="small" @keyup.enter.native="handleQuery" />
@@ -12,7 +12,7 @@
</el-form>
</el-card>
<el-card style="padding-bottom: 100px">
<el-card shadow="never" style="padding-bottom: 100px">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleAdd" v-hasPermi="['iot:category:add']" style="margin-bottom: 10px">{{ $t('add') }}</el-button>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
<el-table v-loading="loading" :data="categoryList" @selection-change="handleSelectionChange" :border="false" header-cell-class-name="table-header">

View File

@@ -1,6 +1,6 @@
<template>
<div style="padding: 20px">
<el-card style="margin-bottom: 15px">
<div class="device_wrap">
<el-card shadow="never" style="margin-bottom: 10px">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="75px" style="margin-bottom: -20px">
<el-form-item :label="$t('device.index.105953-0')" prop="deviceName">
<el-input v-model="queryParams.deviceName" :placeholder="$t('device.index.105953-1')" clearable size="small" @keyup.enter.native="handleQuery" style="width: 150px" />
@@ -18,7 +18,7 @@
<el-option v-for="group in myGroupList" :key="group.groupId" :label="group.groupName" :value="group.groupId" />
</el-select>
</el-form-item>
<el-form-item>
<el-form-item style="float: right">
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">{{ $t('search') }}</el-button>
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">{{ $t('reset') }}</el-button>
<el-button type="text" @click="searchChange">
@@ -28,164 +28,165 @@
<i style="color: #486ff2; margin-left: 10px" :class="{ 'el-icon-arrow-down': !searchShow, 'el-icon-arrow-up': searchShow }"></i>
</el-button>
</el-form-item>
<el-form-item style="float: right">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleEditDevice(0)" v-hasPermi="['iot:device:add']">{{ $t('add') }}</el-button>
<el-button type="primary" plain icon="el-icon-s-grid" size="small" @click="handleChangeShowType" v-hasPermi="['iot:device:add']">{{ $t('device.index.105953-17') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card style="padding-bottom: 100px" v-if="showType == 'list'">
<el-table v-loading="loading" :data="deviceList" :border="false" header-cell-class-name="table-header">
<el-table-column :label="$t('device.index.105953-20')" align="center" header-align="center" prop="deviceId" width="50" />
<el-table-column :label="$t('device.index.105953-0')" align="center" header-align="center" prop="deviceName" min-width="120" />
<el-table-column :label="$t('device.index.105953-2')" align="center" prop="serialNumber" min-width="130" />
<el-table-column :label="$t('device.index.105953-21')" align="center" prop="productName" min-width="120" />
<el-table-column :label="$t('device.index.105953-22')" align="center" prop="transport" min-width="50" />
<el-table-column :label="$t('device.index.105953-23')" align="center" prop="protocolCode" min-width="100" />
<el-table-column :label="$t('device.index.105953-24')" align="center" prop="subDeviceCount" width="80">
<template slot-scope="scope">
{{ scope.row.subDeviceCount }}
</template>
</el-table-column>
<el-table-column :label="$t('device.device-edit.148398-15')" align="center" prop="isShadow" width="80">
<template slot-scope="scope">
<el-tag type="success" size="small" v-if="scope.row.isShadow == 1">{{ $t('device.index.105953-26') }}</el-tag>
<el-tag type="info" size="small" v-else>{{ $t('device.index.105953-27') }}</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('status')" align="center" prop="status" width="80">
<template slot-scope="scope">
<dict-tag :options="dict.type.iot_device_status" :value="scope.row.status" size="small" />
</template>
</el-table-column>
<el-table-column :label="$t('device.index.105953-29')" align="center" prop="rssi" width="60">
<template slot-scope="scope">
<svg-icon v-if="scope.row.status == 3 && scope.row.rssi >= '-55'" icon-class="wifi_4" />
<svg-icon v-else-if="scope.row.status == 3 && scope.row.rssi >= '-70' && scope.row.rssi < '-55'" icon-class="wifi_3" />
<svg-icon v-else-if="scope.row.status == 3 && scope.row.rssi >= '-85' && scope.row.rssi < '-70'" icon-class="wifi_2" />
<svg-icon v-else-if="scope.row.status == 3 && scope.row.rssi >= '-100' && scope.row.rssi < '-85'" icon-class="wifi_1" />
<svg-icon v-else icon-class="wifi_0" />
</template>
</el-table-column>
<el-table-column :label="$t('device.index.105953-30')" align="center" prop="locationWay">
<template slot-scope="scope">
<dict-tag :options="dict.type.iot_location_way" :value="scope.row.locationWay" size="small" />
</template>
</el-table-column>
<el-table-column :label="$t('device.index.105953-31')" align="center" prop="firmwareVersion">
<template slot-scope="scope">
<el-tag size="small" type="info">Ver {{ scope.row.firmwareVersion }}</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('device.index.105953-32')" align="center" prop="activeTime">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.activeTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('creatTime')" align="center" prop="createTime">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-card shadow="never" style="padding-bottom: 100px">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleEditDevice(0)" style="margin-bottom: 10px" v-hasPermi="['iot:device:add']">{{ $t('add') }}</el-button>
<el-button type="primary" plain icon="el-icon-s-grid" size="small" @click="handleChangeShowType" v-hasPermi="['iot:device:add']">{{ $t('device.index.105953-17') }}</el-button>
<div v-if="showType == 'list'">
<el-table v-loading="loading" :data="deviceList" :border="false" header-cell-class-name="table-header">
<el-table-column :label="$t('device.index.105953-20')" align="center" header-align="center" prop="deviceId" width="50" />
<el-table-column :label="$t('device.index.105953-0')" align="center" header-align="center" prop="deviceName" min-width="120" />
<el-table-column :label="$t('device.index.105953-2')" align="center" prop="serialNumber" min-width="130" />
<el-table-column :label="$t('device.index.105953-21')" align="center" prop="productName" min-width="120" />
<el-table-column :label="$t('device.index.105953-22')" align="center" prop="transport" min-width="50" />
<el-table-column :label="$t('device.index.105953-23')" align="center" prop="protocolCode" min-width="100" />
<el-table-column :label="$t('device.index.105953-24')" align="center" prop="subDeviceCount" width="80">
<template slot-scope="scope">
{{ scope.row.subDeviceCount }}
</template>
</el-table-column>
<el-table-column :label="$t('device.device-edit.148398-15')" align="center" prop="isShadow" width="80">
<template slot-scope="scope">
<el-tag type="success" size="small" v-if="scope.row.isShadow == 1">{{ $t('device.index.105953-26') }}</el-tag>
<el-tag type="info" size="small" v-else>{{ $t('device.index.105953-27') }}</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('status')" align="center" prop="status" width="80">
<template slot-scope="scope">
<dict-tag :options="dict.type.iot_device_status" :value="scope.row.status" size="small" />
</template>
</el-table-column>
<el-table-column :label="$t('device.index.105953-29')" align="center" prop="rssi" width="60">
<template slot-scope="scope">
<svg-icon v-if="scope.row.status == 3 && scope.row.rssi >= '-55'" icon-class="wifi_4" />
<svg-icon v-else-if="scope.row.status == 3 && scope.row.rssi >= '-70' && scope.row.rssi < '-55'" icon-class="wifi_3" />
<svg-icon v-else-if="scope.row.status == 3 && scope.row.rssi >= '-85' && scope.row.rssi < '-70'" icon-class="wifi_2" />
<svg-icon v-else-if="scope.row.status == 3 && scope.row.rssi >= '-100' && scope.row.rssi < '-85'" icon-class="wifi_1" />
<svg-icon v-else icon-class="wifi_0" />
</template>
</el-table-column>
<el-table-column :label="$t('device.index.105953-30')" align="center" prop="locationWay">
<template slot-scope="scope">
<dict-tag :options="dict.type.iot_location_way" :value="scope.row.locationWay" size="small" />
</template>
</el-table-column>
<el-table-column :label="$t('device.index.105953-31')" align="center" prop="firmwareVersion">
<template slot-scope="scope">
<el-tag size="small" type="info">Ver {{ scope.row.firmwareVersion }}</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('device.index.105953-32')" align="center" prop="activeTime">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.activeTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('creatTime')" align="center" prop="createTime">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('opation')" align="center" class-name="small-padding fixed-width" width="200">
<template slot-scope="scope">
<el-button type="text" size="small" style="padding: 5px" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:device:remove']">{{ $t('del') }}</el-button>
<el-button type="text" size="small" style="padding: 5px" icon="el-icon-view" @click="handleEditDevice(scope.row)" v-hasPermi="['iot:device:add']">{{ $t('look') }}</el-button>
<el-button type="text" size="small" style="padding: 5px" @click="openSummaryDialog(scope.row)" v-if="form.deviceId != 0">{{ $t('device.index.105953-37') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :pageSizes="[12, 24, 36, 60]" @pagination="getList" />
<el-table-column :label="$t('opation')" align="center" class-name="small-padding fixed-width" width="200">
<template slot-scope="scope">
<el-button type="text" size="small" style="padding: 5px" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:device:remove']">{{ $t('del') }}</el-button>
<el-button type="text" size="small" style="padding: 5px" icon="el-icon-view" @click="handleEditDevice(scope.row)" v-hasPermi="['iot:device:add']">{{ $t('look') }}</el-button>
<el-button type="text" size="small" style="padding: 5px" @click="openSummaryDialog(scope.row)" v-if="form.deviceId != 0">{{ $t('device.index.105953-37') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :pageSizes="[12, 24, 36, 60]" @pagination="getList" />
</div>
</div>
<div style="padding-bottom: 100px" v-if="showType == 'card'">
<el-row :gutter="20" v-loading="loading">
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="(item, index) in deviceList" :key="index" style="margin-bottom: 20px">
<el-card shadow="hover" class="device-card">
<div class="card-header">
<div class="device-name" @click="handleEditDevice(item)">
<span>{{ item.deviceName }}</span>
</div>
<div class="header-status">
<dict-tag :options="dict.type.iot_device_status" :value="item.status" size="mini" />
</div>
</div>
<div class="card-time">
{{ parseTime(item.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
</div>
<div class="card-info">
<div class="info-row">
<span class="info-value" style="width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ $t('device.device-edit.148398-4') }}
<el-tooltip :content="item.productName || '---'" placement="top">
<span>{{ item.productName || '---' }}</span>
</el-tooltip>
</span>
</div>
<div class="info-row">
<span class="info-value" style="width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ $t('device.device-edit.148398-7') }}
<el-tooltip :content="item.serialNumber || '---'" placement="top">
<span>{{ item.serialNumber || '---' }}</span>
</el-tooltip>
</span>
</div>
<div class="info-row" v-if="item.transport">
<span class="info-value">{{ $t('product.product-edit.473153-14') }}{{ item.transport }}</span>
</div>
<div class="info-row">
<span class="info-value" style="width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ $t('device.index.105953-23') }}
<el-tooltip :content="item.protocolCode || '--'" placement="top">
<span>{{ item.protocolCode || '--' }}</span>
</el-tooltip>
</span>
</div>
</div>
<div class="card-footer">
<div class="footer-left">
<el-tooltip :content="$t('device.device-edit.148398-56')" placement="top">
<svg-icon icon-class="qrcode" @click="openSummaryDialog(item)" />
</el-tooltip>
<div class="wifi-signal">
<svg-icon v-if="item.status == 3 && item.rssi >= '-55'" icon-class="wifi_4" />
<svg-icon v-else-if="item.status == 3 && item.rssi >= '-70' && item.rssi < '-55'" icon-class="wifi_3" />
<svg-icon v-else-if="item.status == 3 && item.rssi >= '-85' && item.rssi < '-70'" icon-class="wifi_2" />
<svg-icon v-else-if="item.status == 3 && item.rssi >= '-100' && item.rssi < '-85'" icon-class="wifi_1" />
<svg-icon v-else icon-class="wifi_0" />
</div>
</div>
<div class="footer-actions">
<el-tooltip :content="$t('edit')" placement="top">
<i class="el-icon-edit-outline" @click="handleEditDevice(item)"></i>
</el-tooltip>
<el-tooltip :content="$t('look')" placement="top">
<i class="el-icon-view" @click="handleEditDevice(item, 'basic')"></i>
</el-tooltip>
<el-tooltip :content="$t('del')" placement="top">
<i class="el-icon-delete" @click="handleDelete(item)"></i>
</el-tooltip>
<el-tooltip :content="$t('device.index.105953-40')" placement="top">
<i class="el-icon-odometer" @click="handleRunDevice(item)"></i>
</el-tooltip>
</div>
</div>
</el-card>
</el-col>
</el-row>
<el-empty :description="$t('device.index.105953-41')" v-if="total == 0"></el-empty>
<div class="pagination-container">
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :pageSizes="[12, 24, 36, 60]" @pagination="getList" />
</div>
</div>
</el-card>
<div style="padding-bottom: 100px" v-if="showType == 'card'">
<el-row :gutter="20" v-loading="loading">
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="(item, index) in deviceList" :key="index" style="margin-bottom: 20px">
<el-card shadow="hover" class="device-card">
<div class="card-header">
<div class="device-name" @click="handleEditDevice(item)">
<span>{{ item.deviceName }}</span>
</div>
<div class="header-status">
<dict-tag :options="dict.type.iot_device_status" :value="item.status" size="mini" />
</div>
</div>
<div class="card-time">
{{ parseTime(item.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
</div>
<div class="card-info">
<div class="info-row">
<span class="info-value" style="width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ $t('device.device-edit.148398-4') }}
<el-tooltip :content="item.productName || '---'" placement="top">
<span>{{ item.productName || '---' }}</span>
</el-tooltip>
</span>
</div>
<div class="info-row">
<span class="info-value" style="width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ $t('device.device-edit.148398-7') }}
<el-tooltip :content="item.serialNumber || '---'" placement="top">
<span>{{ item.serialNumber || '---' }}</span>
</el-tooltip>
</span>
</div>
<div class="info-row" v-if="item.transport">
<span class="info-value">{{ $t('product.product-edit.473153-14') }}{{ item.transport }}</span>
</div>
<div class="info-row">
<span class="info-value" style="width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ $t('device.index.105953-23') }}
<el-tooltip :content="item.protocolCode || '--'" placement="top">
<span>{{ item.protocolCode || '--' }}</span>
</el-tooltip>
</span>
</div>
</div>
<div class="card-footer">
<div class="footer-left">
<el-tooltip :content="$t('device.device-edit.148398-56')" placement="top">
<svg-icon icon-class="qrcode" @click="openSummaryDialog(item)" />
</el-tooltip>
<div class="wifi-signal">
<svg-icon v-if="item.status == 3 && item.rssi >= '-55'" icon-class="wifi_4" />
<svg-icon v-else-if="item.status == 3 && item.rssi >= '-70' && item.rssi < '-55'" icon-class="wifi_3" />
<svg-icon v-else-if="item.status == 3 && item.rssi >= '-85' && item.rssi < '-70'" icon-class="wifi_2" />
<svg-icon v-else-if="item.status == 3 && item.rssi >= '-100' && item.rssi < '-85'" icon-class="wifi_1" />
<svg-icon v-else icon-class="wifi_0" />
</div>
</div>
<div class="footer-actions">
<el-tooltip :content="$t('edit')" placement="top">
<i class="el-icon-edit-outline" @click="handleEditDevice(item)"></i>
</el-tooltip>
<el-tooltip :content="$t('look')" placement="top">
<i class="el-icon-view" @click="handleEditDevice(item, 'basic')"></i>
</el-tooltip>
<el-tooltip :content="$t('del')" placement="top">
<i class="el-icon-delete" @click="handleDelete(item)"></i>
</el-tooltip>
<el-tooltip :content="$t('device.index.105953-40')" placement="top">
<i class="el-icon-odometer" @click="handleRunDevice(item)"></i>
</el-tooltip>
</div>
</div>
</el-card>
</el-col>
</el-row>
<el-empty :description="$t('device.index.105953-41')" v-if="total == 0"></el-empty>
<div class="pagination-container">
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :pageSizes="[12, 24, 36, 60]" @pagination="getList" />
</div>
</div>
<!-- 二维码 -->
<el-dialog :visible.sync="openSummary" width="300px" append-to-body>
<div style="border: 1px solid #ccc; width: 220px; text-align: center; margin: 0 auto; margin-top: -15px">
@@ -498,8 +499,10 @@ export default {
</script>
<style lang="scss" scoped>
.card-item {
border-radius: 15px;
.device_wrap {
padding: 15px;
min-height: 100vh;
background-color: #f5f7fa;
}
.table-header {
@@ -511,7 +514,6 @@ export default {
::v-deep .el-table {
th {
background-color: #f5f7fa;
color: #606266;
font-weight: 600;
text-align: center;
@@ -637,16 +639,4 @@ export default {
}
}
}
.pagination-container {
line-height: 40px;
margin-bottom: 30px;
margin-top: 0;
padding: 0;
}
::v-deep .el-pagination {
padding: 0;
text-align: right;
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="group_wrap">
<el-card v-show="showSearch" style="margin-bottom: 10px">
<el-card shadow="never" v-show="showSearch" style="margin-bottom: 10px">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px" style="margin-bottom: -20px">
<el-form-item :label="$t('iot.group.index.637432-0')" prop="groupName">
<el-input v-model="queryParams.groupName" :placeholder="$t('iot.group.index.637432-1')" clearable size="small" @keyup.enter.native="handleQuery" />
@@ -15,7 +15,7 @@
</el-form>
</el-card>
<el-card style="padding-bottom: 100px">
<el-card shadow="never" style="padding-bottom: 100px">
<el-button v-hasPermi="['iot:group:add']" type="primary" plain icon="el-icon-plus" size="small" @click="handleAdd" style="margin-bottom: 10px">{{ $t('iot.group.index.637432-5') }}</el-button>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
<el-table v-loading="loading" :data="groupList" :border="false" @selection-change="handleSelectionChange">

View File

@@ -1,6 +1,6 @@
<template>
<div class="clients_wrap">
<el-card v-show="showSearch" style="margin-bottom: 10px">
<el-card shadow="never" v-show="showSearch" style="margin-bottom: 10px">
<el-form @submit.native.prevent :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom: -20px">
<el-form-item :label="$t('netty.clients.654908-0')" prop="clientId">
<el-input v-model="queryParams.clientId" :placeholder="$t('netty.clients.654908-1')" clearable size="small" @keyup.enter.native="handleQuery" />
@@ -15,7 +15,7 @@
</el-form>
</el-card>
<el-card style="padding-bottom: 100px">
<el-card shadow="never" style="padding-bottom: 100px">
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
<el-table v-loading="loading" :data="clientList" :border="false">
<el-table-column :label="$t('netty.clients.654908-4')" align="left" header-align="center" prop="clientId">

View File

@@ -36,7 +36,7 @@
</el-form-item>
</el-form>
</el-card>
<el-card>
<el-card shadow="never">
<el-row :gutter="10" class="mb8" style="margin-bottom: 10px">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleAdd" v-hasPermi="['iot:news:add']">{{ $t('system.sysclient.652154-4') }}</el-button>

View File

@@ -1,123 +1,114 @@
<template>
<div style="padding:6px;">
<el-card style="margin-bottom:5px;">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom:-20px;">
<el-form-item :label="$t('product.index.091251-0')" prop="productName">
<el-input v-model="queryParams.productName" :placeholder="$t('product.index.091251-1')" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item :label="$t('product.index.091251-2')" prop="categoryName">
<el-input v-model="queryParams.categoryName" :placeholder="$t('product.index.091251-3')" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item :label="$t('product.index.091251-4')" prop="status">
<el-select v-model="queryParams.status" :placeholder="$t('product.index.091251-5')" clearable size="small">
<el-option v-for="dict in dict.type.iot_product_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">{{ $t('search') }}</el-button>
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">{{ $t('reset') }}</el-button>
</el-form-item>
<el-form-item style="float:right;">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleEditProduct(0)" v-hasPermi="['iot:product:add']">{{ $t('add') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card style="padding-bottom:100px;">
<el-row :gutter="30" v-loading="loading">
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="(item,index) in productList" :key="index" style="margin-bottom:30px;text-align:center;">
<el-card :body-style="{ padding: '20px'}" shadow="always" class="card-item">
<el-row type="flex" :gutter="10" justify="space-between">
<el-col :span="20" style="text-align:left;">
<el-link type="" :underline="false" @click="handleEditProduct(item)" style="font-weight:bold;font-size:16px;line-height:32px;white-space:nowrap;">
<svg-icon icon-class="product" /> {{item.productName}}
<el-tag type="info" size="small" style="margin-left:5px;font-weight:200" v-if="item.isSys==1">{{ $t('product.index.091251-47') }}</el-tag>
</el-link>
</el-col>
<el-col :span="4">
<el-tooltip class="item" effect="dark" :content="$t('product.index.091251-12')" placement="top-start" v-if="item.status==2">
<el-button type="success" size="small" style="padding:5px;" @click="changeProductStatus(item.productId,1,item.deviceType)">{{ $t('product.index.091251-13') }}</el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" :content="$t('product.index.091251-14')" placement="top-start" v-if="item.status==1">
<el-button type="info" size="small" style="padding:5px;" @click="changeProductStatus(item.productId,2,item.deviceType)">{{ $t('product.index.091251-15') }}</el-button>
</el-tooltip>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="14">
<el-descriptions :column="1" size="small" style="margin-top:10px;white-space:nowrap;">
<el-descriptions-item :label="$t('product.index.091251-16')">
<el-link type="primary" :underline="false">{{item.categoryName}}</el-link>
</el-descriptions-item>
<el-descriptions-item :label="$t('product.index.091251-17')">
<dict-tag :options="dict.type.iot_device_type" :value="item.deviceType" />
</el-descriptions-item>
<el-descriptions-item :label="$t('product.index.091251-18')">
<dict-tag :options="dict.type.iot_network_method" :value="item.networkMethod" />
</el-descriptions-item>
<el-descriptions-item :label="$t('product.index.091251-19')">
<el-tag type="success" size="small" v-if="item.isAuthorize==1">{{ $t('product.index.091251-20') }}</el-tag>
<el-tag type="info" size="small" v-else>{{ $t('product.index.091251-21') }}</el-tag>
</el-descriptions-item>
</el-descriptions>
</el-col>
<el-col :span="10">
<div style="margin-top:10px;">
<el-image style="width:100%;height:100px;border-radius:10px;" lazy :preview-src-list="[baseUrl+item.imgUrl]" :src="baseUrl+item.imgUrl" fit="cover" v-if="item.imgUrl!=null && item.imgUrl!=''"></el-image>
<el-image style="width:100%;height:100px;border-radius:10px;" :preview-src-list="[require('@/assets/images/gateway.png')]" :src="require('@/assets/images/gateway.png')" fit="cover" v-else-if="item.deviceType==2"></el-image>
<el-image style="width:100%;height:100px;border-radius:10px;" :preview-src-list="[require('@/assets/images/video.png')]" :src="require('@/assets/images/video.png')" fit="cover" v-else-if="item.deviceType==3"></el-image>
<el-image style="width:100%;height:100px;border-radius:10px;" :preview-src-list="[require('@/assets/images/product.png')]" :src="require('@/assets/images/product.png')" fit="cover" v-else></el-image>
</div>
</el-col>
</el-row>
<el-button-group style="margin-top:15px;height:28px;">
<el-button size="small" type="primary" icon="el-icon-view" @click="handleEditProduct(item)" v-hasPermi="['iot:product:query']">{{ $t('product.index.091251-48') }}</el-button>
<el-button size="small" type="danger" icon="el-icon-delete" @click="handleDelete(item)" v-hasPermi="['iot:product:remove']" v-if="item.status==1">{{ $t('product.index.091251-23') }}</el-button>
<el-button size="small" type="success" icon="el-icon-s-check" @click="handleDeviceAuthorize(item)" v-hasPermi="['iot:product:edit']" v-if="item.status==2" :disabled="item.isAuthorize!=1">{{ $t('product.index.091251-19') }}</el-button>
<el-button size="small" type="warning" icon="el-icon-search" @click="handleViewDevice(item.productId)" v-hasPermi="['iot:device:query']">{{ $t('product.index.091251-24') }}</el-button>
</el-button-group>
</el-card>
</el-col>
</el-row>
<el-empty :description="$t('product.index.091251-25')" v-if="total==0"></el-empty>
<div class="pagination-container">
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :pageSizes="[12, 24, 36, 60]" @pagination="getList" />
</div>
<!-- 下载SDK -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-link type="danger" style="padding-left:10px;" :underline="false">{{ $t('product.index.091251-26') }}</el-link>
<el-form label-width="80px">
<el-form-item :label="$t('product.index.091251-27')">
<el-radio-group v-model="form.datatype">
<el-radio v-for="dict in dict.type.iot_device_chip" :key="dict.value" :label="dict.value" style="margin-top:15px;width:160px;">{{dict.label}}</el-radio>
</el-radio-group>
<div class="product_wrap">
<el-card shadow="never" style="margin-bottom: 10px; border-radius: 5px">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom: -20px">
<el-form-item :label="$t('product.index.091251-0')" prop="productName">
<el-input v-model="queryParams.productName" :placeholder="$t('product.index.091251-1')" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item :label="$t('product.index.091251-2')" prop="categoryName">
<el-input v-model="queryParams.categoryName" :placeholder="$t('product.index.091251-3')" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item :label="$t('product.index.091251-4')" prop="status">
<el-select v-model="queryParams.status" :placeholder="$t('product.index.091251-5')" clearable size="small">
<el-option v-for="dict in dict.type.iot_product_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item style="float: right">
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">{{ $t('search') }}</el-button>
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">{{ $t('reset') }}</el-button>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="downloadSdk" disabled>{{ $t('product.index.091251-28') }}</el-button>
<el-button @click="cancel">{{ $t('product.index.091251-29') }}</el-button>
</div>
</el-dialog>
</el-card>
<el-card shadow="never" style="border-radius: 5px">
<el-button type="primary" plain icon="el-icon-plus" style="margin-bottom: 10px" size="small" @click="handleEditProduct(0)" v-hasPermi="['iot:product:add']">{{ $t('add') }}</el-button>
<el-row :gutter="20" v-loading="loading">
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="(item, index) in productList" :key="index" style="margin-bottom: 20px">
<el-card shadow="hover" class="product-card">
<div class="card-header">
<div class="product-name" @click="handleEditProduct(item)">
<span>{{ item.productName }}</span>
<el-tag type="info" size="mini" style="margin-left: 8px; font-weight: normal" v-if="item.isSys == 1">{{ $t('product.index.091251-47') }}</el-tag>
</div>
<div class="header-status">
<dict-tag :options="dict.type.iot_product_status" :value="item.status" size="mini" />
</div>
</div>
</el-card>
</div>
<div class="card-time">
{{ parseTime(item.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
</div>
<div class="card-info">
<div class="info-row">
<span class="info-value">{{ $t('product.index.091251-16') }}{{ item.categoryName }}</span>
</div>
<div class="info-row">
<span class="info-value" style="display: flex">
{{ $t('product.index.091251-17') }}
<dict-tag :options="dict.type.iot_device_type" :value="item.deviceType" size="mini" />
</span>
</div>
<div class="info-row">
<span class="info-value" style="display: flex">
{{ $t('product.index.091251-18') }}
<dict-tag :options="dict.type.iot_network_method" :value="item.networkMethod" size="mini" />
</span>
</div>
<div class="info-row">
<span class="info-value">
{{ $t('product.index.091251-19') }}
<el-tag type="success" size="mini" v-if="item.isAuthorize == 1">{{ $t('product.index.091251-20') }}</el-tag>
<el-tag type="info" size="mini" v-else>{{ $t('product.index.091251-21') }}</el-tag>
</span>
</div>
</div>
<div class="card-footer">
<div class="footer-left"></div>
<div class="footer-actions">
<i class="el-icon-edit-outline" @click="handleEditProduct(item)" :title="$t('product.index.091251-48')"></i>
<i class="el-icon-view" @click="handleViewDevice(item.productId)" :title="$t('product.index.091251-24')"></i>
<i class="el-icon-delete" @click="handleDelete(item)" v-if="item.status == 1" :title="$t('product.index.091251-23')"></i>
<i class="el-icon-s-check" @click="handleDeviceAuthorize(item)" v-if="item.status == 2" :title="$t('product.index.091251-19')"></i>
</div>
</div>
</el-card>
</el-col>
</el-row>
<el-empty :description="$t('product.index.091251-25')" v-if="total == 0"></el-empty>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :pageSizes="[12, 24, 36, 60]" @pagination="getList" />
<!-- 下载SDK -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-link type="danger" style="padding-left: 10px" :underline="false">{{ $t('product.index.091251-26') }}</el-link>
<el-form label-width="80px">
<el-form-item :label="$t('product.index.091251-27')">
<el-radio-group v-model="form.datatype">
<el-radio v-for="dict in dict.type.iot_device_chip" :key="dict.value" :label="dict.value" style="margin-top: 15px; width: 160px">{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="downloadSdk" disabled>{{ $t('product.index.091251-28') }}</el-button>
<el-button @click="cancel">{{ $t('product.index.091251-29') }}</el-button>
</div>
</el-dialog>
</el-card>
</div>
</template>
<script>
import {
listProduct,
delProduct,
changeProductStatus,
deviceCount,
} from "@/api/iot/product";
import { listProduct, delProduct, changeProductStatus, deviceCount } from '@/api/iot/product';
import {
checkPermi
} from "@/utils/permission"
import { checkPermi } from '@/utils/permission';
import RightToolbar from '@/components/RightToolbar';
export default {
name: "Product",
name: 'Product',
components: {
RightToolbar,
},
dicts: ['iot_yes_no', 'iot_product_status', 'iot_device_type', 'iot_network_method', 'iot_vertificate_method', 'iot_device_chip'],
data() {
return {
@@ -128,7 +119,7 @@ export default {
// 产品表格数据
productList: [],
// 弹出层标题
title: "",
title: '',
// 是否显示弹出层
open: false,
// 查询参数
@@ -148,6 +139,8 @@ export default {
// 表单参数
form: {},
baseUrl: process.env.VUE_APP_BASE_API,
// 显示搜索条件
showSearch: true,
};
},
created() {
@@ -165,7 +158,7 @@ export default {
/** 查询产品列表 */
getList() {
this.loading = true;
listProduct(this.queryParams).then(response => {
listProduct(this.queryParams).then((response) => {
this.productList = response.rows;
this.total = response.total;
this.loading = false;
@@ -174,12 +167,14 @@ export default {
/**同步获取产品下的设备数量**/
getDeviceCountByProductId(productId) {
return new Promise((resolve, reject) => {
deviceCount(productId).then(res => {
resolve(res);
}).catch(error => {
reject(error);
})
})
deviceCount(productId)
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
});
});
},
/** 更新产品状态 */
async changeProductStatus(productId, status, deviceType) {
@@ -207,17 +202,21 @@ export default {
this.$confirm(message, this.$t('product.index.091251-34'), {
confirmButtonText: this.$t('product.index.091251-35'),
cancelButtonText: this.$t('cancel'),
type: 'warning'
}).then(() => {
let data = {};
data.productId = productId;
data.status = status;
data.deviceType = deviceType;
changeProductStatus(data).then(response => {
this.getList();
this.$modal.alertSuccess(response.msg);
}).catch(() => {});
}).catch(() => {});
type: 'warning',
})
.then(() => {
let data = {};
data.productId = productId;
data.status = status;
data.deviceType = deviceType;
changeProductStatus(data)
.then((response) => {
this.getList();
this.$modal.alertSuccess(response.msg);
})
.catch(() => {});
})
.catch(() => {});
},
/** 查看设备按钮操作 */
handleViewDevice(productId) {
@@ -226,7 +225,7 @@ export default {
query: {
t: Date.now(),
productId: productId,
}
},
});
},
// 取消按钮
@@ -242,63 +241,181 @@ export default {
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.resetForm('queryForm');
this.handleQuery();
},
/** 生成SDK */
handleGeneratorSDK(row) {
this.title = this.$t('product.index.091251-38')
this.title = this.$t('product.index.091251-38');
this.open = true;
},
/** 下载SDK */
downloadSdk() {
this.$download.zip("/iot/tool/genSdk?deviceChip=" + 1, "fastbee-sdk");
this.$download.zip('/iot/tool/genSdk?deviceChip=' + 1, 'fastbee-sdk');
},
/** 删除按钮操作 */
handleDelete(row) {
const productIds = row.productId || this.ids;
let msg = "";
this.$modal.confirm(this.$i18n.t('product.index.091251-39', [productIds])).then(function () {
// // 删除SIP配置
// delSipconfigByProductId(productIds).then(response => {});
return delProduct(productIds);
}).then(() => {
this.getList();
this.$modal.msgSuccess(msg);
}).catch(() => {});
let msg = '';
this.$modal
.confirm(this.$i18n.t('product.index.091251-39', [productIds]))
.then(function () {
// // 删除SIP配置
// delSipconfigByProductId(productIds).then(response => {});
return delProduct(productIds);
})
.then(() => {
this.getList();
this.$modal.msgSuccess(msg);
})
.catch(() => {});
},
/** 修改按钮操作 */
handleEditProduct(row) {
let productId = 0;
if (row != 0) {
productId = row.productId || this.ids
productId = row.productId || this.ids;
}
this.$router.push({
path: '/iot/product-edit',
query: {
productId: productId,
pageNum: this.queryParams.pageNum
}
pageNum: this.queryParams.pageNum,
},
});
},
/** 设备授权操作 */
handleDeviceAuthorize(row) {
let productId = row.productId
let productId = row.productId;
this.$router.push({
path: '/iot/product-edit',
query: {
productId: productId,
tabPanelName: 'productAuthorize',
pageNum: this.queryParams.pageNum
}
pageNum: this.queryParams.pageNum,
},
});
},
}
},
};
</script>
<style scoped>
.card-item {
border-radius: 15px;
<style lang="scss" scoped>
.product_wrap {
padding: 15px;
min-height: 100vh;
background-color: #f5f7fa !important;
.toolbar {
margin-bottom: 15px;
display: flex;
justify-content: space-between;
align-items: center;
}
}
.product-card {
border-radius: 8px;
// transition: all 0.3s;
&:hover {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-color: #409eff;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
.product-name {
cursor: pointer;
font-weight: 600;
font-size: 15px;
color: #303133;
display: flex;
align-items: center;
&:hover {
color: #409eff;
}
}
.header-status {
flex-shrink: 0;
}
}
.card-time {
font-size: 12px;
color: #909399;
margin-bottom: 16px;
}
.card-info {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-bottom: 16px;
.info-row {
display: flex;
flex-direction: column;
.info-label {
font-size: 12px;
color: #909399;
margin-bottom: 4px;
}
.info-value {
font-size: 13px;
color: #606266;
}
}
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid #f0f0f0;
padding-top: 12px;
.footer-left {
i {
font-size: 18px;
color: #606266;
cursor: pointer;
transition: all 0.3s;
&:hover {
color: #409eff;
}
}
}
.footer-actions {
display: flex;
align-items: center;
gap: 12px;
i {
font-size: 18px;
color: #606266;
cursor: pointer;
transition: all 0.3s;
&:hover {
color: #409eff;
}
&.el-icon-delete:hover {
color: #f56c6c;
}
}
}
}
}
</style>

View File

@@ -1,8 +1,11 @@
<template>
<el-card style="margin:6px;padding-bottom:100px;">
<el-tabs v-model="activeName" tab-position="left" style="padding:10px;min-height:400px;" @tab-click="tabChange">
<el-card style="margin: 6px; padding-bottom: 100px">
<el-tabs v-model="activeName" tab-position="left" style="padding: 10px; min-height: 400px" @tab-click="tabChange">
<el-tab-pane name="basic">
<span slot="label"><span style="color:red;">* </span>{{ $t('product.product-edit.473153-0') }}</span>
<span slot="label">
<span style="color: red">*</span>
{{ $t('product.product-edit.473153-0') }}
</span>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="100">
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8">
@@ -10,124 +13,122 @@
<el-input v-model="form.productName" :placeholder="$t('product.product-edit.473153-2')" :readonly="form.status == 2" />
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-3')" prop="categoryId">
<el-select v-model="form.categoryId" :placeholder="$t('product.product-edit.473153-4')" @change="selectCategory"
style="width:100%" :disabled="form.status == 2">
<el-option v-for="category in categoryShortList" :key="category.id"
:label="category.name" :value="category.id"></el-option>
<el-select v-model="form.categoryId" :placeholder="$t('product.product-edit.473153-4')" @change="selectCategory" style="width: 100%" :disabled="form.status == 2">
<el-option v-for="category in categoryShortList" :key="category.id" :label="category.name" :value="category.id"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-78')" prop="deviceType">
<el-select v-model="form.deviceType" :placeholder="$t('product.product-edit.473153-98')" @change="deviceTypeChange" :disabled="form.status == 2"
style="width:100%">
<el-option v-for="dict in dict.type.iot_device_type" :key="dict.value"
:label="dict.label" :value="parseInt(dict.value)"></el-option>
<el-select v-model="form.deviceType" :placeholder="$t('product.product-edit.473153-98')" @change="deviceTypeChange" :disabled="form.status == 2" style="width: 100%">
<el-option v-for="dict in dict.type.iot_device_type" :key="dict.value" :label="dict.label" :value="Number(dict.value)"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-14')" prop="transport">
<el-select v-model="form.transport" :placeholder="$t('product.product-edit.473153-15')" style="width: 100%"
:disabled="true">
<el-option v-for="dict in dict.type.iot_transport_type" :key="dict.value"
:label="dict.label" :value="dict.value" />
<el-select v-model="form.transport" :placeholder="$t('product.product-edit.473153-15')" style="width: 100%" :disabled="true">
<el-option v-for="dict in dict.type.iot_transport_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-97')" prop="protocolCode">
<el-select v-model="form.protocolCode" :placeholder="$t('product.product-edit.473153-4')" style="width: 100%"
:disabled="form.status == 2" @change="changeProductCode">
<el-option v-for="p in protocolList" :key="p.protocolCode" :label="p.protocolName"
:value="p.protocolCode" />
</el-select>
<el-select v-model="form.protocolCode" :placeholder="$t('product.product-edit.473153-4')" style="width: 100%" :disabled="form.status == 2" @change="changeProductCode">
<el-option v-for="p in protocolList" :key="p.protocolCode" :label="p.protocolName" :value="p.protocolCode" />
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-16')" prop="networkMethod">
<el-select v-model="form.networkMethod" :placeholder="$t('product.product-edit.473153-17')" style="width:100%;"
:disabled="form.status == 2">
<el-option v-for="dict in dict.type.iot_network_method" :key="dict.value"
:label="dict.label" :value="parseInt(dict.value)"></el-option>
<el-select v-model="form.networkMethod" :placeholder="$t('product.product-edit.473153-17')" style="width: 100%" :disabled="form.status == 2">
<el-option v-for="dict in dict.type.iot_network_method" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-32')" prop="remark">
<el-input v-model="form.remark" type="textarea" :placeholder="$t('product.product-edit.473153-33')" rows="3"
:readonly="form.status == 2" />
<el-input v-model="form.remark" type="textarea" :placeholder="$t('product.product-edit.473153-33')" rows="3" :readonly="form.status == 2" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8">
<el-form-item :label="$t('product.product-edit.473153-96')" prop="networkMethod">
<el-switch v-model="form.isAuthorize" @change="changeIsAuthorize(form.isAuthorize)"
:active-value="1" :inactive-value="0"
:disabled="form.status == 2 || form.deviceType == 3" />
<el-switch v-model="form.isAuthorize" @change="changeIsAuthorize(form.isAuthorize)" :active-value="1" :inactive-value="0" :disabled="form.status == 2 || form.deviceType == 3" />
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-21')" prop="vertificateMethod">
<el-select v-model="form.vertificateMethod" :placeholder="$t('product.product-edit.473153-22')" style="width:100%"
:disabled="form.status == 2 || form.deviceType == 3">
<el-option v-for="dict in dict.type.iot_vertificate_method" :key="dict.value"
:label="dict.label" :value="parseInt(dict.value)"></el-option>
<el-select v-model="form.vertificateMethod" :placeholder="$t('product.product-edit.473153-22')" style="width: 100%" :disabled="form.status == 2 || form.deviceType == 3">
<el-option v-for="dict in dict.type.iot_vertificate_method" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-25')" prop="productId">
<el-input v-model="form.productId" :placeholder="$t('product.product-edit.473153-26')"
:disabled="!form.mqttAccount || form.deviceType == 3" readonly />
<el-input v-model="form.productId" :placeholder="$t('product.product-edit.473153-26')" :disabled="!form.mqttAccount || form.deviceType == 3" readonly />
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-27')" prop="mqttAccount">
<el-input v-model="form.mqttAccount" :placeholder="$t('product.product-edit.473153-28')" :disabled="form.deviceType == 3"
:readonly="accountInputType == 'password'" :type="accountInputType">
<el-button slot="append" icon="el-icon-view" style="font-size:18px;"
@click="changeInputType('account')"></el-button>
<el-input
v-model="form.mqttAccount"
:placeholder="$t('product.product-edit.473153-28')"
:disabled="form.deviceType == 3"
:readonly="accountInputType == 'password'"
:type="accountInputType"
>
<el-button slot="append" icon="el-icon-view" style="font-size: 18px" @click="changeInputType('account')"></el-button>
</el-input>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-29')" prop="mqttPassword">
<el-input v-model="form.mqttPassword" :placeholder="$t('product.product-edit.473153-30')" :disabled="form.deviceType == 3"
:readonly="passwordInputType == 'password'" :type="passwordInputType">
<el-button slot="append" icon="el-icon-view" style="font-size:18px;"
@click="changeInputType('password')"></el-button>
<el-input
v-model="form.mqttPassword"
:placeholder="$t('product.product-edit.473153-30')"
:disabled="form.deviceType == 3"
:readonly="passwordInputType == 'password'"
:type="passwordInputType"
>
<el-button slot="append" icon="el-icon-view" style="font-size: 18px" @click="changeInputType('password')"></el-button>
</el-input>
</el-form-item>
<el-form-item :label="$t('product.product-edit.473153-31')" prop="mqttSecret">
<el-input v-model="form.mqttSecret" :placeholder="$t('product.product-edit.473153-26')"
:disabled="!form.mqttAccount || form.deviceType == 3" readonly :type="keyInputType">
<el-button slot="append" icon="el-icon-view" style="font-size:18px;"
@click="changeInputType('key')"></el-button>
<el-input v-model="form.mqttSecret" :placeholder="$t('product.product-edit.473153-26')" :disabled="!form.mqttAccount || form.deviceType == 3" readonly :type="keyInputType">
<el-button slot="append" icon="el-icon-view" style="font-size: 18px" @click="changeInputType('key')"></el-button>
</el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8">
<el-form-item :label="$t('product.product-edit.473153-34')">
<div v-if="form.status == 2 && form.imgUrl == null">
<el-image style="height:145px;height:145px;border-radius:10px;"
<el-image
style="height: 145px; height: 145px; border-radius: 10px"
:preview-src-list="[require('@/assets/images/gateway.png')]"
:src="require('@/assets/images/gateway.png')" fit="cover"
v-if="form.deviceType == 2"></el-image>
<el-image style="height:145px;height:145px;border-radius:10px;"
:src="require('@/assets/images/gateway.png')"
fit="cover"
v-if="form.deviceType == 2"
></el-image>
<el-image
style="height: 145px; height: 145px; border-radius: 10px"
:preview-src-list="[require('@/assets/images/video.png')]"
:src="require('@/assets/images/video.png')" fit="cover"
v-else-if="form.deviceType == 3"></el-image>
<el-image style="height:145px;height:145px;border-radius:10px;"
:src="require('@/assets/images/video.png')"
fit="cover"
v-else-if="form.deviceType == 3"
></el-image>
<el-image
style="height: 145px; height: 145px; border-radius: 10px"
:preview-src-list="[require('@/assets/images/product.png')]"
:src="require('@/assets/images/product.png')" fit="cover" v-else></el-image>
:src="require('@/assets/images/product.png')"
fit="cover"
v-else
></el-image>
</div>
<div v-else>
<imageUpload ref="image-upload" :disabled="true" :value="form.imgUrl"
:limit="form.status == 2 ? 0 : 1" :fileSize="1" @input="getImagePath($event)">
</imageUpload>
<imageUpload ref="image-upload" :disabled="true" :value="form.imgUrl" :limit="form.status == 2 ? 0 : 1" :fileSize="1" @input="getImagePath($event)"></imageUpload>
</div>
<div class="el-upload__tip" style="color:#f56c6c"
v-if="form.productId == null || form.productId == 0">{{ $t('product.product-edit.473153-35') }}</div>
<div class="el-upload__tip" style="color: #f56c6c" v-if="form.productId == null || form.productId == 0">{{ $t('product.product-edit.473153-35') }}</div>
</el-form-item>
</el-col>
</el-row>
<el-col :span="20">
<el-form-item style="text-align: center;margin:40px 0px;">
<el-button type="primary" @click="submitForm" v-hasPermi="['iot:product:edit']"
v-show="form.productId != 0 && form.status != 2">{{ $t('product.product-edit.473153-36') }}</el-button>
<el-button type="primary" @click="submitForm" v-hasPermi="['iot:product:add']"
v-show="form.productId == 0 && form.status != 2">{{ $t('product.product-edit.473153-37') }}</el-button>
<el-form-item style="text-align: center; margin: 40px 0px">
<el-button type="primary" @click="submitForm" v-hasPermi="['iot:product:edit']" v-show="form.productId != 0 && form.status != 2">{{ $t('product.product-edit.473153-36') }}</el-button>
<el-button type="primary" @click="submitForm" v-hasPermi="['iot:product:add']" v-show="form.productId == 0 && form.status != 2">{{ $t('product.product-edit.473153-37') }}</el-button>
</el-form-item>
</el-col>
</el-form>
</el-tab-pane>
<el-tab-pane label="" name="things" :disabled="form.productId == 0">
<span slot="label"><span style="color:red;">* </span>{{ $t('product.product-edit.473153-38') }}</span>
<span slot="label">
<span style="color: red">*</span>
{{ $t('product.product-edit.473153-38') }}
</span>
<product-things-model ref="productThingsModel" :product="form" />
</el-tab-pane>
@@ -143,26 +144,23 @@
<div style="margin-top: 200px"></div>
<div style="margin-top:200px;"></div>
<div style="margin-top: 200px"></div>
<!-- 用于设置间距 -->
<el-tab-pane>
<span slot="label">
<div style="margin-top:200px;"></div>
<div style="margin-top: 200px"></div>
</span>
</el-tab-pane>
<el-tab-pane v-if="form.status == 1" name="product04" disabled>
<span slot="label">
<el-button type="success" size="mini" @click="changeProductStatus(2)"
v-hasPermi="['iot:product:add']">{{ $t('product.product-edit.473153-86') }}</el-button>
<el-button type="success" size="mini" @click="changeProductStatus(2)" v-hasPermi="['iot:product:add']">{{ $t('product.product-edit.473153-86') }}</el-button>
</span>
</el-tab-pane>
<el-tab-pane v-if="form.status == 2" name="product05" disabled>
<span slot="label">
<el-button type="danger" size="mini" @click="changeProductStatus(1)"
v-hasPermi="['iot:product:edit']">{{ $t('product.product-edit.473153-87') }}</el-button>
<el-button type="danger" size="mini" @click="changeProductStatus(1)" v-hasPermi="['iot:product:edit']">{{ $t('product.product-edit.473153-87') }}</el-button>
</span>
</el-tab-pane>
<el-tab-pane name="product06" disabled>
@@ -171,37 +169,24 @@
</span>
</el-tab-pane>
</el-tabs>
</el-card>
</template>
<script>
import productThingsModel from "./product-things-model";
import productApp from "./product-app";
import productAuthorize from "./product-authorize";
import imageUpload from "../../../components/ImageUpload/index";
import productThingsModel from './product-things-model';
import productApp from './product-app';
import productAuthorize from './product-authorize';
import imageUpload from '../../../components/ImageUpload/index';
import configSip from '../sip/sipconfig.vue';
import {
listProtocol
} from "@/api/iot/protocol";
import { listProtocol } from '@/api/iot/protocol';
import {
listShortCategory,
} from "@/api/iot/category";
import {
getProduct,
addProduct,
updateProduct,
changeProductStatus,
deviceCount,
} from "@/api/iot/product";
import { listShortCategory } from '@/api/iot/category';
import { getProduct, addProduct, updateProduct, changeProductStatus, deviceCount } from '@/api/iot/product';
import {
getAllPoints
} from "@/api/iot/template";
import { getAllPoints } from '@/api/iot/template';
export default {
name: "ProductEdit",
name: 'ProductEdit',
dicts: ['iot_device_type', 'iot_network_method', 'iot_vertificate_method', 'iot_transport_type', 'data_collect_type'],
components: {
productThingsModel,
@@ -213,9 +198,9 @@ export default {
data() {
return {
// 输入框类型
keyInputType: "password",
accountInputType: "password",
passwordInputType: "password",
keyInputType: 'password',
accountInputType: 'password',
passwordInputType: 'password',
// 选中选项卡
activeName: 'basic',
// 分类短列表
@@ -228,44 +213,52 @@ export default {
deviceType: 1,
vertificateMethod: 3,
transport: 'MQTT',
imgUrl: "",
protocolCode: "JSON",
imgUrl: '',
protocolCode: 'JSON',
},
// 表单校验
rules: {
productName: [{
required: true,
message: this.$t('product.product-edit.473153-58'),
trigger: "blur",
},
{
min: 1,
max: 64,
message: this.$i18n.t('product.product-edit.473153-59'),
trigger: 'blur',
},
],
categoryId: [{
required: true,
message: this.$t('product.product-edit.473153-59'),
trigger: "blur"
}],
deviceType: [{
required: true,
message: this.$t('product.product-edit.473153-98'),
trigger: "blur"
}],
protocolCode: [{
required: true,
message: this.$t('product.product-edit.473153-60'),
trigger: "blur"
}],
transport: [{
required: true,
message: this.$t('product.product-edit.473153-61'),
trigger: 'blur'
}]
productName: [
{
required: true,
message: this.$t('product.product-edit.473153-58'),
trigger: 'blur',
},
{
min: 1,
max: 64,
message: this.$i18n.t('product.product-edit.473153-59'),
trigger: 'blur',
},
],
categoryId: [
{
required: true,
message: this.$t('product.product-edit.473153-59'),
trigger: 'blur',
},
],
deviceType: [
{
required: true,
message: this.$t('product.product-edit.473153-98'),
trigger: 'blur',
},
],
protocolCode: [
{
required: true,
message: this.$t('product.product-edit.473153-60'),
trigger: 'blur',
},
],
transport: [
{
required: true,
message: this.$t('product.product-edit.473153-61'),
trigger: 'blur',
},
],
},
// 查询参数
queryParams: {
@@ -274,7 +267,7 @@ export default {
pointList: [],
open: false,
// 弹出层标题
title: "",
title: '',
loading: true,
tempList: [],
// 总条数
@@ -293,7 +286,6 @@ export default {
currentRow: {},
selectRowData: {},
isModbus: false,
};
},
created() {
@@ -312,18 +304,18 @@ export default {
this.getShortCategory();
// 设置账号密码输入框类型,新增时为text查看时为password
if (!this.form.productId || this.form.productId == 0) {
this.accountInputType = "text";
this.passwordInputType = "text";
this.accountInputType = 'text';
this.passwordInputType = 'text';
}
this.getProtocol();
},
activated() {
const time = this.$route.query.t;
if (time != null && time != this.uniqueId) {
this.uniqueId = time;
this.uniqueId = time;
}
// 获取产品信息
let productId = this.$route.query.productId
let productId = this.$route.query.productId;
if (productId != null && productId != 0) {
this.form.productId = Number(productId);
this.getProduct();
@@ -334,30 +326,29 @@ export default {
if (tabPanelName != null && tabPanelName != '') {
this.activeName = tabPanelName;
}
},
methods: {
// 获取简短分类列表
getShortCategory() {
listShortCategory().then(response => {
listShortCategory().then((response) => {
this.categoryShortList = response.data;
})
});
},
/** 返回按钮 */
goBack() {
const obj = {
path: "/iot/product",
path: '/iot/product',
query: {
t: Date.now(),
pageNum: this.$route.query.pageNum
}
pageNum: this.$route.query.pageNum,
},
};
this.$tab.closeOpenPage(obj);
this.reset();
},
/** 获取产品信息 */
getProduct() {
getProduct(this.form.productId).then(response => {
getProduct(this.form.productId).then((response) => {
this.form = response.data;
this.changeProductCode(this.form.protocolCode);
});
@@ -379,21 +370,21 @@ export default {
mqttPassword: null,
mqttSecret: null,
remark: null,
imgUrl: "",
imgUrl: '',
};
this.resetForm("form");
this.resetForm('form');
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
this.$refs['form'].validate((valid) => {
if (valid) {
if (this.form.productId != null && this.form.productId != 0) {
updateProduct(this.form).then(response => {
updateProduct(this.form).then((response) => {
this.changeProductCode(this.form.protocolCode);
this.$modal.alertSuccess(this.$t('product.product-edit.473153-62'));
});
} else {
addProduct(this.form).then(response => {
addProduct(this.form).then((response) => {
if (!this.form.isModbus) {
this.$modal.alertSuccess(this.$t('product.product-edit.473153-99'));
} else {
@@ -409,12 +400,14 @@ export default {
/**同步获取产品下的设备数量**/
getDeviceCountByProductId(productId) {
return new Promise((resolve, reject) => {
deviceCount(productId).then(res => {
resolve(res);
}).catch(error => {
reject(error);
})
})
deviceCount(productId)
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
});
});
},
/** 更新产品状态 */
async changeProductStatus(status) {
@@ -430,26 +423,30 @@ export default {
this.$confirm(message, this.$t('product.product-edit.473153-69'), {
confirmButtonText: this.$t('product.product-edit.473153-70'),
cancelButtonText: this.$t('cancel'),
type: 'warning'
}).then(() => {
let data = {};
data.productId = this.form.productId;
data.status = status;
data.deviceType = this.form.deviceType;
changeProductStatus(data).then(response => {
this.$modal.alertSuccess(response.msg);
this.activeName = "basic";
this.getProduct();
}).catch(() => {
if (status == 2) {
this.activeName = "basic";
} else {
this.goBack();
}
type: 'warning',
})
.then(() => {
let data = {};
data.productId = this.form.productId;
data.status = status;
data.deviceType = this.form.deviceType;
changeProductStatus(data)
.then((response) => {
this.$modal.alertSuccess(response.msg);
this.activeName = 'basic';
this.getProduct();
})
.catch(() => {
if (status == 2) {
this.activeName = 'basic';
} else {
this.goBack();
}
});
})
.catch(() => {
this.activeName = 'basic';
});
}).catch(() => {
this.activeName = "basic";
});
},
/** 选择分类 */
selectCategory(val) {
@@ -466,42 +463,45 @@ export default {
},
/**改变输入框类型**/
changeInputType(name) {
if (name == "key") {
this.keyInputType = this.keyInputType == "password" ? "text" : "password";
} else if (name == "account") {
this.accountInputType = this.accountInputType == "password" ? "text" : "password";
} else if (name == "password") {
this.passwordInputType = this.passwordInputType == "password" ? "text" : "password";
if (name == 'key') {
this.keyInputType = this.keyInputType == 'password' ? 'text' : 'password';
} else if (name == 'account') {
this.accountInputType = this.accountInputType == 'password' ? 'text' : 'password';
} else if (name == 'password') {
this.passwordInputType = this.passwordInputType == 'password' ? 'text' : 'password';
}
},
// 授权码状态修改
changeIsAuthorize() {
let text = this.form.isAuthorize == "1" ? this.$t('product.product-edit.473153-72') : this.$t('product.product-edit.473153-74');
this.$modal.confirm(this.$i18n.t('product.product-edit.473153-75', [text])).then(() => {
if (this.form.productId != null && this.form.productId != 0) {
updateProduct(this.form).then(response => {
this.$modal.alertSuccess(this.$i18n.t('product.product-edit.473153-77', [text]));
});
}
}).catch(() => {
this.form.isAuthorize = 0;
});
let text = this.form.isAuthorize == '1' ? this.$t('product.product-edit.473153-72') : this.$t('product.product-edit.473153-74');
this.$modal
.confirm(this.$i18n.t('product.product-edit.473153-75', [text]))
.then(() => {
if (this.form.productId != null && this.form.productId != 0) {
updateProduct(this.form).then((response) => {
this.$modal.alertSuccess(this.$i18n.t('product.product-edit.473153-77', [text]));
});
}
})
.catch(() => {
this.form.isAuthorize = 0;
});
},
//获取设备协议
getProtocol() {
const data = {
protocolStatus: 1
protocolStatus: 1,
};
listProtocol(data).then(res => {
listProtocol(data).then((res) => {
this.protocolList = res.rows;
})
});
},
// 设备类型改变事件
deviceTypeChange(type){
if(type===3){
this.form.transport="GB28181";
}else{
this.form.transport="MQTT";
deviceTypeChange(type) {
if (type === 3) {
this.form.transport = 'GB28181';
} else {
this.form.transport = 'MQTT';
}
},
// 取消按钮
@@ -510,13 +510,13 @@ export default {
// this.reset();
},
getList() {
getAllPoints(this.pointsParams).then(response => {
getAllPoints(this.pointsParams).then((response) => {
this.pointList = response.rows;
this.total = response.total;
});
},
changeProductCode(val) {
if (val && val.startsWith("MODBUS")) {
if (val && val.startsWith('MODBUS')) {
this.form.deviceType = 2;
this.form.isModbus = true;
if (this.form.productId != 0 && this.form.productId != null) {
@@ -529,7 +529,7 @@ export default {
/**选项卡切换事件**/
tabChange(tabItem) {
// 切换到告警配置,获取物模型
if (tabItem.paneName == "alert") {
if (tabItem.paneName == 'alert') {
//this.$refs.productAlert.getCacheThingsModel(this.form.productId);
}
},
@@ -541,16 +541,16 @@ export default {
/** 搜索按钮操作 */
handleQuery() {
this.tempParams.pageNum = 1
this.getTempList()
this.tempParams.pageNum = 1;
this.getTempList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('tempParams')
this.handleQuery()
this.resetForm('tempParams');
this.handleQuery();
},
}
},
};
</script>

View File

@@ -1,6 +1,6 @@
<template>
<div class="script_wrap">
<el-card v-show="showSearch" style="margin-bottom: 10px">
<el-card shadow="never" style="margin-bottom: 10px">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom: -20px">
<el-form-item :label="$t('script.349087-0')" prop="scriptId">
<el-input v-model="queryParams.scriptId" :placeholder="$t('script.349087-1')" clearable @keyup.enter.native="handleQuery" />
@@ -15,7 +15,7 @@
</el-form>
</el-card>
<el-card style="padding-bottom: 100px">
<el-card shadow="never" style="padding-bottom: 100px">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleAdd" v-hasPermi="['iot:script:add']" style="margin-bottom: 10px">{{ $t('add') }}</el-button>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
<el-table v-loading="loading" :data="scriptList" @selection-change="handleSelectionChange" :border="false">

View File

@@ -1,6 +1,6 @@
<template>
<div class="sip_wrap">
<el-card style="margin-bottom: 10px" v-show="showSearch">
<el-card shadow="never" style="margin-bottom: 10px" v-show="showSearch">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="60px" style="margin-bottom: -20px">
<el-form-item :label="$t('sip.index.998533-0')" prop="deviceSipId">
<el-input v-model="queryParams.deviceSipId" :placeholder="$t('sip.index.998533-1')" clearable size="small" @keyup.enter.native="handleQuery" />
@@ -20,7 +20,7 @@
</el-form>
</el-card>
<el-card style="padding-bottom: 100px">
<el-card shadow="never" style="padding-bottom: 100px">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleAdd" v-hasPermi="['iot:video:add']" :disabled="isGeneralUser" style="margin-bottom: 10px">
{{ $t('sip.index.998533-6') }}
</el-button>

View File

@@ -1,53 +1,49 @@
<template>
<div class="mediaServer_wrap">
<el-card style="margin-bottom: 10px">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="75px" style="margin-bottom: -20px">
<el-form-item>
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="add" v-hasPermi="['iot:video:add']" style="margin-right: 10px">{{ $t('sip.mediaServer.998535-0') }}</el-button>
<el-button type="warning" plain icon="el-icon-refresh" size="small" @click="getServerList">{{ $t('refresh') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card shadow="never">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="add" v-hasPermi="['iot:video:add']" style="margin-right: 10px; margin-bottom: 10px">{{ $t('sip.mediaServer.998535-0') }}</el-button>
<el-button type="warning" plain icon="el-icon-refresh" size="small" @click="getServerList">{{ $t('refresh') }}</el-button>
<el-row :gutter="30" v-loading="loading">
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="(item, index) in mediaServerList" :key="index" style="margin-bottom: 30px; text-align: center">
<el-card shadow="always" class="card-item">
<el-row :gutter="10">
<el-col :span="15">
<el-descriptions :column="1" size="mini" style="white-space: nowrap">
<el-descriptions-item :label="$t('sip.mediaServer.998535-1')">
{{ item.serverId }}
</el-descriptions-item>
<el-descriptions-item :label="$t('sip.mediaServer.998535-2')">
{{ item.ip }}
</el-descriptions-item>
<el-descriptions-item :label="$t('sip.mediaServer.998535-3')">
{{ item.protocol }}
</el-descriptions-item>
<el-descriptions-item :label="$t('sip.mediaServer.998535-4')">
{{ parseTime(item.createTime, '{y}-{m}-{d}') }}
</el-descriptions-item>
</el-descriptions>
</el-col>
<el-col :span="8">
<div style="margin-top: 10px">
<el-image :src="require('@/assets/images/zlm-logo.png')" fit="fit"></el-image>
</div>
</el-col>
</el-row>
<el-button-group style="margin-top: 10px">
<el-button type="danger" size="mini" style="padding: 5px 10px" icon="el-icon-delete" v-hasPermi="['iot:video:remove']" @click="del(item)">{{ $t('del') }}</el-button>
<el-button type="primary" size="mini" style="padding: 5px 15px" icon="el-icon-view" @click="view(item)" v-hasPermi="['iot:video:query']">{{ $t('look') }}</el-button>
<el-button v-if="!istrue" type="success" size="mini" style="padding: 5px 15px" icon="el-icon-odometer" @click.native.prevent="edit(item)" v-hasPermi="['iot:video:edit']">
{{ $t('edit') }}
</el-button>
<el-button v-else type="success" size="mini" style="padding: 5px 15px" icon="el-icon-odometer" :loading="true" disabled>{{ $t('sip.mediaServer.998535-5') }}</el-button>
</el-button-group>
</el-card>
</el-col>
</el-row>
<el-empty :description="$t('sip.mediaServer.998535-6')" v-if="total == 0"></el-empty>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :pageSizes="[12, 24, 36, 60]" @pagination="getServerList" />
<el-row :gutter="30" v-loading="loading">
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="(item, index) in mediaServerList" :key="index" style="margin-bottom: 30px; text-align: center">
<el-card shadow="always" class="card-item">
<el-row :gutter="10">
<el-col :span="15">
<el-descriptions :column="1" size="mini" style="white-space: nowrap">
<el-descriptions-item :label="$t('sip.mediaServer.998535-1')">
{{ item.serverId }}
</el-descriptions-item>
<el-descriptions-item :label="$t('sip.mediaServer.998535-2')">
{{ item.ip }}
</el-descriptions-item>
<el-descriptions-item :label="$t('sip.mediaServer.998535-3')">
{{ item.protocol }}
</el-descriptions-item>
<el-descriptions-item :label="$t('sip.mediaServer.998535-4')">
{{ parseTime(item.createTime, '{y}-{m}-{d}') }}
</el-descriptions-item>
</el-descriptions>
</el-col>
<el-col :span="8">
<div style="margin-top: 10px">
<el-image :src="require('@/assets/images/zlm-logo.png')" fit="fit"></el-image>
</div>
</el-col>
</el-row>
<el-button-group style="margin-top: 10px">
<el-button type="danger" size="mini" style="padding: 5px 10px" icon="el-icon-delete" v-hasPermi="['iot:video:remove']" @click="del(item)">{{ $t('del') }}</el-button>
<el-button type="primary" size="mini" style="padding: 5px 15px" icon="el-icon-view" @click="view(item)" v-hasPermi="['iot:video:query']">{{ $t('look') }}</el-button>
<el-button v-if="!istrue" type="success" size="mini" style="padding: 5px 15px" icon="el-icon-odometer" @click.native.prevent="edit(item)" v-hasPermi="['iot:video:edit']">
{{ $t('edit') }}
</el-button>
<el-button v-else type="success" size="mini" style="padding: 5px 15px" icon="el-icon-odometer" :loading="true" disabled>{{ $t('sip.mediaServer.998535-5') }}</el-button>
</el-button-group>
</el-card>
</el-col>
</el-row>
<el-empty :description="$t('sip.mediaServer.998535-6')" v-if="total == 0"></el-empty>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :pageSizes="[12, 24, 36, 60]" @pagination="getServerList" />
</el-card>
<mediaServerEdit ref="mediaServerEdit" :edit-flag="editFlag"></mediaServerEdit>
</div>
@@ -178,7 +174,7 @@ export default {
.mediaServer_wrap {
padding: 15px;
min-height: 100vh;
/* background-color: #f5f7fa; */
background-color: #f5f7fa;
}
::v-deep .pagination-container[data-v-72233bcd] {
background: none;

View File

@@ -1,6 +1,6 @@
<template>
<div class="templete-wrap">
<el-card v-show="showSearch" style="margin-bottom: 10px">
<el-card shadow="never" v-show="showSearch" style="margin-bottom: 10px">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom: -20px">
<el-form-item :label="$t('template.index.891112-22')" prop="templateName">
<el-input v-model="queryParams.templateName" :placeholder="$t('template.index.891112-1')" clearable size="small" @keyup.enter.native="handleQuery" />
@@ -17,7 +17,7 @@
</el-form>
</el-card>
<el-card style="padding-bottom: 100px">
<el-card shadow="never" style="padding-bottom: 100px">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleAdd" v-hasPermi="['iot:template:add']" style="margin-bottom: 10px">{{ $t('add') }}</el-button>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
<el-table v-loading="loading" :data="templateList" @selection-change="handleSelectionChange" :border="false">

View File

@@ -453,7 +453,7 @@ export default {
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -252,7 +252,7 @@ export default {
text-align: right;
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -1,5 +1,5 @@
<template>
<div class="app-container">
<div class="online-wrap">
<el-card shadow="never" class="search-card">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
<el-form-item :label="$t('online.093480-0')" prop="ipaddr">
@@ -110,8 +110,8 @@ export default {
</script>
<style lang="scss" scoped>
.app-container {
padding: 20px;
.online-wrap {
padding: 15px;
min-height: 100vh;
background-color: #f5f7fa;
}
@@ -145,7 +145,7 @@ export default {
text-align: right;
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -1,6 +1,6 @@
<template>
<div class="table-header">
<el-card class="search-card" v-show="showSearch">
<el-card shadow="never" class="search-card" v-show="showSearch">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
<el-form-item :label="$t('operlog.874509-10')" prop="operIp">
<el-input v-model="queryParams.operIp" :placeholder="$t('operlog.874509-10')" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
@@ -309,7 +309,7 @@ export default {
text-align: right;
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -1,241 +1,158 @@
<template>
<div class="system-app-lang">
<el-card v-show="showSearch" style="margin-bottom: 10px">
<el-form
@submit.native.prevent
:model="queryParams"
ref="queryForm"
:inline="true"
label-width="46px"
style="margin-bottom: -20px"
>
<el-form-item prop="langName">
<el-input
v-model="queryParams.langName"
:placeholder="$t('app.lang.755172-14')"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item prop="country">
<el-input
v-model="queryParams.country"
:placeholder="$t('app.lang.755172-12')"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<div style="float: right">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">{{ $t('search') }}</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">{{ $t('reset') }}</el-button>
</div>
</el-form>
</el-card>
<div class="system-app-lang">
<el-card shadow="never" v-show="showSearch" style="margin-bottom: 10px">
<el-form @submit.native.prevent :model="queryParams" ref="queryForm" :inline="true" label-width="46px" style="margin-bottom: -20px">
<el-form-item prop="langName">
<el-input v-model="queryParams.langName" :placeholder="$t('app.lang.755172-14')" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item prop="country">
<el-input v-model="queryParams.country" :placeholder="$t('app.lang.755172-12')" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<div style="float: right">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">{{ $t('search') }}</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">{{ $t('reset') }}</el-button>
</div>
</el-form>
</el-card>
<el-card>
<el-row :gutter="10" style="margin-bottom: 16px">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="small"
@click="handleAdd"
v-hasPermi="['app:language:add']"
>
{{ $t('add') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
plain
icon="el-icon-delete"
size="small"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['app:language:remove']"
>
{{ $t('del') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['app:language:export']"
plain
size="small"
:loading="exportLoading"
@click="handleExport"
>
{{ $t('app.start.891644-43') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-upload v-hasRole="['admin']" :show-file-list="false" ref="upload" action="" :http-request="handleImport">
<el-button slot="trigger" :loading="importLoading" size="small" plain>
{{ $t('app.start.891644-44') }}
</el-button>
</el-upload>
</el-col>
<el-col :span="1.5">
<el-dropdown v-hasRole="['admin']" @command="handleExportBackendMenu($event, true)">
<el-button plain size="small">
{{ $t('app.start.891644-47') }}
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="dict in dict.type.international_configuration_template"
:key="dict.value"
:command="dict.value"
>
{{ dict.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
<el-col :span="1.5">
<el-dropdown v-hasRole="['admin']" @command="handleExportBackendMenu($event, false)">
<el-button plain size="small">
{{ $t('app.start.891644-45') }}
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="dict in dict.type.international_configuration_template"
:key="dict.value"
:command="dict.value"
>
{{ dict.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
<el-col :span="1.5">
<el-dropdown v-hasRole="['admin']" @command="handleImportTranslate">
<el-upload
v-hasRole="['admin']"
:show-file-list="false"
ref="upload"
action=""
:http-request="handleImportBackendMenu"
:disabled="true"
>
<el-button slot="trigger" size="small" plain>
{{ $t('app.start.891644-46') }}
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
</el-upload>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="dict in dict.type.international_configuration_template"
:key="dict.value"
:command="dict.value"
>
{{ dict.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-card>
<el-row :gutter="10" style="margin-bottom: 16px">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="small" @click="handleAdd" v-hasPermi="['app:language:add']">
{{ $t('add') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button plain icon="el-icon-delete" size="small" :disabled="multiple" @click="handleDelete" v-hasPermi="['app:language:remove']">
{{ $t('del') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button v-hasPermi="['app:language:export']" plain size="small" :loading="exportLoading" @click="handleExport">
{{ $t('app.start.891644-43') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-upload v-hasRole="['admin']" :show-file-list="false" ref="upload" action="" :http-request="handleImport">
<el-button slot="trigger" :loading="importLoading" size="small" plain>
{{ $t('app.start.891644-44') }}
</el-button>
</el-upload>
</el-col>
<el-col :span="1.5">
<el-dropdown v-hasRole="['admin']" @command="handleExportBackendMenu($event, true)">
<el-button plain size="small">
{{ $t('app.start.891644-47') }}
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="dict in dict.type.international_configuration_template" :key="dict.value" :command="dict.value">
{{ dict.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
<el-col :span="1.5">
<el-dropdown v-hasRole="['admin']" @command="handleExportBackendMenu($event, false)">
<el-button plain size="small">
{{ $t('app.start.891644-45') }}
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="dict in dict.type.international_configuration_template" :key="dict.value" :command="dict.value">
{{ dict.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
<el-col :span="1.5">
<el-dropdown v-hasRole="['admin']" @command="handleImportTranslate">
<el-upload v-hasRole="['admin']" :show-file-list="false" ref="upload" action="" :http-request="handleImportBackendMenu" :disabled="true">
<el-button slot="trigger" size="small" plain>
{{ $t('app.start.891644-46') }}
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
</el-upload>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="dict in dict.type.international_configuration_template" :key="dict.value" :command="dict.value">
{{ dict.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="languageList" :border="false" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column :label="$t('app.lang.755172-4')" align="center" prop="id" min-width="80" />
<el-table-column :label="$t('app.lang.755172-8')" align="left" prop="langName" min-width="180" />
<el-table-column :label="$t('app.lang.755172-5')" align="center" prop="language" min-width="100" />
<el-table-column :label="$t('app.lang.755172-6')" align="center" prop="country" min-width="120" />
<el-table-column :label="$t('app.lang.755172-7')" align="center" prop="timeZone" min-width="100" />
<el-table-column fixed="right" :label="$t('opation')" align="center" width="130">
<template slot-scope="scope">
<el-button
size="small"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['app:language:edit']"
>
{{ $t('update') }}
</el-button>
<el-button
size="small"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['app:language:remove']"
>
{{ $t('del') }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-table v-loading="loading" :data="languageList" :border="false" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column :label="$t('app.lang.755172-4')" align="center" prop="id" min-width="80" />
<el-table-column :label="$t('app.lang.755172-8')" align="left" prop="langName" min-width="180" />
<el-table-column :label="$t('app.lang.755172-5')" align="center" prop="language" min-width="100" />
<el-table-column :label="$t('app.lang.755172-6')" align="center" prop="country" min-width="120" />
<el-table-column :label="$t('app.lang.755172-7')" align="center" prop="timeZone" min-width="100" />
<el-table-column fixed="right" :label="$t('opation')" align="center" width="130">
<template slot-scope="scope">
<el-button size="small" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['app:language:edit']">
{{ $t('update') }}
</el-button>
<el-button size="small" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['app:language:remove']">
{{ $t('del') }}
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
style="margin-bottom: 20px"
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-card>
<pagination style="margin-bottom: 20px" v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改app语言对话框 -->
<el-dialog :title="title" :visible.sync="open" width="560px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="75px">
<el-form-item :label="$t('app.lang.755172-8')" prop="langName">
<el-input v-model="form.langName" :placeholder="$t('app.lang.755172-14')" style="width: 390px" />
</el-form-item>
<el-form-item :label="$t('app.lang.755172-5')" prop="language">
<el-input v-model="form.language" :placeholder="$t('app.lang.755172-11')" style="width: 390px" />
</el-form-item>
<el-form-item :label="$t('app.lang.755172-6')" prop="country">
<el-input v-model="form.country" :placeholder="$t('app.lang.755172-12')" style="width: 390px" />
</el-form-item>
<el-form-item :label="$t('app.lang.755172-7')" prop="timeZone">
<el-input v-model="form.timeZone" :placeholder="$t('app.lang.755172-13')" style="width: 390px" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">
{{ $t('confirm') }}
</el-button>
<el-button @click="cancel">
{{ $t('cancel') }}
</el-button>
</div>
</el-dialog>
<!-- 添加或修改app语言对话框 -->
<el-dialog :title="title" :visible.sync="open" width="560px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="75px">
<el-form-item :label="$t('app.lang.755172-8')" prop="langName">
<el-input v-model="form.langName" :placeholder="$t('app.lang.755172-14')" style="width: 390px" />
</el-form-item>
<el-form-item :label="$t('app.lang.755172-5')" prop="language">
<el-input v-model="form.language" :placeholder="$t('app.lang.755172-11')" style="width: 390px" />
</el-form-item>
<el-form-item :label="$t('app.lang.755172-6')" prop="country">
<el-input v-model="form.country" :placeholder="$t('app.lang.755172-12')" style="width: 390px" />
</el-form-item>
<el-form-item :label="$t('app.lang.755172-7')" prop="timeZone">
<el-input v-model="form.timeZone" :placeholder="$t('app.lang.755172-13')" style="width: 390px" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">
{{ $t('confirm') }}
</el-button>
<el-button @click="cancel">
{{ $t('cancel') }}
</el-button>
</div>
</el-dialog>
<el-dialog :title="$t('app.lang.755172-22')" :visible.sync="productModelVisible" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item :label="$t('app.lang.755172-23')" prop="productId">
<el-select v-model="productId" :placeholder="$t('pleaseSelect')">
<el-option v-for="item in prodcutModels" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitProdcutModel">
{{ $t('confirm') }}
</el-button>
<el-button @click="closeProductModelDialog">
{{ $t('cancel') }}
</el-button>
</div>
</el-dialog>
</div>
<el-dialog :title="$t('app.lang.755172-22')" :visible.sync="productModelVisible" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item :label="$t('app.lang.755172-23')" prop="productId">
<el-select v-model="productId" :placeholder="$t('pleaseSelect')">
<el-option v-for="item in prodcutModels" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitProdcutModel">
{{ $t('confirm') }}
</el-button>
<el-button @click="closeProductModelDialog">
{{ $t('cancel') }}
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listLanguage,
getLanguage,
delLanguage,
addLanguage,
updateLanguage,
exportTranslate,
importTranslate,
} from '@/api/system/language';
import { listLanguage, getLanguage, delLanguage, addLanguage, updateLanguage, exportTranslate, importTranslate } from '@/api/system/language';
import * as langTransformer from './script/langTransformer';
import * as xlsxHandler from './script/xlsx';
import * as jszip from './script/jszip';
@@ -243,306 +160,306 @@ import { downFileByBlob } from '@/utils/common.js';
import { listShortProduct } from '@/api/iot/product';
export default {
name: 'AppLang',
dicts: ['international_configuration_template'],
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// app语言表格数据
languageList: [],
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
langName: '',
country: '',
pageNum: 1,
pageSize: 10,
},
// 表单参数
form: {},
// 表单校验
rules: {
langName: [
{
required: true,
message: this.$t('app.lang.755172-14'),
trigger: 'blur',
},
],
language: [
{
required: true,
message: this.$t('app.lang.755172-11'),
trigger: 'blur',
},
],
country: [
{
required: true,
message: this.$t('app.lang.755172-12'),
trigger: 'blur',
},
],
},
// 导出语言包loading
exportLoading: false,
// 导入excel生成语言包loading
importLoading: false,
currentLanguage: '',
currentTranslateModule: '',
productModelVisible: false,
prodcutModels: [],
productId: '',
};
},
created() {
this.getList();
this.getProductModels();
},
methods: {
/** 查询app语言列表 */
getList() {
this.loading = true;
listLanguage(this.queryParams).then((response) => {
this.languageList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
id: null,
language: null,
country: null,
timeZone: null,
createBy: null,
createTime: null,
langName: null,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = this.$t('app.lang.755172-17');
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getLanguage(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = this.$t('app.lang.755172-18');
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (valid) {
if (this.form.id != null) {
updateLanguage(this.form).then((response) => {
this.$modal.msgSuccess(this.$t('updateSuccess'));
this.open = false;
this.getList();
});
} else {
addLanguage(this.form).then((response) => {
this.$modal.msgSuccess(this.$t('addSuccess'));
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal
.confirm(this.$t('app.lang.755172-21', [ids]))
.then(function () {
return delLanguage(ids);
})
.then(() => {
this.getList();
this.$modal.msgSuccess(this.$t('delSuccess'));
})
.catch(() => {});
},
// 导出语言包
handleExport() {
if (this.languageList.length === 0) {
return;
}
try {
this.exportLoading = true;
// 中英文映射
const langs = this.languageList.reduce((obj, item) => {
obj[item.language] = item.country;
return obj;
}, {});
// 获取json数据
const jsonMap = langTransformer.getLangJson();
// 转换为excel导出需要的数据格式
const excelData = langTransformer.transoformToExcel(jsonMap, langs);
// 导出为excel
xlsxHandler.exportExcel(excelData, 'lang.xlsx');
} finally {
this.exportLoading = false;
}
},
// 导入语言包excel直接导出转换后的压缩包
async handleImport(fileInfo) {
try {
this.importLoading = true;
// 中英文映射
const langs = this.languageList.reduce((obj, item) => {
obj[item.country] = item.language;
return obj;
}, {});
// 读取excel文件解析为json数据
const data = await xlsxHandler.parseJson(fileInfo.file);
// 将json文件转换为以模块维度的数据用于进一步处理成压缩包文件数据
const jsonData = jszip.parseJsonZipData(data, langs);
// 生成zip的文件列表
const files = jszip.generateJsonZipFiles(jsonData);
// 下载为压缩包
jszip.downloadFiles2Zip({
zipName: 'lang',
files: files,
});
} finally {
this.importLoading = false;
}
},
// 导出菜单名称翻译列表
async handleExportBackendMenu(value, isSource = false) {
this.currentTranslateModule = value;
const exportFn = () => {
const sourceData = this.dict.type.international_configuration_template;
const isThingsModel = this.currentTranslateModule === 'things_model';
exportTranslate(value, isSource, isThingsModel ? this.productId : null).then((response) => {
let name = sourceData.find((item) => item.value === value).name;
if (isThingsModel) {
name += '_' + this.prodcutModels.find((item) => item.id === this.productId).name;
}
if (response.type === 'application/json') {
this.$modal.msgError(`导出异常`);
return;
}
const fileName = isSource ? `${name}原表数据.xlsx` : `${name}翻译数据.xlsx`;
downFileByBlob(response, fileName);
isThingsModel && this.closeProductModelDialog();
});
};
if (value === 'things_model') {
this.productModelVisible = true;
this.callback = () => {
exportFn();
name: 'AppLang',
dicts: ['international_configuration_template'],
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// app语言表格数据
languageList: [],
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
langName: '',
country: '',
pageNum: 1,
pageSize: 10,
},
// 表单参数
form: {},
// 表单校验
rules: {
langName: [
{
required: true,
message: this.$t('app.lang.755172-14'),
trigger: 'blur',
},
],
language: [
{
required: true,
message: this.$t('app.lang.755172-11'),
trigger: 'blur',
},
],
country: [
{
required: true,
message: this.$t('app.lang.755172-12'),
trigger: 'blur',
},
],
},
// 导出语言包loading
exportLoading: false,
// 导入excel生成语言包loading
importLoading: false,
currentLanguage: '',
currentTranslateModule: '',
productModelVisible: false,
prodcutModels: [],
productId: '',
};
} else {
exportFn();
}
},
async handleImportBackendMenu(fileInfo) {
let formData = new FormData();
formData.append('file', fileInfo.file);
const isThingsModel = this.currentTranslateModule === 'things_model';
const productId = isThingsModel && this.productId ? this.productId : '';
importTranslate(formData, this.currentTranslateModule, productId).then((res) => {
if (res.code === 200) {
this.$modal.msgSuccess('导入成功');
} else {
this.$modal.msgError(res.msg);
}
isThingsModel && this.closeProductModelDialog();
});
created() {
this.getList();
this.getProductModels();
},
handleImportTranslate(value) {
this.currentTranslateModule = value;
if (value === 'things_model') {
this.productModelVisible = true;
this.callback = () => {
this.$refs.upload.$el.querySelector('input').click();
};
} else {
this.$refs.upload.$el.querySelector('input').click();
}
methods: {
/** 查询app语言列表 */
getList() {
this.loading = true;
listLanguage(this.queryParams).then((response) => {
this.languageList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
id: null,
language: null,
country: null,
timeZone: null,
createBy: null,
createTime: null,
langName: null,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = this.$t('app.lang.755172-17');
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getLanguage(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = this.$t('app.lang.755172-18');
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (valid) {
if (this.form.id != null) {
updateLanguage(this.form).then((response) => {
this.$modal.msgSuccess(this.$t('updateSuccess'));
this.open = false;
this.getList();
});
} else {
addLanguage(this.form).then((response) => {
this.$modal.msgSuccess(this.$t('addSuccess'));
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal
.confirm(this.$t('app.lang.755172-21', [ids]))
.then(function () {
return delLanguage(ids);
})
.then(() => {
this.getList();
this.$modal.msgSuccess(this.$t('delSuccess'));
})
.catch(() => {});
},
// 导出语言包
handleExport() {
if (this.languageList.length === 0) {
return;
}
try {
this.exportLoading = true;
// 中英文映射
const langs = this.languageList.reduce((obj, item) => {
obj[item.language] = item.country;
return obj;
}, {});
// 获取json数据
const jsonMap = langTransformer.getLangJson();
// 转换为excel导出需要的数据格式
const excelData = langTransformer.transoformToExcel(jsonMap, langs);
// 导出为excel
xlsxHandler.exportExcel(excelData, 'lang.xlsx');
} finally {
this.exportLoading = false;
}
},
// 导入语言包excel直接导出转换后的压缩包
async handleImport(fileInfo) {
try {
this.importLoading = true;
// 中英文映射
const langs = this.languageList.reduce((obj, item) => {
obj[item.country] = item.language;
return obj;
}, {});
// 读取excel文件解析为json数据
const data = await xlsxHandler.parseJson(fileInfo.file);
// 将json文件转换为以模块维度的数据用于进一步处理成压缩包文件数据
const jsonData = jszip.parseJsonZipData(data, langs);
// 生成zip的文件列表
const files = jszip.generateJsonZipFiles(jsonData);
// 下载为压缩包
jszip.downloadFiles2Zip({
zipName: 'lang',
files: files,
});
} finally {
this.importLoading = false;
}
},
// 导出菜单名称翻译列表
async handleExportBackendMenu(value, isSource = false) {
this.currentTranslateModule = value;
const exportFn = () => {
const sourceData = this.dict.type.international_configuration_template;
const isThingsModel = this.currentTranslateModule === 'things_model';
exportTranslate(value, isSource, isThingsModel ? this.productId : null).then((response) => {
let name = sourceData.find((item) => item.value === value).name;
if (isThingsModel) {
name += '_' + this.prodcutModels.find((item) => item.id === this.productId).name;
}
if (response.type === 'application/json') {
this.$modal.msgError(`导出异常`);
return;
}
const fileName = isSource ? `${name}原表数据.xlsx` : `${name}翻译数据.xlsx`;
downFileByBlob(response, fileName);
isThingsModel && this.closeProductModelDialog();
});
};
if (value === 'things_model') {
this.productModelVisible = true;
this.callback = () => {
exportFn();
};
} else {
exportFn();
}
},
async handleImportBackendMenu(fileInfo) {
let formData = new FormData();
formData.append('file', fileInfo.file);
const isThingsModel = this.currentTranslateModule === 'things_model';
const productId = isThingsModel && this.productId ? this.productId : '';
importTranslate(formData, this.currentTranslateModule, productId).then((res) => {
if (res.code === 200) {
this.$modal.msgSuccess('导入成功');
} else {
this.$modal.msgError(res.msg);
}
isThingsModel && this.closeProductModelDialog();
});
},
handleImportTranslate(value) {
this.currentTranslateModule = value;
if (value === 'things_model') {
this.productModelVisible = true;
this.callback = () => {
this.$refs.upload.$el.querySelector('input').click();
};
} else {
this.$refs.upload.$el.querySelector('input').click();
}
},
async getProductModels() {
const params = {
pageSize: 999,
showSenior: true,
};
const res = await listShortProduct(params);
if (res.code === 200) {
this.prodcutModels = res.data || [];
}
},
closeProductModelDialog() {
this.productModelVisible = false;
this.productId = '';
},
submitProdcutModel() {
if (!this.productId) {
this.$message.warning('请选择产品后再确认');
return;
}
this.callback && this.callback(this.productId);
},
},
async getProductModels() {
const params = {
pageSize: 999,
showSenior: true,
};
const res = await listShortProduct(params);
if (res.code === 200) {
this.prodcutModels = res.data || [];
}
},
closeProductModelDialog() {
this.productModelVisible = false;
this.productId = '';
},
submitProdcutModel() {
if (!this.productId) {
this.$message.warning('请选择产品后再确认');
return;
}
this.callback && this.callback(this.productId);
},
},
};
</script>
<style lang="scss" scoped>
.system-app-lang {
padding: 20px;
padding: 20px;
.search-card {
margin-bottom: 15px;
padding: 3px 0;
}
.search-card {
margin-bottom: 15px;
padding: 3px 0;
}
.search-form {
margin-bottom: -22.5px;
}
.search-form {
margin-bottom: -22.5px;
}
}
</style>

View File

@@ -283,7 +283,7 @@ export default {
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -307,7 +307,7 @@ export default {
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -283,7 +283,7 @@ export default {
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -400,7 +400,7 @@ export default {
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -255,7 +255,7 @@ export default {
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -259,7 +259,7 @@ export default {
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -512,7 +512,7 @@ export default {
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {
@@ -534,7 +534,7 @@ export default {
::v-deep .el-table {
th {
background-color: #f5f7fa;
// background-color: #f5f7fa;
color: #606266;
font-weight: 600;
}
@@ -553,7 +553,7 @@ export default {
::v-deep .el-table {
th {
background-color: #f5f7fa;
// background-color: #f5f7fa;
color: #606266;
font-weight: 600;
text-align: center;

View File

@@ -594,7 +594,7 @@ export default {
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {

View File

@@ -1,5 +1,5 @@
<template>
<div class="app-container">
<div class="gen-wrap">
<!-- 搜索栏 - 上栏 -->
<el-card shadow="never" class="search-card" v-show="showSearch">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
@@ -262,14 +262,14 @@ export default {
</script>
<style lang="scss" scoped>
.app-container {
padding: 20px;
.gen-wrap {
padding: 15px;
min-height: 100vh;
background-color: #f5f7fa;
}
.search-card {
margin-bottom: 15px;
margin-bottom: 10px;
border-radius: 8px;
::v-deep .el-card__body {