@@ -26,6 +26,9 @@ const userManageClassManageApi = { | |||||
page(params: SysUserPersonnel.ClassPage) { | page(params: SysUserPersonnel.ClassPage) { | ||||
return http.get("queryAll", params); | return http.get("queryAll", params); | ||||
}, | }, | ||||
getPageList(params: SysUserPersonnel.ClassPage) { | |||||
return http.get("getPageList", params); | |||||
}, | |||||
/** 删除底库 */ | /** 删除底库 */ | ||||
delete(params: ReqId) { | delete(params: ReqId) { | ||||
return http.delete("deleteDfieldD", params); | return http.delete("deleteDfieldD", params); | ||||
@@ -78,6 +78,10 @@ const userManageDormitoryApi = { | |||||
/** 获取归寝时间 */ | /** 获取归寝时间 */ | ||||
getReturnTime() { | getReturnTime() { | ||||
return httpChamber.get("getReturnTime"); | return httpChamber.get("getReturnTime"); | ||||
}, | |||||
// 获取宿舍楼摄像头列表 | |||||
getBuildCameraList() { | |||||
return http.get("getBuildCameraList"); | |||||
} | } | ||||
}; | }; | ||||
@@ -45,6 +45,14 @@ const warnZJRQApi = { | |||||
/** 处理预警 */ | /** 处理预警 */ | ||||
handWarn(params: ReqId) { | handWarn(params: ReqId) { | ||||
return http.post("handWarn", params); | return http.post("handWarn", params); | ||||
}, | |||||
// 首页基础数据 | |||||
basicInfo() { | |||||
return http.get("getBaseStatistics"); | |||||
}, | |||||
// 首页高危预警 | |||||
highWarn() { | |||||
return http.get("getHighRisk"); | |||||
} | } | ||||
}; | }; | ||||
@@ -67,7 +67,7 @@ | |||||
<el-col :span="10"> | <el-col :span="10"> | ||||
<ProTable | <ProTable | ||||
ref="chooseTable" | ref="chooseTable" | ||||
:columns="columns" | |||||
:columns="columns2" | |||||
maxHeight="480" | maxHeight="480" | ||||
:tool-button="true" | :tool-button="true" | ||||
:data="chooseDataTmp" | :data="chooseDataTmp" | ||||
@@ -170,7 +170,30 @@ const columns: ColumnProps<SysUser.SysUserInfo>[] = [ | |||||
{ prop: "dormitoryName", label: "寝室" }, | { prop: "dormitoryName", label: "寝室" }, | ||||
]; | ]; | ||||
const columns2: ColumnProps<SysUser.SysUserInfo>[] = [ | |||||
{ type: "selection", fixed: "left", width: 50 }, | |||||
{ prop: "operation", label: "操作", width: 80, fixed: "left" }, | |||||
{ | |||||
prop: "faceUrl", | |||||
label: "人脸", | |||||
render: scope => { | |||||
return ( | |||||
<img src={scope.row.faces.length > 0 ? scope.row.faces[0].faceUrl : ''} onClick={() => viewHeadImage(scope)} style='width:30px;height:30px;' alt=''/> | |||||
); | |||||
} | |||||
}, | |||||
{ | |||||
prop: "personName", | |||||
label: "姓名", | |||||
render: row => { | |||||
return row.row.name; | |||||
}, | |||||
search: { el: "input", span: 2 } | |||||
}, | |||||
{ prop: "personSetName", label: "班级" }, | |||||
// { prop: "dormitoryName", label: "寝室" }, | |||||
]; | |||||
/** 显示选择器 */ | /** 显示选择器 */ | ||||
function showSelector(data: SysUser.SysUserInfo[] = []) { | function showSelector(data: SysUser.SysUserInfo[] = []) { | ||||
visible.value = true; | visible.value = true; | ||||
@@ -16,7 +16,7 @@ | |||||
</div> | </div> | ||||
<div class="home-bg-content-item-content"> | <div class="home-bg-content-item-content"> | ||||
<div class="home-bg-content-item-title">摄像头数量</div> | <div class="home-bg-content-item-title">摄像头数量</div> | ||||
<div class="home-bg-content-item-value">3</div> | |||||
<div class="home-bg-content-item-value">{{ basicInfo.cameraCount }}</div> | |||||
</div> | </div> | ||||
</div></el-col | </div></el-col | ||||
> | > | ||||
@@ -27,7 +27,7 @@ | |||||
</div> | </div> | ||||
<div class="home-bg-content-item-content"> | <div class="home-bg-content-item-content"> | ||||
<div class="home-bg-content-item-title">预警信息总量</div> | <div class="home-bg-content-item-title">预警信息总量</div> | ||||
<div class="home-bg-content-item-value">1972</div> | |||||
<div class="home-bg-content-item-value">{{ basicInfo.warnCount }}</div> | |||||
</div> | </div> | ||||
</div></el-col | </div></el-col | ||||
> | > | ||||
@@ -38,7 +38,7 @@ | |||||
</div> | </div> | ||||
<div class="home-bg-content-item-content"> | <div class="home-bg-content-item-content"> | ||||
<div class="home-bg-content-item-title">处理意见提交</div> | <div class="home-bg-content-item-title">处理意见提交</div> | ||||
<div class="home-bg-content-item-value">40</div> | |||||
<div class="home-bg-content-item-value">{{ basicInfo.handCount }}</div> | |||||
</div> | </div> | ||||
</div></el-col | </div></el-col | ||||
> | > | ||||
@@ -49,7 +49,7 @@ | |||||
</div> | </div> | ||||
<div class="home-bg-content-item-content"> | <div class="home-bg-content-item-content"> | ||||
<div class="home-bg-content-item-title">参与安防教师</div> | <div class="home-bg-content-item-title">参与安防教师</div> | ||||
<div class="home-bg-content-item-value">22</div> | |||||
<div class="home-bg-content-item-value">{{ basicInfo.teacherCount }}</div> | |||||
</div> | </div> | ||||
</div></el-col | </div></el-col | ||||
> | > | ||||
@@ -86,7 +86,7 @@ | |||||
<div>高危预警信息统计</div> | <div>高危预警信息统计</div> | ||||
</div> | </div> | ||||
<div class="home-bg-content handleBox"> | <div class="home-bg-content handleBox"> | ||||
<ProTable ref="proTable" title="视频列表" :toolButton="false" :pagination="false" :columns="columns" :data="tableData"> </ProTable> | |||||
<ProTable ref="proTable" :toolButton="false" :pagination="false" :columns="columns" :data="highTabledata"> </ProTable> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</el-col> | </el-col> | ||||
@@ -108,7 +108,7 @@ | |||||
<script setup lang="ts" name="home"> | <script setup lang="ts" name="home"> | ||||
import { ref, watch, provide, onMounted, unref, computed, reactive } from "vue"; | import { ref, watch, provide, onMounted, unref, computed, reactive } from "vue"; | ||||
import { ElMessage } from "element-plus"; | import { ElMessage } from "element-plus"; | ||||
import { monitorLIVEApi } from "@/api"; | |||||
import { warnZJRQApi } from "@/api"; | |||||
import { ZJRQ } from "@/api/interface"; | import { ZJRQ } from "@/api/interface"; | ||||
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface"; | import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface"; | ||||
import { useDictStore } from "@/stores/modules"; | import { useDictStore } from "@/stores/modules"; | ||||
@@ -121,9 +121,30 @@ const chart2 = ref(null); | |||||
const chart3 = ref(null); | const chart3 = ref(null); | ||||
onMounted(() => { | onMounted(() => { | ||||
getBasic(); | |||||
getHighWarin(); | |||||
getDataChart(); | getDataChart(); | ||||
getWeekData(); | getWeekData(); | ||||
}); | }); | ||||
let basicInfo = reactive({ | |||||
cameraCount: 0, | |||||
handCount: 0, | |||||
teacherCount: 0, | |||||
warnCount: 0 | |||||
}); | |||||
// 获取基础数据 | |||||
function getBasic() { | |||||
warnZJRQApi.basicInfo().then((res: any) => { | |||||
if (res.code == 200) { | |||||
basicInfo.cameraCount = res.data.cameraCount; | |||||
basicInfo.handCount = res.data.handCount; | |||||
basicInfo.teacherCount = res.data.teacherCount; | |||||
basicInfo.warnCount = res.data.warnCount; | |||||
} | |||||
}); | |||||
} | |||||
function getDataChart() { | function getDataChart() { | ||||
setTimeout(async () => { | setTimeout(async () => { | ||||
await statistionApi.warnstatistion({}).then(res => { | await statistionApi.warnstatistion({}).then(res => { | ||||
@@ -158,6 +179,7 @@ function getDataChart() { | |||||
}); | }); | ||||
}); | }); | ||||
} | } | ||||
function getCharts1(data: any) { | function getCharts1(data: any) { | ||||
const chart = echarts.init(chart1.value); | const chart = echarts.init(chart1.value); | ||||
const option = { | const option = { | ||||
@@ -170,7 +192,7 @@ function getCharts1(data: any) { | |||||
// }, | // }, | ||||
legend: { | legend: { | ||||
orient: "vertical", | orient: "vertical", | ||||
left: "right", | |||||
right: "0%", | |||||
top: "middle" | top: "middle" | ||||
}, | }, | ||||
series: [ | series: [ | ||||
@@ -220,7 +242,7 @@ function getCharts2(data: any) { | |||||
// }, | // }, | ||||
legend: { | legend: { | ||||
orient: "vertical", | orient: "vertical", | ||||
left: "right", | |||||
right: "0%", | |||||
top: "middle" | top: "middle" | ||||
}, | }, | ||||
series: [ | series: [ | ||||
@@ -325,61 +347,37 @@ const dictStore = useDictStore(); | |||||
// 表格配置项 | // 表格配置项 | ||||
const columns: ColumnProps<ZJRQ.WarnInfo>[] = [ | const columns: ColumnProps<ZJRQ.WarnInfo>[] = [ | ||||
{ | { | ||||
prop: "type", | |||||
prop: "name", | |||||
label: "数据类型" | label: "数据类型" | ||||
// render: () => { | // render: () => { | ||||
// return "楼道"; | // return "楼道"; | ||||
// } | // } | ||||
}, | }, | ||||
{ | { | ||||
prop: "warntotal", | |||||
label: "预警总量" | |||||
prop: "day", | |||||
label: "今日预警" | |||||
// render: () => { | // render: () => { | ||||
// return "楼道"; | // return "楼道"; | ||||
// } | // } | ||||
}, | }, | ||||
{ | { | ||||
prop: "lowrisk", | |||||
label: "低危信息 " | |||||
prop: "week", | |||||
label: "七日预警 " | |||||
}, | }, | ||||
{ | { | ||||
prop: "highrisk", | |||||
label: "高危信息" | |||||
prop: "count", | |||||
label: "预警总量" | |||||
} | } | ||||
]; | ]; | ||||
const tableData = ref([ | |||||
{ | |||||
type: "今日", | |||||
warntotal: "20", | |||||
lowrisk: "10", | |||||
highrisk: "10" | |||||
}, | |||||
{ | |||||
type: "本周", | |||||
warntotal: "50", | |||||
lowrisk: "20", | |||||
highrisk: "30" | |||||
}, | |||||
{ | |||||
type: "本月", | |||||
warntotal: "198", | |||||
lowrisk: "176", | |||||
highrisk: "22" | |||||
}, | |||||
{ | |||||
type: "上月", | |||||
warntotal: "10", | |||||
lowrisk: "5", | |||||
highrisk: "5" | |||||
}, | |||||
{ | |||||
type: "环比", | |||||
warntotal: "-9.07%", | |||||
lowrisk: "0%", | |||||
highrisk: "0%" | |||||
} | |||||
]); | |||||
let highTabledata = ref([]); | |||||
// 获取高危预警数据 | |||||
function getHighWarin() { | |||||
warnZJRQApi.highWarn().then((res: any) => { | |||||
if (res.code == 200) { | |||||
highTabledata.value = res.data; | |||||
} | |||||
}); | |||||
} | |||||
const tableLoading = ref(false); | const tableLoading = ref(false); | ||||
</script> | </script> | ||||
@@ -107,12 +107,12 @@ | |||||
<div> | <div> | ||||
<div class="dialogHeader"> | <div class="dialogHeader"> | ||||
<div></div> | <div></div> | ||||
<div class="dialogBtn" @click="refreshUrl"> | |||||
<!-- <div class="dialogBtn" @click="refreshUrl"> | |||||
<el-icon color="#409efc" :size="20"> | <el-icon color="#409efc" :size="20"> | ||||
<Refresh /> | <Refresh /> | ||||
</el-icon> | </el-icon> | ||||
<div>刷新视频</div> | <div>刷新视频</div> | ||||
</div> | |||||
</div> --> | |||||
</div> | </div> | ||||
<div v-if="visible || showVideo" class="prism-player" id="player-con"></div> | <div v-if="visible || showVideo" class="prism-player" id="player-con"></div> | ||||
<!-- <VideoPlay :videoUrl="detailData.videoUrl" :videoType="detailData.videoType" /> --> | <!-- <VideoPlay :videoUrl="detailData.videoUrl" :videoType="detailData.videoType" /> --> | ||||
@@ -436,7 +436,7 @@ function onDetail(row: any) { | |||||
visible.value = true; | visible.value = true; | ||||
detailData.sensorId = row.sensorId; | detailData.sensorId = row.sensorId; | ||||
detailData.title = row.sensorName + "(" + row.sensorId + ")"; | detailData.title = row.sensorName + "(" + row.sensorId + ")"; | ||||
getUrl(); | |||||
getUrl(row.sensorId); | |||||
} | } | ||||
// 刷新 | // 刷新 | ||||
const showVideo = ref(false); | const showVideo = ref(false); | ||||
@@ -449,7 +449,8 @@ function refreshUrl() { | |||||
}, 1000); | }, 1000); | ||||
} | } | ||||
let num = 1; | let num = 1; | ||||
function getUrl() { | |||||
function getUrl(sensorId:any) { | |||||
detailData.videoType = "m3u8"; | detailData.videoType = "m3u8"; | ||||
setTimeout(async () => { | setTimeout(async () => { | ||||
await monitorLIVEApi.detail({ sensorId: detailData.sensorId }).then((res:any) => { | await monitorLIVEApi.detail({ sensorId: detailData.sensorId }).then((res:any) => { | ||||
@@ -463,7 +464,18 @@ function getUrl() { | |||||
detailData.streamId = data.streamId; | detailData.streamId = data.streamId; | ||||
detailData.videoToken = data.videoToken; | detailData.videoToken = data.videoToken; | ||||
// getvideo1() | // getvideo1() | ||||
getvideo2(); | |||||
let localurl = '' | |||||
if(sensorId == 'SXT001') { | |||||
localurl = 'http://123.57.209.16:8004/video/1.mp4' | |||||
getvideo2(localurl); | |||||
} else if(sensorId == 'SXT002'){ | |||||
localurl = 'http://123.57.209.16:8004/video/5.mp4' | |||||
getvideo2(localurl); | |||||
} else if(sensorId == 'SXT003') { | |||||
localurl = 'http://123.57.209.16:8004/video/2.mp4' | |||||
getvideo2(localurl); | |||||
} | |||||
} | } | ||||
}); | }); | ||||
}); | }); | ||||
@@ -500,10 +512,10 @@ function getvideo1() { | |||||
// aliRts.startLiveStream(pullStreamUrl, mediaEle); | // aliRts.startLiveStream(pullStreamUrl, mediaEle); | ||||
} | } | ||||
let player = ref<any>(null); | let player = ref<any>(null); | ||||
function getvideo2() { | |||||
function getvideo2(url:any) { | |||||
var options = { | var options = { | ||||
id: "player-con", | id: "player-con", | ||||
source: detailData.videoUrl + "&subaudio=no&jitterbuffer=6000", | |||||
source: url, | |||||
// "rtsFallbackSource": "降级地址,如HLS", | // "rtsFallbackSource": "降级地址,如HLS", | ||||
width: "100%", | width: "100%", | ||||
height: "500px", | height: "500px", | ||||
@@ -549,7 +561,7 @@ const handleClose = () => { | |||||
visible.value = false; | visible.value = false; | ||||
detailData.videoUrl = ""; | detailData.videoUrl = ""; | ||||
detailData.videoType = ""; | detailData.videoType = ""; | ||||
stopUrl(); | |||||
// stopUrl(); | |||||
if (player.value) { | if (player.value) { | ||||
player.value.dispose(); | player.value.dispose(); | ||||
} | } | ||||
@@ -0,0 +1,600 @@ | |||||
<!-- | |||||
* @Description: 监控管理 | |||||
* @Author: wangwenpei | |||||
* @Date: 2024-07-18 15:44:05 | |||||
!--> | |||||
<template> | |||||
<div class="main-box"> | |||||
<div class="card treeBox"> | |||||
<p class="title">摄像头分组管理</p> | |||||
<div class="btn"> | |||||
<el-button icon="CirclePlus" @click="append('add', {})" type="primary">添加分组</el-button> | |||||
</div> | |||||
<div class="treeContent"> | |||||
<el-input clearable v-model="filterText" style="width: 100%" placeholder="请输入关键字" /> | |||||
<el-tree | |||||
style="max-width: 600px" | |||||
ref="treeRef" | |||||
:data="treeData" | |||||
node-key="id" | |||||
default-expand-all | |||||
:props="defaultProps" | |||||
:expand-on-click-node="false" | |||||
:check-on-click-node="true" | |||||
:highlight-current="true" | |||||
:filter-node-method="filterNode" | |||||
:current-node-key="defaultHighlightKey" | |||||
@node-click="handleNodeClick" | |||||
> | |||||
<template #default="{ node, data }"> | |||||
<span class="custom-tree-node"> | |||||
<span class="node-label" :title="node.label">{{ node.label }}</span> | |||||
<span v-if="data.id && data.id != '-1'"> | |||||
<el-icon size="16" title="添加分组" @click.stop="append('addChild', data)"><CirclePlus /></el-icon> | |||||
<el-icon size="16" title="编辑分组" @click.stop="append('edit', data)" style="margin-left: 8px"><Edit /></el-icon> | |||||
<el-icon size="16" title="设置推送人" @click.stop="pushPerson(FormOptEnum.GroupPushPerson, data)" style="margin-left: 8px" | |||||
><UserFilled | |||||
/></el-icon> | |||||
<el-icon size="16" title="删除分组" @click.stop="remove(data.id, '删除该分组')" style="margin-left: 8px"><Delete /></el-icon> | |||||
</span> | |||||
</span> | |||||
</template> | |||||
</el-tree> | |||||
</div> | |||||
</div> | |||||
<div class="table-box"> | |||||
<ProTable ref="proTable" title="视频列表" :columns="columns" :request-api="monitorLIVEApi.list"> | |||||
<!-- 表格 header 按钮 --> | |||||
<template #tableHeader="scope"> | |||||
<s-button v-auth="monitorLiveButtonCode.add" suffix="摄像头" @click="onOpen(FormOptEnum.ADD)" /> | |||||
<s-button | |||||
type="danger" | |||||
plain | |||||
suffix="摄像头" | |||||
:opt="FormOptEnum.DELETE" | |||||
:disabled="!scope.isSelected" | |||||
@click="onDelete(scope.selectedListIds, '删除所选数据')" | |||||
/> | |||||
<el-button :disabled="!scope.isSelected" plain @click="omMove(FormOptEnum.ADD, scope.selectedListIds)" type="success">移动至分组</el-button> | |||||
</template> | |||||
<!-- 表格 菜单类型 按钮 --> | |||||
<!-- 操作 --> | |||||
<template #operation="scope"> | |||||
<el-space> | |||||
<s-button link :opt="FormOptEnum.EDIT" @click="onOpen(FormOptEnum.EDIT, scope.row)">编辑</s-button> | |||||
<s-button link :opt="FormOptEnum.VIEW" @click="onDetail(scope.row)"> 查看 </s-button> | |||||
<!-- <s-button link :opt="FormOptEnum.DELETE" @click="onDelete([scope.row.id], `确定删除该摄像头吗?`)" /> | |||||
<s-button link :opt="FormOptEnum.VIEW" @click="pushPerson(FormOptEnum.VideoPushPerson, scope.row)"> 推送人 </s-button> --> | |||||
<el-dropdown @command="handleCommand"> | |||||
<el-link type="primary" :underline="false" :icon="ArrowDown"> 更多 </el-link> | |||||
<template #dropdown> | |||||
<el-dropdown-menu> | |||||
<el-dropdown-item :command="command(scope.row, cmdEnum.Delete)"> | |||||
{{ cmdEnum.Delete }} | |||||
</el-dropdown-item> | |||||
<el-dropdown-item :command="command(scope.row, cmdEnum.pushPerson)"> | |||||
{{ cmdEnum.pushPerson }} | |||||
</el-dropdown-item> | |||||
</el-dropdown-menu> | |||||
</template> | |||||
</el-dropdown> | |||||
</el-space> | |||||
</template> | |||||
</ProTable> | |||||
<!-- 添加分组弹框 --> | |||||
<el-dialog v-model="groupVisible" :title="groupTitle" width="600px" :before-close="closeGroup"> | |||||
<el-form :model="groupForm" :rules="groupRules" ref="groupFormRef" label-width="80px"> | |||||
<el-form-item label="分组名称" prop="name"> | |||||
<el-input v-model="groupForm.name" placeholder="请输入分组名称"></el-input> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<div class="dialog-footer"> | |||||
<el-button type="primary" @click="onSubmit">提交</el-button> | |||||
<el-button @click="closeGroup">取消</el-button> | |||||
</div> | |||||
</template> | |||||
</el-dialog> | |||||
<!-- 新增/编辑表单 --> | |||||
<Form ref="formRef" /> | |||||
<!-- 人员选择 --> | |||||
<userForm ref="userFormRef" /> | |||||
<!-- 移动至分组 --> | |||||
<moveForm ref="moveFormRef" /> | |||||
<!-- 视频详情 --> | |||||
<el-dialog v-model="visible" :title="detailData.title" width="830px" :before-close="handleClose"> | |||||
<div> | |||||
<div class="dialogHeader"> | |||||
<div></div> | |||||
<div class="dialogBtn" @click="refreshUrl"> | |||||
<el-icon color="#409efc" :size="20"> | |||||
<Refresh /> | |||||
</el-icon> | |||||
<div>刷新视频</div> | |||||
</div> | |||||
</div> | |||||
<div v-if="visible || showVideo" class="prism-player" id="player-con"></div> | |||||
<!-- <VideoPlay :videoUrl="detailData.videoUrl" :videoType="detailData.videoType" /> --> | |||||
<!-- <video style="width: 100%; height: 500px" id="video" controls muted="false"></video> --> | |||||
<!-- <iframe src="/static/artcvideo.html" width="100%" height="600px" ref="iframeDom"></iframe> --> | |||||
</div> | |||||
<template #footer> | |||||
<div class="dialog-footer"> | |||||
<el-button @click="handleClose">关闭</el-button> | |||||
</div> | |||||
</template> | |||||
</el-dialog> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script setup lang="tsx" name="live"> | |||||
import VideoPlay from "@/components/VideoPlay/videoplay.vue"; | |||||
import { ElMessage, ElMessageBox, ElTree } from "element-plus"; | |||||
import { ArrowDown,More } from "@element-plus/icons-vue"; | |||||
import type Node from "element-plus/es/components/tree/src/model/node"; | |||||
import { monitorLIVEApi, monitorLiveButtonCode,SysOrg,SysUserPersonnel } from "@/api"; | |||||
import { sysCamera } from "@/api/interface"; | |||||
import { useHandleData } from "@/hooks/useHandleData"; | |||||
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface"; | |||||
import { useDictStore } from "@/stores/modules"; | |||||
import Form from "./components/form.vue"; | |||||
import userForm from "./components/userForm.vue"; | |||||
import moveForm from "./components/moveForm.vue"; | |||||
// import { FormOptEnum, SysDictEnum, MenuTypeDictEnum } from "@/enums"; | |||||
// import './aliyun-rts-sdk.js' | |||||
import "./ali.js"; | |||||
enum FormOptEnum { | |||||
/** 新增 */ | |||||
ADD = "新增", | |||||
/** 编辑 */ | |||||
EDIT = "编辑", | |||||
/** 查看 */ | |||||
VIEW = "查看", | |||||
/** 删除 */ | |||||
DELETE = "删除", | |||||
// 分组推送人 | |||||
GroupPushPerson = "分组推送人", | |||||
// 视频推送人 | |||||
VideoPushPerson = "视频推送人", | |||||
// 移动 | |||||
MOVE = "移动", | |||||
// 分组 | |||||
GROUP = "分组" | |||||
} | |||||
/** 更多下拉菜单命令枚举 */ | |||||
enum cmdEnum { | |||||
Delete = "删除", | |||||
pushPerson = "推送人" | |||||
} | |||||
/** 下拉菜单参数接口 */ | |||||
interface Command { | |||||
row: SysUserPersonnel.SysUserPerInfo; | |||||
command: cmdEnum; | |||||
} | |||||
/**配置command的参数 */ | |||||
function command(row: SysUserPersonnel.SysUserPerInfo, command: cmdEnum): Command { | |||||
return { | |||||
row: row, | |||||
command: command | |||||
}; | |||||
} | |||||
function handleCommand(command: Command) { | |||||
switch (command.command) { | |||||
case cmdEnum.Delete: | |||||
ElMessageBox.confirm(`确定要删除此数据吗?`, "提示", { | |||||
confirmButtonText: "确定", | |||||
cancelButtonText: "取消", | |||||
type: "warning" | |||||
}) | |||||
.then(() => { | |||||
onDelete([command.row.id]) | |||||
}) | |||||
.catch(() => { | |||||
}) | |||||
break | |||||
case cmdEnum.pushPerson: | |||||
pushPerson(FormOptEnum.VideoPushPerson, command.row) | |||||
// userManagePersonnelApi.personUnBindDfie({ | |||||
// personId:command.row.personId, | |||||
// personSetId: command.row.personSets[0].personSetId | |||||
// }).then(res=>{ | |||||
// ElMessage.success('底库解绑成功'); | |||||
// RefreshTable() | |||||
// }) | |||||
break; | |||||
} | |||||
} | |||||
// 分组字段配置 | |||||
const defaultProps = { | |||||
children: "children", | |||||
label: "name" | |||||
}; | |||||
// 默认高亮 | |||||
const defaultHighlightKey = ref(""); | |||||
let treeDada1 = ref([ | |||||
{ | |||||
id: "", | |||||
name: "全部" | |||||
} | |||||
]); | |||||
const treeData = ref<any>([]); | |||||
var treeRef = ref<InstanceType<typeof ElTree>>(); | |||||
// 获取摄像头分组 | |||||
function getGroupList() { | |||||
monitorLIVEApi.groupList({}).then((res:any) => { | |||||
if (res.code == 200) { | |||||
treeData.value = [...treeDada1.value, ...res.data]; | |||||
} | |||||
}); | |||||
} | |||||
const groupVisible = ref(false); //是否显示表单 | |||||
const groupTitle = ref("新增分组"); | |||||
const groupForm = reactive({ | |||||
name: "", | |||||
id: "", | |||||
parentId: "" | |||||
}); | |||||
const groupFormRules = ref({ | |||||
}); | |||||
const groupRules = ref({ | |||||
name: [{ required: true, message: "请输入分组名称", trigger: "blur" }] | |||||
}); | |||||
const groupFormRef = ref<any>(null); | |||||
const closeGroup = () => { | |||||
groupVisible.value = false; | |||||
groupFormRef.value.resetFields(); | |||||
groupForm.name = ""; | |||||
groupForm.id = ""; | |||||
groupForm.parentId = ""; | |||||
}; | |||||
const groupFormType = ref<any>(null); | |||||
// 新增编辑分组 | |||||
const append = (type: string, data: Tree) => { | |||||
groupVisible.value = true; | |||||
groupFormType.value = type | |||||
if (type == "edit") { | |||||
groupTitle.value = "编辑分组"; | |||||
groupForm.name = data.name; | |||||
groupForm.id = data.id; | |||||
} else if(type == "addChild") { | |||||
groupTitle.value = "新增分组"; | |||||
groupForm.parentId = data.id | |||||
} else { | |||||
groupTitle.value = "新增分组"; | |||||
} | |||||
}; | |||||
// 删除分组 | |||||
async function remove(id: string[], msg: string) { | |||||
await useHandleData(monitorLIVEApi.deleteGroup, { id }, msg); | |||||
getGroupList(); | |||||
} | |||||
// 提交分组 | |||||
const onSubmit = () => { | |||||
groupFormRef.value.validate((valid: any) => { | |||||
if (valid) { | |||||
let params: any = reactive({ | |||||
id: "", | |||||
name: groupForm.name, | |||||
parentId: groupForm.parentId | |||||
}); | |||||
console.log(groupFormType) | |||||
if (groupFormType.value == 'add') { | |||||
delete params.parentId; | |||||
monitorLIVEApi.addGroup(params).then((res:any) => { | |||||
if (res.code == 200) { | |||||
getGroupList(); | |||||
closeGroup(); | |||||
} | |||||
}); | |||||
} else if(groupFormType.value == 'edit') { | |||||
params.id = groupForm.id; | |||||
delete params.parentId; | |||||
monitorLIVEApi.updateGroup(params).then((res:any) => { | |||||
if (res.code == 200) { | |||||
getGroupList(); | |||||
closeGroup(); | |||||
} | |||||
}); | |||||
} else if(groupFormType.value == 'addChild') { | |||||
delete params.id; | |||||
monitorLIVEApi.addGroup(params).then((res:any) => { | |||||
if (res.code == 200) { | |||||
getGroupList(); | |||||
closeGroup(); | |||||
} | |||||
}); | |||||
} | |||||
closeGroup(); | |||||
} else { | |||||
return false; | |||||
} | |||||
}); | |||||
}; | |||||
// 摄像头分组过滤 | |||||
interface Tree { | |||||
[key: string]: any; | |||||
id: any; | |||||
label: string; | |||||
children?: Tree[]; | |||||
} | |||||
const filterText = ref(""); | |||||
watch(filterText, val => { | |||||
treeRef.value!.filter(val); | |||||
}); | |||||
const filterNode = (value: string, data: Tree) => { | |||||
if (!value) return true; | |||||
return data.name.includes(value); | |||||
}; | |||||
const handleNodeClick = (data: Tree) => { | |||||
proTable.value!.pageable.pageNum = 1; | |||||
proTable.value!.searchParam.groupId = data.id; | |||||
proTable.value!.search(); | |||||
}; | |||||
const visible = ref(false); //是否显示表单 | |||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数) | |||||
const proTable = ref<ProTableInstance>(); | |||||
const dictStore = useDictStore(); | |||||
// 表格配置项 | |||||
const columns: ColumnProps<sysCamera.MonitorInfo>[] = [ | |||||
{ type: "selection", fixed: "left", width: 80 }, | |||||
{ | |||||
prop: "sensorId", | |||||
label: "摄像头ID" | |||||
}, | |||||
{ | |||||
prop: "sensorName", | |||||
label: "摄像头名称" | |||||
}, | |||||
{ | |||||
prop: "fieldName", | |||||
label: "所属学校" | |||||
}, | |||||
{ | |||||
prop: "directUrlIp", | |||||
label: "设备ip" | |||||
}, | |||||
{ | |||||
prop: "resWidth", | |||||
label: "分辨率", | |||||
render: row => { | |||||
return row.row.resWidth + "*" + row.row.resHeight; | |||||
} | |||||
}, | |||||
{ prop: "operation", label: "操作", width: 250, fixed: "right" } | |||||
]; | |||||
// 移动分组禁用 | |||||
const moveFormRef = ref<InstanceType<typeof Form> | null>(null); | |||||
function omMove(opt: FormOptEnum, record: {} | SysOrg.SysOrgInfo = {}) { | |||||
console.log(record,"record") | |||||
moveFormRef.value?.omMove({ opt: opt, records: record, successful: RefreshTable }); | |||||
} | |||||
/** | |||||
* 删除 | |||||
* @param ids id数组 | |||||
*/ | |||||
async function onDelete(ids: string[], msg: string) { | |||||
console.log(1) | |||||
return; | |||||
// 二次确认 => 请求api => 刷新表格 | |||||
await useHandleData(monitorLIVEApi.delete, { ids }, msg); | |||||
RefreshTable(); | |||||
} | |||||
/** | |||||
* 刷新表格 | |||||
*/ | |||||
function RefreshTable() { | |||||
proTable.value?.refresh(); | |||||
} | |||||
function RefreshTables() { | |||||
proTable.value?.refresh(); | |||||
getGroupList(); | |||||
} | |||||
// 表单引用 | |||||
const formRef = ref<InstanceType<typeof Form> | null>(null); | |||||
/** | |||||
* 打开表单 | |||||
* @param opt 操作类型 | |||||
* @param record 记录 | |||||
*/ | |||||
function onOpen(opt: FormOptEnum, record: {} | SysOrg.SysOrgInfo = {}) { | |||||
formRef.value?.onOpen({ opt: opt, record: record, successful: RefreshTable }); | |||||
} | |||||
// 人员选择 | |||||
// 表单引用 | |||||
const userFormRef = ref<InstanceType<typeof Form> | null>(null); | |||||
/** | |||||
* 打开表单 | |||||
* @param opt 操作类型 | |||||
* @param record 记录 | |||||
*/ | |||||
function pushPerson(opt: FormOptEnum, record: {} | SysOrg.SysOrgInfo = {}) { | |||||
userFormRef.value?.onOpen({ opt: opt, record: record, successful: RefreshTables }); | |||||
} | |||||
// 详情数据 | |||||
// let detailData: globalThis.Ref<{}> | |||||
let detailData = reactive({ | |||||
title: "", | |||||
videoUrl: "", | |||||
sensorId: "", | |||||
streamId: "", | |||||
videoToken: "", | |||||
videoType: "" | |||||
}); | |||||
function onDetail(row: any) { | |||||
visible.value = true; | |||||
detailData.sensorId = row.sensorId; | |||||
detailData.title = row.sensorName + "(" + row.sensorId + ")"; | |||||
getUrl(); | |||||
} | |||||
// 刷新 | |||||
const showVideo = ref(false); | |||||
function refreshUrl() { | |||||
stopUrl(); | |||||
showVideo.value = false; | |||||
setTimeout(() => { | |||||
showVideo.value = true; | |||||
getUrl(); | |||||
}, 1000); | |||||
} | |||||
let num = 1; | |||||
function getUrl() { | |||||
detailData.videoType = "m3u8"; | |||||
setTimeout(async () => { | |||||
await monitorLIVEApi.detail({ sensorId: detailData.sensorId }).then((res:any) => { | |||||
let { code, data } = res; | |||||
if (code == '200') { | |||||
// window.location.origin+ | |||||
detailData.videoUrl = ""; | |||||
detailData.videoUrl = data.rtsPullStreamUrls[0].url; | |||||
// detailData.videoUrl = data.pullStreamUrls[2].url; | |||||
detailData.streamId = data.streamId; | |||||
detailData.videoToken = data.videoToken; | |||||
// getvideo1() | |||||
getvideo2(); | |||||
} | |||||
}); | |||||
}); | |||||
} | |||||
function getvideo1() { | |||||
let aliRts = new AliRTS(); | |||||
let pullStreamUrl = detailData.videoUrl; | |||||
const mediaEle = document.querySelector("video"); | |||||
aliRts.on("onError", err => { | |||||
console.log(`errorCode: ${err.errorCode}`); | |||||
console.log(`message: ${err.message}`); | |||||
}); | |||||
const PLAY_EVENT = { | |||||
CANPLAY: "canplay", | |||||
WAITING: "waiting", | |||||
PLAYING: "playing" | |||||
}; | |||||
aliRts.on("onPlayEvent", play => { | |||||
console.log(">>play.event:" + play.event); | |||||
if (play.event === PLAY_EVENT.CANPLAY) { | |||||
// 拉流可以播放 | |||||
console.log("可以播放"); | |||||
} else if (play.event === PLAY_EVENT.WAITING) { | |||||
// 拉流卡顿等待缓冲中 (仅Chrome) | |||||
console.log("拉流卡顿等待缓冲中"); | |||||
} else if (play.event === PLAY_EVENT.PLAYING) { | |||||
// 拉流卡顿结束恢复播放 (仅Chrome) | |||||
console.log("拉流卡顿结束恢复播放"); | |||||
} | |||||
}); | |||||
aliRts.startLiveStream(pullStreamUrl, mediaEle); | |||||
// aliRts.startLiveStream(pullStreamUrl, mediaEle); | |||||
} | |||||
let player = ref<any>(null); | |||||
function getvideo2() { | |||||
var options = { | |||||
id: "player-con", | |||||
source: detailData.videoUrl + "&subaudio=no&jitterbuffer=6000", | |||||
// "rtsFallbackSource": "降级地址,如HLS", | |||||
width: "100%", | |||||
height: "500px", | |||||
autoplay: true, | |||||
isLive: true, | |||||
playsinline: true, | |||||
skipRtsSupportCheck: false, // 对于不在 https://help.aliyun.com/document_detail/397569.html 中的浏览器,可以传 true 跳过检查,强制使用 RTS(有风险,需要自测保证) | |||||
/** | |||||
* RTS 拉流超时会默认重试 | |||||
* 以下两个参数用来控制降级之前的重试策略,比如 3000 毫秒超时,重试一次,如果再拉不到流就降级,那么总共等待 6000 毫秒降级 | |||||
**/ | |||||
// RTS 多久拉不到流会重试,默认 3000 ms | |||||
rtsLoadDataTimeout: 1500, | |||||
// RTS 拉不到流重试的次数,默认 5,此参数建议设为 1,即重试 1 次后降级,可以减少降级等待时间 | |||||
liveRetry: 1 | |||||
}; | |||||
player.value = new Aliplayer(options, function () { | |||||
/* player ready */ | |||||
}); | |||||
// 降级时会触发此事件 | |||||
player.value.on("rtsFallback", function (event:any) { | |||||
console.log("[EVENT]rtsFallback", event.paramData); | |||||
// event.paramData.reason 降级的原因 | |||||
// event.paramData.fallbackUrl 降级到的地址 | |||||
}); | |||||
player.value.on("error", function (event:any) { | |||||
console.log("[EVENT]error", event.paramData); | |||||
}); | |||||
player.value.setVolume(0) | |||||
// 当RTS拉流成功时触发,通过订阅该事件,可以获取到RTS TraceId | |||||
player.value.on("rtsTraceId", function (data:any) { | |||||
console.log("[EVENT]rtsTraceId", data.paramData); | |||||
// event.paramData.traceId 拉流的TraceId | |||||
// event.paramData.source 当前RTS流的播放地址 | |||||
}); | |||||
} | |||||
const handleClose = () => { | |||||
visible.value = false; | |||||
detailData.videoUrl = ""; | |||||
detailData.videoType = ""; | |||||
stopUrl(); | |||||
if (player.value) { | |||||
player.value.dispose(); | |||||
} | |||||
}; | |||||
function stopUrl() { | |||||
detailData.videoUrl = ""; | |||||
if (player.value) { | |||||
player.value.dispose(); | |||||
} | |||||
let params = { | |||||
sensorId: detailData.sensorId, | |||||
streamId: detailData.streamId, | |||||
videoToken: detailData.videoToken | |||||
}; | |||||
setTimeout(async () => { | |||||
await monitorLIVEApi.stopUrl(params).then((res:any) => { | |||||
let { code, data, msg } = res; | |||||
if (code == 200) { | |||||
// ElMessage.success(msg); | |||||
} | |||||
}); | |||||
}); | |||||
} | |||||
onMounted(() => { | |||||
getGroupList(); | |||||
}); | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
@import "https://g.alicdn.com/apsara-media-box/imp-web-player/2.16.3/skins/default/aliplayer-min.css"; | |||||
@import "./index.scss"; | |||||
.dialogHeader { | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
margin: 20px; | |||||
font-size: 18px; | |||||
color: #409efc; | |||||
cursor: pointer; | |||||
.dialogBtn { | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
} | |||||
} | |||||
</style> |
@@ -6,14 +6,7 @@ | |||||
<template> | <template> | ||||
<div class="main-box"> | <div class="main-box"> | ||||
<div class="table-box"> | <div class="table-box"> | ||||
<ProTable | |||||
ref="proTable" | |||||
:pagination="false" | |||||
title="班级管理" | |||||
:columns="columns" | |||||
rowKey="personSetId" | |||||
:request-api="userManageClassManageApi.page" | |||||
> | |||||
<ProTable ref="proTable" title="班级管理" :columns="columns" rowKey="personSetId" :request-api="userManageClassManageApi.getPageList"> | |||||
<!-- 表格 header 按钮 --> | <!-- 表格 header 按钮 --> | ||||
<template #tableHeader="scope"> | <template #tableHeader="scope"> | ||||
<s-button suffix="班级" @click="addClass(FormOptEnum.ADD)" /> | <s-button suffix="班级" @click="addClass(FormOptEnum.ADD)" /> | ||||
@@ -88,9 +88,9 @@ const sysDormitoryProps = reactive<FormProps.Base<SysDormitory.DormitoryInfo>>({ | |||||
// 表单验证规则 | // 表单验证规则 | ||||
const rules = reactive({ | const rules = reactive({ | ||||
name: [required("请输入宿舍楼名称")], | name: [required("请输入宿舍楼名称")], | ||||
gender: [required("请选择宿舍类型")], | |||||
insCameraId: [required("请选择进楼摄像头")], | |||||
outCameraId: [required("请选择出楼摄像头")] | |||||
gender: [required("请选择宿舍类型")] | |||||
// insCameraId: [required("请选择进楼摄像头")], | |||||
// outCameraId: [required("请选择出楼摄像头")] | |||||
}); | }); | ||||
/** | /** | ||||
@@ -142,8 +142,8 @@ onMounted(() => { | |||||
getCreamaList(); | getCreamaList(); | ||||
}); | }); | ||||
const getCreamaList = () => { | const getCreamaList = () => { | ||||
monitorLIVEApi.list({ pageNum: 1, pageSize: 1000 }).then(res => { | |||||
creamaData.value = res.data.list; | |||||
userManageDormitoryApi.getBuildCameraList().then((res: any) => { | |||||
creamaData.value = res.data; | |||||
}); | }); | ||||
}; | }; | ||||
// 暴露给父组件的方法 | // 暴露给父组件的方法 | ||||
@@ -43,8 +43,7 @@ const sysUserProps = reactive<FormProps.Base<SysUserPersonnel.SysUserPerInfo>>({ | |||||
disabled: false | disabled: false | ||||
}); | }); | ||||
const checkAgeNumber = (rule: any, value: any, callback: any) => { | const checkAgeNumber = (rule: any, value: any, callback: any) => { | ||||
if (value === "") callback("请输入年龄"); | |||||
if (value > 100 || value < 0) { | |||||
if (value && (value > 100 || value <= 0)) { | |||||
callback(new Error("请输入正确的年龄(年龄范围1-100岁)")); | callback(new Error("请输入正确的年龄(年龄范围1-100岁)")); | ||||
} else { | } else { | ||||
return callback(); | return callback(); | ||||
@@ -44,8 +44,7 @@ const sysUserProps = reactive<FormProps.Base<SysUserPersonnel.SysUserPerInfo>>({ | |||||
disabled: false | disabled: false | ||||
}); | }); | ||||
const checkAgeNumber = (rule: any, value: any, callback: any) => { | const checkAgeNumber = (rule: any, value: any, callback: any) => { | ||||
if (value === "") callback("请输入年龄"); | |||||
if (value > 100 || value < 0) { | |||||
if (value && (value > 100 || value <= 0)) { | |||||
callback(new Error("请输入正确的年龄(年龄范围1-100岁)")); | callback(new Error("请输入正确的年龄(年龄范围1-100岁)")); | ||||
} else { | } else { | ||||
return callback(); | return callback(); | ||||
@@ -71,7 +71,7 @@ const columns: ColumnProps<SysUserPersonnel.SysUserPerInfo>[] = [ | |||||
{ | { | ||||
prop: "name", | prop: "name", | ||||
label: "姓名", | label: "姓名", | ||||
search: {el:'input',span:1,} | |||||
search: {el:'input',span:1,key:'personName'} | |||||
}, | }, | ||||
{ | { | ||||
prop: "personSetName", | prop: "personSetName", | ||||
@@ -6,7 +6,7 @@ | |||||
</div> | </div> | ||||
<div class="topContent"> | <div class="topContent"> | ||||
<el-row> | <el-row> | ||||
<el-col :span="4" :offset="2"> | |||||
<el-col :span="4" :offset="1"> | |||||
<div class="left"> | <div class="left"> | ||||
<el-image | <el-image | ||||
class="avatar" | class="avatar" | ||||
@@ -25,13 +25,13 @@ | |||||
<Female class="gender GENDER_FEMALE" v-if="formData.gender == 'GENDER_FEMALE'"></Female> | <Female class="gender GENDER_FEMALE" v-if="formData.gender == 'GENDER_FEMALE'"></Female> | ||||
</span> | </span> | ||||
<span class="personId" :title="formData.personId">编号:{{ formData.personId }}</span> | |||||
<!-- <span class="personId" :title="formData.personId">编号:{{ formData.personId }}</span> --> | |||||
<!-- <el-tag type="primary">学霸型</el-tag> --> | <!-- <el-tag type="primary">学霸型</el-tag> --> | ||||
</div></el-col | </div></el-col | ||||
> | > | ||||
<el-col :span="16"> | |||||
<el-col :span="17"> | |||||
<div class="right"> | <div class="right"> | ||||
<el-row> | |||||
<el-row :gutter="20"> | |||||
<el-col :span="6"> | <el-col :span="6"> | ||||
<span v-if="formData.name" | <span v-if="formData.name" | ||||
>姓名拼音:{{ pinyin(formData.name, { toneType: "none", type: "array" }).flat().join(" ") }}</span | >姓名拼音:{{ pinyin(formData.name, { toneType: "none", type: "array" }).flat().join(" ") }}</span | ||||
@@ -42,11 +42,7 @@ | |||||
> | > | ||||
<el-col :span="6"> | <el-col :span="6"> | ||||
<span | |||||
:title="formData.personId" | |||||
style="display: block; text-overflow: ellipsis; max-width: 100%; overflow: hidden; white-space: nowrap" | |||||
>编号:{{ formData.personId }}</span | |||||
></el-col | |||||
<span :title="formData.personId" class="ellipsis">编号:{{ formData.personId }}</span></el-col | |||||
> | > | ||||
<el-col :span="6" | <el-col :span="6" | ||||
@@ -57,20 +53,20 @@ | |||||
> | > | ||||
<el-col :span="6" | <el-col :span="6" | ||||
><span>联系方式:{{ formData.phone }}</span> | |||||
><span :title="formData.phone" class="ellipsis">联系方式:{{ formData.phone }}</span> | |||||
</el-col> | </el-col> | ||||
<el-col :span="6" | <el-col :span="6" | ||||
><span>所属院系:{{ formData.depName }}</span> | |||||
><span :title="formData.depName" class="ellipsis">所属院系:{{ formData.depName }}</span> | |||||
</el-col> | </el-col> | ||||
<el-col :span="6" | <el-col :span="6" | ||||
><span>所属专业:{{ formData.majorName }}</span> | |||||
><span :title="formData.majorName" class="ellipsis">所属专业:{{ formData.majorName }}</span> | |||||
</el-col> | </el-col> | ||||
<el-col :span="6" | <el-col :span="6" | ||||
><span>所属班级:{{ formData.personSetName }}</span> | |||||
><span :title="formData.personSetName" class="ellipsis">所属班级:{{ formData.personSetName }}</span> | |||||
</el-col> | </el-col> | ||||
<el-col :span="6" | <el-col :span="6" | ||||
><span>寝室名称:{{ formData.dormitoryName }}</span> | |||||
><span :title="formData.dormitoryName" class="ellipsis">寝室名称:{{ formData.dormitoryName }}</span> | |||||
</el-col> | </el-col> | ||||
</el-row> | </el-row> | ||||
</div></el-col | </div></el-col | ||||
@@ -631,13 +627,13 @@ onMounted(() => { | |||||
} | } | ||||
} | } | ||||
.personId { | .personId { | ||||
display: block; | |||||
max-width: 90%; | |||||
margin-bottom: 10px; | margin-bottom: 10px; | ||||
overflow: hidden; | |||||
font-size: 14px; | font-size: 14px; | ||||
display: block; | |||||
text-overflow: ellipsis; | text-overflow: ellipsis; | ||||
overflow: hidden; | |||||
white-space: nowrap; | white-space: nowrap; | ||||
max-width: 90%; | |||||
} | } | ||||
} | } | ||||
.right { | .right { | ||||
@@ -647,6 +643,13 @@ onMounted(() => { | |||||
.el-col { | .el-col { | ||||
height: 50px; | height: 50px; | ||||
line-height: 50px; | line-height: 50px; | ||||
.ellipsis { | |||||
display: block; | |||||
max-width: 100%; | |||||
overflow: hidden; | |||||
text-overflow: ellipsis; | |||||
white-space: nowrap; | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -67,16 +67,32 @@ const columns: ColumnProps[] = [ | |||||
label: "姓名" | label: "姓名" | ||||
}, | }, | ||||
{ | { | ||||
prop: "personId", | |||||
label: "人员ID" | |||||
prop: "personSetName", | |||||
label: "所属班级", | |||||
}, | |||||
{ | |||||
prop: "gender", | |||||
label: "性别", | |||||
enum: [ | |||||
{ | |||||
label: "男", | |||||
value: "GENDER_MALE" | |||||
}, | |||||
{ | |||||
label: "女", | |||||
value: "GENDER_FEMALE" | |||||
}], | |||||
}, | }, | ||||
{ | { | ||||
prop: "phone", | prop: "phone", | ||||
label: "手机号" | label: "手机号" | ||||
}, | }, | ||||
{ | { | ||||
prop: "personSetName", | |||||
label: "所属班级", | |||||
prop: "age", | |||||
label: "年龄", | |||||
render: scope => { | |||||
return scope.row.age ? scope.row.age : '--'; | |||||
} | |||||
}, | }, | ||||
{ prop: "operation", label: "操作", width: 250, fixed: "right" } | { prop: "operation", label: "操作", width: 250, fixed: "right" } | ||||
]; | ]; | ||||