Compare commits
9 Commits
dev
...
6613a0651b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6613a0651b | ||
|
|
bccb7d93e3 | ||
|
|
621fee41a4 | ||
|
|
d3403d02f9 | ||
|
|
6eefc67046 | ||
|
|
7e8ef7aa0f | ||
|
|
6da46f87ad | ||
|
|
e9be8f13ed | ||
|
|
3b39f9f3f3 |
@@ -84,36 +84,6 @@ export interface CallNoticeVO {
|
||||
*/
|
||||
voiceType: string;
|
||||
|
||||
/**
|
||||
* 呼叫时间
|
||||
*/
|
||||
callTime?: string;
|
||||
|
||||
/**
|
||||
* 用户名(关联查询)
|
||||
*/
|
||||
userName?: string;
|
||||
|
||||
/**
|
||||
* 设备编号(关联查询)
|
||||
*/
|
||||
serialNum?: string;
|
||||
|
||||
/**
|
||||
* 设备类型(关联查询)
|
||||
*/
|
||||
deviceType?: number;
|
||||
|
||||
/**
|
||||
* 告警类型
|
||||
*/
|
||||
warnType?: number;
|
||||
|
||||
/**
|
||||
* 告警标题
|
||||
*/
|
||||
warnTitle?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface CallNoticeForm extends BaseEntity {
|
||||
|
||||
@@ -16,19 +16,6 @@ export const listDevice = (query?: DeviceQuery): AxiosPromise<DeviceVO[]> => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询太阳能网控设备列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listSolarDevice = (query?: DeviceQuery): AxiosPromise<DeviceVO[]> => {
|
||||
return request({
|
||||
url: '/fishery/device/solar/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询设备管理详细
|
||||
* @param id
|
||||
@@ -74,25 +61,3 @@ export const delDevice = (id: string | number | Array<string | number>) => {
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 硬删除设备(彻底删除)
|
||||
* @param ids
|
||||
*/
|
||||
export const hardDeleteDevice = (ids: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/fishery/device/hard_delete/' + (Array.isArray(ids) ? ids.join(',') : ids),
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 数据清零
|
||||
* @param id
|
||||
*/
|
||||
export const resetTestData = (id: string | number) => {
|
||||
return request({
|
||||
url: '/fishery/device/resetTestData/' + id,
|
||||
method: 'put'
|
||||
});
|
||||
};
|
||||
|
||||
@@ -184,11 +184,6 @@ export interface DeviceVO {
|
||||
*/
|
||||
voltageWarnOpen: number;
|
||||
|
||||
/**
|
||||
* 控制器故障电话报警开关(断电不受此开关限制)
|
||||
*/
|
||||
controllerFaultCallOpen: number;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@@ -219,31 +214,6 @@ export interface DeviceVO {
|
||||
*/
|
||||
batteryWarnLower: number;
|
||||
|
||||
/**
|
||||
* 用户名(关联查询)
|
||||
*/
|
||||
userName?: string;
|
||||
|
||||
/**
|
||||
* 手机号(关联查询)
|
||||
*/
|
||||
mobilePhone?: string;
|
||||
|
||||
/**
|
||||
* 塘口名称(关联查询)
|
||||
*/
|
||||
pondName?: string;
|
||||
|
||||
/**
|
||||
* 在线状态(online/offline)
|
||||
*/
|
||||
onlineStatus?: string;
|
||||
|
||||
/**
|
||||
* 创建时间(激活时间)
|
||||
*/
|
||||
createTime?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DeviceForm extends BaseEntity {
|
||||
@@ -432,11 +402,6 @@ export interface DeviceForm extends BaseEntity {
|
||||
*/
|
||||
voltageWarnOpen?: number;
|
||||
|
||||
/**
|
||||
* 控制器故障电话报警开关(断电不受此开关限制)
|
||||
*/
|
||||
controllerFaultCallOpen?: number;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
@@ -69,11 +69,6 @@ export interface MessageWarnVO {
|
||||
*/
|
||||
createTime?: string;
|
||||
|
||||
/**
|
||||
* 电话通知次数
|
||||
*/
|
||||
callNoticeCount?: number;
|
||||
|
||||
}
|
||||
|
||||
export interface MessageWarnForm extends BaseEntity {
|
||||
|
||||
@@ -61,15 +61,3 @@ export const delPayOrder = (id: string | number | Array<string | number>) => {
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 主动向微信确认并修复支付订单
|
||||
* @param orderId 订单ID
|
||||
*/
|
||||
export const confirmPayOrder = (orderId: string | number) => {
|
||||
return request({
|
||||
url: '/weixin/pay/confirm_order',
|
||||
method: 'post',
|
||||
data: { orderId }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
export interface SolarPropertyCommand {
|
||||
id: string | number;
|
||||
properties: Record<string, any>;
|
||||
cache?: boolean;
|
||||
}
|
||||
|
||||
export interface SolarPropertyCommandResult {
|
||||
deviceId: string | number;
|
||||
serialNum: string;
|
||||
online: boolean;
|
||||
statusCode?: number;
|
||||
properties: Record<string, any>;
|
||||
mode: 'direct' | 'cached';
|
||||
cached: boolean;
|
||||
sent: boolean;
|
||||
}
|
||||
|
||||
export const getDeviceStatus = (devicetype: number, serialnum: string): AxiosPromise<number> => {
|
||||
return request({
|
||||
url: '/iot/device/status',
|
||||
method: 'get',
|
||||
params: {
|
||||
devicetype,
|
||||
serialnum
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const sendSolarPropertyCommand = (data: SolarPropertyCommand): AxiosPromise<SolarPropertyCommandResult> => {
|
||||
return request({
|
||||
url: '/iot/device/solar/property-command',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
1
src/types/components.d.ts
vendored
1
src/types/components.d.ts
vendored
@@ -19,7 +19,6 @@ declare module 'vue' {
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" style="white-space: nowrap">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="用户名" prop="userName">
|
||||
<el-input v-model="queryParams.userName" placeholder="请输入用户名" clearable style="width: 160px" @keyup.enter="handleQuery" />
|
||||
<el-input v-model="queryParams.userName" placeholder="请输入用户名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号" prop="mobilePhone">
|
||||
<el-input v-model="queryParams.mobilePhone" placeholder="请输入手机号" clearable style="width: 160px" @keyup.enter="handleQuery" />
|
||||
<el-input v-model="queryParams.mobilePhone" placeholder="请输入手机号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="省份" prop="province">
|
||||
<el-input v-model="queryParams.province" placeholder="请输入省份" clearable @keyup.enter="handleQuery" />
|
||||
@@ -20,13 +20,7 @@
|
||||
<el-input v-model="queryParams.district" placeholder="请输入区县" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="报警电话" prop="warnPhoneJson">
|
||||
<el-input v-model="queryParams.warnPhoneJson" placeholder="请输入报警电话" clearable style="width: 160px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否管理员" prop="isManager">
|
||||
<el-select v-model="queryParams.isManager" placeholder="请选择" clearable style="width: 120px">
|
||||
<el-option label="是" :value="1" />
|
||||
<el-option label="否" :value="0" />
|
||||
</el-select>
|
||||
<el-input v-model="queryParams.warnPhoneJson" placeholder="请输入报警电话" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
@@ -65,13 +59,6 @@
|
||||
<el-table-column label="主键id" align="center" prop="id" v-if="false" />
|
||||
<el-table-column label="用户名" align="center" prop="userName" />
|
||||
<el-table-column label="手机号" align="center" prop="mobilePhone" />
|
||||
<el-table-column label="是否管理员" align="center" prop="isManager" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.isManager === 1 ? 'success' : 'info'" size="small">
|
||||
{{ scope.row.isManager === 1 ? '是' : '否' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="省份" align="center" prop="province" />
|
||||
<el-table-column label="城市" align="center" prop="city" />
|
||||
<el-table-column label="区县" align="center" prop="district" /> -->
|
||||
@@ -135,10 +122,7 @@
|
||||
<el-input v-model="form.wxSessionKey" placeholder="请输入微信SessionKey" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否管理员" prop="isManager">
|
||||
<el-select v-model="form.isManager" placeholder="请选择是否管理员" clearable style="width: 200px">
|
||||
<el-option label="是" :value="1" />
|
||||
<el-option label="否" :value="0" />
|
||||
</el-select>
|
||||
<el-input v-model="form.isManager" placeholder="请输入是否管理员" />
|
||||
</el-form-item>
|
||||
<el-form-item label="微信unionId" prop="wxUnionId">
|
||||
<el-input v-model="form.wxUnionId" placeholder="请输入微信unionId" />
|
||||
@@ -470,15 +454,6 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="10" class="mt-3">
|
||||
<el-col :span="6">
|
||||
<div class="param-item">
|
||||
<div class="param-label">控制器故障电话告警</div>
|
||||
<dict-tag :options="[{label:'关',value:'0'},{label:'开',value:'1'}]" :value="String(device.controllerFaultCallOpen ?? 1)"/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="10" class="mt-3">
|
||||
<el-col :span="6">
|
||||
<div class="param-item">
|
||||
@@ -690,15 +665,6 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="10" class="mt-3">
|
||||
<el-col :span="6">
|
||||
<div class="param-item">
|
||||
<div class="param-label">控制器故障电话告警</div>
|
||||
<dict-tag :options="[{label:'关',value:'0'},{label:'开',value:'1'}]" :value="String(device.controllerFaultCallOpen ?? 1)"/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="10" class="mt-3">
|
||||
<el-col :span="6">
|
||||
<div class="param-item">
|
||||
@@ -907,7 +873,6 @@ const data = reactive<PageData<AquUserForm, AquUserQuery>>({
|
||||
city: undefined,
|
||||
district: undefined,
|
||||
warnPhoneJson: undefined,
|
||||
isManager: undefined,
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
<el-option v-for="dict in warn_type" :key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="告警标题" prop="params.warnTitle">
|
||||
<el-input v-model="queryParams.params.warnTitle" placeholder="请输入告警标题" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="呼叫电话" prop="mobilePhone">
|
||||
<el-input v-model="queryParams.mobilePhone" placeholder="请输入呼叫电话" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
@@ -59,7 +56,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="callNoticeList" @selection-change="handleSelectionChange" class="hidden-sm-and-down">
|
||||
<el-table v-loading="loading" border :data="callNoticeList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="用户名" align="center" prop="userName" width="120"/>
|
||||
<!-- <el-table-column label="手机号" align="center" prop="mobilePhone" width="120"/> -->
|
||||
@@ -111,64 +108,6 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 移动端卡片展示 -->
|
||||
<div v-loading="loading" class="mobile-card-list hidden-sm-and-up">
|
||||
<div v-if="callNoticeList.length === 0" class="no-data">
|
||||
<el-empty description="暂无数据" />
|
||||
</div>
|
||||
<el-card v-for="item in callNoticeList" :key="item.id" class="mobile-notice-card" shadow="hover">
|
||||
<!-- 卡片头部 -->
|
||||
<div class="card-header">
|
||||
<div class="header-left">
|
||||
<dict-tag :options="call_status" :value="item.callStatus" class="status-tag"/>
|
||||
<span class="call-time">{{ item.callTime || '-' }}</span>
|
||||
</div>
|
||||
<el-checkbox :model-value="ids.includes(item.id)" @change="handleMobileSelect(item, $event)" />
|
||||
</div>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<div class="info-section">
|
||||
<div class="info-list">
|
||||
<div class="info-row"><span class="label">用户名</span><span class="value">{{ item.userName || '-' }}</span></div>
|
||||
<div class="info-row"><span class="label">设备编号</span><span class="value">{{ item.serialNum || '-' }}</span></div>
|
||||
<div class="info-row"><span class="label">设备类型</span><span class="value"><dict-tag :options="aqu_device_type" :value="item.deviceType"/></span></div>
|
||||
<div class="info-row"><span class="label">呼叫电话</span><span class="value highlight">{{ item.mobilePhone || '-' }}</span></div>
|
||||
<div class="info-row"><span class="label">主叫号码</span><span class="value">{{ item.caller || '-' }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 告警信息 -->
|
||||
<div class="info-section warn-section">
|
||||
<div class="section-title">告警信息</div>
|
||||
<div class="warn-grid">
|
||||
<div class="warn-item">
|
||||
<span class="warn-label">告警类型</span>
|
||||
<span class="warn-value"><dict-tag :options="warn_type" :value="item.warnType"/></span>
|
||||
</div>
|
||||
<div class="warn-item">
|
||||
<span class="warn-label">告警标题</span>
|
||||
<span class="warn-value">{{ item.warnTitle || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 结果信息 -->
|
||||
<div class="info-section" v-if="item.statusMsg">
|
||||
<div class="section-title">呼叫结果</div>
|
||||
<div class="result-box">
|
||||
<span class="result-text">{{ item.statusMsg }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="card-footer">
|
||||
<el-button type="danger" size="small" plain @click="handleDelete(item)" v-hasPermi="['fishery:callNotice:remove']">
|
||||
<el-icon><Delete /></el-icon>删除
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改告警电话通知记录对话框 -->
|
||||
@@ -397,19 +336,6 @@ const handleSelectionChange = (selection: CallNoticeVO[]) => {
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
/** 移动端选择 */
|
||||
const handleMobileSelect = (item: CallNoticeVO, checked: boolean | string | number) => {
|
||||
if (checked) {
|
||||
if (!ids.value.includes(item.id)) {
|
||||
ids.value.push(item.id);
|
||||
}
|
||||
} else {
|
||||
ids.value = ids.value.filter(id => id !== item.id);
|
||||
}
|
||||
single.value = ids.value.length != 1;
|
||||
multiple.value = !ids.value.length;
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
@@ -464,185 +390,3 @@ onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 移动端卡片样式
|
||||
.mobile-card-list {
|
||||
.no-data {
|
||||
padding: 40px 0;
|
||||
}
|
||||
|
||||
.mobile-notice-card {
|
||||
margin-bottom: 12px;
|
||||
border-radius: 8px;
|
||||
|
||||
:deep(.el-card__body) {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
.status-tag {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.call-time {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-section {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #e6a23c;
|
||||
margin-bottom: 8px;
|
||||
padding-left: 8px;
|
||||
border-left: 3px solid #e6a23c;
|
||||
}
|
||||
|
||||
.info-list {
|
||||
background-color: #fafafa;
|
||||
border-radius: 6px;
|
||||
padding: 4px 0;
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px dashed #ebeef5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #909399;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
text-align: right;
|
||||
word-break: break-all;
|
||||
flex: 1;
|
||||
margin-left: 12px;
|
||||
|
||||
&.highlight {
|
||||
color: #409eff;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.warn-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 8px;
|
||||
|
||||
.warn-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 8px 12px;
|
||||
background: linear-gradient(135deg, #fdf6ec 0%, #faecd8 100%);
|
||||
border-radius: 6px;
|
||||
border: 1px solid #f5dab1;
|
||||
|
||||
.warn-label {
|
||||
font-size: 11px;
|
||||
color: #909399;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.warn-value {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.result-box {
|
||||
padding: 10px 12px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 6px;
|
||||
|
||||
.result-text {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
margin-top: 4px;
|
||||
|
||||
.el-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 8px 16px;
|
||||
font-size: 13px;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s;
|
||||
|
||||
.el-icon {
|
||||
font-size: 16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式隐藏
|
||||
.hidden-sm-and-down {
|
||||
@media (max-width: 768px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden-sm-and-up {
|
||||
@media (min-width: 769px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,15 +32,15 @@
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:deviceBindRecord:add']">新增</el-button>
|
||||
</el-col> -->
|
||||
<!-- <el-col :span="1.5">
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:deviceBindRecord:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
<!-- <el-col :span="1.5">
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:deviceBindRecord:remove']">删除</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['fishery:deviceBindRecord:export']">导出</el-button>
|
||||
</el-col> -->
|
||||
@@ -58,14 +58,14 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="设备编号" align="center" prop="serialNum" />
|
||||
|
||||
|
||||
<el-table-column label="绑定/解绑" align="center" prop="isBind">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="is_bind" :value="scope.row.isBind"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作时间" align="center" prop="createTime" />
|
||||
<!-- <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['fishery:deviceBindRecord:edit']"></el-button>
|
||||
@@ -74,7 +74,7 @@
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['fishery:deviceBindRecord:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
@@ -83,10 +83,10 @@
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="deviceBindRecordFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="用户" prop="userId">
|
||||
<el-input
|
||||
:value="selectedUser ? `${selectedUser.userName} (${selectedUser.mobilePhone})` : ''"
|
||||
placeholder="请选择用户"
|
||||
readonly
|
||||
<el-input
|
||||
:value="selectedUser ? `${selectedUser.userName} (${selectedUser.mobilePhone})` : ''"
|
||||
placeholder="请选择用户"
|
||||
readonly
|
||||
@click="openUserSelect"
|
||||
style="cursor: pointer;"
|
||||
>
|
||||
@@ -108,9 +108,9 @@
|
||||
<el-form-item label="设备编号" prop="serialNum">
|
||||
<el-input v-model="form.serialNum" placeholder="请输入设备编号" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="物联网IotId" prop="iotId">
|
||||
<el-form-item label="物联网IotId" prop="iotId">
|
||||
<el-input v-model="form.iotId" placeholder="请输入物联网IotId" />
|
||||
</el-form-item> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="绑定/解绑" prop="isBind">
|
||||
<el-select v-model="form.isBind" placeholder="请选择绑定/解绑" style="width: 100%">
|
||||
<el-option
|
||||
@@ -129,25 +129,25 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
<!-- 用户选择对话框 -->
|
||||
<el-dialog title="选择用户" v-model="userSelectVisible" width="900px" append-to-body>
|
||||
<!-- 搜索条件 -->
|
||||
<el-form :model="userQueryParams" :inline="true" class="mb-4">
|
||||
<el-form-item label="用户名">
|
||||
<el-input
|
||||
v-model="userQueryParams.userName"
|
||||
placeholder="请输入用户名"
|
||||
clearable
|
||||
<el-input
|
||||
v-model="userQueryParams.userName"
|
||||
placeholder="请输入用户名"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
@keyup.enter="handleUserQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号">
|
||||
<el-input
|
||||
v-model="userQueryParams.mobilePhone"
|
||||
placeholder="请输入手机号"
|
||||
clearable
|
||||
<el-input
|
||||
v-model="userQueryParams.mobilePhone"
|
||||
placeholder="请输入手机号"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
@keyup.enter="handleUserQuery"
|
||||
/>
|
||||
@@ -157,10 +157,10 @@
|
||||
<el-button icon="Refresh" @click="resetUserQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
|
||||
<!-- 用户表格 -->
|
||||
<el-table
|
||||
:data="aquUserList"
|
||||
<el-table
|
||||
:data="aquUserList"
|
||||
highlight-current-row
|
||||
height="400px"
|
||||
border
|
||||
@@ -172,9 +172,9 @@
|
||||
<el-table-column label="区县" align="center" prop="district" />
|
||||
<el-table-column label="操作" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleUserSelect(scope.row)"
|
||||
>
|
||||
选择
|
||||
@@ -182,17 +182,17 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-show="userTotal > 0"
|
||||
:total="userTotal"
|
||||
v-model:page="userQueryParams.pageNum"
|
||||
v-model:limit="userQueryParams.pageSize"
|
||||
<pagination
|
||||
v-show="userTotal > 0"
|
||||
:total="userTotal"
|
||||
v-model:page="userQueryParams.pageNum"
|
||||
v-model:limit="userQueryParams.pageSize"
|
||||
@pagination="handleUserPaginationChange"
|
||||
class="mt-4"
|
||||
/>
|
||||
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="cancelUserSelect">取 消</el-button>
|
||||
@@ -345,7 +345,7 @@ const handleUpdate = async (row?: DeviceBindRecordVO) => {
|
||||
const _id = row?.id || ids.value[0]
|
||||
const res = await getDeviceBindRecord(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
|
||||
|
||||
// 回显用户信息
|
||||
if (form.value.userId) {
|
||||
try {
|
||||
@@ -368,7 +368,7 @@ const handleUpdate = async (row?: DeviceBindRecordVO) => {
|
||||
} else {
|
||||
selectedUser.value = null;
|
||||
}
|
||||
|
||||
|
||||
dialog.visible = true;
|
||||
dialog.title = "修改设备绑定记录";
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:deviceCorrectRecord:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:deviceCorrectRecord:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:deviceCorrectRecord:remove']">删除</el-button>
|
||||
</el-col>
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:deviceErrorCode:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:deviceErrorCode:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:deviceErrorCode:remove']">删除</el-button>
|
||||
</el-col>
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:deviceSwitch:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:deviceSwitch:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:deviceSwitch:remove']">删除</el-button>
|
||||
</el-col>
|
||||
@@ -271,15 +271,10 @@
|
||||
<el-dialog
|
||||
:title="`定时控制 - ${currentSwitch?.switchName || ''} (序号:${currentSwitch?.index || ''})`"
|
||||
v-model="timingCtrlDialogVisible"
|
||||
width="1080px"
|
||||
width="800px"
|
||||
append-to-body
|
||||
@close="closeTimingCtrlDialog"
|
||||
>
|
||||
<!-- 工具栏 -->
|
||||
<div style="margin-bottom: 12px;">
|
||||
<el-button type="primary" plain icon="Plus" size="small" @click="handleTimingCtrlAdd" v-hasPermi="['fishery:timingCtrl:add']">新增</el-button>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
v-loading="timingCtrlLoading"
|
||||
:data="timingCtrlList"
|
||||
@@ -298,17 +293,6 @@
|
||||
<dict-tag :options="open_close" :value="scope.row.isOpen"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip /> -->
|
||||
<el-table-column label="操作" align="center" width="120" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleTimingCtrlUpdate(scope.row)" v-hasPermi="['fishery:timingCtrl:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="danger" icon="Delete" @click="handleTimingCtrlDelete(scope.row)" v-hasPermi="['fishery:timingCtrl:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<template #footer>
|
||||
@@ -317,49 +301,6 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 定时控制编辑对话框 -->
|
||||
<el-dialog :title="timingCtrlEditDialog.title" v-model="timingCtrlEditDialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="timingCtrlFormRef" :model="timingCtrlForm" :rules="timingCtrlRules" label-width="90px">
|
||||
<el-form-item label="开启时间" prop="openTime">
|
||||
<el-date-picker clearable
|
||||
v-model="timingCtrlForm.openTime"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择开启时间"
|
||||
style="width: 100%">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="关闭时间" prop="closeTime">
|
||||
<el-date-picker clearable
|
||||
v-model="timingCtrlForm.closeTime"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择关闭时间"
|
||||
style="width: 100%">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="循环类型" prop="loopType">
|
||||
<el-select v-model="timingCtrlForm.loopType" placeholder="请选择循环类型" style="width: 100%">
|
||||
<el-option v-for="dict in loop_type" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否启用" prop="isOpen">
|
||||
<el-select v-model="timingCtrlForm.isOpen" placeholder="请选择是否启用" style="width: 100%">
|
||||
<el-option v-for="dict in open_close" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="timingCtrlForm.remark" type="textarea" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="timingCtrlEditLoading" type="primary" @click="submitTimingCtrlForm">确 定</el-button>
|
||||
<el-button @click="timingCtrlEditDialog.visible = false">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -368,8 +309,8 @@ import { listDeviceSwitch, getDeviceSwitch, delDeviceSwitch, addDeviceSwitch, up
|
||||
import { DeviceSwitchVO, DeviceSwitchQuery, DeviceSwitchForm } from '@/api/fishery/deviceSwitch/types';
|
||||
import { listDevice } from '@/api/fishery/device';
|
||||
import { DeviceVO } from '@/api/fishery/device/types';
|
||||
import { listTimingCtrl, getTimingCtrl, addTimingCtrl, updateTimingCtrl, delTimingCtrl } from '@/api/fishery/timingCtrl';
|
||||
import { TimingCtrlVO, TimingCtrlForm } from '@/api/fishery/timingCtrl/types';
|
||||
import { listTimingCtrl } from '@/api/fishery/timingCtrl';
|
||||
import { TimingCtrlVO } from '@/api/fishery/timingCtrl/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { aqu_device_type, open_close, connect_voltage_type, is_linked_ctrl, loop_type } = toRefs<any>(proxy?.useDict('aqu_device_type', 'open_close', 'connect_voltage_type', 'is_linked_ctrl', 'loop_type'));
|
||||
@@ -700,79 +641,6 @@ const closeTimingCtrlDialog = () => {
|
||||
timingCtrlDialogVisible.value = false;
|
||||
currentSwitch.value = null;
|
||||
timingCtrlList.value = [];
|
||||
getList();
|
||||
};
|
||||
|
||||
// 定时控制编辑对话框
|
||||
const timingCtrlEditDialog = reactive<DialogOption>({ visible: false, title: '' });
|
||||
const timingCtrlFormRef = ref<ElFormInstance>();
|
||||
const timingCtrlEditLoading = ref(false);
|
||||
const initTimingCtrlForm: TimingCtrlForm = {
|
||||
id: undefined,
|
||||
switchId: undefined,
|
||||
openTime: undefined,
|
||||
closeTime: undefined,
|
||||
loopType: undefined,
|
||||
isOpen: undefined,
|
||||
remark: undefined
|
||||
};
|
||||
const timingCtrlForm = ref<TimingCtrlForm>({ ...initTimingCtrlForm });
|
||||
const timingCtrlRules = {
|
||||
openTime: [{ required: true, message: '开启时间不能为空', trigger: 'blur' }],
|
||||
closeTime: [{ required: true, message: '关闭时间不能为空', trigger: 'blur' }],
|
||||
loopType: [{ required: true, message: '循环类型不能为空', trigger: 'change' }],
|
||||
isOpen: [{ required: true, message: '是否启用不能为空', trigger: 'change' }]
|
||||
};
|
||||
|
||||
/** 新增定时控制 */
|
||||
const handleTimingCtrlAdd = () => {
|
||||
timingCtrlForm.value = { ...initTimingCtrlForm, switchId: currentSwitch.value?.id };
|
||||
timingCtrlFormRef.value?.resetFields();
|
||||
timingCtrlEditDialog.title = '新增定时控制';
|
||||
timingCtrlEditDialog.visible = true;
|
||||
};
|
||||
|
||||
/** 修改定时控制 */
|
||||
const handleTimingCtrlUpdate = async (row: TimingCtrlVO) => {
|
||||
const res = await getTimingCtrl(row.id);
|
||||
timingCtrlForm.value = { ...res.data };
|
||||
timingCtrlFormRef.value?.resetFields();
|
||||
timingCtrlEditDialog.title = '修改定时控制';
|
||||
timingCtrlEditDialog.visible = true;
|
||||
};
|
||||
|
||||
/** 提交定时控制表单 */
|
||||
const submitTimingCtrlForm = () => {
|
||||
timingCtrlFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
timingCtrlEditLoading.value = true;
|
||||
try {
|
||||
if (timingCtrlForm.value.id) {
|
||||
await updateTimingCtrl(timingCtrlForm.value);
|
||||
} else {
|
||||
await addTimingCtrl(timingCtrlForm.value);
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
timingCtrlEditDialog.visible = false;
|
||||
// 刷新定时控制列表
|
||||
if (currentSwitch.value) {
|
||||
await getTimingCtrlList(currentSwitch.value.id);
|
||||
}
|
||||
} finally {
|
||||
timingCtrlEditLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除定时控制 */
|
||||
const handleTimingCtrlDelete = async (row: TimingCtrlVO) => {
|
||||
await proxy?.$modal.confirm('是否确认删除该定时控制?');
|
||||
await delTimingCtrl(row.id);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
if (currentSwitch.value) {
|
||||
await getTimingCtrlList(currentSwitch.value.id);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:deviceThreshold:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:deviceThreshold:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:deviceThreshold:remove']"
|
||||
>删除</el-button
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:fish:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:fish:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:fish:remove']"
|
||||
>删除</el-button
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:linkedCtrl:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:linkedCtrl:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:linkedCtrl:remove']">删除</el-button>
|
||||
</el-col>
|
||||
|
||||
@@ -25,15 +25,15 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:mapMessageWarnCallNotice:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:mapMessageWarnCallNotice:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:mapMessageWarnCallNotice:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['fishery:mapMessageWarnCallNotice:export']">导出</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:messageOpRecord:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:messageOpRecord:remove']">删除</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['fishery:messageOpRecord:export']">导出</el-button>
|
||||
</el-col> -->
|
||||
@@ -63,9 +63,9 @@
|
||||
<!-- <el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['fishery:messageOpRecord:edit']"></el-button>
|
||||
</el-tooltip> -->
|
||||
<!-- <el-tooltip content="删除" placement="top">
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['fishery:messageOpRecord:remove']"></el-button>
|
||||
</el-tooltip> -->
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
@@ -9,16 +9,12 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="设备信息" prop="params.deviceKeyword">
|
||||
<el-input v-model="queryParams.params.deviceKeyword" placeholder="请输入设备名称或设备编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="告警标题" prop="title">
|
||||
<el-input v-model="queryParams.title" placeholder="请输入告警标题" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="告警类型" prop="warnType">
|
||||
<el-select v-model="queryParams.warnType" placeholder="请选择告警类型" clearable >
|
||||
<el-option v-for="dict in warn_type" :key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否已读" prop="isRead">
|
||||
<el-select v-model="queryParams.isRead" placeholder="请选择是否已读" clearable >
|
||||
<el-option v-for="dict in yes_no" :key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
@@ -52,7 +48,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="messageWarnList" @selection-change="handleSelectionChange" class="hidden-sm-and-down">
|
||||
<el-table v-loading="loading" border :data="messageWarnList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="用户名" align="center" prop="userName" width="120"/>
|
||||
<el-table-column label="手机号" align="center" prop="mobilePhone" width="120"/>
|
||||
@@ -96,55 +92,6 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 移动端卡片展示 -->
|
||||
<div v-loading="loading" class="mobile-card-list hidden-sm-and-up">
|
||||
<div v-if="messageWarnList.length === 0" class="no-data">
|
||||
<el-empty description="暂无数据" />
|
||||
</div>
|
||||
<el-card v-for="item in messageWarnList" :key="item.id" class="mobile-warn-card" shadow="hover">
|
||||
<!-- 卡片头部 -->
|
||||
<div class="card-header">
|
||||
<dict-tag :options="warn_type" :value="item.warnType" class="warn-type-tag"/>
|
||||
<el-checkbox :model-value="ids.includes(item.id)" @change="handleMobileSelect(item, $event)" />
|
||||
</div>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<div class="info-section">
|
||||
<div class="info-list">
|
||||
<div class="info-row"><span class="label">告警标题</span><span class="value">{{ item.title || '-' }}</span></div>
|
||||
<div class="info-row"><span class="label">告警时间</span><span class="value">{{ item.createTime || '-' }}</span></div>
|
||||
<div class="info-row"><span class="label">是否已读</span><dict-tag :options="yes_no" :value="item.isRead" /></div>
|
||||
<div class="info-row"><span class="label">用户名</span><span class="value">{{ item.userName || '-' }}</span></div>
|
||||
<div class="info-row"><span class="label">手机号</span><span class="value">{{ item.mobilePhone || '-' }}</span></div>
|
||||
<div class="info-row"><span class="label">设备编号</span><span class="value">{{ item.serialNum || '-' }}</span></div>
|
||||
<div class="info-row"><span class="label">设备名称</span><span class="value">{{ item.deviceName || '-' }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 告警内容 -->
|
||||
<div class="message-section">
|
||||
<div class="message-label">告警内容</div>
|
||||
<div class="message-content">{{ item.message || '-' }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 电话通知 -->
|
||||
<div class="notice-section" v-if="item.callNoticeCount && item.callNoticeCount > 0">
|
||||
<span class="notice-label">电话通知</span>
|
||||
<span class="notice-count" @click="handleViewCallNotice(item)">{{ item.callNoticeCount }}次</span>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="card-footer">
|
||||
<el-button type="primary" size="small" plain @click="handleView(item)" v-hasPermi="['fishery:messageWarn:query']">
|
||||
<el-icon><View /></el-icon>查看
|
||||
</el-button>
|
||||
<el-button type="danger" size="small" plain @click="handleDelete(item)" v-hasPermi="['fishery:messageWarn:remove']">
|
||||
<el-icon><Delete /></el-icon>删除
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 查看设备告警记录对话框 -->
|
||||
@@ -392,19 +339,6 @@ const handleSelectionChange = (selection: MessageWarnVO[]) => {
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
/** 移动端选择 */
|
||||
const handleMobileSelect = (item: MessageWarnVO, checked: boolean | string | number) => {
|
||||
if (checked) {
|
||||
if (!ids.value.includes(item.id)) {
|
||||
ids.value.push(item.id);
|
||||
}
|
||||
} else {
|
||||
ids.value = ids.value.filter(id => id !== item.id);
|
||||
}
|
||||
single.value = ids.value.length != 1;
|
||||
multiple.value = !ids.value.length;
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
@@ -469,150 +403,3 @@ onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 移动端卡片样式
|
||||
.mobile-card-list {
|
||||
.no-data {
|
||||
padding: 40px 0;
|
||||
}
|
||||
|
||||
.mobile-warn-card {
|
||||
margin-bottom: 12px;
|
||||
border-radius: 8px;
|
||||
|
||||
:deep(.el-card__body) {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
|
||||
.info-list {
|
||||
background-color: #fafafa;
|
||||
border-radius: 6px;
|
||||
padding: 4px 0;
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
border-bottom: 1px dashed #ebeef5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #909399;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
text-align: right;
|
||||
word-break: break-all;
|
||||
flex: 1;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-section {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
|
||||
.message-label {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.message-content {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
line-height: 1.6;
|
||||
padding: 8px 12px;
|
||||
background-color: #fef0f0;
|
||||
border-radius: 6px;
|
||||
border-left: 3px solid #f56c6c;
|
||||
}
|
||||
}
|
||||
|
||||
.notice-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
font-size: 12px;
|
||||
|
||||
.notice-label {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.notice-count {
|
||||
color: #409eff;
|
||||
font-weight: 600;
|
||||
margin-left: 8px;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 8px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
margin-top: 4px;
|
||||
|
||||
.el-button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: auto;
|
||||
padding: 10px 8px;
|
||||
font-size: 12px;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s;
|
||||
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式隐藏
|
||||
.hidden-sm-and-down {
|
||||
@media (max-width: 768px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden-sm-and-up {
|
||||
@media (min-width: 769px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button type="warning" plain icon="Download" :disabled="historyData.length === 0" @click="handleExport">导出 Excel</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
@@ -185,7 +184,6 @@
|
||||
import { ref, reactive, onMounted, nextTick, computed } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import type { EChartsOption } from 'echarts';
|
||||
import FileSaver from 'file-saver';
|
||||
import { getHistoryData } from '@/api/fishery/monitorHistory';
|
||||
import type { DeviceSensorDataQueryBo, DeviceSensorData } from '@/api/fishery/monitorHistory/types';
|
||||
import { listDevice } from '@/api/fishery/device';
|
||||
@@ -264,73 +262,6 @@ const tabConfig = {
|
||||
battery: { label: '电量', unit: '%', color: '#9a60b4' }
|
||||
};
|
||||
|
||||
const exportColumns: Array<{ label: string; unit?: string; getValue: (item: DeviceSensorData) => unknown }> = [
|
||||
{ label: '监测时间', getValue: item => item.time },
|
||||
{ label: '塘口', getValue: item => (item as DeviceSensorData & { pondName?: string }).pondName || selectedDevice.value?.pondName || '' },
|
||||
{ label: '设备名称', getValue: item => item.deviceName || selectedDevice.value?.deviceName || '' },
|
||||
{ label: '设备编号', getValue: item => item.serialNum || selectedDevice.value?.serialNum || queryParams.value.serialNum || '' },
|
||||
{ label: '溶解氧', unit: 'Mg/L', getValue: item => item.dissolvedOxygen },
|
||||
{ label: '水温', unit: '℃', getValue: item => item.temperature },
|
||||
{ label: '饱和度', unit: '%', getValue: item => item.saturability }
|
||||
];
|
||||
|
||||
const escapeHtml = (value: unknown) => {
|
||||
if (value === null || value === undefined) {
|
||||
return '';
|
||||
}
|
||||
return String(value)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
};
|
||||
|
||||
const getExportFileName = () => {
|
||||
const serialNum = queryParams.value.serialNum || 'all';
|
||||
const startTime = queryParams.value.startTime || dateRange.value?.[0] || '';
|
||||
const endTime = queryParams.value.endTime || dateRange.value?.[1] || '';
|
||||
const dateText = startTime && endTime ? `_${startTime}_${endTime}` : '';
|
||||
return `监测历史记录_${serialNum}${dateText}_${new Date().getTime()}.xls`;
|
||||
};
|
||||
|
||||
const getExportLimit = () => {
|
||||
const intervalType = Number(queryParams.value.intervalType || 1);
|
||||
if (intervalType === 1) {
|
||||
return { months: 1, message: '实时数据最多只能导出1个月内的数据' };
|
||||
}
|
||||
if (intervalType === 2 || intervalType === 3) {
|
||||
return { months: 3, message: '10分钟和30分钟数据最多只能导出3个月内的数据' };
|
||||
}
|
||||
return { months: 6, message: '1小时以上数据最多只能导出6个月内的数据' };
|
||||
};
|
||||
|
||||
const validateExportDateRange = () => {
|
||||
const startTime = queryParams.value.startTime || dateRange.value?.[0];
|
||||
const endTime = queryParams.value.endTime || dateRange.value?.[1];
|
||||
if (!startTime || !endTime) {
|
||||
proxy?.$modal.msgWarning('请先选择导出时间范围');
|
||||
return false;
|
||||
}
|
||||
|
||||
const startDate = new Date(`${startTime} 00:00:00`.replace(/-/g, '/'));
|
||||
const endDate = new Date(`${endTime} 23:59:59`.replace(/-/g, '/'));
|
||||
if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime()) || startDate > endDate) {
|
||||
proxy?.$modal.msgWarning('导出时间范围不正确,请重新选择');
|
||||
return false;
|
||||
}
|
||||
|
||||
const limit = getExportLimit();
|
||||
const maxEndDate = new Date(startDate);
|
||||
maxEndDate.setMonth(maxEndDate.getMonth() + limit.months);
|
||||
maxEndDate.setHours(23, 59, 59, 999);
|
||||
if (endDate > maxEndDate) {
|
||||
proxy?.$modal.msgWarning(limit.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/** 查询历史数据 */
|
||||
const getHistoryList = async () => {
|
||||
// 验证是否选择了设备
|
||||
@@ -400,63 +331,6 @@ const resetQuery = () => {
|
||||
endTime: '',
|
||||
intervalType: '3'
|
||||
};
|
||||
historyData.value = [];
|
||||
updateChart();
|
||||
};
|
||||
|
||||
/** 导出查询结果 */
|
||||
const handleExport = () => {
|
||||
if (historyData.value.length === 0) {
|
||||
proxy?.$modal.msgWarning('暂无可导出的历史数据,请先查询');
|
||||
return;
|
||||
}
|
||||
if (!validateExportDateRange()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const headerHtml = exportColumns
|
||||
.map(column => `<th>${escapeHtml(column.unit ? `${column.label}(${column.unit})` : column.label)}</th>`)
|
||||
.join('');
|
||||
const rowsHtml = historyData.value
|
||||
.map(item => {
|
||||
const cells = exportColumns
|
||||
.map(column => `<td style="mso-number-format:'\\@';">${escapeHtml(column.getValue(item))}</td>`)
|
||||
.join('');
|
||||
return `<tr>${cells}</tr>`;
|
||||
})
|
||||
.join('');
|
||||
const worksheet = `<!DOCTYPE html>
|
||||
<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<!--[if gte mso 9]>
|
||||
<xml>
|
||||
<x:ExcelWorkbook>
|
||||
<x:ExcelWorksheets>
|
||||
<x:ExcelWorksheet>
|
||||
<x:Name>监测历史记录</x:Name>
|
||||
<x:WorksheetOptions></x:WorksheetOptions>
|
||||
</x:ExcelWorksheet>
|
||||
</x:ExcelWorksheets>
|
||||
</x:ExcelWorkbook>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
th, td { border: 1px solid #dcdfe6; padding: 6px 10px; white-space: nowrap; }
|
||||
th { background: #f5f7fa; font-weight: bold; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<thead><tr>${headerHtml}</tr></thead>
|
||||
<tbody>${rowsHtml}</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const blob = new Blob([worksheet], { type: 'application/vnd.ms-excel;charset=utf-8' });
|
||||
FileSaver.saveAs(blob, getExportFileName());
|
||||
};
|
||||
|
||||
/** 标签页切换 */
|
||||
@@ -581,8 +455,6 @@ const updateChart = () => {
|
||||
type: chartType.value,
|
||||
data: yData,
|
||||
smooth: chartType.value === 'line',
|
||||
symbol: 'circle', // 使用圆形标记
|
||||
symbolSize: chartType.value === 'line' ? 0 : 6, // 折线图默认不显示点,柱状图不受影响
|
||||
itemStyle: {
|
||||
color: config.color
|
||||
},
|
||||
@@ -591,17 +463,6 @@ const updateChart = () => {
|
||||
} : undefined,
|
||||
areaStyle: chartType.value === 'line' ? {
|
||||
opacity: 0.1
|
||||
} : undefined,
|
||||
emphasis: chartType.value === 'line' ? {
|
||||
symbol: 'circle',
|
||||
symbolSize: 12,
|
||||
itemStyle: {
|
||||
color: config.color,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 3,
|
||||
shadowBlur: 8,
|
||||
shadowColor: config.color
|
||||
}
|
||||
} : undefined
|
||||
}
|
||||
]
|
||||
|
||||
@@ -509,9 +509,9 @@ const data = reactive<PageData<PayDeviceForm, PayDeviceQuery>>({
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
// userId: [
|
||||
// { required: true, message: "用户不能为空", trigger: "blur" }
|
||||
// ],
|
||||
userId: [
|
||||
{ required: true, message: "用户不能为空", trigger: "blur" }
|
||||
],
|
||||
serialNum: [
|
||||
{ required: true, message: "设备编号不能为空", trigger: "blur" }
|
||||
],
|
||||
|
||||
@@ -55,18 +55,7 @@
|
||||
<dict-tag :options="profit_status" :value="scope.row.profitStatus"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160"/>
|
||||
<el-table-column label="操作" align="center" width="140" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.orderStatus !== 2"
|
||||
link
|
||||
type="primary"
|
||||
icon="Refresh"
|
||||
@click="handleConfirmPay(scope.row)"
|
||||
>修复支付状态</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160"/>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
@@ -75,7 +64,7 @@
|
||||
</template>
|
||||
|
||||
<script setup name="PayOrder" lang="ts">
|
||||
import { confirmPayOrder, listPayOrder } from '@/api/fishery/payOrder';
|
||||
import { listPayOrder } from '@/api/fishery/payOrder';
|
||||
import { PayOrderVO, PayOrderQuery } from '@/api/fishery/payOrder/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@@ -131,23 +120,6 @@ const handleExport = () => {
|
||||
}, `payOrder_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
|
||||
/** 主动确认并修复微信支付状态 */
|
||||
const handleConfirmPay = async (row: PayOrderVO) => {
|
||||
await proxy?.$modal.confirm('是否向微信支付查询并修复该订单状态?');
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await confirmPayOrder(row.id);
|
||||
if (res.code === 200) {
|
||||
proxy?.$modal.msgSuccess('修复成功');
|
||||
} else {
|
||||
proxy?.$modal.msgWarning(res.msg || '微信侧尚未确认支付成功');
|
||||
}
|
||||
await getList();
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:pond:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:pond:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:pond:remove']"
|
||||
>删除</el-button
|
||||
|
||||
@@ -1,586 +0,0 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
|
||||
<el-form-item label="用户信息" prop="params.userKeyword">
|
||||
<el-input v-model="queryParams.params.userKeyword" placeholder="请输入用户名或手机号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备编号" prop="serialNum">
|
||||
<el-input v-model="queryParams.serialNum" placeholder="请输入设备编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备名称" prop="deviceName">
|
||||
<el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="塘口名称" prop="params.pondKeyword">
|
||||
<el-input v-model="queryParams.params.pondKeyword" placeholder="请输入塘口名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="在线状态" prop="params.onlineStatus">
|
||||
<el-select v-model="queryParams.params.onlineStatus" placeholder="请选择在线状态" clearable style="width: 180px" @change="handleQuery">
|
||||
<el-option v-for="item in onlineStatusOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="deviceList" row-key="id">
|
||||
<el-table-column label="用户名" align="center" prop="userName" min-width="120" />
|
||||
<el-table-column label="手机号" align="center" prop="mobilePhone" min-width="120" />
|
||||
<el-table-column label="设备编号" align="center" prop="serialNum" min-width="150" />
|
||||
<el-table-column label="设备名称" align="center" prop="deviceName" min-width="130" />
|
||||
<el-table-column label="塘口名称" align="center" prop="pondName" min-width="120" />
|
||||
<el-table-column label="在线状态" align="center" width="120">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusTagType(scope.row)" effect="light">
|
||||
{{ getStatusText(scope.row) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="盐度补偿" align="center" prop="salinityCompensation" width="120">
|
||||
<template #default="scope">
|
||||
{{ formatValue(scope.row.salinityCompensation) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="线性补偿" align="center" prop="phaseCompensation" width="120">
|
||||
<template #default="scope">
|
||||
{{ formatValue(scope.row.phaseCompensation) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="相位差补偿" align="center" prop="phasedifCompensation" width="120">
|
||||
<template #default="scope">
|
||||
{{ formatValue(scope.row.phasedifCompensation) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="温度补偿" align="center" prop="temperatureCompensation" width="120">
|
||||
<template #default="scope">
|
||||
{{ formatValue(scope.row.temperatureCompensation) }}
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column label="最后上数时间" align="center" prop="lastReportTime" min-width="170">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.lastReportTime, '{y}-{m}-{d} {h}:{i}:{s}') || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" fixed="right" width="260">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="Refresh" :loading="statusLoadingId === scope.row.id" @click="refreshStatus(scope.row)">刷新状态</el-button>
|
||||
<el-button link type="primary" icon="Position" @click="openCommand(scope.row)" v-hasPermi="['fishery:solarControl:command']">下发指令</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="commandOpen" :title="commandTitle" width="680px" append-to-body destroy-on-close>
|
||||
<template v-if="currentDevice">
|
||||
<div class="device-summary">
|
||||
<div>
|
||||
<div class="device-summary__name">{{ currentDevice.deviceName || '-' }}</div>
|
||||
<div class="device-summary__serial">{{ currentDevice.serialNum }}</div>
|
||||
</div>
|
||||
<el-tag :type="getStatusTagType(currentDevice)" size="large">{{ getStatusText(currentDevice) }}</el-tag>
|
||||
</div>
|
||||
|
||||
<el-form ref="commandFormRef" :model="commandForm" :rules="commandRules" label-width="130px">
|
||||
<el-form-item label="下发属性" prop="identifier">
|
||||
<el-select v-model="commandForm.identifier" filterable placeholder="请选择属性" style="width: 100%" @change="handlePropertyChange">
|
||||
<el-option-group v-for="group in propertyGroups" :key="group.label" :label="group.label">
|
||||
<el-option v-for="item in group.options" :key="item.identifier" :label="item.name" :value="item.identifier">
|
||||
<span>{{ item.name }}</span>
|
||||
<span class="property-option-code">{{ item.identifier }}</span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<template v-if="selectedProperty">
|
||||
<el-form-item v-if="selectedProperty.type === 'enum'" :label="selectedProperty.name" prop="value">
|
||||
<el-select v-model="commandForm.value" placeholder="请选择值" style="width: 100%">
|
||||
<el-option v-for="option in selectedProperty.options" :key="String(option.value)" :label="option.label" :value="option.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<template v-else-if="selectedProperty.type === 'struct'">
|
||||
<el-form-item
|
||||
v-for="field in selectedProperty.fields"
|
||||
:key="field.identifier"
|
||||
:label="field.name"
|
||||
:prop="`structValue.${field.identifier}`"
|
||||
:rules="[{ required: true, message: `${field.name}不能为空`, trigger: 'blur' }]"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="commandForm.structValue[field.identifier]"
|
||||
:min="field.min"
|
||||
:max="field.max"
|
||||
:step="field.step"
|
||||
:precision="field.precision"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<el-form-item v-else :label="selectedProperty.name" prop="value">
|
||||
<el-input-number
|
||||
v-model="commandForm.value"
|
||||
:min="selectedProperty.min"
|
||||
:max="selectedProperty.max"
|
||||
:step="selectedProperty.step"
|
||||
:precision="selectedProperty.precision"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<div class="property-meta">
|
||||
<span>{{ selectedProperty.identifier }}</span>
|
||||
<span v-if="selectedProperty.rangeText">{{ selectedProperty.rangeText }}</span>
|
||||
<span v-if="selectedProperty.unit">{{ selectedProperty.unit }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<div class="command-footer">
|
||||
<el-button @click="commandOpen = false">取消</el-button>
|
||||
<el-button type="primary" icon="Position" :loading="submitLoading" @click="submitCommand">下发</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="SolarControl" lang="ts">
|
||||
import { listSolarDevice } from '@/api/fishery/device';
|
||||
import { DeviceQuery, DeviceVO } from '@/api/fishery/device/types';
|
||||
import { getDeviceStatus, sendSolarPropertyCommand } from '@/api/iot';
|
||||
|
||||
type PropertyType = 'float' | 'double' | 'int' | 'enum' | 'struct';
|
||||
|
||||
interface PropertyOption {
|
||||
identifier: string;
|
||||
name: string;
|
||||
type: PropertyType;
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
precision?: number;
|
||||
unit?: string;
|
||||
rangeText?: string;
|
||||
options?: Array<{ label: string; value: number }>;
|
||||
fields?: Array<Required<Pick<PropertyOption, 'identifier' | 'name' | 'min' | 'max' | 'step' | 'precision'>> & { unit?: string }>;
|
||||
defaultValue?: number;
|
||||
}
|
||||
|
||||
interface SolarDeviceVO extends DeviceVO {
|
||||
online?: boolean;
|
||||
statusCode?: number;
|
||||
}
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const commandFormRef = ref<ElFormInstance>();
|
||||
|
||||
const deviceList = ref<SolarDeviceVO[]>([]);
|
||||
const loading = ref(false);
|
||||
const showSearch = ref(true);
|
||||
const total = ref(0);
|
||||
const commandOpen = ref(false);
|
||||
const currentDevice = ref<SolarDeviceVO>();
|
||||
const submitLoading = ref(false);
|
||||
const statusLoadingId = ref<string | number>();
|
||||
|
||||
const onlineStatusOptions = [
|
||||
{ label: '在线', value: 'online' },
|
||||
{ label: '离线', value: 'offline' }
|
||||
];
|
||||
|
||||
const data = reactive<PageData<{}, DeviceQuery>>({
|
||||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
serialNum: undefined,
|
||||
deviceName: undefined,
|
||||
deviceType: 3,
|
||||
params: {
|
||||
userKeyword: undefined,
|
||||
onlineStatus: undefined,
|
||||
pondKeyword: undefined
|
||||
}
|
||||
},
|
||||
rules: {}
|
||||
});
|
||||
|
||||
const { queryParams } = toRefs(data);
|
||||
|
||||
const propertyGroups = [
|
||||
{
|
||||
label: '常用设置',
|
||||
options: [
|
||||
numberProperty('salinitySet', '盐度设置', 'float', 0, 100, 0.01, undefined, 0),
|
||||
enumProperty('PowerMode', '电源模式', {
|
||||
0: '太阳能网控常驻模式',
|
||||
1: '太阳能网控节能模式',
|
||||
2: '适配器网控'
|
||||
}),
|
||||
numberProperty('WakeUpTime', '休眠时长', 'int', 1, 2147483647, 1, 'min', 10),
|
||||
numberProperty('BootToSleepTimeout', '工作时长', 'int', 2, 2147483647, 1, 'min', 2),
|
||||
numberProperty('updatatime', '数据上报时间', 'int', 0, 65535, 1, 's', 60),
|
||||
numberProperty('FirstBootToSleepTimeout', '首次上电工作时间', 'int', 3, 2147483647, 1, 'min', 3)
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '校准与补偿',
|
||||
options: [
|
||||
enumProperty('correct', '校准', {
|
||||
1: '下发溶解氧传感器校准指令',
|
||||
2: '下发盐度传感器校准指令',
|
||||
11: '氧探头饱和校准',
|
||||
12: '氧探头无氧校准',
|
||||
13: '氧探头低温系数设置',
|
||||
14: '氧探头高温系数设置',
|
||||
31: '下发pH传感器校准第1步',
|
||||
32: '下发pH传感器校准第2步'
|
||||
}),
|
||||
numberProperty('phasedif_compensation', '相位差补偿', 'float', -10, 100, 0.001, '°', 0),
|
||||
numberProperty('phase_compensation', '线性补偿', 'float', 0, 10, 0.0001, undefined, 1),
|
||||
numberProperty('temperature_compensation', '温度补偿', 'float', -10, 10, 0.001, '°C', 0),
|
||||
numberProperty('stdsatphase', '标准饱和相位差', 'double', 0, 360, 0.01, '°', 0),
|
||||
numberProperty('stdphaseinterval', '标准相位区间', 'double', 0, 360, 0.01, '°', 0)
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '高级参数',
|
||||
options: [
|
||||
numberProperty('SaturationPoint', '饱和相位差测量值', 'float', -1000, 1000, 0.01, '°', 0),
|
||||
numberProperty('AnaerobicPoint', '无氧相位差测量值', 'float', -1000, 1000, 0.01, '°', 0),
|
||||
numberProperty('LowtempCOEF', '低温系数', 'float', -1000, 1000, 0.0001, undefined, 0),
|
||||
numberProperty('HightempCOEF', '高温系数', 'float', -1000, 1000, 0.0001, undefined, 0),
|
||||
numberProperty('ammonia_nitrogen', '氨氮', 'float', 0, 1000, 0.01, 'mg/L', 0),
|
||||
numberProperty('TempPobeOffSet1', '温度偏移量通道1', 'float', -12.7, 12.7, 0.1, '°C', 0),
|
||||
numberProperty('TempPobeOffSet2', '温度偏移量通道2', 'float', -12.7, 12.7, 1, '°C', 0),
|
||||
structProperty('CorrectCharge', '电量校准', [
|
||||
numberProperty('lowvoltage', '低压', 'float', 0, 10, 0.01, 'V', 0),
|
||||
numberProperty('highvoltage', '高压', 'float', 0, 10, 0.01, 'V', 0)
|
||||
])
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const propertyList = computed(() => propertyGroups.flatMap((group) => group.options));
|
||||
const selectedProperty = computed(() => propertyList.value.find((item) => item.identifier === commandForm.identifier));
|
||||
const commandTitle = computed(() => `太阳能网控指令 - ${currentDevice.value?.deviceName || ''}`);
|
||||
|
||||
const commandForm = reactive({
|
||||
identifier: 'PowerMode',
|
||||
value: undefined as number | undefined,
|
||||
structValue: {} as Record<string, number | undefined>
|
||||
});
|
||||
|
||||
const commandRules = {
|
||||
identifier: [{ required: true, message: '请选择下发属性', trigger: 'change' }],
|
||||
value: [{ required: true, message: '属性值不能为空', trigger: 'blur' }]
|
||||
};
|
||||
|
||||
function numberProperty(
|
||||
identifier: string,
|
||||
name: string,
|
||||
type: Extract<PropertyType, 'float' | 'double' | 'int'>,
|
||||
min: number,
|
||||
max: number,
|
||||
step: number,
|
||||
unit?: string,
|
||||
defaultValue?: number
|
||||
): PropertyOption {
|
||||
return {
|
||||
identifier,
|
||||
name,
|
||||
type,
|
||||
min,
|
||||
max,
|
||||
step,
|
||||
unit,
|
||||
precision: getPrecision(step),
|
||||
rangeText: `${min} - ${max}`,
|
||||
defaultValue
|
||||
};
|
||||
}
|
||||
|
||||
function enumProperty(identifier: string, name: string, options: Record<number, string>): PropertyOption {
|
||||
const values = Object.entries(options).map(([value, label]) => ({ value: Number(value), label }));
|
||||
return {
|
||||
identifier,
|
||||
name,
|
||||
type: 'enum',
|
||||
options: values,
|
||||
defaultValue: values[0]?.value
|
||||
};
|
||||
}
|
||||
|
||||
function structProperty(identifier: string, name: string, fields: PropertyOption[]): PropertyOption {
|
||||
return {
|
||||
identifier,
|
||||
name,
|
||||
type: 'struct',
|
||||
fields: fields.map((field) => ({
|
||||
identifier: field.identifier,
|
||||
name: field.name,
|
||||
min: field.min ?? 0,
|
||||
max: field.max ?? 0,
|
||||
step: field.step ?? 1,
|
||||
precision: field.precision ?? 0,
|
||||
unit: field.unit
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
function getPrecision(step: number) {
|
||||
const text = String(step);
|
||||
if (!text.includes('.')) {
|
||||
return 0;
|
||||
}
|
||||
return text.split('.')[1].length;
|
||||
}
|
||||
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
queryParams.value.deviceType = 3;
|
||||
const res = await listSolarDevice(queryParams.value);
|
||||
deviceList.value = ((res.rows || []) as SolarDeviceVO[]).map(initStatusFromList);
|
||||
total.value = res.total;
|
||||
await refreshVisibleStatuses();
|
||||
sortDeviceListByOnline();
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const initStatusFromList = (item: SolarDeviceVO) => {
|
||||
if (item.onlineStatus?.toLowerCase() === 'online') {
|
||||
item.online = true;
|
||||
item.statusCode = 1;
|
||||
} else {
|
||||
item.online = false;
|
||||
item.statusCode = 3;
|
||||
}
|
||||
return item;
|
||||
};
|
||||
|
||||
const refreshVisibleStatuses = async () => {
|
||||
await Promise.all(
|
||||
deviceList.value.map(async (item) => {
|
||||
try {
|
||||
await refreshStatus(item, false);
|
||||
} catch {
|
||||
// 列表已有后端状态,单台云端状态刷新失败时不影响整页展示。
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const refreshStatus = async (row: SolarDeviceVO, showMessage = true) => {
|
||||
if (!row.serialNum) {
|
||||
row.online = false;
|
||||
row.statusCode = 0;
|
||||
return;
|
||||
}
|
||||
statusLoadingId.value = row.id;
|
||||
try {
|
||||
const res = await getDeviceStatus(3, row.serialNum);
|
||||
row.statusCode = res.data;
|
||||
row.online = res.data === 1;
|
||||
if (currentDevice.value?.id === row.id) {
|
||||
currentDevice.value = row;
|
||||
}
|
||||
sortDeviceListByOnline();
|
||||
if (showMessage) {
|
||||
ElMessage.success('状态已刷新');
|
||||
}
|
||||
} finally {
|
||||
statusLoadingId.value = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
queryParams.value.deviceType = 3;
|
||||
queryParams.value.params = {
|
||||
userKeyword: undefined,
|
||||
onlineStatus: undefined,
|
||||
pondKeyword: undefined
|
||||
};
|
||||
getList();
|
||||
};
|
||||
|
||||
const openCommand = async (row: SolarDeviceVO) => {
|
||||
currentDevice.value = row;
|
||||
resetCommandForm();
|
||||
commandOpen.value = true;
|
||||
await refreshStatus(row, false);
|
||||
};
|
||||
|
||||
const resetCommandForm = () => {
|
||||
commandForm.identifier = 'PowerMode';
|
||||
handlePropertyChange('PowerMode');
|
||||
nextTick(() => commandFormRef.value?.clearValidate());
|
||||
};
|
||||
|
||||
const handlePropertyChange = (identifier: string) => {
|
||||
const property = propertyList.value.find((item) => item.identifier === identifier);
|
||||
commandForm.value = property?.defaultValue;
|
||||
commandForm.structValue = {};
|
||||
if (property?.type === 'struct') {
|
||||
property.fields?.forEach((field) => {
|
||||
commandForm.structValue[field.identifier] = 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const submitCommand = async () => {
|
||||
if (!currentDevice.value || !selectedProperty.value) {
|
||||
return;
|
||||
}
|
||||
await commandFormRef.value?.validate();
|
||||
const property = selectedProperty.value;
|
||||
const value = property.type === 'struct' ? { ...commandForm.structValue } : commandForm.value;
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
await sendSolarPropertyCommand({
|
||||
id: currentDevice.value.id,
|
||||
properties: {
|
||||
[property.identifier]: value
|
||||
}
|
||||
});
|
||||
ElMessage.success('下发成功');
|
||||
commandOpen.value = false;
|
||||
await getList();
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusText = (row: SolarDeviceVO) => {
|
||||
if (row.online) {
|
||||
return '在线';
|
||||
}
|
||||
if (row.statusCode === 3) {
|
||||
return '离线';
|
||||
}
|
||||
if (row.statusCode === 8) {
|
||||
return '禁用';
|
||||
}
|
||||
if (row.statusCode === 0) {
|
||||
return '未激活';
|
||||
}
|
||||
return '未知';
|
||||
};
|
||||
|
||||
const getStatusTagType = (row: SolarDeviceVO) => {
|
||||
if (row.online) {
|
||||
return 'success';
|
||||
}
|
||||
if (row.statusCode === 3) {
|
||||
return 'warning';
|
||||
}
|
||||
if (row.statusCode === 8) {
|
||||
return 'danger';
|
||||
}
|
||||
return 'info';
|
||||
};
|
||||
|
||||
const formatValue = (value: unknown) => {
|
||||
if (value === undefined || value === null || value === '') {
|
||||
return '-';
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const sortDeviceListByOnline = () => {
|
||||
deviceList.value = deviceList.value
|
||||
.map((item, index) => ({ item, index }))
|
||||
.sort((a, b) => {
|
||||
const onlineDiff = Number(Boolean(b.item.online)) - Number(Boolean(a.item.online));
|
||||
if (onlineDiff !== 0) {
|
||||
return onlineDiff;
|
||||
}
|
||||
return a.index - b.index;
|
||||
})
|
||||
.map(({ item }) => item);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.device-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 12px;
|
||||
background: #f6f8fb;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.device-summary__name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.device-summary__serial {
|
||||
margin-top: 4px;
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.property-option-code {
|
||||
float: right;
|
||||
margin-left: 16px;
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.property-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-left: 130px;
|
||||
margin-bottom: 16px;
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.command-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -38,9 +38,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:timingCtrl:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:timingCtrl:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:timingCtrl:remove']">删除</el-button>
|
||||
</el-col>
|
||||
|
||||
@@ -25,15 +25,15 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:userRelation:add']">新增</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:userRelation:edit']">修改</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:userRelation:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['fishery:userRelation:export']">导出</el-button>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
<lang-select />
|
||||
</div> -->
|
||||
<el-form-item v-if="tenantEnabled" prop="tenantId">
|
||||
<el-select v-model="loginForm.tenantId" filterable :placeholder="proxy.$t('login.selectPlaceholder')" style="width: 100%">
|
||||
<el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"></el-option>
|
||||
<template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
|
||||
</el-select>
|
||||
<!-- <el-select v-model="loginForm.tenantId" filterable :placeholder="proxy.$t('login.selectPlaceholder')" style="width: 100%">-->
|
||||
<!-- <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"></el-option>-->
|
||||
<!-- <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>-->
|
||||
<!-- </el-select>-->
|
||||
</el-form-item>
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" :placeholder="proxy.$t('login.username')">
|
||||
@@ -87,8 +87,8 @@ const { t } = useI18n();
|
||||
|
||||
const loginForm = ref<LoginData>({
|
||||
tenantId: '111111',
|
||||
username: 'admin',
|
||||
password: 'admin123',
|
||||
username: 'fishery',
|
||||
password: 'fishery@123',
|
||||
rememberMe: false,
|
||||
code: '',
|
||||
uuid: ''
|
||||
@@ -216,7 +216,7 @@ const doSocialLogin = (type: string) => {
|
||||
|
||||
onMounted(() => {
|
||||
getCode();
|
||||
initTenantList();
|
||||
// initTenantList();
|
||||
getLoginData();
|
||||
});
|
||||
</script>
|
||||
@@ -301,7 +301,7 @@ onMounted(() => {
|
||||
backdrop-filter: blur(2px);
|
||||
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.8);
|
||||
z-index: 2;
|
||||
|
||||
|
||||
span {
|
||||
padding: 5px 15px;
|
||||
border-radius: 15px;
|
||||
@@ -309,12 +309,12 @@ onMounted(() => {
|
||||
backdrop-filter: blur(5px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color:rgb(255, 255, 255) !important;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
|
||||
|
||||
&:hover {
|
||||
color: #66b1ff !important;
|
||||
text-shadow: 0 0 5px rgba(64, 158, 255, 0.5);
|
||||
|
||||
@@ -25,7 +25,7 @@ export default defineConfig(({ mode, command }) => {
|
||||
proxy: {
|
||||
[env.VITE_APP_BASE_API]: {
|
||||
// target: 'http://localhost:8080',
|
||||
target: 'https://api.yuceyun.cn/prod-api/',
|
||||
target: 'https://www.qdintc.com/fishery-api/',
|
||||
changeOrigin: true,
|
||||
ws: true,
|
||||
rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
|
||||
|
||||
Reference in New Issue
Block a user