移动端可添加大棚。

大棚关联用户,
移动端可邀请用户
master
lld 2026-02-16 01:00:17 +08:00
parent a2b6a770a4
commit c4df5fd9a8
11 changed files with 332 additions and 39 deletions

View File

@ -4,3 +4,7 @@ logging:
level:
com.agri: debug
org.springframework: warn
agri:
manager:
num: 5

View File

@ -4,3 +4,8 @@ logging:
level:
com.agri: info
org.springframework: warn
# 大棚管理者
agri:
manager:
num: 5

View File

@ -7,6 +7,7 @@ import com.agri.common.core.page.TableDataInfo;
import com.agri.common.enums.BusinessType;
import com.agri.common.utils.poi.ExcelUtil;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.vo.AgriInfoView;
import com.agri.system.service.ISysAgriInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
@ -21,6 +22,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/**
* Controller
@ -108,4 +110,23 @@ public class SysAgriInfoController extends BaseController
{
return toAjax(sysAgriInfoService.deleteSysAgriInfoByIds(ids));
}
@PreAuthorize("@ss.hasPermi('assets:agri:list')")
@GetMapping("/findAgriInfoByUser")
public AjaxResult findAgriInfoByUser(SysAgriInfo sysAgriInfo) {
List<AgriInfoView> list = sysAgriInfoService.findAgriInfoByUser(sysAgriInfo);
return success(list);
}
/**
*
* @param sysAgriInfo
* @return
*/
@PreAuthorize("@ss.hasPermi('assets:agri:addAgriFromMobile')")
@GetMapping("/addAgriFromMobile")
public Map<String, Object> addAgriFromMobile(SysAgriInfo sysAgriInfo) {
return success(sysAgriInfoService.addAgriFromMobile(sysAgriInfo));
}
}

View File

