Merge branch 'main' of http://47.107.152.87:3000/liubiao/dyf-vue-ui
@ -5,8 +5,8 @@ VITE_APP_TITLE = 云平台管理系统
|
||||
VITE_APP_ENV = 'development'
|
||||
|
||||
# 开发环境
|
||||
VITE_APP_BASE_API = 'http://47.120.79.150/backend'
|
||||
#VITE_APP_BASE_API = 'http://192.168.2.23:8000'
|
||||
# VITE_APP_BASE_API = 'http://47.120.79.150/backend'
|
||||
VITE_APP_BASE_API = 'http://192.168.2.23:8000'
|
||||
# VITE_APP_BASE_API = 'http://localhost:8000'
|
||||
|
||||
|
||||
|
24
src/api/home/index.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
// 获取 数据总览 DataOverview
|
||||
export const getDataOverview = (params) => {
|
||||
return request({
|
||||
url: '/api/device/homepage/getDataOverview',
|
||||
method: 'get',
|
||||
params: params
|
||||
});
|
||||
};
|
||||
// 设备分类
|
||||
export const getEquipmentClassification = (params) => {
|
||||
return request({
|
||||
url: '/api/device/homepage/getEquipmentClassification',
|
||||
method: 'get',
|
||||
params: params
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
getDataOverview,
|
||||
getEquipmentClassification
|
||||
}
|
6
src/api/home/types.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export interface DataOverviewType {
|
||||
devicesNumber: number | string;
|
||||
equipmentOnline: number | string;
|
||||
bindingNew: number | string;
|
||||
equipmentAbnormal: number | string;
|
||||
}
|
BIN
src/assets/index/add.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
src/assets/index/conton.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
src/assets/index/device_add.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
src/assets/index/device_group.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
src/assets/index/device_type.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
src/assets/index/device_yc.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
src/assets/index/devices_online.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
src/assets/index/online.png
Normal file
After Width: | Height: | Size: 29 KiB |
@ -229,7 +229,7 @@ const laserMode = ref<LightMode>({
|
||||
active: false
|
||||
});
|
||||
|
||||
const deviceDetail = ref<DeviceDetail>({
|
||||
const deviceDetail = ref<DeviceDetail & { typeName: string }>({
|
||||
// 重点:personnelInfo 初始化为空对象,避免 undefined
|
||||
personnelInfo: {
|
||||
unitName: '',
|
||||
@ -246,7 +246,9 @@ const deviceDetail = ref<DeviceDetail>({
|
||||
longitude: '',
|
||||
latitude: '',
|
||||
address: '',
|
||||
sendMsg: ''
|
||||
sendMsg: '',
|
||||
chargeState: '0',
|
||||
typeName: ''
|
||||
});
|
||||
// 保留原有的操作中标志位
|
||||
const isUpdatingStatus = ref(false);
|
||||
@ -429,7 +431,7 @@ const saveBtn = () => {
|
||||
// 强制报警
|
||||
const forceAlarm = async () => {
|
||||
try {
|
||||
await proxy?.$modal.confirm('确定要对该设备开启强制报警?', '');
|
||||
await proxy?.$modal.confirm('确定要对该设备开启强制报警?', '提示');
|
||||
forceAlarmLoading.value = true
|
||||
// 2. 准备请求数据
|
||||
const batchId = generateShortId();
|
||||
@ -586,7 +588,7 @@ const handleDeviceMessage = (msg: any) => {
|
||||
deviceDetail.value.batteryPercentage = deviceState[3]; //电量
|
||||
deviceDetail.value.batteryRemainingTime = deviceState[5]; //续航时间
|
||||
// getList(); // 重新获取设备详情
|
||||
if (deviceDetail.value.batteryPercentage < 20 && deviceDetail.value.chargeState == 0) {
|
||||
if (deviceDetail.value.batteryPercentage < 20 && Number(deviceDetail.value.chargeState) == 0) {
|
||||
centerDialogVisible.value=true
|
||||
}
|
||||
break;
|
||||
|
@ -64,6 +64,7 @@
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.communicationMode == 0">4G</div>
|
||||
<div v-if="scope.row.communicationMode == 1">蓝牙</div>
|
||||
<div v-if="scope.row.communicationMode == 2">4G&蓝牙</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建日期" />
|
||||
@ -105,7 +106,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="pc路由跳转" prop="pcModelDictionary" style="display: none;">
|
||||
<el-select v-model="form.pcModelDictionary" placeholder="请选择" >
|
||||
<el-select v-model="form.pcModelDictionary" placeholder="请选择">
|
||||
<el-option v-for="item in pcmodelDictionaryOptions" :key="item.dictCode" :label="item.dictLabel"
|
||||
:value="item.dictValue" />
|
||||
</el-select>
|
||||
@ -141,6 +142,7 @@
|
||||
<el-select v-model="form.communicationMode" placeholder="请选择">
|
||||
<el-option label="4G" :value="0" />
|
||||
<el-option label="蓝牙" :value="1" />
|
||||
<el-option label="4G&蓝牙" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -43,39 +43,44 @@
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd()">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain :disabled="single" icon="Edit" @click="handleUpdate()">
|
||||
修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['equipment:devices:add']" type="primary" plain icon="Plus"
|
||||
@click="handleAdd()">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['equipment:devices:edit']" type="success" plain :disabled="single" icon="Edit"
|
||||
@click="handleUpdate()">
|
||||
修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" :disabled="multiple" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain :disabled="multiple" @click="handleDelete()">
|
||||
批量删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain @click="handleBatchImport">
|
||||
批量导入
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain :disabled="multiple" @click="handleBatchAssign">
|
||||
批量分配客户
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" :search="true" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['equipment:devices:export']" type="warning" :disabled="multiple" plain
|
||||
icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['equipment:devices:remove']" type="danger" plain :disabled="multiple"
|
||||
@click="handleDelete()">
|
||||
批量删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['equipment:devices:import']" type="warning" plain @click="handleBatchImport">
|
||||
批量导入
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['equipment:devices:allocate']" type="warning" plain :disabled="multiple"
|
||||
@click="handleBatchAssign">
|
||||
批量分配客户
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" :search="true" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="deviceDist" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
@ -115,93 +120,42 @@
|
||||
<el-table-column prop="createTime" label="创建日期" width="160" />
|
||||
<el-table-column prop="createByName" label="创建人" />
|
||||
|
||||
<el-table-column label="操作" fixed="right" width="280" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
|
||||
|
||||
<el-tooltip v-if="scope.row.id !== 1 && scope.row.deviceStatus == 1" content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="!scope.row.customerName" content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="scope.row.deviceStatus == 1 && !scope.row.customerName" content="分配" placement="top">
|
||||
<el-button link type="primary" icon="User" @click="handleAssign(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="scope.row.customerName && scope.row.deviceStatus == 1" content="撤回" placement="top">
|
||||
<el-button link type="primary" icon="UploadFilled" @click="handleWithdraw(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="scope.row.bindingStatus == 1" :disabled="scope.row.deviceStatus === 0" content="解绑"
|
||||
placement="top">
|
||||
<el-button link type="primary" icon="Refresh" @click="handleUnbind(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="scope.row.deviceImei" content="查看二维码" placement="top">
|
||||
<el-button link type="primary" icon="Postcard" @click="showQrCode(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="详情" placement="top">
|
||||
<el-table-column label="操作" fixed="right" width="280" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip v-if="scope.row.id !== 1 && scope.row.deviceStatus == 1" content="修改" placement="top">
|
||||
<el-button v-hasPermi="['equipment:devices:edit']" link type="primary" icon="Edit"
|
||||
@click="handleUpdate(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="!scope.row.customerName" content="删除" placement="top">
|
||||
<el-button v-hasPermi="['equipment:devices:remove']" link type="primary" icon="Delete"
|
||||
@click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="scope.row.deviceStatus == 1 && !scope.row.customerName" content="分配" placement="top">
|
||||
<el-button v-hasPermi="['equipment:devices:allocate']" link type="primary" icon="User"
|
||||
@click="handleAssign(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="scope.row.customerName && scope.row.deviceStatus == 1" content="撤回" placement="top">
|
||||
<el-button v-hasPermi="['equipment:devices:revoke']" link type="primary" icon="UploadFilled"
|
||||
@click="handleWithdraw(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="scope.row.bindingStatus == 1" :disabled="scope.row.deviceStatus === 0" content="解绑"
|
||||
placement="top">
|
||||
<el-button v-hasPermi="['equipment:devices:unbind']" link type="primary" icon="Refresh"
|
||||
@click="handleUnbind(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="scope.row.deviceImei" content="查看二维码" placement="top">
|
||||
<el-button link type="primary" icon="Postcard" @click="showQrCode(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="详情" placement="top">
|
||||
<el-button link type="primary" icon="More" @click="handleDetail(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||
:total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||
:total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<div :class="Status.Mode == PageMode.detail ? '' : 'displayNone'" class="detailMain">
|
||||
<div class="tabContent">
|
||||
<div class="tabHeader">
|
||||
<div class="indexContent">
|
||||
|
||||
|
||||
<div class="tabIndex" :class="Status.tabActive == 1 ? 'active' : ''" @click="tabIndexChange(1)">
|
||||
设备信息
|
||||
</div>
|
||||
<div class="tabIndex" :class="Status.tabActive == 2 ? 'active' : ''" @click="tabIndexChange(2)">
|
||||
用户信息
|
||||
</div>
|
||||
<div class="tabIndex" :class="Status.tabActive == 3 ? 'active' : ''" @click="tabIndexChange(3)">
|
||||
操作记录
|
||||
</div>
|
||||
<div class="tabIndex" :class="Status.tabActive == 4 ? 'active' : ''" @click="tabIndexChange(4)">
|
||||
报警记录
|
||||
</div>
|
||||
<div class="tabIndex" :class="Status.tabActive == 5 ? 'active' : ''" @click="tabIndexChange(5)">
|
||||
分享管理
|
||||
</div>
|
||||
<div class="tabIndex" :class="Status.tabActive == 6 ? 'active' : ''" @click="tabIndexChange(6)">
|
||||
充放电
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabClose">
|
||||
<el-icon @click="closeDetail()" :size="20" :color="'#7787a4'">
|
||||
<Close />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tabItem" v-show="Status.tabActive == 1">
|
||||
<eqDetail :data="detailData" :acIndex="Status.tabActive" data-name="eqDetail"></eqDetail>
|
||||
</div>
|
||||
<div class="tabItem" v-show="Status.tabActive == 2">
|
||||
<Usr :data="detailData" :acIndex="Status.tabActive" data-name="Usr"></Usr>
|
||||
</div>
|
||||
<div class="tabItem" v-show="Status.tabActive == 3">
|
||||
<OpraRecored :data="detailData" :acIndex="Status.tabActive" data-name="OpraRecored"></OpraRecored>
|
||||
</div>
|
||||
<div class="tabItem" v-show="Status.tabActive == 4">
|
||||
<WarnRecord :data="detailData" :acIndex="Status.tabActive" data-name="WarnRecord"></WarnRecord>
|
||||
</div>
|
||||
<div class="tabItem" v-show="Status.tabActive == 5">
|
||||
<shareManage :data="detailData" :acIndex="Status.tabActive" data-name="shareManage"></shareManage>
|
||||
</div>
|
||||
<div class="tabItem" v-show="Status.tabActive == 6">
|
||||
<Charge :data="detailData" :acIndex="Status.tabActive" data-name="Charge"></Charge>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加或修改用户配置对话框 -->
|
||||
<el-dialog ref="formDialogRef" v-model="dialog.visible" :title="dialog.title" width="30%" append-to-body
|
||||
@ -370,6 +324,7 @@ import WarnRecord from './WarnRecord.vue';
|
||||
import shareManage from './shareManage.vue';
|
||||
import Charge from './Charge.vue';
|
||||
|
||||
import router from '@/router';
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
|
||||
@ -609,7 +564,6 @@ const handleAdd = async () => {
|
||||
// 每次打开弹框时获取最新的设备类型数据
|
||||
getDeviceType();
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: deviceForm) => {
|
||||
reset();
|
||||
@ -645,6 +599,7 @@ const handleUpdate = async (row?: deviceForm) => {
|
||||
// 设备类型触发事件
|
||||
let isProcessing = false; // 添加处理锁
|
||||
const handleDeviceTypeChange = async (deviceTypeId: string | number) => {
|
||||
console.log(deviceTypeId, 'deviceTypeIddeviceTypeId');
|
||||
// 重置规则和显示状态
|
||||
rules.value.deviceMac = [];
|
||||
rules.value.deviceImei = [];
|
||||
@ -653,12 +608,31 @@ const handleDeviceTypeChange = async (deviceTypeId: string | number) => {
|
||||
communicationModeInfo.value = null;
|
||||
// 编辑时如果有值,根据已有值确定显示哪个字段
|
||||
if (form.value.id) {
|
||||
if (form.value.deviceMac) {
|
||||
console.log('zheshi me1 ');
|
||||
// 1. 先判断:Mac 和 Imei 都有值(新增的关键分支)
|
||||
const hasMac = typeof form.value.deviceMac === 'string' && form.value.deviceMac.trim() !== '';
|
||||
const hasImei = typeof form.value.deviceImei === 'string' && form.value.deviceImei.trim() !== '';
|
||||
if (hasMac && hasImei) {
|
||||
//两个都有值:显示两个字段 + 都加校验
|
||||
showMacField.value = true;
|
||||
rules.value.deviceMac = [{ required: true, message: '请输入设备MAC', trigger: 'blur' }];
|
||||
} else if (form.value.deviceImei) {
|
||||
showImeiField.value = true;
|
||||
rules.value.deviceMac = [{ required: true, message: '请输入设备MAC', trigger: 'blur' }];
|
||||
rules.value.deviceImei = [{ required: true, message: '请输入设备IMEI', trigger: 'blur' }];
|
||||
console.log('两个字段都有值');
|
||||
}
|
||||
else if (hasMac) {
|
||||
showMacField.value = true;
|
||||
showImeiField.value = false;
|
||||
rules.value.deviceMac = [{ required: true, message: '请输入设备MAC', trigger: 'blur' }];
|
||||
rules.value.deviceImei = [];
|
||||
console.log('只有 Mac 有值');
|
||||
}
|
||||
else if (hasImei) {
|
||||
showImeiField.value = true;
|
||||
showMacField.value = false;
|
||||
rules.value.deviceImei = [{ required: true, message: '请输入设备IMEI', trigger: 'blur' }];
|
||||
rules.value.deviceMac = [];
|
||||
console.log('只有 Imei 有值');
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -683,6 +657,9 @@ const handleDeviceTypeChange = async (deviceTypeId: string | number) => {
|
||||
showImeiField.value = true;
|
||||
form.value.deviceMac = ''; // 清空MAC
|
||||
form.value.bluetoothName = '' // 清空蓝牙名称
|
||||
} else if (res.data.communicationMode == '2') { //既是4G设备又是蓝牙设备
|
||||
showImeiField.value = true;
|
||||
showMacField.value = true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|