# Conflicts:
#	yanzhu-bigscreen/public/index.html
dev_xd
姜玉琦 2025-12-30 08:57:55 +08:00
commit 6417d07c7a
49 changed files with 8815 additions and 283 deletions

View File

@ -0,0 +1,8 @@
增加表
sys_work_area
修改表
pro_mobile_attendance_data 增加 work_area_id 工区id
attendance_ubi_data 增加 work_area_id 工区id
attendance_ubi_device 增加 work_area_id 工区id
pro_video_monitor 增加 work_area_id 工区id

File diff suppressed because one or more lines are too long

View File

@ -21,7 +21,7 @@ spring:
# 配置中心地址
server-addr: @discovery.server-addr@
# 工作空间配置
# namespace: a113aa27-4d61-46e0-81d6-9cede0457f0d
namespace: a113aa27-4d61-46e0-81d6-9cede0457f0d
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -14,10 +14,16 @@
<link rel="stylesheet" href="css/sichuanTibet.css?v=2024103201" />
<<<<<<< HEAD
<script
type="text/javascript"
src="https://api.map.baidu.com/api?type=webgl&v=1.0&ak=nDcjhjtaNwnVrKNIDbjibTm6i4u0k0fk"
></script>
=======
<script
type="text/javascript"
src="https://api.map.baidu.com/api?v=1.0&&type=webgl&ak=nDcjhjtaNwnVrKNIDbjibTm6i4u0k0fk"></script>
>>>>>>> 2f324e08658671aca3fac0cfad1a31289cbd8dc3
<script src="/cdn/vue/dist/vue.js"></script>
<script src="/cdn/element-ui/lib/index.js"></script>
<script src="/cdn/jquery/3.5.1/jquery.min.js"></script>

View File

@ -12,7 +12,16 @@ const listVideoMonitor = (query) => {
method: 'get'
})
}
const workAreaTree = (projectId) => {
return request({
url: '/system/workAarea/workAreaTree?projectId=' + projectId,
method: 'get'
})
}
export default {
listVideoMonitor,
getYsToken
getYsToken,
workAreaTree
}

View File