@ -128,7 +128,7 @@ public class SysUserAgriController extends BaseController {
@PostMapping("/batchAssociaUser")
public AjaxResult batchAssociaUser(@RequestBody List<SysUserAgri> userList) {
if (CollectionUtils.isNotEmpty(userList) && !userList.isEmpty()) {
Long agriId = userList.get(0).getAgriId();
String agriId = userList.get(0).getAgriId();
if (ObjectUtils.isNotEmpty(agriId)) {
QueryWrapper<SysUserAgri> wrapper = new QueryWrapper<>();
wrapper.eq("agri_id",agriId);

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -37,6 +38,10 @@ public class SysAgriInfo extends BaseEntity
@Excel(name = "大棚名称")
private String agriName;
/** 工作模式 */
@Excel(name = "工作模式")
private Integer workMode;
/** 关联用户ID */
@Excel(name = "关联用户ID")
private Long userId;
@ -45,6 +50,7 @@ public class SysAgriInfo extends BaseEntity
@Excel(name = "告警开关(0-关闭1-开启)")
private Integer alarmStatus;
@TableField(exist = false)
/** 设备状态(0-离线1-在线2-故障) */
@Excel(name = "设备状态(0-离线1-在线2-故障)")
private Integer deviceStatus;
@ -62,6 +68,12 @@ public class SysAgriInfo extends BaseEntity
@Excel(name = "逻辑删除(0-未删1-已删)")
private Integer isDeleted;
/**
* 01
*/
@TableField(exist = false)
private Integer sourceCode;
public void setId(Long id)
{
this.id = id;
@ -152,12 +164,31 @@ public class SysAgriInfo extends BaseEntity
return isDeleted;
}
public Integer getWorkMode() {
return workMode;
}
public void setWorkMode(Integer workMode) {
this.workMode = workMode;
}
public Integer getSourceCode() {
return sourceCode;
}
public void setSourceCode(Integer sourceCode) {
this.sourceCode = sourceCode;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("imei", getImei())
.append("agriName", getAgriName())
.append("workMode", getWorkMode())
.append("userId", getUserId())
.append("alarmStatus", getAlarmStatus())
.append("deviceStatus", getDeviceStatus())

View File

@ -35,8 +35,7 @@ public class SysUserAgri extends BaseEntity
/** 大棚ID */
@Excel(name = "大棚ID")
@JsonSerialize(using = ToStringSerializer.class)
private Long agriId;
private String agriId;
/** 协同用户ID */
@Excel(name = "协同用户ID")
@ -44,15 +43,15 @@ public class SysUserAgri extends BaseEntity
/** 角色3-OWNER/2-ADMIN/1-OPERATOR/0-VIEWER */
@Excel(name = "角色3-OWNER/2-ADMIN/1-OPERATOR/0-VIEWER")
private Long role;
private Integer role;
/** 权限位位运算1=查看 2=控制 4=配置 8=分享/成员管理 16=导出等 */
@Excel(name = "权限位", readConverterExp = "位=运算")
private Long permMask;
private Integer permMask;
/** 状态0=禁用 1=启用 2=待接受邀请 */
@Excel(name = "状态0=禁用 1=启用 2=待接受邀请")
private Long status;
private Integer status;
/** 邀请人用户ID */
@Excel(name = "邀请人用户ID")
@ -71,7 +70,7 @@ public class SysUserAgri extends BaseEntity
/** 版本号(乐观锁) */
@Excel(name = "版本号", readConverterExp = "乐=观锁")
@Version
private Long version;
private Integer version;
@TableField(exist = false)
private SysUser sysUser;
@ -116,12 +115,12 @@ public class SysUserAgri extends BaseEntity
return id;
}
public void setAgriId(Long agriId)
public void setAgriId(String agriId)
{
this.agriId = agriId;
}
public Long getAgriId()
public String getAgriId()
{
return agriId;
}
@ -136,32 +135,23 @@ public class SysUserAgri extends BaseEntity
return userId;
}
public void setRole(Long role)
public void setRole(Integer role)
{
this.role = role;
}
public Long getRole()
public Integer getRole()
{
return role;
}
public void setPermMask(Long permMask)
{
this.permMask = permMask;
}
public Long getPermMask()
{
return permMask;
}
public void setStatus(Long status)
public void setStatus(Integer status)
{
this.status = status;
}
public Long getStatus()
public Integer getStatus()
{
return status;
}
@ -196,16 +186,22 @@ public class SysUserAgri extends BaseEntity
return acceptTime;
}
public void setVersion(Long version)
{
this.version = version;
public Integer getPermMask() {
return permMask;
}
public Long getVersion()
{
public void setPermMask(Integer permMask) {
this.permMask = permMask;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -0,0 +1,50 @@
package com.agri.system.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class AgriInfoView {
/** 主键ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 设备IMEI */
private String imei;
/** 大棚名称 */
private String agriName;
/** 工作模式 */
private Integer workMode;
/** 设备状态(0-离线1-在线2-故障) */
private Integer deviceStatus;
/** 关联用户ID */
private Long userId;
/** ts转换后的正常时间(由服务端转换入库) */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date time;
@JsonSerialize(using = ToStringSerializer.class)
private Long ts;
/** 温度1(℃) */
private BigDecimal temp1;
/** 温度2(℃) */
private BigDecimal temp2;
/** 温度3(℃) */
private BigDecimal temp3;
/** 温度4(℃) */
private BigDecimal temp4;
}

View File

@ -1,6 +1,7 @@
package com.agri.system.mapper;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.vo.AgriInfoView;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
@ -67,4 +68,7 @@ public interface SysAgriInfoMapper extends BaseMapper<SysAgriInfo> {
*/
public List<SysAgriInfo> findAgriByUser(SysAgriInfo sysAgriInfo);
public List<AgriInfoView> findAgriInfoByUser(SysAgriInfo sysAgriInfo);
}

View File

@ -1,9 +1,11 @@
package com.agri.system.service;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.vo.AgriInfoView;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* Service
@ -63,4 +65,7 @@ public interface ISysAgriInfoService extends IService<SysAgriInfo> {
public List<SysAgriInfo> findAgriByUser(SysAgriInfo sysAgriInfo);
public List<AgriInfoView> findAgriInfoByUser(SysAgriInfo sysAgriInfo);
Map<String,Object> addAgriFromMobile(SysAgriInfo sysAgriInfo);
}

View File

@ -1,14 +1,22 @@
package com.agri.system.service.impl;
import com.agri.common.core.domain.entity.SysUser;
import com.agri.common.utils.DateUtils;
import com.agri.common.utils.SecurityUtils;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.SysUserAgri;
import com.agri.system.domain.vo.AgriInfoView;
import com.agri.system.mapper.SysAgriInfoMapper;
import com.agri.system.service.ISysAgriInfoService;
import com.agri.system.service.ISysUserAgriService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.*;
/**
* Service
@ -20,6 +28,12 @@ import java.util.List;
public class SysAgriInfoServiceImpl extends ServiceImpl<SysAgriInfoMapper, SysAgriInfo> implements ISysAgriInfoService
{
@Value("${agri.manager.num}")
private Integer agriManagerNum;
@Autowired
private ISysUserAgriService userAgriService;
/**
*
*
@ -101,4 +115,121 @@ public class SysAgriInfoServiceImpl extends ServiceImpl<SysAgriInfoMapper, SysAg
}
return baseMapper.findAgriByUser(sysAgriInfo);
}
@Override
public List<AgriInfoView> findAgriInfoByUser(SysAgriInfo sysAgriInfo) {
if (!SecurityUtils.isAdmin()) {
sysAgriInfo.setUserId(SecurityUtils.getUserId());
}
return baseMapper.findAgriInfoByUser(sysAgriInfo);
}
/**
* 0 1 userId
* @param sysAgriInfo
* @return
*/
@Override
public Map<String,Object> addAgriFromMobile(SysAgriInfo sysAgriInfo) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("code", 1);
resultMap.put("msg", "添加大棚成功");
Integer sourceCode = sysAgriInfo.getSourceCode();
// 邀请是前端传值,扫码是自己获取
Long userId;
if (sourceCode.equals(0)) {
userId = SecurityUtils.getUserId();
} else {
userId = sysAgriInfo.getUserId();
}
sysAgriInfo.setUserId(userId);
SysAgriInfo agriInfo = super.lambdaQuery()
.eq(SysAgriInfo::getImei, sysAgriInfo.getImei())
.one();
// 默认手动模式
sysAgriInfo.setWorkMode(0);
// 默认关闭告警开关
sysAgriInfo.setAlarmStatus(0);
sysAgriInfo.setIsDeleted(0);
SysUserAgri sysUserAgri = new SysUserAgri();
sysUserAgri.setAgriId(sysAgriInfo.getImei());
sysUserAgri.setUserId(userId);
sysUserAgri.setInviteBy(SecurityUtils.getUserId());
sysUserAgri.setInviteTime(new Date());
sysUserAgri.setRemark("用户所有者绑定");
// 大棚未添加。没有大棚信息就是没有
if (ObjectUtils.isEmpty(agriInfo)) {
int insert = baseMapper.insert(sysAgriInfo);
if (insert > 0 && !SecurityUtils.isAdmin()) {
sysUserAgri.setRole(3);
sysUserAgri.setStatus(1);
sysUserAgri.setAcceptTime(new Date());
userAgriService.save(sysUserAgri);
return resultMap;
}
}
// 管理员无需添加直接返回
if (SecurityUtils.isAdmin()) {
resultMap.put("msg", "添加大棚成功");
return resultMap;
}
/// 1. 大棚已添加
/// 1.当前大棚已添加但未绑定用户
List<SysUserAgri> userAgriList = userAgriService.lambdaQuery()
.eq(SysUserAgri::getAgriId, sysAgriInfo.getImei())
.list();
if (CollectionUtils.isEmpty(userAgriList)) {
sysUserAgri.setRole(3);
sysUserAgri.setStatus(1);
sysUserAgri.setAcceptTime(new Date());
userAgriService.save(sysUserAgri);
resultMap.put("msg", "关联用户成功!");
return resultMap;
}
// 大棚已经扫码 过来只有所有者和非所有者
/// 2.当前大棚已绑定当前用户且又扫了次码
Optional<SysUserAgri> optional = userAgriList.stream()
.filter(userAgri -> userAgri.getUserId().equals(userId)).findFirst();
// 扫码,没关联上大棚,大棚有关联用户,但是没当前用户 提示大棚已被关联
if (Integer.valueOf(0).equals(sourceCode)
&& (!optional.isPresent() || !optional.get().getRole().equals(3))) {
resultMap.put("code", 0);
resultMap.put("msg","当前大棚已被关联,请联系大棚所有者!");
return resultMap;
}
// 扫码或邀请,是关联着者,就应该提示不应重复绑定;
if (optional.isPresent()) {
resultMap.put("code", 0);
resultMap.put("msg","已关联当前大棚,请勿重复绑定!");
if (sourceCode.equals(1)) {
resultMap.put("msg","该用户已被邀请,请勿重复关联!");
}
return resultMap;
}
// ---------扫码场景到此为止,强制返回,避免进入邀请逻辑-------- 扫码有用户。但是没绑定
if (Integer.valueOf(0).equals(sourceCode)) {
return resultMap;
}
/// 3.绑定用户超过数量
if (userAgriList.size()>=agriManagerNum) {
resultMap.put("code", 0);
resultMap.put("msg","当前大棚关联超过限制,请联系大棚所有者!");
return resultMap;
}
/// 4.有所有者,当前用户非所有者 此处只可能为邀请时逻辑
sysUserAgri.setStatus(2);
sysUserAgri.setRemark("用户邀请");
userAgriService.save(sysUserAgri);
if (Integer.valueOf(1).equals(sourceCode)) {
resultMap.put("msg", "邀请已发送,请等待确认");
}
return resultMap;
}
}

View File

@ -8,9 +8,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="id" column="id" />
<result property="imei" column="imei" />
<result property="agriName" column="agri_name" />
<result property="workMode" column="work_mode" />
<result property="userId" column="user_id" />
<result property="alarmStatus" column="alarm_status" />
<result property="deviceStatus" column="device_status" />
<result property="installTime" column="install_time" />
<result property="location" column="location" />
<result property="remark" column="remark" />
@ -22,7 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectSysAgriInfoVo">
select id, imei, agri_name, user_id, alarm_status, device_status, install_time, location, remark, create_time, create_by, update_time, update_by, is_deleted from sys_agri_info
select id, imei, agri_name, user_id, alarm_status, install_time, location, remark, create_time, create_by, update_time, update_by, is_deleted from sys_agri_info
</sql>
<sql id="agriUserVo">
@ -31,7 +31,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
agri.imei,
agri.agri_name,
agri.alarm_status,
agri.device_status,
agri.install_time,
agri.location,
agri.remark,
@ -46,6 +45,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
LEFT JOIN sys_user_agri user_agri ON user_agri.agri_id = agri.imei
</sql>
<sql id="agriInfoVo">
SELECT
agri.id,
agri.imei,
agri.agri_name,
agri.work_mode,
user_agri.user_id,
dtu_last.time,
dtu_last.ts,
dtu_last.temp1,
dtu_last.temp2,
dtu_last.temp3,
dtu_last.temp4
FROM
sys_agri_info agri
LEFT JOIN sys_user_agri user_agri ON user_agri.agri_id = agri.imei
<if test="userId == null"> and user_agri.user_id is null </if>
LEFT JOIN (
SELECT
dtu.imei,
dtu.time,
dtu.ts,
dtu.temp1,
dtu.temp2,
dtu.temp3,
dtu.temp4,
ROW_NUMBER() OVER (PARTITION BY dtu.imei ORDER BY dtu.create_time DESC, dtu.id DESC) AS rn
FROM sys_dtu_data dtu
WHERE dtu.create_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
) dtu_last ON dtu_last.imei = agri.imei AND dtu_last.rn = 1
</sql>
<select id="selectSysAgriInfoList" parameterType="SysAgriInfo" resultMap="SysAgriInfoResult">
<include refid="selectSysAgriInfoVo"/>
<where>
@ -53,7 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="agriName != null and agriName != ''"> and agri_name like concat('%', #{agriName}, '%')</if>
<if test="userId != null "> and user_id = #{userId}</if>
<if test="alarmStatus != null "> and alarm_status = #{alarmStatus}</if>
<if test="deviceStatus != null "> and device_status = #{deviceStatus}</if>
<if test="workMode != null and workMode != ''"> and work_mode = #{workMode}</if>
<if test="installTime != null "> and install_time = #{installTime}</if>
<if test="location != null and location != ''"> and location = #{location}</if>
<if test="isDeleted != null "> and is_deleted = #{isDeleted}</if>
@ -70,9 +101,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="imei != null and imei != ''">imei,</if>
<if test="agriName != null and agriName != ''">agri_name,</if>
<if test="workMode != null and workMode != ''">work_mode,</if>
<if test="userId != null">user_id,</if>
<if test="alarmStatus != null">alarm_status,</if>
<if test="deviceStatus != null">device_status,</if>
<if test="installTime != null">install_time,</if>
<if test="location != null">location,</if>
<if test="remark != null">remark,</if>
@ -85,9 +116,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="imei != null and imei != ''">#{imei},</if>
<if test="agriName != null and agriName != ''">#{agriName},</if>
<if test="workMode != null and workMode != ''">#{workMode},</if>
<if test="userId != null">#{userId},</if>
<if test="alarmStatus != null">#{alarmStatus},</if>
<if test="deviceStatus != null">#{deviceStatus},</if>
<if test="installTime != null">#{installTime},</if>
<if test="location != null">#{location},</if>
<if test="remark != null">#{remark},</if>
@ -103,10 +134,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update sys_agri_info
<trim prefix="SET" suffixOverrides=",">
<if test="imei != null and imei != ''">imei = #{imei},</if>
<if test="workMode != null and workMode != ''"> and work_mode = #{workMode}</if>
<if test="agriName != null and agriName != ''">agri_name = #{agriName},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="alarmStatus != null">alarm_status = #{alarmStatus},</if>
<if test="deviceStatus != null">device_status = #{deviceStatus},</if>
<if test="installTime != null">install_time = #{installTime},</if>
<if test="location != null">location = #{location},</if>
<if test="remark != null">remark = #{remark},</if>
@ -138,9 +169,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
is_deleted = 0
<if test="userId != null"> and user_agri.user_id = #{userId}</if>
<if test="imei != null and imei != ''"> and agri.imei = #{imei}</if>
<if test="workMode != null and workMode != ''"> and agri.work_mode = #{workMode}</if>
<if test="agriName != null and agriName != ''"> and agri.agri_name like concat('%', #{agriName}, '%')</if>
<if test="alarmStatus != null "> and agri.alarm_status = #{alarmStatus}</if>
<if test="installTime != null "> and agri.install_time = #{installTime}</if>
<if test="location != null and location != ''"> and agri.location = #{location}</if>
<if test="isDeleted != null "> and agri.is_deleted = #{isDeleted}</if>
</where>
</select>
<select id="findAgriInfoByUser" parameterType="SysAgriInfo" resultType="com.agri.system.domain.vo.AgriInfoView">
<include refid="agriInfoVo"/>
<where>
is_deleted = 0
<if test="userId != null"> and user_agri.user_id = #{userId}</if>
<if test="imei != null and imei != ''"> and agri.imei = #{imei}</if>
<if test="workMode != null and workMode != ''"> and agri.work_mode = #{workMode}</if>
<if test="agriName != null and agriName != ''"> and agri.agri_name like concat('%', #{agriName}, '%')</if>
<if test="alarmStatus != null "> and agri.alarm_status = #{alarmStatus}</if>
<if test="deviceStatus != null "> and agri.device_status = #{deviceStatus}</if>
<if test="installTime != null "> and agri.install_time = #{installTime}</if>
<if test="location != null and location != ''"> and agri.location = #{location}</if>
<if test="isDeleted != null "> and agri.is_deleted = #{isDeleted}</if>