1. 解析日志,是否入库日志

2. 定时器修改更新onenet
This commit is contained in:
邱贞招 2024-03-31 20:30:26 +08:00
parent 55c4ec8a90
commit 8f91a75244
10 changed files with 460 additions and 91 deletions

View File

@ -25,7 +25,7 @@ public class DatapointValue {
private int sec;//
private Boolean sw;// 开关
private int week;//周转成二进制 bit0位开始为周一 0110 (week&1<<0) 1<<1 1<<2 00000110
private int id;
}
// 内部类 Mc 脉冲

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询植物解析日志列表
export function listAnalysisLog(query) {
return request({
url: '/plant/analysis/list',
method: 'get',
params: query
})
}
// 查询植物解析日志详细
export function getAnalysisLog(id) {
return request({
url: '/plant/analysis/' + id,
method: 'get'
})
}
// 新增植物解析日志
export function addAnalysisLog(data) {
return request({
url: '/plant/analysis',
method: 'post',
data: data
})
}
// 修改植物解析日志
export function updateAnalysisLog(data) {
return request({
url: '/plant/analysis',
method: 'put',
data: data
})
}
// 删除植物解析日志
export function delAnalysisLog(id) {
return request({
url: '/plant/analysis/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,211 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="是否入库" prop="isExist">
<el-select v-model="queryParams.isExist" placeholder="请选择是否入库" clearable>
<el-option
v-for="dict in dict.type.as_plant_is_exist"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['device:analysisLog:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="analysisLogList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="id" align="center" prop="id" />
<!-- <el-table-column label="识别日志id" align="center" prop="identifyId" />-->
<el-table-column label="植物名称" align="center" prop="plantName" />
<el-table-column label="是否入库" align="center" prop="isExist">
<template slot-scope="scope">
<dict-tag :options="dict.type.as_plant_is_exist" :value="scope.row.isExist"/>
</template>
</el-table-column>
<el-table-column label="消息" align="center" prop="msg" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改植物解析日志对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listAnalysisLog, getAnalysisLog, delAnalysisLog, addAnalysisLog, updateAnalysisLog } from "@/api/plant/analysisLog";
export default {
name: "AnalysisLog",
dicts: ['as_plant_is_exist'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
analysisLogList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
isExist: null,
},
//
form: {},
//
rules: {
}
};
},
created() {
this.getList();
},
methods: {
/** 查询植物解析日志列表 */
getList() {
this.loading = true;
listAnalysisLog(this.queryParams).then(response => {
this.analysisLogList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
identifyId: null,
plantName: null,
isExist: null,
msg: null,
createTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加植物解析日志";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getAnalysisLog(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改植物解析日志";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateAnalysisLog(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addAnalysisLog(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除植物解析日志编号为"' + ids + '"的数据项?').then(function() {
return delAnalysisLog(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('device/analysisLog/export', {
...this.queryParams
}, `analysisLog_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -211,6 +211,7 @@ public class AppController extends BaseController
/** 记录植物库中没有该植物,用于后期补充植物库*/
AsPlantAnalysisLog asPlantAnalysisLog = AsPlantAnalysisLog.builder()
.plantName(name)
.isExist("0")
.identifyId(asPlantIdentifyLog.getId())
.msg("没有该植物信息")
.build();

View File

@ -83,6 +83,9 @@ public class AsDevice extends BaseEntity
// @Excel(name = "定时浇水规则json")
private String regularWatering;
/** 下次浇水json */
private String nextDs;
/** 启动土壤湿度值 */
@Excel(name = "启动土壤湿度值")
private Integer soilMoistureOpen;

View File

@ -33,6 +33,10 @@ public class AsPlantAnalysisLog extends BaseEntity
@Excel(name = "名称")
private String plantName;
/** 是否存在植物库0-不存在1-存在 */
@Excel(name = "是否入库")
private String isExist;
/** 消息 */
@Excel(name = "消息")
private String msg;

View File

@ -31,6 +31,9 @@ public class AsTimer extends BaseEntity
@Excel(name = "定时模式1:-单次浇水2-循环浇水")
private String mode;
/** 定时器索引 */
private Long index;
/** 启动时间 */
@Excel(name = "启动时间", width = 30, dateFormat = "HH:mm")
private Time startTime;

View File

@ -1,16 +1,5 @@
package com.ruoyi.device.service.impl;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.HttpStatus;
@ -18,25 +7,37 @@ import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.core.domain.onenet.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.onenet.IotUtil;
import com.ruoyi.common.utils.onenet.Token;
import com.ruoyi.device.domain.AsDevice;
import com.ruoyi.device.domain.AsWateringRecord;
import com.ruoyi.device.domain.AsTimer;
import com.ruoyi.device.mapper.AsTimerMapper;
import com.ruoyi.device.service.IAsDeviceService;
import com.ruoyi.device.service.IAsTimerService;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.device.mapper.AsTimerMapper;
import com.ruoyi.device.domain.AsTimer;
import com.ruoyi.device.service.IAsTimerService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 定时器Service业务层处理
@ -85,10 +86,39 @@ public class AsTimerServiceImpl implements IAsTimerService
* @param asTimer 定时器
* @return 定时器
*/
@SneakyThrows
@Override
public List<AsTimer> selectAsTimerList(AsTimer asTimer)
{
return asTimerMapper.selectAsTimerList(asTimer);
/** 根据设备id请求onenet获取到该设备的定时器列表*/
String token = Token.getToken();
Long deviceId = asTimer.getDeviceId();
AsDevice device = asDeviceService.selectAsDeviceByDeviceId(deviceId);
String mac = device.getMac();
if(StringUtils.isEmpty(mac)){
throw new ServiceException("设备无mac号");
}
/**请求onenet获取到该设备的定时器列表*/
List<DatapointValue.Ds> dsArray = getDs("add",asTimer, token, device);
/**组装定时器信息返回给前端*/
List<AsTimer> asTimers = new ArrayList<>();
for (int i = 0; i < dsArray.size(); i++) {
AsTimer asTimer1 = new AsTimer();
DatapointValue.Ds ds = dsArray.get(i);
Boolean once = ds.getOnce();
asTimer1.setMode(once?"1":"2");
asTimer1.setDeviceId(asTimer.getDeviceId());
asTimer1.setIndex((long)i);
//将week将10进制转成2进制
asTimer1.setWeek(Integer.toBinaryString(ds.getWeek()));
asTimer1.setIsSwitch(ds.getSw());
// 将时分秒hour,min,sec,转成java.sql.Time类型
LocalTime localTime = LocalTime.of(ds.getHour(), ds.getMin(), ds.getSec());
asTimer1.setStartTime(Time.valueOf(localTime));
asTimers.add(asTimer1);
}
// List<AsTimer> asTimers = asTimerMapper.selectAsTimerList(asTimer);
return asTimers;
}
/**
@ -106,75 +136,111 @@ public class AsTimerServiceImpl implements IAsTimerService
Time sqlTime = new Time(timeFormat.parse(asTimer.getStartTimeStr()).getTime());
asTimer.setStartTime(sqlTime);
asTimer.setCreateTime(DateUtils.getNowDate());
//
// Long deviceId = asTimer.getDeviceId();
// AsDevice device = asDeviceService.selectAsDeviceByDeviceId(deviceId);
//
// /**1.请求onenet获取到该设备的定时器信息*/
// String param = "device_name=" + device.getMac() + "&product_id=" + productId;
// String sendUrl = iotUrl+ IotConstants.ADDS_HISTORY_DATAPOINTS + "?"+param;
//
// String token = Token.getToken();
// logger.info("IOT获取到Authorization:【{}】",token);
// String result = HttpUtils.sendGetWithToken(sendUrl, null, token);
//
// logger.info("IOT返回的结果【{}】",result);
// /**2.处理返回的参数*/
// DataPointRes dataPointRes = JSONObject.parseObject(result, DataPointRes.class);
// Data data = dataPointRes.getData();
// List<Datastream> datastreams = data.getDatastreams();
// List<DatapointValue.Ds> dsArray = null;
// for (Datastream datastream: datastreams) {
// if(datastream.getId().equals("jj")){
// List<Datapoint> datapoints = datastream.getDatapoints();
// for (Datapoint obj:datapoints) {
// DatapointValue value = obj.getValue();
// dsArray = value.getDsArray();
// DatapointValue.Ds ds = new DatapointValue.Ds();
// //将week(二进制)转成十进制
// String week = asTimer.getWeek();
// ds.setWeek(Integer.parseInt(week, 2));
// //将startTimeStrHH:mm转成time提取小时分钟
// Date parse = timeFormat.parse(asTimer.getStartTimeStr());
// Instant instant = parse.toInstant();
// LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
// //time提取出小时分钟
// ds.setHour(localDateTime.getHour());
// ds.setMin(localDateTime.getMinute());
// ds.setSec(localDateTime.getSecond());
// String mode = asTimer.getMode();
// ds.setOnce("1".equals(mode)?true:false);
// ds.setSw(asTimer.getIsSwitch());
// dsArray.add(ds);
// }
// }
// }
//
// /** 向onenet发送编辑指令 更新设备定时器*/
// /** 1.获取参数*/
// String command = getTimerCommand(dsArray);
// logger.info("IOT获取到下发命令:【{}】",command);
//
// /** 2.发送请求*/
// String deviceName = device.getMac();//mac地址就是产品名称
// String param2 = "device_name=" + deviceName + "&product_id=" + productId +"&timeout=" + timeout;
// String sendUrl2 = iotUrl+ IotConstants.ADDS_COMMAND + "?"+param2;
//
// logger.info("IOT获取到Authorization:【{}】",token);
//
// String result2 = HttpUtils.sendPostWithToken(sendUrl2, command, token);
//
// /** 2.返回结果处理*/
// JSONObject paramsObj = JSON.parseObject(result2);
// String code = paramsObj.getString("code");
// if (!HttpStatus.IOT_SUCCESS.equals(code))
// {
// throw new ServiceException(code+"-----"+ IotUtil.formatMsg(code));
// }
// logger.info("IOT请求调用结果:【{}】",result2);
String token = Token.getToken();
Long deviceId = asTimer.getDeviceId();
AsDevice device = asDeviceService.selectAsDeviceByDeviceId(deviceId);
/**请求onenet获取到该设备的定时器列表*/
List<DatapointValue.Ds> dsArray = getDs("add",asTimer, token, device);
/**向onenet发送编辑指令*/
sendCommand(token, device, dsArray);
return asTimerMapper.insertAsTimer(asTimer);
}
private void sendCommand(String token, AsDevice device, List<DatapointValue.Ds> dsArray) {
/** 向onenet发送编辑指令 更新设备定时器*/
/** 1.获取参数*/
String command = getTimerCommand(dsArray);
logger.info("IOT获取到下发命令:【{}】",command);
/** 2.发送请求*/
String deviceName = device.getMac();//mac地址就是产品名称
String param2 = "device_name=" + deviceName + "&product_id=" + productId +"&timeout=" + timeout;
String sendUrl2 = iotUrl+ IotConstants.ADDS_COMMAND + "?"+param2;
logger.info("IOT获取到Authorization:【{}】", token);
String result2 = HttpUtils.sendPostWithToken(sendUrl2, command, token);
/** 3.返回结果处理*/
JSONObject paramsObj = JSON.parseObject(result2);
String code = paramsObj.getString("code");
if (!HttpStatus.IOT_SUCCESS.equals(code))
{
throw new ServiceException(code+"-----"+ IotUtil.formatMsg(code));
}
logger.info("IOT请求调用结果:【{}】",result2);
}
/**
* 请求onenet获取到该设备的定时器信息
*
* @param asTimer 定时器
* @return 结果
*/
@Nullable
private List<DatapointValue.Ds> getDs(String type, AsTimer asTimer, String token, AsDevice device) throws ParseException {
/**1.请求onenet获取到该设备的定时器信息*/
String param = "device_name=" + device.getMac() + "&product_id=" + productId;
String sendUrl = iotUrl+ IotConstants.ADDS_HISTORY_DATAPOINTS + "?"+param;
logger.info("IOT获取到Authorization:【{}】", token);
String result = HttpUtils.sendGetWithToken(sendUrl, null, token);
logger.info("IOT返回的结果【{}】",result);
/**2.处理返回的参数*/
DataPointRes dataPointRes = JSONObject.parseObject(result, DataPointRes.class);
Data data = dataPointRes.getData();
List<Datastream> datastreams = data.getDatastreams();
List<DatapointValue.Ds> dsArray = null;
for (Datastream datastream: datastreams) {
if(datastream.getId().equals("jj")){
List<Datapoint> datapoints = datastream.getDatapoints();
for (Datapoint obj:datapoints) {
DatapointValue value = obj.getValue();
dsArray = value.getDsArray();
DatapointValue.Ds ds = getDsItem(asTimer);
if("add".equals(type)){
//添加定时器
dsArray.add(ds);
}else if("edit".equals(type)){
//编辑定时器
for (int i = 0; i < dsArray.size(); i++) {
if(i == asTimer.getIndex() ){
dsArray.remove(i);
dsArray.add(ds);
}
}
}
}
}
}
logger.info("请求onenet获取到定时器列表【{}】",JSON.toJSON(dsArray));
return dsArray;
}
@NotNull
private DatapointValue.Ds getDsItem(AsTimer asTimer) throws ParseException {
DatapointValue.Ds ds = new DatapointValue.Ds();
//将week(二进制)转成十进制
String week = asTimer.getWeek();
ds.setWeek(Integer.parseInt(week, 2));
//将startTimeStrHH:mm转成time提取小时分钟
Date parse = new SimpleDateFormat("HH:mm").parse(asTimer.getStartTimeStr());
Instant instant = parse.toInstant();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
//time提取出小时分钟
ds.setHour(localDateTime.getHour());
ds.setMin(localDateTime.getMinute());
ds.setSec(localDateTime.getSecond());
String mode = asTimer.getMode();
ds.setOnce("1".equals(mode)?true:false);
ds.setSw(asTimer.getIsSwitch());
return ds;
}
//拼接定时器命令
private String getTimerCommand(List<DatapointValue.Ds> dsArray) {
if (dsArray == null || dsArray.size() == 0)
@ -192,7 +258,6 @@ public class AsTimerServiceImpl implements IAsTimerService
.append("hour").append(ds.getHour()).append(IotConstants.COMMAND_SEPARATOR)
.append("min").append(ds.getMin()).append(IotConstants.COMMAND_SEPARATOR)
.append("sec").append(ds.getSec()).append(IotConstants.COMMAND_SEPARATOR);
}
return command.toString();
}
@ -203,9 +268,21 @@ public class AsTimerServiceImpl implements IAsTimerService
* @param asTimer 定时器
* @return 结果
*/
@SneakyThrows
@Override
public int updateAsTimer(AsTimer asTimer)
{
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
Time sqlTime = new Time(timeFormat.parse(asTimer.getStartTimeStr()).getTime());
asTimer.setStartTime(sqlTime);
String token = Token.getToken();
Long deviceId = asTimer.getDeviceId();
AsDevice device = asDeviceService.selectAsDeviceByDeviceId(deviceId);
/** 请求onenet获取到该设备的定时器列表*/
List<DatapointValue.Ds> dsArray = getDs("edit",asTimer, token, device);
/** 根据定时器索引修改定时器 */
/**向onenet发送编辑指令*/
sendCommand(token, device, dsArray);
asTimer.setUpdateTime(DateUtils.getNowDate());
return asTimerMapper.updateAsTimer(asTimer);
}

View File

@ -8,6 +8,7 @@ import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.onenet.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
@ -426,8 +427,29 @@ public class AsUserServiceImpl implements IAsUserService
String code = paramsObj.getString("code");
if (!HttpStatus.IOT_SUCCESS.equals(code)) {
asDevice1.setOnlineStatus("不在线");
return asDevices;
}else{
asDevice1.setOnlineStatus("在线");
// 查询onenet设备参数
String datapointsUrl = iotUrl+ IotConstants.ADDS_HISTORY_DATAPOINTS + "?"+param;
log.info("IOT获取到Authorization:【{}】", token);
String result2 = HttpUtils.sendGetWithToken(datapointsUrl, null, token);
DataPointRes dataPointRes = JSONObject.parseObject(result2, DataPointRes.class);
Data data = dataPointRes.getData();
List<Datastream> datastreams = data.getDatastreams();
for (Datastream datastream: datastreams) {
if(datastream.getId().equals("jj")){
List<Datapoint> datapoints = datastream.getDatapoints();
Datapoint datapoint = datapoints.get(0);
DatapointValue value = datapoint.getValue();
asDevice1.setWaterIntensity(value.getJiaoshui_qiangdu());
DatapointValue.Tr tr = value.getTr();
asDevice1.setSoilMoistureClose(tr.getEnd_sd());
asDevice1.setSoilMoistureOpen(tr.getStart_sd());
asDevice1.setPulseModeParam(JSON.toJSONString(value.getMc()));
asDevice1.setNextDs(JSON.toJSONString(value.getNext_ds()));
}
}
}
}
return asDevices;

View File

@ -3,41 +3,44 @@
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.device.mapper.AsPlantAnalysisLogMapper">
<resultMap type="AsPlantAnalysisLog" id="AsPlantAnalysisLogResult">
<result property="id" column="id" />
<result property="identifyId" column="identify_id" />
<result property="plantName" column="plant_name" />
<result property="isExist" column="is_exist" />
<result property="createTime" column="create_time" />
<result property="msg" column="msg" />
</resultMap>
<sql id="selectAsPlantAnalysisLogVo">
select id, identify_id, plant_name, create_time, msg from as_plant_analysis_log
select id, identify_id, plant_name, is_exist, create_time, msg from as_plant_analysis_log
</sql>
<select id="selectAsPlantAnalysisLogList" parameterType="AsPlantAnalysisLog" resultMap="AsPlantAnalysisLogResult">
<include refid="selectAsPlantAnalysisLogVo"/>
<where>
<where>
</where>
</select>
<select id="selectAsPlantAnalysisLogById" parameterType="Long" resultMap="AsPlantAnalysisLogResult">
<include refid="selectAsPlantAnalysisLogVo"/>
where id = #{id}
</select>
<insert id="insertAsPlantAnalysisLog" parameterType="AsPlantAnalysisLog" useGeneratedKeys="true" keyProperty="id">
insert into as_plant_analysis_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="identifyId != null">identify_id,</if>
<if test="plantName != null">plant_name,</if>
<if test="isExist != null">is_exist,</if>
<if test="createTime != null">create_time,</if>
<if test="msg != null">msg,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="identifyId != null">#{identifyId},</if>
<if test="plantName != null">#{plantName},</if>
<if test="isExist != null">#{isExist},</if>
<if test="createTime != null">#{createTime},</if>
<if test="msg != null">#{msg},</if>
</trim>
@ -48,6 +51,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<trim prefix="SET" suffixOverrides=",">
<if test="identifyId != null">identify_id = #{identifyId},</if>
<if test="plantName != null">plant_name = #{plantName},</if>
<if test="isExist != null">is_exist = #{isExist},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="msg != null">msg = #{msg},</if>
</trim>
@ -59,9 +63,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete>
<delete id="deleteAsPlantAnalysisLogByIds" parameterType="String">
delete from as_plant_analysis_log where id in
delete from as_plant_analysis_log where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>
</mapper>