@ -6,12 +6,23 @@
<img src="/cdn/bsimages/nodata.png" style="width: 240px;" />
<div style="text-align: center;">暂无数据</div>
</div>
<div class="video-list">
<div class="video-list" v-else-if="!showTree">
<div v-for="it in videoMonitors" :key="it.id" class="video-item command" :class="it.active ? 'is-active' : ''" @click="doSelectItem(it)">
<svg-icon class-name="video-icon" icon-class="video" />
{{ it.monitorName }}
</div>
</div>
<div v-else class="video-tree">
<el-tree ref="treeRef" :data="treeData" :props="{ label: 'label', children: 'children' }"
highlight-current node-key="id" @node-click="handleTreeNodeClick">
<template #default="{ node, data }">
<span v-if="data.vdata" class="tree-node-content">
<svg-icon class-name="video-icon" icon-class="video" />{{ node.label }}
</span>
<span v-else class="tree-node-content">{{ node.label }}</span>
</template>
</el-tree>
</div>
</module-one-1-3>
</el-col>
<el-col :span="20" class="h100">
@ -62,6 +73,9 @@ export default {
showIndex: 1,
showList: [],
elKey: 0,
showTree: false,
treeData: [],
workAreaOptions: []
}
},
mounted() {
@ -106,12 +120,177 @@ export default {
return it
})
this.showAllVideo()
this.getWorkAreaTree()
})
},
/** 查询工区树结构 */
getWorkAreaTree() {
this.$api.videoMonitor.workAreaTree(this.selProject.id).then(response => {
// el-tree-select
this.workAreaOptions = response.data || [];
if (this.videoMonitors.filter(d => d.workAreaId).length > 0) {
// makeTreevideoMonitors
this.treeData = this.makeTree();
if (this.treeData.length > 0) {
this.showTree = true;
setTimeout(() => {
this.handleTreeNodeClick(this.treeData[0]);
// 使ref使
this.$nextTick(() => {
if (this.$refs.treeRef) {
this.$refs.treeRef.setCurrentKey(this.treeData[0].id);
}
});
}, 400);
} else {
this.showTree = false;
}
} else {
this.treeData = [];
this.showTree = false;
}
});
},
makeTree() {
const videoMonitorMap = {};
let defNode = {
id: '',
label: '默认工区',
type: 'workArea',
children: []
}
this.videoMonitors.forEach(video => {
if (video.workAreaId) {
if (!videoMonitorMap[video.workAreaId]) {
videoMonitorMap[video.workAreaId] = [];
}
videoMonitorMap[video.workAreaId].push(video);
} else {
defNode.children.push({
id: video.id,
label: video.monitorName,
vdata: video,
type: 'workArea',
children: []
});
}
});
// videoMonitors
function attachVideoMonitors(nodes) {
if (!nodes || !Array.isArray(nodes)) return [];
return nodes.map(node => {
//
const newNode = JSON.parse(JSON.stringify(node));
// videoMonitors
if (videoMonitorMap[node.id] && videoMonitorMap[node.id].length > 0) {
if (!newNode.children) {
newNode.children = [];
}
// videoMonitors
videoMonitorMap[node.id].forEach(video => {
newNode.children.push({
id: video.id,
label: video.monitorName,
type: 'workArea',
vdata: video,
children: []
});
});
}
//
if (newNode.children && newNode.children.length > 0) {
newNode.children = attachVideoMonitors(newNode.children);
}
return newNode;
});
}
// videoMonitors(treeNodetypeworkArea)
function pruneEmptyNodes(nodes) {
if (!nodes || !Array.isArray(nodes)) return [];
const result = [];
for (const node of nodes) {
//
const newNode = { ...node };
// videoMonitorsvdata
const hasDirectVideoMonitors = node.children && node.children.some(child => child.vdata && child.type === 'workArea');
//
if (node.children && node.children.length > 0) {
newNode.children = pruneEmptyNodes(node.children);
}
//
// 1. videoMonitors
// 2. videoMonitors
if (hasDirectVideoMonitors || (newNode.children && newNode.children.length > 0) || newNode.type === 'workArea') {
result.push(newNode);
}
}
return result;
}
//
const workAreaOptionsCopy = JSON.parse(JSON.stringify(this.workAreaOptions));
const treeWithVideos = attachVideoMonitors(workAreaOptionsCopy);
const prunedTree = pruneEmptyNodes(treeWithVideos);
//
if (defNode.children && defNode.children.length > 0) {
return [defNode, ...prunedTree];
}
return prunedTree;
},
handleTreeNodeClick(node) {
// vdata
if (node.vdata) {
this.doSelectItem(node.vdata, true);
} else {
//
let videoNodes = [];
function getVideoNodes(nodes) {
if (!nodes || !Array.isArray(nodes)) return [];
nodes.forEach(node => {
if (node.vdata) {
videoNodes.push(node);
}
if (node.children && node.children.length > 0) {
getVideoNodes(node.children);
}
});
}
getVideoNodes(node.children);
let videoList = videoNodes.map(d => d.vdata);
this.videoMonitors = videoList;
if (videoList.length > 1) {
this.showMode = 'all';
this.showAllData();
} else {
this.showMode = 'sigle';
this.doSelectItem(videoList[0], true);
}
}
},
loadVideo(it) {
this.$api.videoMonitor.getYsToken(it.id).then((d) => {
it.accessToken = d.msg
it.iframeSrc =
it.iframeSrc =
'https://open.ys7.com/ezopen/h5/iframe?url=' + it.url + '&autoplay=1&accessToken=' + d.msg + '&t=' + +new Date()
})
},
@ -120,8 +299,8 @@ export default {
this.showIndex = 1
this.showAllData()
},
doSelectItem(it) {
if (it.active) {
doSelectItem(it, reLoad = false) {
if (it.active && !reLoad) {
return
}
this.showMode = 'sigle'
@ -173,6 +352,147 @@ export default {
}
}
}
.video-tree {
width: 100%;
height: 100%;
font-size: 16px; /* 增大字体大小 */
.el-tree{
background: transparent;
color:#fff;
}
.tree-node-content {
display: inline-block;
width: 100%;
padding: 4px 4px; /* 增大内边距 */
cursor: pointer;
border-radius: 4px;
transition: background-color 0.2s;
line-height: 20px; /* 增大行高 */
&:hover {
background-color: transparent;
}
}
.el-tree-node__content{
&:hover{
background-color: rgba(255, 255, 255, 0.2);
}
}
.el-tree-node:focus > .el-tree-node__content {
background-color: rgba(255, 255, 255, 0.2);
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
background-color: rgba(4, 148, 238, 0.787);
color: white;
font-size: 16px; /* 保持选中状态的字体大小 */
padding: 4px 4px; /* 保持选中状态的内边距 */
.el-tree-node__expand-icon,
.el-icon-arrow-right,
.el-icon-arrow-down {
color: white;
font-size: 16px; /* 增大箭头图标大小 */
}
}
/* 覆盖默认的el-tree样式以适应大屏 */
.el-tree-node__content {
padding: 4px 4px; /* 增大节点内容的内边距 */
height: auto; /* 允许内容高度自适应 */
}
.el-tree-node__expand-icon {
font-size: 16px; /* 增大展开/折叠图标大小 */
width: 24px; /* 增大图标容器宽度 */
height: 24px; /* 增大图标容器高度 */
line-height: 20px; /* 调整图标行高 */
}
.el-tree-node__label {
font-size: 16px; /* 确保标签字体大小一致 */
}
}
/* 针对大屏分辨率的额外调整 */
@media (min-width: 1921px) and (max-width: 2560px) {
.video-tree {
font-size: 18px; /* 更大屏显时的字体 */
.tree-node-content {
padding: 8px 4px; /* 更大的内边距 */
line-height: 32px; /* 更大的行高 */
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
font-size: 18px;
padding: 8px 4px;
.el-tree-node__expand-icon,
.el-icon-arrow-right,
.el-icon-arrow-down {
font-size: 18px;
}
}
.el-tree-node__content {
padding: 8px 4px;
line-height: 24px;
}
.el-tree-node__expand-icon {
font-size: 18px;
width: 24px;
height: 24px;
line-height: 24px;
}
.el-tree-node__label {
font-size: 18px;
}
}
}
/* 针对大屏分辨率的额外调整 */
@media (min-width: 2561px) {
.video-tree {
font-size: 24px; /* 更大屏显时的字体 */
.tree-node-content {
padding: 8px 4px; /* 更大的内边距 */
line-height: 32px; /* 更大的行高 */
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
font-size: 24px;
padding: 8px 4px;
.el-tree-node__expand-icon,
.el-icon-arrow-right,
.el-icon-arrow-down {
font-size: 18px;
}
}
.el-tree-node__content {
padding: 8px 4px;
line-height: 24px;
}
.el-tree-node__expand-icon {
font-size: 24px;
width: 24px;
height: 24px;
line-height: 24px;
}
.el-tree-node__label {
font-size: 24px;
}
}
}
.all-mode {
.all-header {

View File

@ -76,6 +76,16 @@ public class AttendanceUbiData extends BaseEntity
@Excel(name = "设备NO")
private String deviceNo;
private Long workAreaId;
public Long getWorkAreaId() {
return workAreaId;
}
public void setWorkAreaId(Long workAreaId) {
this.workAreaId = workAreaId;
}
/** $column.columnComment */
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Long isDel;

View File

@ -100,6 +100,10 @@ public class AttendanceUbiDevice extends BaseEntity
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Long isDel;
/** 工区ID */
@Excel(name = "工区ID")
private Long workAreaId;
private String compName;
private String projectName;
@ -148,6 +152,7 @@ public class AttendanceUbiDevice extends BaseEntity
private String souceName;
private String workAreaName; // 工区名称,用于显示
public void setId(Long id)
{
this.id = id;
@ -337,6 +342,24 @@ public class AttendanceUbiDevice extends BaseEntity
{
return isDel;
}
public void setWorkAreaId(Long workAreaId)
{
this.workAreaId = workAreaId;
}
public Long getWorkAreaId()
{
return workAreaId;
}
public String getWorkAreaName() {
return workAreaName;
}
public void setWorkAreaName(String workAreaName) {
this.workAreaName = workAreaName;
}
@Override
public String toString() {

View File

@ -91,6 +91,16 @@ public class ProMobileAttendanceData extends BaseEntity
@Excel(name = "考勤设备")
private String attDevice;
private Long workAreaId;
public Long getWorkAreaId() {
return workAreaId;
}
public void setWorkAreaId(Long workAreaId) {
this.workAreaId = workAreaId;
}
public String getAttDevice() {
return attDevice;
}

View File

@ -65,12 +65,20 @@ public class ProVideoMonitor extends BaseEntity
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Long isDel;
/** 工区ID */
@Excel(name = "工区ID")
private Long workAreaId;
/** $column.columnComment */
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Date upadteTime;
private String compName;
private String projectName;
private String workAreaName;
private String workAreaAncestors;
public String getCompName() {
return compName;
@ -196,6 +204,33 @@ public class ProVideoMonitor extends BaseEntity
{
return isDel;
}
public void setWorkAreaId(Long workAreaId)
{
this.workAreaId = workAreaId;
}
public Long getWorkAreaId()
{
return workAreaId;
}
public void setWorkAreaName(String workAreaName) {
this.workAreaName = workAreaName;
}
public String getWorkAreaName() {
return workAreaName;
}
public void setWorkAreaAncestors(String workAreaAncestors) {
this.workAreaAncestors = workAreaAncestors;
}
public String getWorkAreaAncestors() {
return workAreaAncestors;
}
public void setUpadteTime(Date upadteTime)
{
this.upadteTime = upadteTime;
@ -222,6 +257,9 @@ public class ProVideoMonitor extends BaseEntity
.append("remark", getRemark())
.append("state", getState())
.append("isDel", getIsDel())
.append("workAreaId", getWorkAreaId())
.append("workAreaName", getWorkAreaName())
.append("workAreaAncestors", getWorkAreaAncestors())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())

View File

@ -0,0 +1,182 @@
package com.yanzhu.system.domain;
import com.yanzhu.common.core.annotation.Excel;
import com.yanzhu.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.ArrayList;
import java.util.List;
/**
* sys_work_area
*
* @author yanzhu
* @date 2025-12-25
*/
public class SysWorkArea extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** $column.columnComment */
private Long id;
/** 公司主键 */
@Excel(name = "公司主键")
private Long comId;
/** 项目ID */
@Excel(name = "项目ID")
private Long projectId;
/** 父ID */
@Excel(name = "父ID")
private Long parentId;
/** 祖级列表 */
@Excel(name = "祖级列表")
private String ancestors;
/** 工区名称 */
@Excel(name = "工区名称")
private String title;
/** 防护等级 */
@Excel(name = "防护等级")
private String level;
/** 排序 */
@Excel(name = "排序")
private Long orderNum;
/** 状态 */
@Excel(name = "状态")
private Long state;
/** 删除标志0代表存在 1代表删除 */
private String delFlag;
/** 子工区 */
private List<SysWorkArea> children = new ArrayList<>();
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setComId(Long comId)
{
this.comId = comId;
}
public Long getComId()
{
return comId;
}
public void setProjectId(Long projectId)
{
this.projectId = projectId;
}
public Long getProjectId()
{
return projectId;
}
public void setParentId(Long parentId)
{
this.parentId = parentId;
}
public Long getParentId()
{
return parentId;
}
public void setAncestors(String ancestors)
{
this.ancestors = ancestors;
}
public String getAncestors()
{
return ancestors;
}
public void setTitle(String title)
{
this.title = title;
}
public String getTitle()
{
return title;
}
public void setLevel(String level)
{
this.level = level;
}
public String getLevel()
{
return level;
}
public void setOrderNum(Long orderNum)
{
this.orderNum = orderNum;
}
public Long getOrderNum()
{
return orderNum;
}
public void setState(Long state)
{
this.state = state;
}
public Long getState()
{
return state;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
public List<SysWorkArea> getChildren() {
return children;
}
public void setChildren(List<SysWorkArea> children) {
this.children = children != null ? children : new ArrayList<>();
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("comId", getComId())
.append("projectId", getProjectId())
.append("parentId", getParentId())
.append("ancestors", getAncestors())
.append("title", getTitle())
.append("level", getLevel())
.append("orderNum", getOrderNum())
.append("state", getState())
.append("remark", getRemark())
.append("delFlag", getDelFlag())
.append("children", getChildren())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.yanzhu.system.api.domain.SysDept;
import com.yanzhu.system.domain.SysArea;
import com.yanzhu.system.domain.SysMenu;
import com.yanzhu.system.domain.SysWorkArea;
/**
* Treeselect
@ -65,6 +66,14 @@ public class TreeSelect implements Serializable
this.children = area.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
this.data=area;
}
public TreeSelect(SysWorkArea workArea)
{
this.id = workArea.getId();
this.label = workArea.getTitle();
this.children = workArea.getChildren() != null ? workArea.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()) : null;
this.data=workArea;
}
public Long getId()
{

View File

@ -0,0 +1,95 @@
package com.yanzhu.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.yanzhu.system.domain.SysWorkArea;
/**
*
*
* @author yanzhu
*/
public interface SysWorkAreaMapper
{
/**
*
*
* @param id
* @return
*/
public SysWorkArea selectSysWorkAreaById(Long id);
/**
*
*
* @param sysWorkArea
* @return
*/
public List<SysWorkArea> selectSysWorkAreaList(SysWorkArea sysWorkArea);
/**
*
*
* @param sysWorkArea
* @return
*/
public int insertSysWorkArea(SysWorkArea sysWorkArea);
/**
*
*
* @param sysWorkArea
* @return
*/
public int updateSysWorkArea(SysWorkArea sysWorkArea);
/**
*
*
* @param id
* @return
*/
public int deleteSysWorkAreaById(Long id);
/**
*
*
* @param ids
* @return
*/
public int deleteSysWorkAreaByIds(Long[] ids);
/**
* ID
*
* @param id ID
* @return
*/
public List<SysWorkArea> selectChildrenWorkAreaById(Long id);
/**
*
*
* @param workAreas
* @return
*/
public int updateWorkAreaChildren(@Param("workAreas") List<SysWorkArea> workAreas);
/**
*
*
* @param workAreaId ID
* @param state
* @return
*/
public int updateSubWorkAreaStateByAncestors(@Param("workAreaId") Long workAreaId, @Param("state") Long state);
/**
* ID
*
* @param comId ID
* @return
*/
public List<SysWorkArea> selectSysWorkAreaListByComId(@Param("comId") Long comId);
}

View File

@ -33,17 +33,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="eventGuid" column="eventGuid"/>
<result property="inPhoto" column="inPhoto"/>
<result property="outPhoto" column="outPhoto"/>
<result property="workAreaId" column="work_area_id"/>
</resultMap>
<sql id="selectAttendanceUbiDataVo">
select id, comId, projectId, userId, userName, sub_dept_group, sub_dept_group_name, craft_type, craft_post,admitGuid,
eventGuid,inPhoto,outPhoto,comName,projectName,sub_dept_id,sub_dept_name,
eventGuid,inPhoto,outPhoto,comName,projectName,sub_dept_id,sub_dept_name,work_area_id,
inTime, outTime, deviceNo, is_del, state, remark, create_by, create_time, update_by, update_time from attendance_ubi_data
</sql>
<sql id="selectAttendanceUbiDataAllVo">
select id, comId, projectId, userId, userName, sub_dept_group, sub_dept_group_name, craft_type, craft_post,admitGuid,
eventGuid,inPhoto,outPhoto,inData,outData,comName,projectName,sub_dept_id,sub_dept_name,
eventGuid,inPhoto,outPhoto,inData,outData,comName,projectName,sub_dept_id,sub_dept_name,work_area_id,
inTime, outTime, deviceNo, is_del, state, remark, create_by, create_time, update_by, update_time from attendance_ubi_data
</sql>
@ -133,6 +134,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="inData != null">inData,</if>
<if test="outTime != null">outTime,</if>
<if test="outData != null">outData,</if>
<if test="workAreaId!=null">work_area_id,</if>
<if test="deviceNo != null">deviceNo,</if>
<if test="isDel != null">is_del,</if>
<if test="subDeptId != null">sub_dept_id,</if>
@ -163,6 +165,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="inData != null">#{inData},</if>
<if test="outTime != null">#{outTime},</if>
<if test="outData != null">#{outData},</if>
<if test="workAreaId!=null">#{workAreaId},</if>
<if test="deviceNo != null">#{deviceNo},</if>
<if test="isDel != null">#{isDel},</if>
<if test="subDeptId != null">#{subDeptId},</if>

View File

@ -36,17 +36,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="compName" column="comp_name"/>
<result property="projectName" column="project_name"/>
<result property="souceName" column="souce_name"/>
<result property="workAreaId" column="work_area_id"/>
<result property="workAreaName" column="work_area_name"/>
</resultMap>
<sql id="selectAttendanceUbiDeviceVo">
select ud.id, ud.com_id, ud.project_id, ud.name, ud.tag, ud.scene_guid, ud.source, ud.device_no, ud.addition, ud.bind_default_scene, ud.force_empty_device,
ud.direction,ud.channel,
ud.work_area_id,
ud.device_model, ud.device_state, ud.rec_type, ud.online_state, ud.version_no, ud.last_active_time, ud.has_register, ud.state, ud.remark, ud.is_del,
ud.create_by, ud.create_time, ud.update_by, ud.update_time ,dp.`dept_name` comp_name,pp.`project_name`,dic.`dict_label` souce_name
ud.create_by, ud.create_time, ud.update_by, ud.update_time ,dp.`dept_name` comp_name,pp.`project_name`,dic.`dict_label` souce_name,wa.`title` work_area_name
from attendance_ubi_device ud
left join sys_dept dp on ud.`com_id`=dp.`dept_id`
left join pro_project_info pp on ud.`project_id`=pp.`id`
left join sys_dict_data dic on ud.`source`=dic.`dict_value` and dic.`dict_type`='ubi_device_source'
left join sys_work_area wa on ud.`work_area_id`=wa.`id`
</sql>
<select id="selectAttendanceUbiDeviceList" parameterType="AttendanceUbiDevice" resultMap="AttendanceUbiDeviceResult">
@ -107,6 +111,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="hasRegister != null">has_register,</if>
<if test="state != null">state,</if>
<if test="remark != null">remark,</if>
<if test="workAreaId != null">work_area_id,</if>
<if test="isDel != null">is_del,</if>
<if test="direction != null">direction,</if>
<if test="channel != null">channel,</if>
@ -137,6 +142,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="hasRegister != null">#{hasRegister},</if>
<if test="state != null">#{state},</if>
<if test="remark != null">#{remark},</if>
<if test="workAreaId != null">#{workAreaId},</if>
<if test="isDel != null">#{isDel},</if>
<if test="direction != null">#{direction},</if>
<if test="channel != null">#{channel},</if>
@ -170,6 +176,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="hasRegister != null">has_register = #{hasRegister},</if>
<if test="state != null">state = #{state},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="workAreaId != null">work_area_id = #{workAreaId},</if>
<if test="isDel != null">is_del = #{isDel},</if>
<if test="direction != null">direction = #{direction},</if>
<if test="channel != null">channel = #{channel},</if>

View File

@ -30,6 +30,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="userPost" column="user_post" />
<result property="userSex" column="user_sex" />
<result property="attDevice" column="att_device" />
<result property="workAreaId" column="wa.work_area_id"/>
</resultMap>
<sql id="selectProMobileAttendanceDataVo">
@ -62,6 +63,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="attImg != null and attImg != ''"> and pma.att_img = #{attImg}</if>
<if test="isDel != null "> and pma.is_del = #{isDel}</if>
<if test="state != null "> and pma.state = #{state}</if>
<if test="workAreaId != null "> and wa.work_area_id = #{workAreaId}</if>
<if test="userName!=null and userName!=''"> and psu.user_name like concat('%', #{userName}, '%')</if>
<if test="userPhone!=null and userPhone!=''"> and psu.user_phone like concat('%', #{userPhone}, '%')</if>
<if test="startDate!=null"> and date(pma.att_date) &gt;= date(#{startDate})</if>
@ -87,6 +89,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="attDate != null">att_date,</if>
<if test="attImg != null">att_img,</if>
<if test="attDevice != null">att_device,</if>
<if test="workAreaId != null">work_area_id,</if>
<if test="isDel != null">is_del,</if>
<if test="remark != null">remark,</if>
<if test="state != null">state,</if>
@ -106,6 +109,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="attImg != null">#{attImg},</if>
<if test="attDevice != null">#{attDevice},</if>
<if test="isDel != null">#{isDel},</if>
<if test="workAreaId != null">#{workAreaId},</if>
<if test="remark != null">#{remark},</if>
<if test="state != null">#{state},</if>
<if test="createBy != null">#{createBy},</if>

View File

@ -113,7 +113,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="userPhone != null and userPhone != ''"> and psu.user_phone = #{userPhone}</if>
<if test='activeTags == "finished"'> and psu.approve_status <![CDATA[ >= ]]> 100 </if>
<if test="isDel != null "> and psu.is_del = #{isDel}</if>
<if test='searchValue == "subUsers"'> and psu.user_post != '66' </if>
<if test='searchValue == "subUsers"'> and (psu.user_post != '66' or psu.user_post is null) </if>
<if test='searchValue == "magUsers"'> and psu.user_post = '66' </if>
<if test='searchValue == "sedUsers"'> and psu.sub_dept_type in ('1','4','5') and psu.user_post not in ('4','5') </if>
<if test="params.beginTime != null and params.beginTime != '' and params.endTime != null and params.endTime != ''"> and date(psu.use_date) between #{params.beginTime} and #{params.endTime}</if>

View File

@ -18,21 +18,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="remark" column="remark" />
<result property="state" column="state" />
<result property="isDel" column="is_del" />
<result property="workAreaId" column="work_area_id" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="upadteTime" column="upadte_time" />
<result property="compName" column="comp_name"/>
<result property="projectName" column="project_name"/>
<result property="workAreaName" column="work_area_name"/>
<result property="workAreaAncestors" column="work_area_ancestors"/>
</resultMap>
<sql id="selectProVideoMonitorVo">
select pv.id, pv.com_id, pv.project_id, pv.monitor_name, pv.monitor_type, pv.url, pv.appkey, pv.secret,
pv.manufacturer, pv.key_point, pv.remark, pv.state, pv.is_del, pv.create_by, pv.create_time,
pv.update_by, pv.upadte_time,dp.`dept_name` comp_name,pi.`project_name`
pv.manufacturer, pv.key_point, pv.remark, pv.state, pv.is_del, pv.work_area_id, pv.create_by, pv.create_time,
pv.update_by, pv.upadte_time,dp.`dept_name` comp_name,pi.`project_name`, wa.`title` work_area_name, wa.ancestors work_area_ancestors
from pro_video_monitor pv
LEFT JOIN sys_dept dp ON pv.com_id=dp.dept_id
LEFT JOIN pro_project_info pi ON pv.project_id=pi.id
LEFT JOIN sys_work_area wa ON pv.work_area_id=wa.id
</sql>
<select id="selectProVideoMonitorList" parameterType="ProVideoMonitor" resultMap="ProVideoMonitorResult">
@ -40,6 +44,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where>
<if test="comId != null "> and pv.com_id = #{comId}</if>
<if test="projectId != null "> and pv.project_id = #{projectId}</if>
<if test="workAreaId != null "> and pv.work_area_id = #{workAreaId} </if>
<if test="workAreaAncestors != null "> and (pv.work_area_id = #{workAreaAncestors} or FIND_IN_SET(#{workAreaAncestors}, wa.ancestors) > 0)</if>
<if test="monitorName != null and monitorName != ''"> and pv.monitor_name like concat('%', #{monitorName}, '%')</if>
<if test="monitorType != null and monitorType != ''"> and pv.monitor_type = #{monitorType}</if>
<if test="url != null and url != ''"> and pv.url = #{url}</if>
@ -73,6 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="remark != null">remark,</if>
<if test="state != null">state,</if>
<if test="isDel != null">is_del,</if>
<if test="workAreaId != null">work_area_id,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
@ -91,6 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="remark != null">#{remark},</if>
<if test="state != null">#{state},</if>
<if test="isDel != null">#{isDel},</if>
<if test="workAreaId != null">#{workAreaId},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
@ -113,6 +121,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="remark != null">remark = #{remark},</if>
<if test="state != null">state = #{state},</if>
<if test="isDel != null">is_del = #{isDel},</if>
<if test="workAreaId != null">work_area_id = #{workAreaId},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>

View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yanzhu.system.mapper.SysWorkAreaMapper">
<resultMap type="SysWorkArea" id="SysWorkAreaResult">
<result property="id" column="id" />
<result property="comId" column="com_id" />
<result property="projectId" column="project_id" />
<result property="parentId" column="parent_id" />
<result property="ancestors" column="ancestors" />
<result property="title" column="title" />
<result property="level" column="level" />
<result property="orderNum" column="order_num" />
<result property="state" column="state" />
<result property="remark" column="remark" />
<result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectSysWorkAreaVo">
select id, com_id, project_id, parent_id, ancestors, title, level, order_num, state, remark, del_flag, create_by, create_time, update_by, update_time from sys_work_area
</sql>
<select id="selectSysWorkAreaList" parameterType="SysWorkArea" resultMap="SysWorkAreaResult">
<include refid="selectSysWorkAreaVo"/>
<where>
<if test="comId != null "> and com_id = #{comId}</if>
<if test="projectId != null "> and project_id = #{projectId}</if>
<if test="parentId != null "> and parent_id = #{parentId}</if>
<if test="ancestors != null and ancestors != ''"> and FIND_IN_SET(#{ancestors}, ancestors) > 0</if>
<if test="title != null and title != ''"> and title = #{title}</if>
<if test="level != null and level != ''"> and level = #{level}</if>
<if test="orderNum != null "> and order_num = #{orderNum}</if>
<if test="state != null "> and state = #{state}</if>
and del_flag = '0'
</where>
</select>
<select id="selectSysWorkAreaById" parameterType="Long" resultMap="SysWorkAreaResult">
<include refid="selectSysWorkAreaVo"/>
where id = #{id} and del_flag = '0'
</select>
<insert id="insertSysWorkArea" parameterType="SysWorkArea">
insert into sys_work_area
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="comId != null">com_id,</if>
<if test="projectId != null">project_id,</if>
<if test="parentId != null">parent_id,</if>
<if test="ancestors != null">ancestors,</if>
<if test="title != null">title,</if>
<if test="level != null">level,</if>
<if test="orderNum != null">order_num,</if>
<if test="state != null">state,</if>
<if test="remark != null">remark,</if>
del_flag,
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="comId != null">#{comId},</if>
<if test="projectId != null">#{projectId},</if>
<if test="parentId != null">#{parentId},</if>
<if test="ancestors != null">#{ancestors},</if>
<if test="title != null">#{title},</if>
<if test="level != null">#{level},</if>
<if test="orderNum != null">#{orderNum},</if>
<if test="state != null">#{state},</if>
<if test="remark != null">#{remark},</if>
'0',
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
<selectKey keyProperty="id" resultType="long" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
<update id="updateSysWorkArea" parameterType="SysWorkArea">
update sys_work_area
<trim prefix="SET" suffixOverrides=",">
<if test="comId != null">com_id = #{comId},</if>
<if test="projectId != null">project_id = #{projectId},</if>
<if test="parentId != null">parent_id = #{parentId},</if>
<if test="ancestors != null">ancestors = #{ancestors},</if>
<if test="title != null">title = #{title},</if>
<if test="level != null">level = #{level},</if>
<if test="orderNum != null">order_num = #{orderNum},</if>
<if test="state != null">state = #{state},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<update id="deleteSysWorkAreaById" parameterType="Long">
update sys_work_area set del_flag = '1' where id = #{id}
</update>
<update id="deleteSysWorkAreaByIds" parameterType="String">
update sys_work_area set del_flag = '1' where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<select id="selectChildrenWorkAreaById" parameterType="long" resultMap="SysWorkAreaResult">
<include refid="selectSysWorkAreaVo"/>
WHERE parent_id = #{id} and del_flag = '0'
</select>
<update id="updateWorkAreaChildren" parameterType="java.util.List">
<foreach collection="workAreas" item="item" separator=";">
UPDATE sys_work_area SET ancestors = #{item.ancestors}
WHERE id = #{item.id}
</foreach>
</update>
<update id="updateSubWorkAreaStateByAncestors" parameterType="map">
UPDATE sys_work_area
SET state = #{state}
WHERE FIND_IN_SET(#{workAreaId}, ancestors) > 0
AND del_flag = '0'
</update>
<select id="selectSysWorkAreaListByComId" parameterType="long" resultMap="SysWorkAreaResult">
<include refid="selectSysWorkAreaVo"/>
WHERE com_id = #{comId} and del_flag = '0'
ORDER BY parent_id, order_num
</select>
</mapper>

View File

@ -20,6 +20,8 @@ spring:
config:
# 配置中心地址
server-addr: @discovery.server-addr@
# 工作空间配置
namespace: a113aa27-4d61-46e0-81d6-9cede0457f0d
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -17,9 +17,12 @@ spring:
server-addr: @discovery.server-addr@
# 服务分组
# group: lijun
config:
# 配置中心地址
server-addr: @discovery.server-addr@
# 工作空间配置
namespace: a113aa27-4d61-46e0-81d6-9cede0457f0d
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -16,10 +16,13 @@ spring:
# 服务注册地址
server-addr: @discovery.server-addr@
# 服务分组
group: JiangYuQi
#group: JiangYuQi
config:
# 配置中心地址
server-addr: @discovery.server-addr@
# 工作空间配置
namespace: a113aa27-4d61-46e0-81d6-9cede0457f0d
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -147,10 +147,12 @@ public class UniCallBackController {
addData.setSubDeptGroupName(proUser.getSubDeptGroupName());
addData.setCraftPost(proUser.getCraftPost());
addData.setCraftType(proUser.getCraftType());
addData.setWorkAreaId(device.getWorkAreaId());
attendanceData.setUserId(proUser.getUserId());
attendanceData.setProjectId(projectId);
attendanceData.setAttDate(showTime);
attendanceData.setAttImg(filePath);
attendanceData.setWorkAreaId(device.getWorkAreaId());
if(device.getDirection()==0) {
addData.setInTime(showTime);
addData.setInData(data);
@ -171,12 +173,14 @@ public class UniCallBackController {
}else{
//修改操作
AttendanceUbiData upData= list.get(0);
upData.setWorkAreaId(device.getWorkAreaId());
if(upData.getEventGuid().equals(eventGuid)){
return AjaxResult.error("此记录已入库!");
}
Date dt1=upData.getInTime();
Date dt2=upData.getOutTime();
attendanceData.setUserId(upData.getUserId());
attendanceData.setWorkAreaId(device.getWorkAreaId());
attendanceData.setProjectId(projectId);
attendanceData.setAttDate(showTime);
attendanceData.setAttImg(filePath);

View File

@ -20,13 +20,13 @@ spring:
discovery:
# 服务注册地址
server-addr: @discovery.server-addr@
# 工作空间配置
# namespace: a113aa27-4d61-46e0-81d6-9cede0457f0d
# 服务分组
group: JiangYuQi
#group: JiangYuQi
config:
# 配置中心地址
server-addr: @discovery.server-addr@
# 工作空间配置
namespace: a113aa27-4d61-46e0-81d6-9cede0457f0d
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -0,0 +1,142 @@
package com.yanzhu.system.controller;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.yanzhu.common.core.utils.poi.ExcelUtil;
import com.yanzhu.common.core.web.controller.BaseController;
import com.yanzhu.common.core.web.domain.AjaxResult;
import com.yanzhu.common.core.web.page.TableDataInfo;
import com.yanzhu.common.log.annotation.Log;
import com.yanzhu.common.log.enums.BusinessType;
import com.yanzhu.common.security.annotation.RequiresPermissions;
import com.yanzhu.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yanzhu.system.domain.SysWorkArea;
import com.yanzhu.system.service.ISysWorkAreaService;
import com.yanzhu.system.domain.vo.TreeSelect;
/**
* Controller
*
* @author yanzhu
* @date 2025-12-25
*/
@RestController
@RequestMapping("/workAarea")
public class SysWorkAreaController extends BaseController
{
@Autowired
private ISysWorkAreaService sysWorkAreaService;
/**
*
*/
@RequiresPermissions("system:workAarea:list")
@GetMapping("/list")
public TableDataInfo list(SysWorkArea sysWorkArea)
{
startPage();
List<SysWorkArea> list = sysWorkAreaService.selectSysWorkAreaList(sysWorkArea);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("system:workAarea:export")
@Log(title = "工区管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysWorkArea sysWorkArea)
{
List<SysWorkArea> list = sysWorkAreaService.selectSysWorkAreaList(sysWorkArea);
ExcelUtil<SysWorkArea> util = new ExcelUtil<SysWorkArea>(SysWorkArea.class);
util.exportExcel(response, list, "工区管理数据");
}
/**
*
*/
@RequiresPermissions("system:workAarea:query")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(sysWorkAreaService.selectSysWorkAreaById(id));
}
/**
*
*/
@RequiresPermissions("system:workAarea:add")
@Log(title = "工区管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysWorkArea sysWorkArea)
{
return toAjax(sysWorkAreaService.insertSysWorkArea(sysWorkArea));
}
/**
*
*/
@RequiresPermissions("system:workAarea:edit")
@Log(title = "工区管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysWorkArea sysWorkArea)
{
return toAjax(sysWorkAreaService.updateSysWorkArea(sysWorkArea));
}
/**
*
*/
@RequiresPermissions("system:workAarea:remove")
@Log(title = "工区管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(sysWorkAreaService.deleteSysWorkAreaByIds(ids));
}
/**
*
*/
@RequiresPermissions("system:workAarea:list")
@GetMapping("/workAreaTree")
public AjaxResult workAreaTree(Long projectId){
// 创建查询条件对象
SysWorkArea query = new SysWorkArea();
// 获取当前用户的公司ID
Long comId = SecurityUtils.getLoginUser().getSysUser().getComId();
query.setComId(comId);
// 如果传入了项目ID则设置项目ID查询条件
if (projectId != null) {
query.setProjectId(projectId);
// 使用通用的查询方法,会根据条件进行过滤
List<SysWorkArea> workAreas = sysWorkAreaService.selectSysWorkAreaList(query);
// 构建树形结构
List<TreeSelect> treeList = sysWorkAreaService.buildWorkAreaTreeSelect(workAreas);
return success(treeList);
} else {
// 如果没有传入项目ID则保持原逻辑查询该公司下的所有工区
List<SysWorkArea> workAreas = sysWorkAreaService.selectSysWorkAreaListByComId(comId);
// 构建树形结构
List<TreeSelect> treeList = sysWorkAreaService.buildWorkAreaTreeSelect(workAreas);
return success(treeList);
}
}
}

View File

@ -0,0 +1,86 @@
package com.yanzhu.system.service;
import java.util.List;
import com.yanzhu.system.domain.SysWorkArea;
import com.yanzhu.system.domain.vo.TreeSelect;
/**
* Service
*
* @author yanzhu
* @date 2025-12-25
*/
public interface ISysWorkAreaService
{
/**
*
*
* @param id
* @return
*/
public SysWorkArea selectSysWorkAreaById(Long id);
/**
*
*
* @param sysWorkArea
* @return
*/
public List<SysWorkArea> selectSysWorkAreaList(SysWorkArea sysWorkArea);
/**
*
*
* @param sysWorkArea
* @return
*/
public int insertSysWorkArea(SysWorkArea sysWorkArea);
/**
*
*
* @param sysWorkArea
* @return
*/
public int updateSysWorkArea(SysWorkArea sysWorkArea);
/**
*
*
* @param ids
* @return
*/
public int deleteSysWorkAreaByIds(Long[] ids);
/**
*
*
* @param id
* @return
*/
public int deleteSysWorkAreaById(Long id);
/**
* ID
*
* @param comId ID
* @return
*/
public List<SysWorkArea> selectSysWorkAreaListByComId(Long comId);
/**
*
*
* @param workAreas
* @return
*/
public List<SysWorkArea> buildWorkAreaTree(List<SysWorkArea> workAreas);
/**
*
*
* @param workAreas
* @return
*/
public List<TreeSelect> buildWorkAreaTreeSelect(List<SysWorkArea> workAreas);
}

View File

@ -0,0 +1,328 @@
package com.yanzhu.system.service.impl;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import com.yanzhu.common.core.utils.StringUtils;
import com.yanzhu.common.core.context.SecurityContextHolder;
import com.yanzhu.common.core.utils.DateUtils;
import com.yanzhu.common.core.utils.StringUtils;
import com.yanzhu.system.domain.vo.TreeSelect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yanzhu.system.mapper.SysWorkAreaMapper;
import com.yanzhu.system.domain.SysWorkArea;
import com.yanzhu.system.service.ISysWorkAreaService;
/**
* Service
*
* @author yanzhu
* @date 2025-12-25
*/
@Service
public class SysWorkAreaServiceImpl implements ISysWorkAreaService
{
@Autowired
private SysWorkAreaMapper sysWorkAreaMapper;
/**
*
*
* @param id
* @return
*/
@Override
public SysWorkArea selectSysWorkAreaById(Long id)
{
return sysWorkAreaMapper.selectSysWorkAreaById(id);
}
/**
*
*
* @param sysWorkArea
* @return
*/
@Override
public List<SysWorkArea> selectSysWorkAreaList(SysWorkArea sysWorkArea)
{
return sysWorkAreaMapper.selectSysWorkAreaList(sysWorkArea);
}
/**
*
*
* @param sysWorkArea
* @return
*/
@Override
public int insertSysWorkArea(SysWorkArea sysWorkArea)
{
// 如果不是根节点,需要构建祖先路径
if (sysWorkArea.getParentId() != null && sysWorkArea.getParentId() > 0) {
SysWorkArea parentWorkArea = sysWorkAreaMapper.selectSysWorkAreaById(sysWorkArea.getParentId());
if (parentWorkArea != null) {
// 构建祖先路径:父节点的祖先路径 + 父节点ID
String ancestors = parentWorkArea.getAncestors() + "," + parentWorkArea.getId();
sysWorkArea.setAncestors(ancestors);
}
} else {
// 根节点的祖先路径就是自己
sysWorkArea.setAncestors("0");
}
sysWorkArea.setCreateBy(SecurityContextHolder.getUserName());
sysWorkArea.setCreateTime(DateUtils.getNowDate());
return sysWorkAreaMapper.insertSysWorkArea(sysWorkArea);
}
/**
*
*
* @param sysWorkArea
* @return
*/
@Override
public int updateSysWorkArea(SysWorkArea sysWorkArea)
{
// 获取当前工区信息
SysWorkArea oldWorkArea = sysWorkAreaMapper.selectSysWorkAreaById(sysWorkArea.getId());
if (oldWorkArea == null) {
return 0;
}
// 如果父节点发生了变化
if (!Objects.equals(oldWorkArea.getParentId(), sysWorkArea.getParentId())) {
// 获取新的父节点信息
SysWorkArea newParentWorkArea = sysWorkAreaMapper.selectSysWorkAreaById(sysWorkArea.getParentId());
if (newParentWorkArea != null) {
// 构建新的祖先路径
String newAncestors = newParentWorkArea.getAncestors() + "," + newParentWorkArea.getId();
sysWorkArea.setAncestors(newAncestors);
// 更新所有子节点的祖先路径
updateSubWorkAreaAncestors(sysWorkArea.getId(), newAncestors, oldWorkArea.getAncestors());
}
} else {
// 父节点未变化,保持原有祖先路径
sysWorkArea.setAncestors(oldWorkArea.getAncestors());
}
// 如果状态发生变化,需要同时更新所有子工区的状态
if (!Objects.equals(oldWorkArea.getState(), sysWorkArea.getState())) {
updateSubWorkAreaState(sysWorkArea.getId(), sysWorkArea.getState());
}
sysWorkArea.setUpdateBy(SecurityContextHolder.getUserName());
sysWorkArea.setUpdateTime(DateUtils.getNowDate());
return sysWorkAreaMapper.updateSysWorkArea(sysWorkArea);
}
/**
*
*
* @param workAreaId ID
* @param state
*/
private void updateSubWorkAreaState(Long workAreaId, Long state) {
// 通过ancestors字段一次性更新所有子工区的状态
// 更新所有ancestors包含当前工区ID的工区状态
sysWorkAreaMapper.updateSubWorkAreaStateByAncestors(workAreaId, state);
}
/**
*
*
* @param workAreaId ID
* @param newAncestors
* @param oldAncestors
*/
private void updateSubWorkAreaAncestors(Long workAreaId, String newAncestors, String oldAncestors)
{
List<SysWorkArea> children = sysWorkAreaMapper.selectChildrenWorkAreaById(workAreaId);
for (SysWorkArea child : children)
{
// 保存原始祖先路径,用于递归调用
String originalAncestors = child.getAncestors();
String updatedAncestors = originalAncestors.replaceFirst(oldAncestors, newAncestors);
child.setAncestors(updatedAncestors);
// 递归更新子节点的子节点
// 传递更新后的祖先路径作为新的newAncestors原始祖先路径作为旧的oldAncestors
updateSubWorkAreaAncestors(child.getId(), updatedAncestors, originalAncestors);
}
if (children.size() > 0)
{
sysWorkAreaMapper.updateWorkAreaChildren(children);
}
}
/**
*
*
* @param ids
* @return
*/
@Override
public int deleteSysWorkAreaByIds(Long[] ids)
{
// 检查是否有工区被使用
for (Long id : ids) {
if (checkWorkAreaUsed(id)) {
throw new RuntimeException("工区ID为 " + id + " 的工区正在被使用,无法删除");
}
// 检查是否存在未被删除的子工区
if (hasChildrenWorkArea(id)) {
throw new RuntimeException("工区ID为 " + id + " 的工区存在子工区,无法删除");
}
}
return sysWorkAreaMapper.deleteSysWorkAreaByIds(ids);
}
/**
*
*
* @param id
* @return
*/
@Override
public int deleteSysWorkAreaById(Long id)
{
// 检查工区是否被使用
if (checkWorkAreaUsed(id)) {
throw new RuntimeException("工区ID为 " + id + " 的工区正在被使用,无法删除");
}
// 检查是否存在未被删除的子工区
if (hasChildrenWorkArea(id)) {
throw new RuntimeException("工区ID为 " + id + " 的工区存在子工区,无法删除");
}
return sysWorkAreaMapper.deleteSysWorkAreaById(id);
}
@Override
public List<SysWorkArea> selectSysWorkAreaListByComId(Long comId)
{
return sysWorkAreaMapper.selectSysWorkAreaListByComId(comId);
}
/**
*
*
* @param workAreas
* @return
*/
@Override
public List<SysWorkArea> buildWorkAreaTree(List<SysWorkArea> workAreas)
{
List<SysWorkArea> returnList = new ArrayList<SysWorkArea>();
List<Long> tempList = workAreas.stream().map(SysWorkArea::getId).collect(Collectors.toList());
for (SysWorkArea workArea : workAreas)
{
// 如果是顶级节点, 遍历该父节点的所有子节点
if (!tempList.contains(workArea.getParentId()))
{
recursionFn(workAreas, workArea);
returnList.add(workArea);
}
}
if (returnList.isEmpty())
{
returnList = workAreas;
}
return returnList;
}
/**
*
*
* @param workAreas
* @return
*/
@Override
public List<TreeSelect> buildWorkAreaTreeSelect(List<SysWorkArea> workAreas)
{
List<SysWorkArea> workAreaTrees = buildWorkAreaTree(workAreas);
return workAreaTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
}
/**
*
*
* @param list
* @param t
*/
private void recursionFn(List<SysWorkArea> list, SysWorkArea t)
{
// 得到子节点列表
List<SysWorkArea> childList = getChildList(list, t);
t.setChildren(childList != null ? childList : new ArrayList<>());
for (SysWorkArea tChild : childList)
{
if (hasChild(list, tChild))
{
recursionFn(list, tChild);
}
}
}
/**
*
*/
private List<SysWorkArea> getChildList(List<SysWorkArea> list, SysWorkArea t)
{
List<SysWorkArea> tlist = new ArrayList<SysWorkArea>();
Iterator<SysWorkArea> it = list.iterator();
while (it.hasNext())
{
SysWorkArea n = (SysWorkArea) it.next();
if (n.getParentId().longValue() == t.getId().longValue())
{
tlist.add(n);
}
}
return tlist;
}
/**
*
*/
private boolean hasChild(List<SysWorkArea> list, SysWorkArea t)
{
return getChildList(list, t).size() > 0;
}
/**
*
*
* @param id ID
* @return true-false-
*/
private boolean hasChildrenWorkArea(Long id) {
SysWorkArea sysWorkArea = new SysWorkArea();
sysWorkArea.setParentId(id);
List<SysWorkArea> children = sysWorkAreaMapper.selectSysWorkAreaList(sysWorkArea);
return !children.isEmpty();
}
/**
* 使
*
* @param id ID
* @return true-使false-使
*/
private boolean checkWorkAreaUsed(Long id) {
// TODO: 实现工区使用情况检查逻辑
// 例如:检查是否有用户、设备、项目等关联到该工区
// 目前暂时返回false表示未被使用
return false;
}
}

View File

@ -20,6 +20,8 @@ spring:
config:
# 配置中心地址
server-addr: @discovery.server-addr@
# 工作空间配置
namespace: a113aa27-4d61-46e0-81d6-9cede0457f0d
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -39,5 +39,18 @@
- [[智慧农业认养系统]](https://gitee.com/tony2y/smart-breed)基于Java + SpringBoot + Mybatis Plus + Redis + Vue + antdv支持认养、商城、营销、会员、进销存、多租户等功能包含小程序系统管理后台。
- [[智慧景区管理系统]](https://gitee.com/tony2y/scenic-spot)基于Java + SpringBoot + Mybatis Plus + Redis + Vue + antdv支持景区管理、售票、地块管理、认养、商城、农资管理、积分兑换等功能包含小程序系统管理后台。
数字项管wx46466c7828eede2b
筑安施工wx007a8fd50dc185b2
写一个切换环境的 js根据不同的环境修改 config.js,config.wxs 和 project.config.json 文件中的配置项
数字项管A
appid:wx46466c7828eede2b
baseUrl:https://xiangguan.sxyanzhu.com/wechat
baseImgUrl:https://xiangguan.sxyanzhu.com
筑安施工B
appid:wx007a8fd50dc185b2
baseUrl:https://jaszpt.crfeb.com.cn/wechat
baseImgUrl:https://jaszpt.crfeb.com.cn
注意修改图片路径要修改两个文件
config.js
config.wxs

View File

@ -1,12 +1,12 @@
// 应用全局配置
module.exports = {
timeout: 60000,
appId: "wx007a8fd50dc185b2",
//baseUrl: "https://xiangguan.sxyanzhu.com/wechat",
baseUrl: "https://jaszpt.crfeb.com.cn/wechat",
appId: "wx46466c7828eede2b",
baseUrl: "https://xiangguan.sxyanzhu.com/wechat",
////baseUrl: "https://jaszpt.crfeb.com.cn/wechat",
//baseUrl: "http://127.0.0.1:8080",
//baseImgUrl: "https://xiangguan.sxyanzhu.com",
baseImgUrl: "https://jaszpt.crfeb.com.cn",
baseImgUrl: "https://xiangguan.sxyanzhu.com",
////baseImgUrl: "https://jaszpt.crfeb.com.cn",
//baseImgUrl: 'http://127.0.0.1:9300',
noSecuritys: [
"/code",

View File

@ -1,5 +1,5 @@
{
"appid": "wx007a8fd50dc185b2",
"appid": "wx46466c7828eede2b",
"compileType": "miniprogram",
"libVersion": "3.8.9",
"packOptions": {

View File

@ -1,7 +1,7 @@
// WXS 配置文件
var config = {
// 与 config.js 中的 baseImgUrl 保持同步
baseImgUrl: "https://jaszpt.crfeb.com.cn",
baseImgUrl: "https://xiangguan.sxyanzhu.com",
};
module.exports = config;

View File

@ -0,0 +1,16 @@
{
"name": "yanzhu-ui-app",
"version": "1.0.0",
"description": "研筑-临时工程项目管理App",
"scripts": {
"switch": "node switchEnv.js"
},
"keywords": [
"微信小程序",
"工程项目管理",
"Flowable",
"RuoYi"
],
"author": "研筑团队",
"license": "MIT"
}

View File

@ -0,0 +1,180 @@
const fs = require("fs");
const path = require("path");
// 环境配置
const envConfigs = {
A: {
name: "数字项管",
displayName: "A (数字项管)",
appId: "wx46466c7828eede2b",
baseUrl: "https://xiangguan.sxyanzhu.com/wechat",
baseImgUrl: "https://xiangguan.sxyanzhu.com",
},
B: {
name: "筑安施工",
displayName: "B (筑安施工)",
appId: "wx007a8fd50dc185b2",
baseUrl: "https://jaszpt.crfeb.com.cn/wechat",
baseImgUrl: "https://jaszpt.crfeb.com.cn",
},
};
// 文件路径
const configJsPath = path.join(__dirname, "miniprogram", "config.js");
const configWxsPath = path.join(
__dirname,
"miniprogram",
"utils",
"config.wxs"
);
const projectConfigPath = path.join(
__dirname,
"miniprogram",
"project.config.json"
);
// 更新 config.js
function updateConfigJs(env) {
let content = fs.readFileSync(configJsPath, "utf8");
// 更新 appId
content = content.replace(/appId:\s*"[^"]*"/, `appId: "${env.appId}"`);
// 更新 baseUrl (取消注释目标环境,注释其他环境)
if (env.name === "数字项管") {
// 启用数字项管,注释其他
content = content.replace(
/\/\/baseUrl:\s*"https:\/\/xiangguan\.sxyanzhu\.com\/wechat"/,
`baseUrl: "${env.baseUrl}"`
);
content = content.replace(
/baseUrl:\s*"https:\/\/jaszpt\.crfeb\.com\.cn\/wechat"/,
`//baseUrl: "https://jaszpt.crfeb.com.cn/wechat"`
);
content = content.replace(
/\/\/baseUrl:\s*"http:\/\/127\.0\.0\.1:8080"/,
`//baseUrl: "http://127.0.0.1:8080"`
);
} else {
// 启用筑安施工,注释其他
content = content.replace(
/\/\/baseUrl:\s*"https:\/\/jaszpt\.crfeb\.com\.cn\/wechat"/,
`baseUrl: "${env.baseUrl}"`
);
content = content.replace(
/baseUrl:\s*"https:\/\/xiangguan\.sxyanzhu\.com\/wechat"/,
`//baseUrl: "https://xiangguan.sxyanzhu.com/wechat"`
);
content = content.replace(
/\/\/baseUrl:\s*"http:\/\/127\.0\.0\.1:8080"/,
`//baseUrl: "http://127.0.0.1:8080"`
);
}
// 更新 baseImgUrl (取消注释目标环境,注释其他)
if (env.name === "数字项管") {
// 启用数字项管,注释其他
content = content.replace(
/\/\/baseImgUrl:\s*"https:\/\/xiangguan\.sxyanzhu\.com"/,
`baseImgUrl: "${env.baseImgUrl}"`
);
content = content.replace(
/baseImgUrl:\s*"https:\/\/jaszpt\.crfeb\.com\.cn"/,
`//baseImgUrl: "https://jaszpt.crfeb.com.cn"`
);
content = content.replace(
/\/\/baseImgUrl:\s*'http:\/\/127\.0\.0\.1:9300'/,
`//baseImgUrl: 'http://127.0.0.1:9300'`
);
} else {
// 启用筑安施工,注释其他
content = content.replace(
/\/\/baseImgUrl:\s*"https:\/\/jaszpt\.crfeb\.com\.cn"/,
`baseImgUrl: "${env.baseImgUrl}"`
);
content = content.replace(
/baseImgUrl:\s*"https:\/\/xiangguan\.sxyanzhu\.com"/,
`//baseImgUrl: "https://xiangguan.sxyanzhu.com"`
);
content = content.replace(
/\/\/baseImgUrl:\s*'http:\/\/127\.0\.0\.1:9300'/,
`//baseImgUrl: 'http://127.0.0.1:9300'`
);
}
fs.writeFileSync(configJsPath, content, "utf8");
console.log(`✅ 已更新 config.js 为 ${env.name} 环境`);
}
// 更新 config.wxs
function updateConfigWxs(env) {
let content = fs.readFileSync(configWxsPath, "utf8");
// 更新 baseImgUrl
content = content.replace(
/baseImgUrl:\s*"[^"]*"/,
`baseImgUrl: "${env.baseImgUrl}"`
);
fs.writeFileSync(configWxsPath, content, "utf8");
console.log(`✅ 已更新 config.wxs 为 ${env.name} 环境`);
}
// 更新 project.config.json
function updateProjectConfig(env) {
const content = fs.readFileSync(projectConfigPath, "utf8");
const config = JSON.parse(content);
// 更新 appId
config.appid = env.appId;
fs.writeFileSync(projectConfigPath, JSON.stringify(config, null, 4), "utf8");
console.log(`✅ 已更新 project.config.json 为 ${env.name} 环境`);
}
// 主函数
function main() {
const args = process.argv.slice(2);
let envName = args[0];
// 如果没有传参数,提示用户选择
if (!envName) {
console.log("🔧 当前支持的环境:");
console.log(" A - 数字项管");
console.log(" B - 筑安施工");
console.log("\n💡 使用方法: node switchEnv.js <环境标识>");
console.log(" 例如: node switchEnv.js A");
return;
}
// 匹配环境
let selectedEnv = null;
for (const [key, env] of Object.entries(envConfigs)) {
if (key.includes(envName) || env.name.includes(envName)) {
selectedEnv = env;
break;
}
}
if (!selectedEnv) {
console.error(`❌ 未找到环境: ${envName}`);
console.log("🔧 支持的环境:");
Object.entries(envConfigs).forEach(([key, env]) => {
console.log(` ${key} - ${env.name}`);
});
return;
}
console.log(`🔄 正在切换到 ${selectedEnv.displayName} 环境...`);
try {
updateConfigJs(selectedEnv);
updateConfigWxs(selectedEnv);
updateProjectConfig(selectedEnv);
console.log(`\n🎉 环境切换成功!当前环境: ${selectedEnv.displayName}`);
} catch (error) {
console.error(`❌ 环境切换失败: ${error.message}`);
}
}
main();

View File

@ -113,4 +113,7 @@ a {
.svg-icon{
outline: none;
}
.hidden{
display: none;
}
</style>

View File

@ -0,0 +1,74 @@
import request from '@/utils/request'
// 查询工区管理列表
export function listWorkAarea(query) {
return request({
url: '/system/workAarea/list',
method: 'get',
params: query
})
}
// 查询工区管理详细
export function getWorkAarea(id) {
return request({
url: '/system/workAarea/' + id,
method: 'get'
})
}
// 新增工区管理
export function addWorkAarea(data) {
return request({
url: '/system/workAarea',
method: 'post',
data: data
})
}
// 修改工区管理
export function updateWorkAarea(data) {
return request({
url: '/system/workAarea',
method: 'put',
data: data
})
}
// 删除工区管理
export function delWorkAarea(id) {
return request({
url: '/system/workAarea/' + id,
method: 'delete'
})
}
export function workAreaTree(projectId) {
return request({
url: '/system/workAarea/workAreaTree?projectId=' + projectId,
method: 'get'
})
}
/** 转换树形数据格式 */
export function transformTreeData(apiData) {
if (!apiData || !Array.isArray(apiData)) {
return [];
}
return apiData.map(item => {
// 先展开item.data再设置children避免被覆盖
const transformedItem = {
id: item.id,
title: item.label, // 使用label作为显示文本
ancestors: item.data?.ancestors, // 从data字段中获取ancestors
// 保留原始数据以备后用
...item.data
};
// 确保children使用正确转换后的数据
transformedItem.children = item.children ? transformTreeData(item.children) : [];
return transformedItem;
});
}

View File

@ -0,0 +1,151 @@
// Tailwind CSS
/* Spacing */
.p-y-0 { padding-top: 0; padding-bottom: 0; }
.p-x-0 { padding-left: 0; padding-right: 0; }
.p-0 { padding: 0; }
.m-y-0 { margin-top: 0; margin-bottom: 0; }
.m-x-0 { margin-left: 0; margin-right: 0; }
.m-0 { margin: 0; }
.p-y-1 { padding-top: 1rem; padding-bottom: 1rem; }
.p-x-1 { padding-left: 1rem; padding-right: 1rem; }
.p-1 { padding: 1rem; }
.m-y-1 { margin-top: 1rem; margin-bottom: 1rem; }
.m-x-1 { margin-left: 1rem; margin-right: 1rem; }
.p-y-2 { padding-top: 2rem; padding-bottom: 2rem; }
.p-x-2 { padding-left: 2rem; padding-right: 2rem; }
.p-2 { padding: 2rem; }
.m-y-2 { margin-top: 2rem; margin-bottom: 2rem; }
.m-x-2 { margin-left: 2rem; margin-right: 2rem; }
.p-y-3 { padding-top: 3rem; padding-bottom: 3rem; }
.p-x-3 { padding-left: 3rem; padding-right: 3rem; }
.p-3 { padding: 3rem; }
.m-y-3 { margin-top: 3rem; margin-bottom: 3rem; }
.m-x-3 { margin-left: 3rem; margin-right: 3rem; }
.mt-1 { margin-top: 1rem; }
.mb-1 { margin-bottom: 1rem; }
.mb-2 { margin-bottom: 2rem; }
.mb-3 { margin-bottom: 3rem; }
.mt-2 { margin-top: 2rem; }
.mt-3 { margin-top: 3rem; }
.ml-1 { margin-left: 1rem; }
.ml-2 { margin-left: 2rem; }
.ml-3 { margin-left: 3rem; }
.mr-1 { margin-right: 1rem; }
.mr-2 { margin-right: 2rem; }
.mr-3 { margin-right: 3rem; }
.pl-1 { padding-left: 1rem; }
.pl-2 { padding-left: 2rem; }
.pl-3 { padding-left: 3rem; }
.pr-1 { padding-right: 1rem; }
.pr-2 { padding-right: 2rem; }
.pr-3 { padding-right: 3rem; }
.p-y-auto { padding-top: auto; padding-bottom: auto; }
.p-x-auto { padding-left: auto; padding-right: auto; }
.pt-1 { padding-top: 1rem; }
.pt-2 { padding-top: 2rem; }
.pt-3 { padding-top: 3rem; }
.pb-1 { padding-bottom: 1rem; }
.pb-2 { padding-bottom: 2rem; }
.pb-3 { padding-bottom: 3rem; }
/* Flexbox */
.flex { display: flex; }
.inline-flex { display: inline-flex; }
.flex-row { flex-direction: row; }
.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.justify-start { justify-content: flex-start; }
.justify-end { justify-content: flex-end; }
/* Width */
.w-full { width: 100%; }
.w-1\/2 { width: 50%; }
.w-1\/3 { width: 33.333333%; }
.w-2\/3 { width: 66.666667%; }
.w-1\/4 { width: 25%; }
.w-3\/4 { width: 75%; }
.w-1\/5 { width: 20%; }
.w-4\/5 { width: 80%; }
.w-1\/6 { width: 16.666667%; }
.w-5\/6 { width: 83.333333%; }
/* Height */
.h-full { height: 100%; }
.h-screen { height: 100vh; }
/* Text Alignment */
.text-left { text-align: left; }
.text-center { text-align: center; }
.text-right { text-align: right; }
/* Text Colors */
.text-white { color: #fff; }
.text-black { color: #000; }
.text-gray { color: #6b7280; }
.text-gray-dark { color: #374151; }
.text-blue { color: #3b82f6; }
.text-green { color: #10b981; }
.text-red { color: #ef4444; }
.text-yellow { color: #f59e0b; }
/* Background Colors */
.bg-white { background-color: #fff; }
.bg-black { background-color: #000; }
.bg-gray { background-color: #6b7280; }
.bg-gray-light { background-color: #f3f4f6; }
.bg-blue { background-color: #3b82f6; }
.bg-green { background-color: #10b981; }
.bg-red { background-color: #ef4444; }
.bg-yellow { background-color: #f59e0b; }
/* Border */
.border { border: 1px solid #e5e7eb; }
.border-t { border-top: 1px solid #e5e7eb; }
.border-b { border-bottom: 1px solid #e5e7eb; }
.border-l { border-left: 1px solid #e5e7eb; }
.border-r { border-right: 1px solid #e5e7eb; }
.border-gray { border-color: #e5e7eb; }
.rounded { border-radius: 0.25rem; }
.rounded-md { border-radius: 0.375rem; }
.rounded-lg { border-radius: 0.5rem; }
.rounded-full { border-radius: 9999px; }
/* Display */
.block { display: block; }
.inline-block { display: inline-block; }
.hidden { display: none; }
/* Position */
.relative { position: relative; }
.absolute { position: absolute; }
/* Font */
.font-normal { font-weight: 400; }
.font-medium { font-weight: 500; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-sm { font-size: 0.875rem; }
.text-base { font-size: 1rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
/* Other Utilities */
.overflow-hidden { overflow: hidden; }
.overflow-auto { overflow: auto; }
.overflow-scroll { overflow: scroll; }
.cursor-pointer { cursor: pointer; }
.select-none { user-select: none; }
.dlg-hide-form-hidden-scroll{
.el-dialog__body{
overflow: hidden !important;
.el-form{
overflow: hidden !important;
}
}
}

View File

@ -15,6 +15,10 @@
</div>
</div>
<div id="index-map" style="width: 100%; height: 600px"></div>
<!-- 添加加载提示 -->
<div v-if="mapLoading" class="map-loading">
地图加载中...
</div>
</el-dialog>
</template>
<script setup>
@ -25,11 +29,14 @@ const title = ref("");
const map = ref("");
const point = ref("");
const cityInfo = ref("");
const mapLoading = ref(false); //
const data = reactive({
txtAarea: "",
});
const emit = defineEmits(["docom"]);
// API
const BAIDU_MAP_AK = "0WF4D7OmWBQ0CGIdVXS8rmpk";
function doOk() {
emit("docom", point.value, cityInfo.value);
@ -41,15 +48,109 @@ function getAddress() {
return addr;
}
// API
function loadBaiduMapAPI() {
return new Promise((resolve, reject) => {
console.log("开始加载百度地图API...");
//
if (typeof BMapGL !== 'undefined') {
console.log("BMapGL已存在直接使用");
resolve();
return;
}
//
if (window.baiduMapLoading) {
console.log("百度地图API正在加载中...");
//
window.baiduMapCallbacks = window.baiduMapCallbacks || [];
window.baiduMapCallbacks.push(() => {
console.log("百度地图API加载完成通过回调");
resolve();
});
return;
}
//
window.baiduMapLoading = true;
window.baiduMapCallbacks = [];
// script
const script = document.createElement('script');
script.type = 'text/javascript';
// 使WebGLAPIs=1
script.src = `https://api.map.baidu.com/api?v=1.0&type=webgl&ak=${BAIDU_MAP_AK}&callback=onBaiduMapLoaded`;
script.onload = () => {
console.log("百度地图API脚本加载成功");
};
script.onerror = () => {
console.error("百度地图API脚本加载失败");
window.baiduMapLoading = false;
reject(new Error('百度地图API脚本加载失败'));
};
//
window.onBaiduMapLoaded = function() {
console.log("百度地图API加载完成回调");
// BMapGL
if (typeof BMapGL !== 'undefined') {
console.log("BMapGL已定义API加载成功");
window.baiduMapLoading = false;
//
window.baiduMapCallbacks.forEach(callback => callback());
window.baiduMapCallbacks = [];
resolve();
} else {
console.error("BMapGL仍未定义API加载可能存在问题");
window.baiduMapLoading = false;
reject(new Error('百度地图API加载完成但BMapGL未定义'));
}
};
//
document.head.appendChild(script);
console.log("百度地图API脚本已添加到页面");
});
}
function showDlg(opt) {
title.value = opt?.title || "选择地址";
show.value = true;
setTimeout(() => {
initMap(opt);
}, 400);
mapLoading.value = true; //
//
console.log("尝试加载百度地图API...");
// API
loadBaiduMapAPI()
.then(() => {
console.log("百度地图API已就绪开始初始化地图...");
initMap(opt);
})
.catch(error => {
console.error("百度地图API加载失败:", error);
mapLoading.value = false;
// AK
if (error.message.includes('AK')) {
proxy.$modal.msgError("地图加载失败: API密钥无效或配额已用完");
} else {
proxy.$modal.msgError("地图加载失败: " + error.message);
}
});
}
function currentPoint() {
// BMapGL
if (typeof BMapGL === 'undefined') {
console.error("BMapGL未定义无法获取当前位置");
proxy.$modal.msgError("地图服务未加载完成,请稍后重试");
return;
}
let geolocation = new BMapGL.Geolocation();
geolocation.enableSDKLocation();
geolocation.getCurrentPosition((e) => {
@ -62,6 +163,11 @@ function currentPoint() {
}
function mapClick(e) {
// BMapGL
if (typeof BMapGL === 'undefined') {
return;
}
point.value = e.latlng;
let myGeo = new BMapGL.Geocoder({ extensions_town: true });
myGeo.getLocation(e.latlng, (r) => {
@ -84,42 +190,68 @@ function mapClick(e) {
}
function initMap(opt) {
let imap = new BMapGL.Map("index-map");
map.value = imap;
let point = new BMapGL.Point(116.404, 39.915);
//
map.value.centerAndZoom(point, 15);
map.value.setDefaultCursor("crosshair"); //
map.value.enableScrollWheelZoom(); //
//
//
let initMarker = new BMapGL.Marker(point);
//
map.value.addOverlay(initMarker);
//
//
map.value.addControl(new BMapGL.NavigationControl());
//
map.value.addEventListener("click", mapClick);
var myGeo = new BMapGL.Geocoder();
if (opt && opt.address) {
let myGeo = new BMapGL.Geocoder();
myGeo.getPoint(opt.address, function (pt) {
if (pt) {
map.value.centerAndZoom(pt, 16);
mapClick({ latlng: pt });
} else {
currentPoint();
}
});
} else {
currentPoint();
// BMapGL
if (typeof BMapGL === 'undefined') {
console.error("BMapGL未定义无法初始化地图");
proxy.$modal.msgError("地图服务未加载完成,请稍后重试");
mapLoading.value = false;
return;
}
console.log("开始初始化地图...");
//
const container = document.getElementById("index-map");
if (container) {
container.innerHTML = "";
}
try {
let imap = new BMapGL.Map("index-map");
map.value = imap;
let point = new BMapGL.Point(116.404, 39.915);
//
map.value.centerAndZoom(point, 15);
map.value.setDefaultCursor("crosshair"); //
map.value.enableScrollWheelZoom(); //
//
//
let initMarker = new BMapGL.Marker(point);
//
map.value.addOverlay(initMarker);
//
//
map.value.addControl(new BMapGL.NavigationControl());
//
map.value.addEventListener("click", mapClick);
if (opt && opt.address) {
let myGeo = new BMapGL.Geocoder();
myGeo.getPoint(opt.address, function (pt) {
if (pt) {
map.value.centerAndZoom(pt, 16);
mapClick({ latlng: pt });
} else {
currentPoint();
}
});
} else {
currentPoint();
}
//
mapLoading.value = false;
console.log("地图初始化完成");
} catch (error) {
console.error("地图初始化过程中发生错误:", error);
mapLoading.value = false;
proxy.$modal.msgError("地图初始化失败: " + error.message);
}
}
function initMapData(opt) {
if (opt.latitude && opt.longitude) {
point.value = {};
@ -138,7 +270,14 @@ defineExpose({
showDlg,
initMapData,
});
function search() {
// BMapGL
if (typeof BMapGL === 'undefined') {
proxy.$modal.msgError("地图服务未加载完成,请稍后重试");
return;
}
if (!data.txtAarea) {
proxy.$modal.msgError("请输入要搜索的地址");
return;
@ -159,7 +298,7 @@ function search() {
.el-dialog__body {
position: relative;
padding: 0px;
.div-info {
position: absolute;
top: 0px;
@ -174,6 +313,22 @@ function search() {
color: #51b5ff;
line-height: 24px;
}
//
.map-loading {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.8);
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
color: #666;
z-index: 1000;
}
}
}
</style>

View File

@ -6,6 +6,7 @@ import ElementPlus from "element-plus";
import locale from "element-plus/es/locale/lang/zh-cn";
import "element-plus/theme-chalk/index.css";
import "@/assets/styles/index.scss"; // global css
import "@/assets/styles/tailwind.scss";
import App from "./App";
import store from "./store";

View File

@ -14,6 +14,12 @@
<el-option v-for="(it) in data.subdepts" :key="it.id" :label="it.subDeptName" :value="it.id" />
</el-select>
</el-form-item>
<el-form-item label="所属工区" prop="workAreaAncestors">
<el-tree-select v-model="queryParams.workAreaId" :data="data.workAreaOptions"
:props="{ value: 'id', label: 'title', children: 'children' }" value-key="id" placeholder="请选择工区"
clearable style="width: 240px" />
</el-form-item>
<el-form-item label="姓名" prop="userName">
<el-input v-model="queryParams.userName" placeholder="请输入姓名" clearable @keyup.enter="handleQuery" />
</el-form-item><el-form-item label="" prop="inTime">
@ -157,7 +163,7 @@ import { listAttendanceUbiData, getAttendanceUbiData, delAttendanceUbiData, addA
import { findMyProjectList } from "@/api/publics";
import useUserStore from '@/store/modules/user'
import { listProProjectInfoSubdepts } from "@/api/manage/proProjectInfoSubdepts";
import { workAreaTree, transformTreeData } from '@/api/system/workAarea'
const { proxy } = getCurrentInstance();
const { pro_craft_type, pro_craft_post } = proxy.useDict( 'pro_craft_type', 'pro_craft_post');
@ -200,6 +206,8 @@ const data = reactive({
projects:[],
subdepts:[],
currentPrjId: '',
//
workAreaOptions: [],
});
const { queryParams, form, rules } = toRefs(data);
@ -271,6 +279,14 @@ function reset() {
proxy.resetForm("attendanceUbiDataRef");
}
/** 查询工区树结构 */
function getWorkAreaTree() {
workAreaTree(userStore.currentPrjId).then(response => {
// el-tree-select
data.workAreaOptions = transformTreeData(response.data);
});
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
@ -350,7 +366,8 @@ function handleExport() {
queryParams.value.inTime= proxy.$dt(new Date()).format("YYYY-MM-DD");
getList();
getProjectList();
//
getWorkAreaTree();
</script>
<style lang="scss">
.attendance-ubi-data{

View File

@ -2,8 +2,10 @@
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="90px">
<el-form-item label="项目" prop="projectId">
<el-select :disabled="data.currentPrjId != ''" v-model="queryParams.projectId" placeholder="请选择项目" clearable @change="handleQuery">
<el-option v-for="prj in data.projects" :key="prj.id" :label="prj.projectName" :value="prj.id"></el-option>
<el-select :disabled="data.currentPrjId != ''" v-model="queryParams.projectId" placeholder="请选择项目"
clearable @change="handleQuery">
<el-option v-for="prj in data.projects" :key="prj.id" :label="prj.projectName"
:value="prj.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="设备名称" prop="name">
@ -23,16 +25,20 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['manage:attendance_ubi_device:add']"></el-button>
<el-button type="primary" plain icon="Plus" @click="handleAdd"
v-hasPermi="['manage:attendance_ubi_device:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['manage:attendance_ubi_device:edit']"></el-button>
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
v-hasPermi="['manage:attendance_ubi_device:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['manage:attendance_ubi_device:remove']"></el-button>
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
v-hasPermi="['manage:attendance_ubi_device:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['manage:attendance_ubi_device:export']"></el-button>
<el-button type="warning" plain icon="Download" @click="handleExport"
v-hasPermi="['manage:attendance_ubi_device:export']">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
@ -40,6 +46,7 @@
<el-table v-loading="loading" :data="attendance_ubi_deviceList" @selection-change="handleSelectionChange">
<el-table-column label="公司" align="center" prop="compName" />
<el-table-column label="所属项目" align="center" prop="projectName" />
<el-table-column label="所属工区" align="center" prop="workAreaName" />
<el-table-column label="设备名称" align="center" prop="name" />
<el-table-column label="设备标签" align="center" prop="tag" />
<el-table-column label="设备来源" align="center" prop="souceName" />
@ -47,21 +54,21 @@
<el-table-column label="设备模式" align="center" prop="deviceModel" v-if="false" />
<el-table-column label="设备状态" align="center" prop="deviceState">
<template #default="scope">
<span v-if="scope.row.deviceState==1"></span>
<span v-if="scope.row.deviceState==2"></span>
<span v-if="scope.row.deviceState==3"></span>
<span v-if="scope.row.deviceState == 1"></span>
<span v-if="scope.row.deviceState == 2"></span>
<span v-if="scope.row.deviceState == 3"></span>
</template>
</el-table-column>
<el-table-column label="比对模式" align="center" prop="recType">
<template #default="scope">
<span v-if="scope.row.recType==1"></span>
<span v-if="scope.row.recType==2"></span>
<span v-if="scope.row.recType == 1"></span>
<span v-if="scope.row.recType == 2"></span>
</template>
</el-table-column>
<el-table-column label="在线状态" align="center" prop="onlineState">
<template #default="scope">
<span v-if="scope.row.onlineState==1">线</span>
<span v-if="scope.row.onlineState==2">线</span>
<span v-if="scope.row.onlineState == 1">线</span>
<span v-if="scope.row.onlineState == 2">线</span>
</template>
</el-table-column>
<el-table-column label="版本号" align="center" prop="versionNo" />
@ -72,23 +79,28 @@
</el-table-column>
<el-table-column label="注册状态" align="center" prop="hasRegister">
<template #default="scope">
<span v-if="scope.row.onlineState==1"></span>
<span v-if="scope.row.onlineState == 1"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="150">
<template #default="scope">
<el-button link type="primary" icon="ChromeFilled" @click="handleAuth(scope.row)" v-hasPermi="['manage:attendance_ubi_device:edit']"></el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['manage:attendance_ubi_device:edit']"></el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['manage:attendance_ubi_device:remove']"></el-button>
<el-button link type="primary" icon="ChromeFilled" @click="handleAuth(scope.row)"
v-hasPermi="['manage:attendance_ubi_device:edit']">同步</el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
v-hasPermi="['manage:attendance_ubi_device:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
v-hasPermi="['manage:attendance_ubi_device:remove']">删除</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" />
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改宇泛的设备信息对话框 -->
<el-dialog :title="title" v-model="open" width="600px" append-to-body :close-on-click-modal="false" :close-on-press-escape="false">
<el-dialog :title="title" v-model="open" width="600px" append-to-body :close-on-click-modal="false"
:close-on-press-escape="false" class="dlg-hide-form-hidden-scroll">
<el-form ref="attendance_ubi_deviceRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="所属项目">
<el-tag effect="plain">{{ form.projectName }}</el-tag>
@ -101,19 +113,25 @@
</el-form-item>
<el-form-item label="设备来源" prop="source">
<el-select v-model="form.source" placeholder="请选择设备来源" clearable>
<el-option v-for="dict in ubi_device_source" :key="dict.value" :label="dict.label" :value="dict.value" />
<el-option v-for="dict in ubi_device_source" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="设备序列号" prop="deviceNo">
<el-input v-model="form.deviceNo" placeholder="请输入设备序列号" />
</el-form-item>
<el-form-item label="所属工区" prop="workAreaId">
<el-tree-select v-model="form.workAreaId" :data="data.workAreaOptions"
:props="{ value: 'id', label: 'title', children: 'children' }" value-key="id"
placeholder="请选择工区" clearable style="width:300px;" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button type="primary" @click="submitForm" :loading="data.submitLoading"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
@ -132,10 +150,12 @@ import {
} from '@/api/manage/attendanceubidevice'
import useUserStore from '@/store/modules/user'
import { findMyProjectList } from '@/api/publics'
import { workAreaTree, transformTreeData } from '@/api/system/workAarea'
const { proxy } = getCurrentInstance()
const userStore = useUserStore()
const { ubi_device_source } = proxy.useDict('ubi_device_source')
const attendance_ubi_deviceList = ref([])
const workAreaList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
@ -176,10 +196,13 @@ const data = reactive({
tag: [{ required: true, trigger: ['blur', 'change'], message: '请输入设备标签' }],
source: [{ required: true, trigger: ['blur', 'change'], message: '请选择设备来源' }],
deviceNo: [{ required: true, trigger: ['blur', 'change'], message: '请输入设备序列号' }],
workAreaId: [{ required: false, trigger: 'blur', message: '请选择所属工区' }],
},
projects: [],
currentPrjId: '',
mode: '',
workAreaOptions: [],
submitLoading: false,
})
const { queryParams, form, rules } = toRefs(data)
@ -248,6 +271,7 @@ function reset() {
state: null,
remark: null,
isDel: null,
workAreaId: null,
createBy: null,
createTime: null,
updateBy: null,
@ -309,17 +333,22 @@ function submitForm() {
proxy.$refs['attendance_ubi_deviceRef'].validate((valid) => {
if (valid) {
form.value.comId = userStore.currentComId
data.submitLoading = true
if (form.value.id != null) {
updateAttendance_ubi_device(form.value).then((response) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
}).finally(() => {
data.submitLoading = false
})
} else {
addAttendance_ubi_device(form.value).then((response) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getList()
}).finally(() => {
data.submitLoading = false
})
}
}
@ -338,7 +367,7 @@ function handleDelete(row) {
getList()
proxy.$modal.msgSuccess('删除成功')
})
.catch(() => {})
.catch(() => { })
}
/** 导出按钮操作 */
@ -351,7 +380,16 @@ function handleExport() {
`attendance_ubi_device_${new Date().getTime()}.xlsx`
)
}
/** 查询工区树结构 */
function getWorkAreaTree() {
workAreaTree(userStore.currentPrjId).then(response => {
// el-tree-select
data.workAreaOptions = transformTreeData(response.data);
});
}
getList()
getProjectList()
getWorkAreaTree()
</script>

View File

@ -8,28 +8,30 @@
</el-row>
<el-table v-loading="loading" :data="attendance_ubi_deviceList" @selection-change="handleSelectionChange">
<el-table-column type="index" width="50" label="序号"/>
<el-table-column label="公司" align="center" prop="compName" v-if="1==2"/>
<el-table-column type="index" width="50" label="序号" />
<el-table-column label="公司" align="center" prop="compName" v-if="1 == 2" />
<el-table-column label="所属项目" align="center" prop="projectName" />
<el-table-column label="所属工区" align="center" prop="workAreaName" />
<el-table-column label="设备序列号" align="center" prop="deviceNo">
<template #default="scope"><span style="color: var(--el-color-warning);">{{scope.row.deviceNo}}</span></template>
<template #default="scope"><span style="color: var(--el-color-warning);">{{ scope.row.deviceNo
}}</span></template>
</el-table-column>
<el-table-column label="通道编号" align="center" prop="channel" />
<el-table-column label="方向" align="center" prop="direction">
<template #default="scope">
{{ scope.row.direction==0?'进':'出' }}
{{ scope.row.direction == 0 ? '进' : '出' }}
</template>
</el-table-column>
</el-table-column>
<el-table-column label="用途" align="center" prop="tag" />
<el-table-column label="设备模式" align="center" prop="deviceModel" v-if="false" />
<el-table-column label="设备状态" align="center" prop="deviceState" v-if="false" >
<el-table-column label="设备状态" align="center" prop="deviceState" v-if="false">
<template #default="scope">
<span v-if="scope.row.deviceState == 1"></span>
<span v-if="scope.row.deviceState == 2"></span>
<span v-if="scope.row.deviceState == 3"></span>
</template>
</el-table-column>
<el-table-column label="比对模式" align="center" prop="recType" v-if="false" >
<el-table-column label="比对模式" align="center" prop="recType" v-if="false">
<template #default="scope">
<span v-if="scope.row.recType == 1"></span>
<span v-if="scope.row.recType == 2"></span>
@ -38,19 +40,23 @@
<el-table-column label="在线状态" align="center" prop="onlineState">
<template #default="scope">
<span v-if="scope.row.onlineState == 1" style="color:green;">
<el-icon style="vertical-align: middle;"><SuccessFilled /></el-icon>
<el-icon style="vertical-align: middle;">
<SuccessFilled />
</el-icon>
在线</span>
<span v-if="scope.row.onlineState == 2" style="color: red;">
<el-icon style="vertical-align: middle;"><CircleCloseFilled /></el-icon>线</span>
<el-icon style="vertical-align: middle;">
<CircleCloseFilled />
</el-icon>线</span>
</template>
</el-table-column>
<el-table-column label="版本号" align="center" prop="versionNo" v-if="false" />
<el-table-column label="最后激活时间" align="center" prop="lastActiveTime" width="180" v-if="false" >
<el-table-column label="最后激活时间" align="center" prop="lastActiveTime" width="180" v-if="false">
<template #default="scope">
<span>{{ parseTime(scope.row.lastActiveTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="注册状态" align="center" prop="hasRegister" v-if="false" >
<el-table-column label="注册状态" align="center" prop="hasRegister" v-if="false">
<template #default="scope">
<span v-if="scope.row.onlineState == 1"></span>
<span v-else></span>
@ -58,7 +64,7 @@
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="150">
<template #default="scope">
<el-button link type="primary" icon="ChromeFilled" @click="handleAuth(scope.row)" v-if="1==2"
<el-button link type="primary" icon="ChromeFilled" @click="handleAuth(scope.row)" v-if="1 == 2"
v-hasPermi="['manage:attendance_ubi_device:edit']">同步</el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
v-hasPermi="['manage:attendance_ubi_device:edit']">修改</el-button>
@ -79,15 +85,14 @@
<el-tag effect="plain">{{ form.projectName }}</el-tag>
</el-form-item>
<el-form-item label="设备序列号" prop="deviceNo">
<el-input v-model="form.deviceNo" :disabled="data.mode=='edit'" placeholder="请输入设备序列号" />
</el-form-item>
<el-input v-model="form.deviceNo" :disabled="data.mode == 'edit'" placeholder="请输入设备序列号" />
</el-form-item>
<el-form-item label="通道编号" prop="channel">
<el-input v-model="form.channel" placeholder="请输入通道编号" />
</el-form-item>
</el-form-item>
<el-form-item label="设备用途" prop="tag">
<el-select v-model="form.tag" placeholder="请选择设备用途" clearable>
<el-option v-for="(dict,idx) in ['','']" :key="idx" :label="dict"
:value="dict" />
<el-option v-for="(dict, idx) in ['', '']" :key="idx" :label="dict" :value="dict" />
</el-select>
</el-form-item>
@ -97,14 +102,20 @@
<el-radio :value="1" :label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="设备来源" prop="source" v-if="1==2">
<el-form-item label="设备来源" prop="source" v-if="1 == 2">
<el-select v-model="form.source" placeholder="请选择设备来源" clearable>
<el-option v-for="dict in ubi_device_source" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="所属工区" prop="workAreaId" v-if="false">
<el-select v-model="form.workAreaId" placeholder="请选择工区" clearable>
<el-option v-for="workArea in workAreaList" :key="workArea.workAreaId"
:label="workArea.workAreaName" :value="workArea.workAreaId" />
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark" v-if="false">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
@ -128,6 +139,7 @@ const { proxy } = getCurrentInstance();
const { ubi_device_source } = proxy.useDict('ubi_device_source');
const attendance_ubi_deviceList = ref([]);
const workAreaList = ref([]);
const open = ref(false);
const loading = ref(true);
const ids = ref([]);
@ -140,7 +152,7 @@ const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
pageSize: 10,
projectId: null,
},
rules: {
@ -158,25 +170,25 @@ const data = reactive({
const { queryParams, form, rules } = toRefs(data);
/*行进场,离场操作 */
function handleEnter(row){
function handleEnter(row) {
}
/**
* 设备人员同步
*/
function handleAuth(row){
authAttendance_ubi_device(row).then(d=>{
if(d.code==200){
proxy.$modal.msgSuccess("同步成功!");
}else{
proxy.$modal.msgError("同步失败!");
}
});
function handleAuth(row) {
authAttendance_ubi_device(row).then(d => {
if (d.code == 200) {
proxy.$modal.msgSuccess("同步成功!");
} else {
proxy.$modal.msgError("同步失败!");
}
});
}
/** 查询宇泛的设备信息列表 */
function getList() {
queryParams.value.projectId=data.row.projectId
queryParams.value.projectId = data.row.projectId
loading.value = true;
listAttendance_ubi_device(queryParams.value).then(response => {
attendance_ubi_deviceList.value = response.rows;
@ -187,135 +199,138 @@ function getList() {
//
function cancel() {
open.value = false;
reset();
open.value = false;
reset();
}
//
function reset() {
form.value = {
id: null,
comId: null,
projectId: null,
name: null,
tag: '考勤',
direction:0,
channel:'',
sceneGuid: "",
source: null,
deviceNo: null,
addition: null,
bindDefaultScene: null,
forceEmptyDevice: null,
password: null,
deviceModel: null,
deviceState: null,
recType: null,
onlineState: null,
versionNo: null,
lastActiveTime: null,
hasRegister: null,
state: null,
remark: null,
isDel: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
proxy.resetForm("attendance_ubi_deviceRef");
form.value = {
id: null,
comId: null,
projectId: null,
name: null,
tag: '考勤',
direction: 0,
channel: '',
sceneGuid: "",
source: null,
deviceNo: null,
addition: null,
bindDefaultScene: null,
forceEmptyDevice: null,
password: null,
deviceModel: null,
deviceState: null,
recType: null,
onlineState: null,
versionNo: null,
lastActiveTime: null,
hasRegister: null,
state: null,
remark: null,
isDel: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
workAreaId: null
};
proxy.resetForm("attendance_ubi_deviceRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
proxy.resetForm("queryRef");
handleQuery();
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
ids.value = selection.map(item => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
data.mode="add"
form.value.projectId = data.row.projectId;
form.value.projectName = data.row.projectName;
form.value.source=ubi_device_source.value[0].value;
open.value = true;
title.value = "添加宇泛的设备信息";
function handleAdd() {
reset();
data.mode = "add"
form.value.projectId = data.row.projectId;
form.value.projectName = data.row.projectName;
form.value.source = ubi_device_source.value[0].value;
open.value = true;
title.value = "添加宇泛的设备信息";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
data.mode="edit"
const _id = row.id || ids.value
getAttendance_ubi_device(_id).then(response => {
form.value = response.data;
open.value = true;
title.value = "修改宇泛的设备信息";
});
function handleUpdate(row) {
reset();
data.mode = "edit"
const _id = row.id || ids.value
getAttendance_ubi_device(_id).then(response => {
form.value = response.data;
open.value = true;
title.value = "修改宇泛的设备信息";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["attendance_ubi_deviceRef"].validate(valid => {
if (valid) {
form.value.comId=data.row.comId;
form.value.name=form.value.deviceNo;
if (form.value.id != null) {
updateAttendance_ubi_device(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addAttendance_ubi_device(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
proxy.$refs["attendance_ubi_deviceRef"].validate(valid => {
if (valid) {
form.value.comId = data.row.comId;
form.value.name = form.value.deviceNo;
if (form.value.id != null) {
updateAttendance_ubi_device(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addAttendance_ubi_device(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _ids = row.id || ids.value;
proxy.$modal.confirm('是否确认删除宇泛的设备信息编号为"' + _ids + '"的数据项?').then(function () {
return delAttendance_ubi_device(_ids);
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => { });
const _ids = row.id || ids.value;
proxy.$modal.confirm('是否确认删除宇泛的设备信息编号为"' + _ids + '"的数据项?').then(function () {
return delAttendance_ubi_device(_ids);
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => { });
}
function showDrawer(row) {
data.row = row;
data.show = true;
getList();
getList();
}
defineExpose({
showDrawer
})
</script>
<style lang="scss">
.ubi-device-drawer{
.el-drawer__header{
.ubi-device-drawer {
.el-drawer__header {
margin-bottom: 0px;
}
}</style>
}
</style>

View File

@ -1,36 +1,13 @@
<template>
<div class="app-container">
<el-form v-if="false" :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="${comment}" prop="comId">
<el-input v-model="queryParams.comId" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="${comment}" prop="projectId">
<el-input v-model="queryParams.projectId" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="监控名称" prop="monitorName">
<el-input v-model="queryParams.monitorName" placeholder="请输入监控名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="AppKey" prop="appkey">
<el-input v-model="queryParams.appkey" placeholder="请输入AppKey" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="Secret" prop="secret">
<el-input v-model="queryParams.secret" placeholder="请输入Secret" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="设备厂商" prop="manufacturer">
<el-input v-model="queryParams.manufacturer" placeholder="请输入设备厂商" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="是否关键点" prop="keyPoint">
<el-input v-model="queryParams.keyPoint" placeholder="请输入是否关键点" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="${comment}" prop="state">
<el-input v-model="queryParams.state" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="${comment}" prop="isDel">
<el-input v-model="queryParams.isDel" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="${comment}" prop="upadteTime">
<el-date-picker clearable v-model="queryParams.upadteTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择${comment}"></el-date-picker>
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"
v-if="data.workAreaOptions && data.workAreaOptions.length > 0">
<el-form-item label="所属工区" prop="workAreaAncestors">
<el-tree-select v-model="queryParams.workAreaAncestors" :data="data.workAreaOptions"
:props="{ value: 'id', label: 'title', children: 'children' }" value-key="id" placeholder="请选择工区"
clearable style="width: 240px" check-strictly />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
@ -39,7 +16,8 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['manage:videoMonitor:add']"></el-button>
<el-button type="primary" plain icon="Plus" @click="handleAdd"
v-hasPermi="['manage:videoMonitor:add']">新增</el-button>
</el-col>
<!--
<el-col :span="1.5">
@ -61,22 +39,28 @@
<el-table v-loading="loading" :data="videoMonitorList" @selection-change="handleSelectionChange">
<el-table-column label="监控名称" align="center" prop="monitorName" />
<el-table-column label="项目名称" align="center" prop="projectName" />
<el-table-column label="工区" align="center" prop="workAreaName"
v-if="data.workAreaOptions && data.workAreaOptions.length > 0" />
<el-table-column label="链接" align="center" prop="url" />
<el-table-column label="萤石云AppKey" align="center" prop="appkey" />
<el-table-column label="萤石云Secret" align="center" prop="secret" />
<el-table-column label="设备厂商" align="center" prop="manufacturer" />
<el-table-column label="是否重点" align="center" prop="keyPoint">
<template #default="scope">{{scope.row.keyPoint==1?'是':'否' }}</template>
<template #default="scope">{{ scope.row.keyPoint == 1 ? '是' : '否' }}</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160px">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['manage:videoMonitor:edit']"></el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['manage:videoMonitor:remove']"></el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
v-hasPermi="['manage:videoMonitor:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
v-hasPermi="['manage:videoMonitor:remove']">删除</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" />
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改延迟摄影管理对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
@ -115,7 +99,8 @@
<el-input v-model="form.isDel" placeholder="请输入${comment}" />
</el-form-item>
<el-form-item label="${comment}" prop="upadteTime">
<el-date-picker clearable v-model="form.upadteTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择${comment}"></el-date-picker>
<el-date-picker clearable v-model="form.upadteTime" type="date" value-format="YYYY-MM-DD"
placeholder="请选择${comment}"></el-date-picker>
</el-form-item>
</el-form>
<template #footer>
@ -131,6 +116,7 @@
<script setup name="VideoMonitor">
import { listVideoMonitor, getVideoMonitor, delVideoMonitor, addVideoMonitor, updateVideoMonitor } from '@/api/manage/videoMonitor'
import { workAreaTree, transformTreeData } from '@/api/system/workAarea'
import useUserStore from '@/store/modules/user'
import videoMonitorDrawer from './videoMonitorDrawer.vue'
const { proxy } = getCurrentInstance()
@ -151,8 +137,9 @@ const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
comId: null,
projectId: null,
workAreaAncestors: '',
comId: userStore.currentComId,
projectId: userStore.currentPrjId,
monitorName: null,
monitorType: null,
url: null,
@ -165,14 +152,51 @@ const data = reactive({
upadteTime: null,
},
rules: {},
//
workAreaOptions: [],
})
const { queryParams, form, rules } = toRefs(data)
/** 查询工区树结构 */
function getWorkAreaTree() {
workAreaTree(userStore.currentPrjId).then(response => {
// el-tree-select
data.workAreaOptions = transformTreeData(response.data);
});
}
/** 查找树节点 */
function findTreeNode(nodes, id) {
for (let node of nodes) {
if (node.id === id) {
return node;
}
if (node.children && node.children.length > 0) {
const found = findTreeNode(node.children, id);
if (found) return found;
}
}
return null;
}
/** 查询延迟摄影管理列表 */
function getList() {
loading.value = true
queryParams.value.projectId = userStore.currentPrjId
// workAreaAncestors
if (queryParams.value.comId) {
// queryParamsworkAreaAncestors
// ancestors
const selectedNode = findTreeNode(data.workAreaOptions, queryParams.value.comId);
if (selectedNode && selectedNode.ancestors) {
queryParams.value.workAreaAncestors = selectedNode.ancestors;
}
} else {
delete queryParams.value.workAreaAncestors; //
}
listVideoMonitor(queryParams.value).then((response) => {
videoMonitorList.value = response.rows
total.value = response.total
@ -290,7 +314,7 @@ function handleDelete(row) {
getList()
proxy.$modal.msgSuccess('删除成功')
})
.catch(() => {})
.catch(() => { })
}
/** 导出按钮操作 */
@ -304,5 +328,8 @@ function handleExport() {
)
}
//
getWorkAreaTree();
//
getList()
</script>

View File

@ -9,17 +9,25 @@
</el-select>
</el-form-item>
</el-form>
<el-row v-if="data.selPrjId" class="video-main" :class="!data.currentPrjId?'show-prjs':''">
<el-row v-if="data.selPrjId" class="video-main" :class="!data.currentPrjId ? 'show-prjs' : ''">
<el-col :span="4" class="video-name-list">
<div class="video-title command" @click="showAllVideo"></div>
<div class="video-list">
<div class="video-list" v-if="!data.showTree">
<div v-for="it in data.videoMonitors" :key="it.id" class="video-item command"
:class="it.active ? 'is-active' : ''" @click="doSelectItem(it)">
<svg-icon class-name="video-icon" icon-class="video" /> {{ it.monitorName }}
</div>
</div>
<div v-else class="video-tree">
<el-tree ref="treeRef" :data="data.treeData" :props="{ label: 'label', children: 'children' }"
highlight-current node-key="id" @node-click="handleTreeNodeClick" :class="'video-tree'">
<template #default="{ node, data }"> <span v-if="data.vdata" class="tree-node-content">
<svg-icon class-name="video-icon" icon-class="video" />{{ node.label }}</span> <span
v-else class="tree-node-content">{{ node.label }}</span> </template>
</el-tree>
</div>
</el-col>
<el-col :span="20" :key="data.elKey" style="height: 100%;">
<el-col :span="20" :key="data.elKey" style="height: 100%;padding-left: 4px;">
<template v-if="data.showMode == 'sigle'">
<iframe v-if="data.selVideo" frameborder="0" :src="data.selVideo.iframeSrc"
style="width:100%;height:100%;" id="ysOpenDevice" allowfullscreen>
@ -33,11 +41,13 @@
:class="data.showSize != data.mode1 ? 'is-active' : ''" icon-class="9screen" />
</div>
<div class="all-list" :class="data.showSize == data.mode1 ? 'mode1' : 'mode2'">
<div class="all-item command" v-for="it in data.showList" :key="it.id" >
<div class="all-item command" v-for="it in data.showList" :key="it.id">
<iframe frameborder="0" :src="it.iframeSrc" style="width:100%;height:calc(100% - 30px);"
id="ysOpenDevice" allowfullscreen>
</iframe>
<div class="command" @click="doSelectItem(it)" style="text-align: center;height: 30px; line-height: 30px;">{{ it.monitorName }}</div>
<div class="command" @click="doSelectItem(it)"
style="text-align: center;height: 30px; line-height: 30px;">
{{ it.monitorName }}</div>
</div>
</div>
<div class="all-pager">
@ -57,11 +67,13 @@ import {
getYsToken
} from "@/api/manage/videoMonitor";
import useUserStore from '@/store/modules/user'
import { workAreaTree } from '@/api/system/workAarea'
const userStore = useUserStore()
const { proxy } = getCurrentInstance();
const treeRef = ref(null);
const data = reactive({
mode1:4,
mode2:9,
mode1: 4,
mode2: 9,
prjInfo: null,
projects: [],
selPrjId: '',
@ -75,6 +87,8 @@ const data = reactive({
showSize: 4,
showIndex: 1,
showList: [],
workAreaOptions: [],
treeData: []
})
function loadVideo(it) {
getYsToken(it.id).then(d => {
@ -83,17 +97,48 @@ function loadVideo(it) {
})
}
/** 查询工区树结构 */
function getWorkAreaTree() {
workAreaTree(userStore.currentPrjId).then(response => {
// el-tree-select
data.workAreaOptions = response.data || [];
if (data.videoMonitors.filter(d => d.workAreaId).length > 0) {
// makeTreevideoMonitors
data.treeData = makeTree();
if (data.treeData.length > 0) {
data.showTree = true;
setTimeout(() => {
handleTreeNodeClick(data.treeData[0]);
// 使ref使
nextTick(() => {
if (treeRef.value) {
treeRef.value.setCurrentKey(data.treeData[0].id);
}
});
}, 400);
} else {
data.showTree = false;
}
} else {
data.treeData = [];
data.showTree = false;
}
});
}
function changeSize(n) {
data.showSize = n;
data.showIndex = 1;
showAllData();
}
function doSelectItem(it) {
if (it.active) {
function doSelectItem(it, reLoad = false) {
if (it.active && !reLoad) {
return;
}
data.showMode = "sigle";
if(data.selVideo){
if (data.selVideo) {
data.selVideo.active = false;
}
data.selVideo = it;
@ -101,7 +146,7 @@ function doSelectItem(it) {
loadVideo(data.selVideo);
}
function showAllVideo() {
if(data.selVideo){
if (data.selVideo) {
data.selVideo.active = false;
}
data.selVideo = null;
@ -141,11 +186,7 @@ function loadData() {
return it;
});
showAllVideo();
//data.selVideo = data.videoMonitors.length > 0 ? data.videoMonitors[0] : null;
//if (data.selVideo) {
// data.selVideo.active = true;
// loadVideo(data.selVideo);
//}
getWorkAreaTree();
});
}
/** 查询项目列表 */
@ -161,6 +202,138 @@ function getProjectList() {
});
}
getProjectList();
function makeTree() {
const videoMonitorMap = {};
let defNode = {
id: '',
label: '默认工区',
type: 'workArea',
children: []
}
data.videoMonitors.forEach(video => {
if (video.workAreaId) {
if (!videoMonitorMap[video.workAreaId]) {
videoMonitorMap[video.workAreaId] = [];
}
videoMonitorMap[video.workAreaId].push(video);
} else {
defNode.children.push({
id: video.id,
label: video.monitorName,
vdata: video,
type: 'workArea',
children: []
});
}
});
// videoMonitors
function attachVideoMonitors(nodes) {
if (!nodes || !Array.isArray(nodes)) return [];
return nodes.map(node => {
//
const newNode = JSON.parse(JSON.stringify(node));
// videoMonitors
if (videoMonitorMap[node.id] && videoMonitorMap[node.id].length > 0) {
if (!newNode.children) {
newNode.children = [];
}
// videoMonitors
videoMonitorMap[node.id].forEach(video => {
newNode.children.push({
id: video.id,
label: video.monitorName,
type: 'workArea',
vdata: video,
children: []
});
});
}
//
if (newNode.children && newNode.children.length > 0) {
newNode.children = attachVideoMonitors(newNode.children);
}
return newNode;
});
}
// videoMonitors(treeNodetypeworkArea)
function pruneEmptyNodes(nodes) {
if (!nodes || !Array.isArray(nodes)) return [];
const result = [];
for (const node of nodes) {
//
const newNode = { ...node };
// videoMonitorsdata
const hasDirectVideoMonitors = node.children && node.children.some(child => child.data && child.type === 'workArea');
//
if (node.children && node.children.length > 0) {
newNode.children = pruneEmptyNodes(node.children);
}
//
// 1. videoMonitors
// 2. videoMonitors
if (hasDirectVideoMonitors || (newNode.children && newNode.children.length > 0) || newNode.type === 'workArea') {
result.push(newNode);
}
}
return result;
}
//
const workAreaOptionsCopy = JSON.parse(JSON.stringify(data.workAreaOptions));
const treeWithVideos = attachVideoMonitors(workAreaOptionsCopy);
const prunedTree = pruneEmptyNodes(treeWithVideos);
//
if (defNode.children && defNode.children.length > 0) {
return [defNode, ...prunedTree];
}
return prunedTree;
}
function handleTreeNodeClick(node) {
// data
if (node.vdata) {
doSelectItem(node.vdata, true);
} else {
//
let videoNodes = [];
function getVideoNodes(nodes) {
if (!nodes || !Array.isArray(nodes)) return [];
nodes.forEach(node => {
if (node.vdata) {
videoNodes.push(node);
}
if (node.children && node.children.length > 0) {
getVideoNodes(node.children);
}
});
}
getVideoNodes(node.children);
let videoList = videoNodes.map(d => d.vdata);
data.videoMonitors = videoList;
if (videoList.length > 1) {
data.showMode = 'all';
showAllData();
} else {
data.showMode = 'single';
doSelectItem(videoList[0], true);
}
}
}
</script>
<style lang="scss">
@ -169,12 +342,15 @@ getProjectList();
position: absolute;
width: 100%;
padding: 12px;
.video-main{
.video-main {
height: 100%;
&.show-prjs{
&.show-prjs {
height: calc(100% - 40px);
}
}
.video-name-list {
height: 100%;
background: #fff;
@ -228,25 +404,25 @@ getProjectList();
}
.all-list {
display:grid;
display: grid;
grid-gap: 10px;
height: calc(100% - 80px);
&.mode1{
grid-template-columns: 50% 50%;
grid-template-rows: 50% 50%;
.all-item{
}
}
&.mode2{
grid-template-columns: 33% 33% 33%;
grid-template-rows: 33% 33% 33%;
.all-item{
}
&.mode1 {
grid-template-columns: 50% 50%;
grid-template-rows: 50% 50%;
.all-item {}
}
&.mode2 {
grid-template-columns: 33% 33% 33%;
grid-template-rows: 33% 33% 33%;
.all-item {}
}
}
.all-pager {
@ -256,5 +432,37 @@ getProjectList();
}
}
.video-tree {
width: 100%;
height: 100%;
.tree-node-content {
display: inline-block;
width: 100%;
padding: 2px 4px;
cursor: pointer;
border-radius: 4px;
transition: background-color 0.2s;
&:hover {
background-color: transparent;
}
}
.el-tree-node:focus>.el-tree-node__content {
background-color: #e6f7ff;
}
.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
background-color: #409eff;
color: white;
.el-tree-node__expand-icon,
.el-icon-arrow-right,
.el-icon-arrow-down {
color: white;
}
}
}
}
</style>

View File

@ -1,9 +1,12 @@
<template>
<el-drawer class="video-monitor-drawer" v-if="data.isOpen" v-model="data.isOpen" direction="rtl" size="50%" style="padding-left: 20px" :title="data.title">
<el-drawer class="video-monitor-drawer" v-if="data.isOpen" v-model="data.isOpen" direction="rtl" size="50%"
style="padding-left: 20px" :title="data.title">
<el-form ref="videoMonitorRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="项目名称" prop="projectId">
<el-select :disabled="data.currentPrjId != ''||data.type=='edit'" v-model="form.projectId" placeholder="请选择项目" clearable style="width:300px;">
<el-option v-for="prj in data.projects" :key="prj.id" :label="prj.projectName" :value="prj.id"></el-option>
<el-select :disabled="data.currentPrjId != '' || data.type == 'edit'" v-model="form.projectId"
placeholder="请选择项目" clearable style="width:300px;">
<el-option v-for="prj in data.projects" :key="prj.id" :label="prj.projectName"
:value="prj.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="监控名称" prop="monitorName">
@ -32,6 +35,11 @@
<el-option label="否" value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="工区" prop="workAreaId">
<el-tree-select v-model="form.workAreaId" :data="data.workAreaOptions"
:props="{ value: 'id', label: 'title', children: 'children' }" value-key="id" placeholder="请选择工区"
clearable style="width:300px;" />
</el-form-item>
</el-form>
<div style="text-align: center;">
<el-button type="primary" @click="doSave"></el-button>
@ -43,6 +51,7 @@
<script setup>
import { listVideoMonitor, getVideoMonitor, delVideoMonitor, addVideoMonitor, updateVideoMonitor } from '@/api/manage/videoMonitor'
import { findMyProjectList } from '@/api/publics'
import { workAreaTree, transformTreeData } from '@/api/system/workAarea'
import useUserStore from '@/store/modules/user'
const $emit = defineEmits('success')
const userStore = useUserStore()
@ -54,7 +63,7 @@ const rules = reactive({
monitorType: [{ required: true, trigger: ['blur', 'change'], message: '请选择监控类型' }],
url: [{ required: true, trigger: ['blur', 'change'], message: '请输入监控链接' }],
appkey: [{ required: true, trigger: ['blur', 'change'], message: '请输入萤石云AppKey' }],
secret: [{ required: true, trigger: ['blur', 'change'], message: '请输入萤石云Secret' }],
secret: [{ required: true, trigger: ['blur', 'change'], message: '请输入萤石云Secret' }]
})
const data = reactive({
isOpen: false,
@ -64,6 +73,7 @@ const data = reactive({
currentPrjId: '',
editRow: null,
comId: '',
workAreaOptions: [],
})
function showDrawer(opt) {
@ -101,6 +111,16 @@ function getSelectProject() {
return objs.length > 0 ? objs[0] : { id: data.currentPrjId, comId: userStore.currentComId }
}
/** 查询工区树结构 */
function getWorkAreaTree() {
workAreaTree(userStore.currentPrjId).then(response => {
// el-tree-select
data.workAreaOptions = transformTreeData(response.data);
});
}
function doSave() {
proxy.$refs['videoMonitorRef'].validate((valid) => {
if (valid) {
@ -127,6 +147,7 @@ function doCancel() {
data.isOpen = false
}
getProjectList()
getWorkAreaTree()
defineExpose({
showDrawer,
})

View File

@ -0,0 +1,155 @@
<template>
<el-dialog :title="title" v-model="dialogVisible" width="500px" append-to-body class="dlg-hide-form-hidden-scroll">
<el-form ref="workAareaRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="父区域" v-if="data.row && data.row.parentId!=0">
{{ data.row.fullPath }}
</el-form-item>
<el-form-item label="工区名称" prop="title">
<el-input v-model="form.title" placeholder="请输入工区名称" />
</el-form-item>
<el-form-item :label="data.row && data.row.parentId!=0?'区域编号':'防护等级'" prop="level">
<el-input v-model="form.level" placeholder="请输入防护等级" />
</el-form-item>
<el-form-item label="排序" prop="orderNum">
<el-input v-model="form.orderNum" placeholder="请输入排序" />
</el-form-item>
<el-form-item label="状态" prop="state">
<el-switch v-model="form.state" :active-value="1" :inactive-value="0" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive, toRefs, nextTick } from 'vue';
import { ElMessage } from 'element-plus';
import { addWorkAarea, updateWorkAarea } from '@/api/system/workAarea';
import useUserStore from "@/store/modules/user";
const emit = defineEmits(['confirm', 'cancel']);
const dialogVisible = ref(false);
const workAareaRef = ref();
const title = ref('');
const action = ref(''); // 'add' or 'edit'
const userStore = useUserStore();
const data = reactive({
isAdd:true,
row:null,
form: {
id: null,
comId: userStore.currentComId,
projectId: userStore.currentPrjId,
parentId: 0,
ancestors: null,
title: null,
level: null,
orderNum: 1,
state: 1,
remark: null,
delFlag: 0
},
rules: {
title: [
{ required: true, message: "工区名称不能为空", trigger: "blur" }
]
}
});
const { form, rules } = toRefs(data);
/** 表单重置 */
function reset(row) {
form.value = {
id: null,
comId: userStore.currentComId,
projectId: userStore.currentPrjId,
parentId: row?.id||0,
ancestors: row?.ancestors || null,
title: '',
level: '',
orderNum: 1,
state: 1,
remark: '',
delFlag: 0
};
nextTick(() => {
if (workAareaRef.value) {
workAareaRef.value.clearValidate();
}
});
}
/** 打开对话框 */
function openDialog(row = null,mode='add') {
data.isAdd = mode === 'add';
data.row = row;
reset(row);
if (!data.isAdd) {
//
title.value = "修改工区管理";
action.value = 'edit';
// rowform
Object.assign(form.value, JSON.parse(JSON.stringify(row)));
} else {
//
title.value = "添加工区管理";
action.value = 'add';
}
dialogVisible.value = true;
}
/** 关闭对话框 */
function closeDialog() {
dialogVisible.value = false;
}
/** 提交表单 */
async function submitForm() {
if (workAareaRef.value) {
const valid = await workAareaRef.value.validate().catch(() => false);
if (valid) {
try {
let response;
if (action.value === 'edit') {
//
response = await updateWorkAarea(form.value);
ElMessage.success("修改成功");
} else {
//
response = await addWorkAarea(form.value);
ElMessage.success("新增成功");
}
dialogVisible.value = false;
emit('confirm', { action: action.value, data: response });
} catch (error) {
const actionText = action.value === 'edit' ? '修改' : '新增';
ElMessage.error(`${actionText}失败: ${error.message || '未知错误'}`);
}
}
}
}
/** 取消 */
function cancel() {
dialogVisible.value = false;
emit('cancel');
}
// 使
defineExpose({
openDialog,
closeDialog
});
</script>
<style scoped>
.dialog-footer {
text-align: right;
}
</style>

View File

@ -0,0 +1,220 @@
<template>
<div class="work-area-main app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="工区名称" prop="title">
<el-input v-model="queryParams.title" placeholder="请输入工区名称" clearable @keyup.enter="handleQuery" />
</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-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd"
v-hasPermi="['system:workAarea:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
v-hasPermi="['system:workAarea:remove']">删除</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="workAareaList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="工区名称" align="center" prop="title" />
<el-table-column label="防护等级" align="center" prop="level" />
<el-table-column label="排序" align="center" prop="orderNum" />
<el-table-column label="状态" align="center" prop="state" />
<el-table-column label="创建时间" align="center" prop="createTime" />
<el-table-column label="创建人" align="center" prop="createBy" />
<el-table-column label="操作" align="center" width="240">
<template #default="scope">
<el-button link type="primary" @click="handleAddChild(scope.row)"
v-hasPermi="['system:workAarea:query']">子区域</el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
v-hasPermi="['system:workAarea:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
v-hasPermi="['system:workAarea:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
<workAreaDrawer ref="workAreaDrawerRef" />
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" />
<WorkAreaDialog ref="workAreaDialogRef" @confirm="onDialogConfirm" @cancel="onDialogCancel" />
</div>
</template>
<script setup name="WorkAarea">
import { listWorkAarea, getWorkAarea, delWorkAarea, addWorkAarea, updateWorkAarea } from "@/api/system/workAarea";
import WorkAreaDialog from './WorkAreaDialog.vue';
import useUserStore from "@/store/modules/user";
import workAreaDrawer from "./workAreaDrawer.vue";
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
const workAareaList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const workAreaDialogRef = ref();
const workAreaDrawerRef = ref(null);
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
comId: userStore.currentComId,
projectId: userStore.currentPrjId,
parentId: 0,
ancestors: null,
title: null,
level: null,
orderNum: null,
state: null,
},
rules: {
title: [
{ required: true, message: "工区名称不能为空", trigger: "blur" }
]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询工区管理列表 */
function getList() {
loading.value = true;
listWorkAarea(queryParams.value).then(response => {
workAareaList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
function handleAddChild(row) {
workAreaDrawerRef.value.showDrawer(row);
}
//
function cancel() {
open.value = false;
reset();
}
//
function reset() {
form.value = {
id: null,
comId: userStore.currentComId,
projectId: userStore.currentPrjId,
parentId: null,
ancestors: null,
title: null,
level: null,
orderNum: 1,
state: 1,
remark: null,
delFlag: 0
};
proxy.resetForm("workAareaRef");
}
/** 对话框确认事件 */
function onDialogConfirm({ action, data }) {
proxy.$modal.msgSuccess(action === 'add' ? "新增成功" : "修改成功");
getList();
}
/** 对话框取消事件 */
function onDialogCancel() {
//
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
if (workAreaDialogRef.value) {
workAreaDialogRef.value.openDialog(null,'add');
}
}
/** 修改按钮操作 */
function handleUpdate(row) {
if (workAreaDialogRef.value) {
workAreaDialogRef.value.openDialog(row,'edit');
}
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["workAareaRef"].validate(valid => {
if (valid) {
if (form.value.id != null) {
updateWorkAarea(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addWorkAarea(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _ids = row.id || ids.value;
proxy.$modal.confirm('是否确认删除工区管理编号为"' + _ids + '"的数据项?').then(function () {
return delWorkAarea(_ids);
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => { });
}
/** 导出按钮操作 */
function handleExport() {
proxy.download('system/workAarea/export', {
...queryParams.value
}, `workAarea_${new Date().getTime()}.xlsx`)
}
getList();
</script>

View File

@ -0,0 +1,180 @@
<template>
<el-drawer v-model="open" :title="title" size="60%" class="p-y-0 area-worker-drawer">
<div class="p-y-1">
<el-button type="success" class="mb-1" @click="handleAddRoot"></el-button>
<el-table v-loading="loading" :data="workAreaList" row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
<el-table-column label="工区名称" prop="title" width="200" />
<el-table-column label="区域编号" prop="level" width="200" />
<el-table-column label="操作" width="280" fixed="right">
<template #default="{ row }">
<el-button link type="primary" icon="Plus" @click="handleAddChild(row)"
v-hasPermi="['system:workAarea:add']">增加子区域</el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(row)"
v-hasPermi="['system:workAarea:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(row)"
v-hasPermi="['system:workAarea:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<WorkAreaDialog ref="workAreaDialogRef" @confirm="onDialogConfirm" @cancel="onDialogCancel" />
</el-drawer>
</template>
<script>
import { listWorkAarea, delWorkAarea } from '@/api/system/workAarea';
import WorkAreaDialog from './WorkAreaDialog.vue';
export default {
name: "WorkAreaDrawer",
components: {
WorkAreaDialog
},
data() {
return {
open: false,
loading: true,
title: '',
workAreaList: [],
row: null
};
},
methods: {
/** 查询工区管理列表 */
getList() {
this.loading = true;
let queryParams = {
ancestors: this.row.id,
projectId: this.row.projectId,
comId: this.row.comId,
pageNum: 1,
pageSize: 10000
};
listWorkAarea(queryParams).then(response => {
this.workAreaList = this.buildTree(response.rows);
this.loading = false;
});
},
/** 构建树形结构 */
buildTree(data) {
const map = {};
const roots = [];
let rootPath = `/${this.row.title}/`
// fullPath
for (let i = 0; i < data.length; i++) {
map[data[i].id] = {
...data[i],
children: [],
fullPath: data[i].title || data[i].name || ''
};
}
//
for (let i = 0; i < data.length; i++) {
let node = map[data[i].id];
if (data[i].parentId && map[data[i].parentId]) {
//
// fullPath
node.fullPath = rootPath + map[data[i].parentId].fullPath + ' / ' + (data[i].title || data[i].name || '');
map[data[i].parentId].children.push(node);
} else {
//
node.fullPath = rootPath + node.fullPath;
roots.push(node);
}
}
return roots;
},
/** 新增根区域 */
handleAddRoot() {
if (this.$refs.workAreaDialogRef) {
//
this.$refs.workAreaDialogRef.openDialog({
...this.row,
comId: this.row.comId,
projectId: this.row.projectId,
parentId: this.row.id,
ancestors: this.row.ancestors ? this.row.ancestors + ',' + this.row.id : this.row.id.toString(),
}, 'add');
}
},
/** 新增子区域 */
handleAddChild(row) {
if (this.$refs.workAreaDialogRef) {
this.$refs.workAreaDialogRef.openDialog({
...row,
fullPath: row.fullPath,
comId: row.comId,
projectId: row.projectId,
parentId: row.id,
ancestors: row.ancestors ? row.ancestors + ',' + row.id : row.id.toString()
});
}
},
/** 修改 */
handleUpdate(row) {
if (this.$refs.workAreaDialogRef) {
this.$refs.workAreaDialogRef.openDialog(row, 'edit');
}
},
/** 删除 */
handleDelete(row) {
this.$modal.confirm('是否确认删除工区管理编号为"' + row.id + '"的数据项?')
.then(() => {
return delWorkAarea(row.id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => { });
},
/** 打开抽屉 */
showDrawer(row = null) {
if (row) {
row.fullPath = '/' + row.title
}
this.row = row;
this.title = row.title;
this.open = true;
this.getList();
},
/** 关闭抽屉 */
closeDrawer() {
this.open = false;
},
/** 对话框确认事件 */
onDialogConfirm({ action, data }) {
this.$modal.msgSuccess(action === 'add' ? "新增成功" : "修改成功");
this.getList();
},
/** 对话框取消事件 */
onDialogCancel() {
//
}
}
}
</script>
<style lang="scss">
.area-worker-drawer {
.el-drawer__header {
margin-bottom: 0px;
}
.el-drawer__body {
padding-top: 0px;
padding-bottom: 0px;
}
}
</style>

View File

@ -39,8 +39,8 @@ export default defineConfig(({ mode, command }) => {
},
// https://cn.vitejs.dev/config/#server-proxy
"/dev-api": {
//target: "http://localhost:8080",
target: "http://62.234.3.186",
target: "http://localhost:8080",
//target: "http://62.234.3.186",
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, ""),
},