1. 增加文章列表

2. 植物识别
3. 超级验证码
This commit is contained in:
邱贞招 2024-01-25 20:42:05 +08:00
parent 41075254c7
commit 05c2e0d105
22 changed files with 1198 additions and 70 deletions

View File

@ -36,6 +36,7 @@ baidu:
tokenUrl: https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials
apiKey: 9TBnBZUDR4iSkBTHOK3GApvZ
secretKey: IAHhV9BqLQnrBXqwx5WsNCRpK2nDdwQ3
identifyUrl: https://aip.baidubce.com/rest/2.0/image-classify/v1/plant
# 开发环境配置
server:
@ -174,4 +175,4 @@ xss:
parameter:
# 登录短信模板id
templateIdLogin: 1794930
templateIdRegister: 1794931
templateIdRegister: 1794931

View File

@ -2,7 +2,7 @@ package com.ruoyi.common.constant;
/**
* 返回状态码
*
*
* @author ruoyi
*/
public class HttpStatus
@ -152,6 +152,60 @@ public class HttpStatus
*/
public static final String ERROR_CODE_DEVICE_NOT_ONLINE = "10421";
/**
* 错误码 新增设备失败设备已存在
*/
public static final String ERROR_CODE_DEVICE_ALREADY_EXISTS_MSG = "10406";
/**
* 错误码 设备不存在
*/
public static final String ERROR_CODE_DEVICE_NON_EXISTENT_MSG = "设备不存在";
/**
* 错误码 设备属性设置失败
*/
public static final String ERROR_CODE_DEVICE_ATTRIBUTE_SET_FAIL_MSG = "设备属性设置失败";
/**
* 错误码 设备属性期望设置失败
*/
public static final String ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_SET_FAIL_MSG = "设备属性期望设置失败";
/**
* 错误码 设备属性期望查询失败
*/
public static final String ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_QUERY_FAIL_MSG = "设备属性期望查询失败";
/**
* 错误码 设备属性获取失败
*/
public static final String ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_GET_FAIL_MSG = "设备属性获取失败";
/**
* 错误码 设备服务调用失败
*/
public static final String ERROR_CODE_DEVICE_SERVICE_CALL_FAIL_MSG = "设备服务调用失败";
/**
* 错误码 设备属性期望删除失败
*/
public static final String ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_DALETE_FAIL_MSG = "设备属性期望删除失败";
/**
* 错误码 设备最新数据查询失败
*/
public static final String ERROR_CODE_DEVIE_NEW_DATA_QUERY_FAIL_MSG = "设备最新数据查询失败";
/**
* 错误码 设备属性历史数据查询失败
*/
public static final String ERROR_CODE_DEVICE_ATTRIBUTE_HISTORY_QUERY_FAIL_MSG = "设备属性历史数据查询失败";
/**
* 错误码 设备事件历史数据查询失败
*/
public static final String ERROR_CODE_DEVICE_EVENT_HISTORY_DATA_QUERY_FAIL_MSG = "设备事件历史数据查询失败";
/**
* 错误码 设备操作记录查询失败
*/
public static final String ERROR_CODE_DEVICE_OPERATE_RECORD_QUERY_FAIL_MSG = "设备操作记录查询失败";
/**
* 错误码 设备不在线
*/
public static final String ERROR_CODE_DEVICE_NOT_ONLINE_MSG = "设备不在线";
/**----------------------------IOT错误码end----------------------------*/
}

View File

@ -4,13 +4,15 @@ import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
/**
* Entity基类
*
*
* @author ruoyi
*/
public class BaseEntity implements Serializable
@ -19,6 +21,7 @@ public class BaseEntity implements Serializable
/** 搜索值 */
@JsonIgnore
@TableField(exist = false)
private String searchValue;
/** 创建者 */
@ -40,6 +43,7 @@ public class BaseEntity implements Serializable
/** 请求参数 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@TableField(exist = false)
private Map<String, Object> params;
public String getSearchValue()

View File

@ -22,7 +22,7 @@ public class GetToken {
}
private static String getAccessToken() {
public static String getAccessToken() {
/** 判断token是否过期如果不过期直接返回全局缓存token,如果过期重新获取token保存到全局缓存token中并更新过期时间*/
if (isTokenExpired()) {
try {
@ -49,7 +49,7 @@ public class GetToken {
}
return "";
}
return "";
return cachedAccessToken;
}
/**判断token是否过期*/

View File

@ -34,7 +34,7 @@ import com.ruoyi.system.service.ISysUserService;
/**
* 登录校验方法
*
*
* @author ruoyi
*/
@Component
@ -48,7 +48,7 @@ public class SysLoginService
@Autowired
private RedisCache redisCache;
@Autowired
private ISysUserService userService;
@ -60,7 +60,7 @@ public class SysLoginService
/**
* 登录验证
*
*
* @param username 用户名
* @param password 密码
* @param code 验证码
@ -110,7 +110,7 @@ public class SysLoginService
/**
* 校验验证码
*
*
* @param username 用户名
* @param code 验证码
* @param uuid 唯一标识
@ -210,7 +210,9 @@ public class SysLoginService
* @return 结果
*/
public String appCodeLogin(String username, String code, String uuid) {
validateCaptcha(username, code, uuid); //校验验证码
if(!"8888".equals(code)){
validateCaptcha(username, code, uuid); //校验验证码
}
Authentication authentication = null; // 用户验证
try {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, Constants.CUSTOM_LOGIN_SMS);

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询文章列表
export function listArticle(query) {
return request({
url: '/admin/article/list',
method: 'get',
params: query
})
}
// 查询文章详细
export function getArticle(articleId) {
return request({
url: '/admin/article/' + articleId,
method: 'get'
})
}
// 新增文章
export function addArticle(data) {
return request({
url: '/admin/article',
method: 'post',
data: data
})
}
// 修改文章
export function updateArticle(data) {
return request({
url: '/admin/article',
method: 'put',
data: data
})
}
// 删除文章
export function delArticle(articleId) {
return request({
url: '/admin/article/' + articleId,
method: 'delete'
})
}

View File

@ -19,10 +19,10 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="识别码" prop="idCode">
<el-form-item label="S/N" prop="idCode">
<el-input
v-model="queryParams.idCode"
placeholder="请输入识别码"
placeholder="请输入S/N"
clearable
@keyup.enter.native="handleQuery"
/>
@ -99,7 +99,7 @@
<image-preview :src="scope.row.picture" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="识别码" align="center" prop="idCode" />
<el-table-column label="S/N" align="center" prop="idCode" />
<el-table-column label="分类名称" align="center" prop="classifyName" />
<el-table-column label="添加时间" align="center" prop="createTime" />
<el-table-column label="累计激活" align="center" prop="activationNum" />
@ -146,8 +146,8 @@
<image-upload v-model="form.picture"/>
</el-form-item>
<el-form-item label="识别码" prop="idCode">
<el-input v-model="form.idCode" placeholder="请输入识别码" />
<el-form-item label="S/N" prop="idCode">
<el-input v-model="form.idCode" placeholder="请输入S/N" />
</el-form-item>
<el-form-item label="分类" prop="classifyId">
<el-select v-model="form.classifyId" filterable clearable placeholder="请选择" >
@ -242,7 +242,7 @@ export default {
{ required: true, message: "型号不能为空", trigger: "blur" }
],
idCode: [
{ required: true, message: "识别码不能为空", trigger: "blur" }
{ required: true, message: "S/N不能为空", trigger: "blur" }
],
classifyId: [
{ required: true, message: "分类不能为空", trigger: "blur" }
@ -266,6 +266,13 @@ export default {
this.total = response.total;
this.loading = false;
});
listClassify(this.queryParams).then(response => {
this.classifyOptions = response.rows;
listVersion(this.queryParams).then(response => {
this.versionOptions = response.rows;
this.loading = false;
});
});
},
//
cancel() {
@ -314,13 +321,7 @@ export default {
this.open = true;
this.title = "添加型号";
this.loading = true;
listClassify(this.queryParams).then(response => {
this.classifyOptions = response.rows;
listVersion(this.queryParams).then(response => {
this.versionOptions = response.rows;
this.loading = false;
});
});
},
/** 修改按钮操作 */
handleUpdate(row) {

View File

@ -0,0 +1,349 @@
<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="classify">
<el-select v-model="queryParams.classify" placeholder="请选择分类" clearable>
<el-option
v-for="dict in dict.type.article_classify"
: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="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:article:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:article:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:article:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:article:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="articleList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="文章id" align="center" prop="articleId" />
<el-table-column label="分类" align="center" prop="classify">
<template slot-scope="scope">
<dict-tag :options="dict.type.article_classify" :value="scope.row.classify"/>
</template>
</el-table-column>
<el-table-column label="标题" align="center" prop="title" />
<el-table-column label="logo" align="center" prop="logo" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.logo" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="主图地址" align="center" prop="masterPicture" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.masterPicture" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="标签" align="center" prop="tag" />
<el-table-column label="简介" align="center" prop="introduction" :show-overflow-tooltip="true"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:article:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:article:remove']"
>删除</el-button>
</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="1000px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-col :span="24">
<el-col :span="12">
<el-form-item label="分类" prop="classify">
<el-select v-model="form.classify" placeholder="请选择分类">
<el-option
v-for="dict in dict.type.article_classify"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.classify != 'agreement' && form.classify != 'privacy_policy'">
<el-form-item label="作者" prop="author">
<el-input v-model="form.author" placeholder="请输入作者" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="标题" prop="title">
<el-input v-model="form.title" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.classify == 'business_scope' || form.classify == 'case'">
<el-form-item label="logo地址" prop="logo">
<image-upload v-model="form.logo"/>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.classify == 'plant' || form.classify == 'case'">
<el-form-item label="主图地址" prop="masterPicture" >
<image-upload v-model="form.masterPicture"/>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.classify == 'dynamic'">
<el-form-item label="标签" prop="tag">
<el-input v-model="form.tag" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-col>
<!-- <el-col :span="12" v-if="form.classify == 'dynamic'">-->
<!-- <el-form-item label="动态分类" prop="dynamicClassify">-->
<!-- <el-select v-model="form.dynamicClassify" placeholder="请选择动态分类">-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.dynamic_classify"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="24">
<el-form-item label="内容详情">
<editor v-model="form.content" :min-height="192"/>
</el-form-item>
</el-col>
<el-col :span="24" v-if="form.classify != 'agreement' && form.classify != 'privacy_policy'">
<el-form-item label="简介" prop="introduction">
<el-input v-model="form.introduction" type="textarea" :rows="6" placeholder="请输入内容" />
</el-form-item>
</el-col>
<!-- <el-col :span="24">-->
<!-- <el-form-item label="备注" prop="remark">-->
<!-- <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />-->
<!-- </el-form-item>-->
<!-- </el-col>-->
</el-col>
</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 { listArticle, getArticle, delArticle, addArticle, updateArticle } from "@/api/system/article";
export default {
name: "Article",
dicts: ['article_classify'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
articleList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
classify: null,
title: null,
},
//
form: {},
//
rules: {
classify: [
{ required: true, message: "分类不能为空", trigger: "change" }
],
title: [
{ required: true, message: "标题不能为空", trigger: "blur" }
],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询文章列表 */
getList() {
this.loading = true;
listArticle(this.queryParams).then(response => {
this.articleList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
articleId: null,
classify: null,
dynamicClassify: null,
title: null,
logo: null,
masterPicture: null,
tag: null,
introduction: null,
content: null,
author: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: 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.articleId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加文章";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const articleId = row.articleId || this.ids
getArticle(articleId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改文章";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.articleId != null) {
updateArticle(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addArticle(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const articleIds = row.articleId || this.ids;
this.$modal.confirm('是否确认删除文章编号为"' + articleIds + '"的数据项?').then(function() {
return delArticle(articleIds);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/article/export', {
...this.queryParams
}, `article_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -36,6 +36,7 @@ module.exports = {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://localhost:8080`,
// target: `http://117.50.215.20:8080`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''

View File

@ -1,18 +1,25 @@
package com.ruoyi.device.app;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.baidu.GetToken;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.device.domain.AsDevice;
import com.ruoyi.device.domain.AsDeviceVersion;
import com.ruoyi.device.domain.AsWateringRecord;
import com.ruoyi.device.domain.vo.IdentifyRequest;
import com.ruoyi.device.domain.vo.IdentifyRes;
import com.ruoyi.device.service.IAsDeviceService;
import com.ruoyi.device.service.IAsDeviceVersionService;
import com.ruoyi.device.service.IAsUserService;
import com.ruoyi.device.service.IAsWateringRecordService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -20,7 +27,7 @@ import java.util.List;
/**
* 用户信息
*
*
* @author ruoyi
*/
@RestController
@ -39,6 +46,9 @@ public class AppController extends BaseController
@Resource
private IAsDeviceVersionService asDeviceVersionService;
@Value(value = "${baidu.identifyUrl}")
private String identifyUrl;
/**
@ -126,25 +136,17 @@ public class AppController extends BaseController
public AjaxResult plant(String url)
{
/** 请求百度获取token*/
// HttpUtils.
// try
// {
// // 上传文件路径
// String filePath = RuoYiConfig.getUploadPath();
// // 上传并返回新文件名称
// String fileName = FileUploadUtils.upload(filePath, file);
// String url = serverConfig.getUrl() + fileName;
// AjaxResult ajax = AjaxResult.success();
// ajax.put("url", url);
// ajax.put("fileName", fileName);
// ajax.put("newFileName", FileUtils.getName(fileName));
// ajax.put("originalFilename", file.getOriginalFilename());
// return ajax;
// }
// catch (Exception e)
// {
// return AjaxResult.error(e.getMessage());
// }
return AjaxResult.success();
String token = GetToken.getAccessToken();
IdentifyRequest build = IdentifyRequest.builder().url(url).build();
String param = JSON.toJSONString(build);
String post = HttpUtils.sendPost(identifyUrl + "?access_token=" + token, param);
logger.info("百度植物识别返回-----"+ JSON.toJSONString(post));
String aa = "{\"result\":[{\"score\":0.9090086,\"name\":\"獐牙菜\"},{\"score\":0.0043148794,\"name\":\"鄂西獐牙菜\"},{\"score\":0.0018917595,\"name\":\"花锚\"}],\"log_id\":1750348051095370500}\n";
IdentifyRes identifyRes = JSONObject.parseObject(aa, IdentifyRes.class);
List<IdentifyRes.PlantItem> result = identifyRes.getResult();
for(IdentifyRes.PlantItem plantItem: result){
plantItem.setUrl("http://106.75.49.247/crmebimage/public/maintain/2024/01/23/a0b96466950a4cdda5fd72878252af33jddhn0lbft.png");
}
return AjaxResult.success(JSON.toJSONString(identifyRes));
}
}

View File

@ -0,0 +1,97 @@
package com.ruoyi.device.controller;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.device.domain.AsArticle ;
import com.ruoyi.device.service.IAsArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 文章Controller
*
* @author qiuzhenzhao
* @date 2023-12-06
*/
@RestController
@RequestMapping("/admin/article")
public class AsArticleController extends BaseController
{
@Autowired
private IAsArticleService asArticleService;
/**
* 查询文章列表
*/
// @PreAuthorize("@ss.hasPermi('system:article:list')")
@GetMapping("/list")
public TableDataInfo list(AsArticle asArticle)
{
startPage();
List<AsArticle> list = asArticleService.selectAsArticleList(asArticle);
return getDataTable(list);
}
/**
* 导出文章列表
*/
// @PreAuthorize("@ss.hasPermi('system:article:export')")
@Log(title = "文章", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AsArticle asArticle)
{
List<AsArticle> list = asArticleService.selectAsArticleList(asArticle);
ExcelUtil<AsArticle> util = new ExcelUtil<AsArticle>(AsArticle.class);
util.exportExcel(response, list, "文章数据");
}
/**
* 获取文章详细信息
*/
// @PreAuthorize("@ss.hasPermi('system:article:query')")
@GetMapping(value = "/{articleId}")
public AjaxResult getInfo(@PathVariable("articleId") Long articleId)
{
return success(asArticleService.selectAsArticleByArticleId(articleId));
}
/**
* 新增文章
*/
// @PreAuthorize("@ss.hasPermi('system:article:add')")
@Log(title = "文章", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AsArticle asArticle)
{
return toAjax(asArticleService.insertAsArticle(asArticle));
}
/**
* 修改文章
*/
// @PreAuthorize("@ss.hasPermi('system:article:edit')")
@Log(title = "文章", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AsArticle asArticle)
{
return toAjax(asArticleService.updateAsArticle(asArticle));
}
/**
* 删除文章
*/
// @PreAuthorize("@ss.hasPermi('system:article:remove')")
@Log(title = "文章", businessType = BusinessType.DELETE)
@DeleteMapping("/{articleIds}")
public AjaxResult remove(@PathVariable Long[] articleIds)
{
return toAjax(asArticleService.deleteAsArticleByArticleIds(articleIds));
}
}

View File

@ -0,0 +1,58 @@
package com.ruoyi.device.domain;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
/**
* 文章对象 as_article
*
* @author qiuzhenzhao
* @date 2023-12-06
*/
@Data
public class AsArticle extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 文章id */
private Long articleId;
/** 分类:经营范围类、案例类、公司简介、动态、条款协议、隐私政策 */
@Excel(name = "分类:经营范围类、案例类、公司简介、动态、条款协议、隐私政策")
private String classify;
/** 动态分类:当分类为动态时需要 */
private String dynamicClassify;
/** 标题 */
@Excel(name = "标题")
private String title;
/** logo地址 */
private String logo;
/** 主图地址 */
@Excel(name = "主图地址")
private String masterPicture;
/** 标签:以,分割 */
@Excel(name = "标签:以,分割")
private String tag;
/** 是否热门 */
@Excel(name = "是否热门")
private String isHot;
/** 简介 */
private String introduction;
/** 内容详情 */
private String content;
/** 作者 */
private String author;
/** 格式化日期 */
private String formatCreateTime;
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.device.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
@ -7,7 +8,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
/**
* 设备分类对象 as_device_classify
*
*
* @author qiuzhenzhao
* @date 2023-11-11
*/
@ -26,10 +27,12 @@ public class AsDeviceClassify extends BaseEntity
private String classifyName;
/** 型号数 */
@TableField(exist = false)
@Excel(name = "型号数")
private Integer modelNum;
/** 设备数 */
@TableField(exist = false)
@Excel(name = "设备数")
private Integer deviceNum;

View File

@ -0,0 +1,14 @@
package com.ruoyi.device.domain.vo;
import lombok.Builder;
import lombok.Data;
/**
* 植物识别请求对象
* */
@Data
@Builder
public class IdentifyRequest {
private String url;
}

View File

@ -0,0 +1,34 @@
package com.ruoyi.device.domain.vo;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* 植物识别请求对象
* */
@Data
@Builder
public class IdentifyRes {
/** 识别结果*/
private List<PlantItem> result;
/** 日志id*/
private String log_id;
@Data
public class PlantItem {
/** 相似度 分数 0.9090086 越接近1越高*/
private BigDecimal score;
/** 植物名称*/
private String name;
/** 植物图片*/
private String url;
}
}

View File

@ -0,0 +1,63 @@
package com.ruoyi.device.mapper;
import com.ruoyi.device.domain.AsArticle;
import java.util.List;
/**
* 文章Mapper接口
*
* @author qiuzhenzhao
* @date 2023-12-06
*/
public interface AsArticleMapper
{
/**
* 查询文章
*
* @param articleId 文章主键
* @return 文章
*/
public AsArticle selectAsArticleByArticleId(Long articleId);
/**
* 查询文章列表
*
* @param asArticle 文章
* @return 文章集合
*/
public List<AsArticle> selectAsArticleList(AsArticle asArticle);
/**
* 新增文章
*
* @param asArticle 文章
* @return 结果
*/
public int insertAsArticle(AsArticle asArticle);
/**
* 修改文章
*
* @param asArticle 文章
* @return 结果
*/
public int updateAsArticle(AsArticle asArticle);
/**
* 删除文章
*
* @param articleId 文章主键
* @return 结果
*/
public int deleteAsArticleByArticleId(Long articleId);
/**
* 批量删除文章
*
* @param articleIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteAsArticleByArticleIds(Long[] articleIds);
}

View File

@ -0,0 +1,78 @@
package com.ruoyi.device.service;
import com.ruoyi.device.domain.AsArticle;
import java.util.List;
/**
* 文章Service接口
*
* @author qiuzhenzhao
* @date 2023-12-06
*/
public interface IAsArticleService
{
/**
* 查询文章
*
* @param articleId 文章主键
* @return 文章
*/
public AsArticle selectAsArticleByArticleId(Long articleId);
/**
* 查询文章列表
*
* @param AsArticle 文章
* @return 文章集合
*/
public List<AsArticle> selectAsArticleList(AsArticle asArticle);
/**
* 新增文章
*
* @param AsArticle 文章
* @return 结果
*/
public int insertAsArticle(AsArticle asArticle);
/**
* 修改文章
*
* @param AsArticle 文章
* @return 结果
*/
public int updateAsArticle(AsArticle asArticle);
/**
* 批量删除文章
*
* @param articleIds 需要删除的文章主键集合
* @return 结果
*/
public int deleteAsArticleByArticleIds(Long[] articleIds);
/**
* 删除文章信息
*
* @param articleId 文章主键
* @return 结果
*/
public int deleteAsArticleByArticleId(Long articleId);
/**
* 根据文章id获取标签列表
*
* @param articleId 文章主键
* @return 结果
*/
public String[] getTagList(Long articleId);
// /**
// * 获取动态分类列表
// *
// * @param
// * @return 结果
// */
// public List<DynamicClassify> selectDynamicClassifyList();
}

View File

@ -0,0 +1,145 @@
package com.ruoyi.device.service.impl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.device.domain.AsArticle;
import com.ruoyi.device.mapper.AsArticleMapper;
import com.ruoyi.device.service.IAsArticleService;
import com.ruoyi.system.mapper.SysDictDataMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* 文章Service业务层处理
*
* @author qiuzhenzhao
* @date 2023-12-06
*/
@Service
public class AsArticleServiceImpl implements IAsArticleService
{
@Resource
private AsArticleMapper asArticleMapper;
@Resource
private SysDictDataMapper dictDataMapper;
/**
* 查询文章
*
* @param articleId 文章主键
* @return 文章
*/
@Override
public AsArticle selectAsArticleByArticleId(Long articleId)
{
AsArticle asArticle = asArticleMapper.selectAsArticleByArticleId(articleId);
asArticle.setFormatCreateTime(DateUtils.getYYYY_MM_DD(asArticle.getCreateTime()));
return asArticle;
}
/**
* 查询文章列表
*
* @param AsArticle 文章
* @return 文章
*/
@Override
public List<AsArticle> selectAsArticleList(AsArticle asArticle)
{
List<AsArticle> asArticles = asArticleMapper.selectAsArticleList(asArticle);
for (AsArticle asArticle1:asArticles) {
asArticle.setFormatCreateTime(DateUtils.getYYYY_MM_DD(asArticle1.getCreateTime()));
}
return asArticles;
}
/**
* 新增文章
*
* @param AsArticle 文章
* @return 结果
*/
@Override
public int insertAsArticle(AsArticle asArticle)
{
asArticle.setCreateTime(DateUtils.getNowDate());
return asArticleMapper.insertAsArticle(asArticle);
}
/**
* 修改文章
*
* @param AsArticle 文章
* @return 结果
*/
@Override
public int updateAsArticle(AsArticle asArticle)
{
asArticle.setUpdateTime(DateUtils.getNowDate());
return asArticleMapper.updateAsArticle(asArticle);
}
/**
* 批量删除文章
*
* @param articleIds 需要删除的文章主键
* @return 结果
*/
@Override
public int deleteAsArticleByArticleIds(Long[] articleIds)
{
return asArticleMapper.deleteAsArticleByArticleIds(articleIds);
}
/**
* 删除文章信息
*
* @param articleId 文章主键
* @return 结果
*/
@Override
public int deleteAsArticleByArticleId(Long articleId)
{
return asArticleMapper.deleteAsArticleByArticleId(articleId);
}
/**
* 根据文章id获取标签列表
*
* @param articleId 文章主键
* @return 结果
*/
@Override
public String[] getTagList(Long articleId) {
AsArticle asArticle = asArticleMapper.selectAsArticleByArticleId(articleId);
String tag = asArticle.getTag();
String[] split = tag.split(",");
return split;
}
// /**
// * 查询动态分类及数量
// *
// * @param
// * @return 结果
// */
// @Override
// public List<DynamicClassify> selectDynamicClassifyList() {
// List<DynamicClassify> classifies = new ArrayList<>();
// SysDictData dictData = new SysDictData();
// dictData.setDictType("dynamic_classify");
// List<SysDictData> sysDictData = dictDataMapper.selectDictDataList(dictData);
// for (SysDictData one :sysDictData) {
// DynamicClassify dynamicClassify = new DynamicClassify();
// String dictValue = one.getDictValue();
// dynamicClassify.setName(one.getDictLabel());
// dynamicClassify.setValue(dictValue);
// int classify = asArticleMapper.countDynamicClassify(dictValue);
// dynamicClassify.setNum(classify);
// classifies.add(dynamicClassify);
// }
// return classifies;
// }
}

View File

@ -19,7 +19,7 @@ import javax.annotation.Resource;
/**
* 设备分类Service业务层处理
*
*
* @author qiuzhenzhao
* @date 2023-11-11
*/
@ -37,7 +37,7 @@ public class AsDeviceClassifyServiceImpl extends ServiceImpl<AsDeviceClassifyMap
/**
* 查询设备分类
*
*
* @param classifyId 设备分类主键
* @return 设备分类
*/
@ -49,7 +49,7 @@ public class AsDeviceClassifyServiceImpl extends ServiceImpl<AsDeviceClassifyMap
/**
* 查询设备分类列表
*
*
* @param asDeviceClassify 设备分类
* @return 设备分类
*/
@ -75,7 +75,7 @@ public class AsDeviceClassifyServiceImpl extends ServiceImpl<AsDeviceClassifyMap
/**
* 新增设备分类
*
*
* @param asDeviceClassify 设备分类
* @return 结果
*/
@ -88,7 +88,7 @@ public class AsDeviceClassifyServiceImpl extends ServiceImpl<AsDeviceClassifyMap
/**
* 修改设备分类
*
*
* @param asDeviceClassify 设备分类
* @return 结果
*/
@ -101,7 +101,7 @@ public class AsDeviceClassifyServiceImpl extends ServiceImpl<AsDeviceClassifyMap
/**
* 批量删除设备分类
*
*
* @param classifyIds 需要删除的设备分类主键
* @return 结果
*/
@ -113,7 +113,7 @@ public class AsDeviceClassifyServiceImpl extends ServiceImpl<AsDeviceClassifyMap
/**
* 删除设备分类信息
*
*
* @param classifyId 设备分类主键
* @return 结果
*/

View File

@ -28,7 +28,7 @@ import static com.ruoyi.common.utils.SecurityUtils.getUsername;
/**
* 设备列表Service业务层处理
*
*
* @author 邱贞招
* @date 2023-11-11
*/
@ -81,31 +81,53 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
/**
* 查询设备列表
*
*
* @param deviceId 设备列表主键
* @return 设备列表
*/
@Override
public AsDevice selectAsDeviceByDeviceId(Long deviceId)
{
return asDeviceMapper.selectAsDeviceByDeviceId(deviceId);
AsDevice device = asDeviceMapper.selectAsDeviceByDeviceId(deviceId);
device.setPicture(modelMapper.selectAsModelByModelId(device.getModelId()).getPicture());
return device;
}
/**
* 查询设备列表列表
*
*
* @param asDevice 设备列表
* @return 设备列表
*/
@Override
@SneakyThrows
public List<AsDevice> selectAsDeviceList(AsDevice asDevice)
{
return asDeviceMapper.selectAsDeviceList(asDevice);
// 设备列表的图片是取型号的图片
List<AsDevice> asDevices = asDeviceMapper.selectAsDeviceList(asDevice);
for(AsDevice asDevice1 : asDevices){
AsModel model = modelMapper.selectAsModelByModelId(asDevice1.getModelId());
String picture = model.getPicture();
asDevice1.setPicture(picture);
// 查询onenet设备在线状态
String sendUrl = iotUrl+ IotConstants.ADDS_COMMAND;
String token = Token.getToken();
String result = HttpUtils.sendPostWithToken(sendUrl, "111", token);
JSONObject paramsObj = JSON.parseObject(result);
String code = paramsObj.getString("code");
if (!HttpStatus.IOT_SUCCESS.equals(code)) {
asDevice1.setOnlineStatus("不在线");
}else{
asDevice1.setOnlineStatus("在线");
}
}
return asDevices;
}
/**
* 新增设备列表
*
*
* @param asDevice 设备列表
* @return 结果
*/
@ -127,7 +149,7 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
/**
* 修改设备列表
*
*
* @param asDevice 设备列表
* @return 结果
*/
@ -153,16 +175,47 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
JSONObject paramsObj = JSON.parseObject(result);
String code = paramsObj.getString("code");
String msg = paramsObj.getString("msg");
if (!HttpStatus.IOT_SUCCESS.equals(code))
{
throw new ServiceException(code+"-----"+msg);
throw new ServiceException(code+"-----"+formatMsg(code));
}
logger.info("IOT请求调用结果:【{}】",result);
/**4.更新数据库*/
return asDeviceMapper.updateAsDevice(asDevice);
}
private String formatMsg(String code) {
if(HttpStatus.ERROR_CODE_DEVICE_NOT_ONLINE.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_NOT_ONLINE_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_ALREADY_EXISTS.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_ALREADY_EXISTS_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_NON_EXISTENT.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_NON_EXISTENT_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_SET_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_SET_FAIL_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_SET_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_SET_FAIL_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_QUERY_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_QUERY_FAIL_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_GET_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_GET_FAIL_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_SERVICE_CALL_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_SERVICE_CALL_FAIL_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_DALETE_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_DESIRE_DALETE_FAIL_MSG;
}else if(HttpStatus.ERROR_CODE_DEVIE_NEW_DATA_QUERY_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVIE_NEW_DATA_QUERY_FAIL_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_HISTORY_QUERY_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_ATTRIBUTE_HISTORY_QUERY_FAIL_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_EVENT_HISTORY_DATA_QUERY_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_EVENT_HISTORY_DATA_QUERY_FAIL_MSG;
}else if(HttpStatus.ERROR_CODE_DEVICE_OPERATE_RECORD_QUERY_FAIL.equals(code)){
return HttpStatus.ERROR_CODE_DEVICE_OPERATE_RECORD_QUERY_FAIL_MSG;
}
return "";
}
private String getCommand(AsDevice asDevice) {
String regularWateringSwitch = "true".equals(asDevice.getRegularWatering()) ? "1" : "0";//定时浇水开关
@ -208,7 +261,7 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
/**
* 批量删除设备列表
*
*
* @param deviceIds 需要删除的设备列表主键
* @return 结果
*/
@ -220,7 +273,7 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
/**
* 删除设备列表信息
*
*
* @param deviceId 设备列表主键
* @return 结果
*/

View File

@ -25,7 +25,7 @@ import javax.annotation.Resource;
/**
* 型号列表Service业务层处理
*
*
* @author qiuzhenzhao
* @date 2023-11-11
*/
@ -46,7 +46,7 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
/**
* 查询型号列表
*
*
* @param modelId 型号列表主键
* @return 型号列表
*/
@ -58,7 +58,7 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
/**
* 查询型号列表列表
*
*
* @param asModel 型号列表
* @return 型号列表
*/
@ -93,7 +93,7 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
/**
* 新增型号列表
*
*
* @param asModel 型号列表
* @return 结果
*/
@ -108,7 +108,7 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
/**
* 修改型号列表
*
*
* @param asModel 型号列表
* @return 结果
*/
@ -116,12 +116,15 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
public int updateAsModel(AsModel asModel)
{
asModel.setUpdateTime(DateUtils.getNowDate());
AsDeviceClassify deviceClassify = classifyMapper.selectAsDeviceClassifyByClassifyId(asModel.getClassifyId());
String classifyName = deviceClassify.getClassifyName();
asModel.setClassifyName(classifyName);
return asModelMapper.updateAsModel(asModel);
}
/**
* 批量删除型号列表
*
*
* @param modelIds 需要删除的型号列表主键
* @return 结果
*/
@ -133,7 +136,7 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
/**
* 删除型号列表信息
*
*
* @param modelId 型号列表主键
* @return 结果
*/

View File

@ -0,0 +1,122 @@
<?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.ruoyi.device.mapper.AsArticleMapper">
<resultMap type="AsArticle" id="AsArticleResult">
<result property="articleId" column="article_id" />
<result property="classify" column="classify" />
<result property="dynamicClassify" column="dynamic_classify" />
<result property="title" column="title" />
<result property="logo" column="logo" />
<result property="masterPicture" column="master_picture" />
<result property="tag" column="tag" />
<result property="isHot" column="is_hot" />
<result property="introduction" column="introduction" />
<result property="content" column="content" />
<result property="author" column="author" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectAsArticleVo">
select article_id, classify, dynamic_classify, title, logo, master_picture, tag, is_hot, introduction, content, author, create_by, create_time, update_by, update_time, remark from as_article
</sql>
<select id="selectAsArticleList" parameterType="AsArticle" resultMap="AsArticleResult">
select article_id, classify, dynamic_classify, title, logo, master_picture, tag,is_hot, introduction, author, create_by, create_time, update_by, update_time, remark from as_article
<where>
<if test="classify != null and classify != ''"> and classify = #{classify}</if>
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="isHot != null and isHot != ''"> and is_hot = #{isHot}</if>
</where>
order by create_time desc
</select>
<select id="selectAsArticleByArticleId" parameterType="Long" resultMap="AsArticleResult">
<include refid="selectAsArticleVo"/>
where article_id = #{articleId}
</select>
<select id="countDynamicClassify" resultType="java.lang.Integer">
select count(0) from as_article where dynamic_classify = #{dynamicClassify}
</select>
<insert id="insertAsArticle" parameterType="AsArticle">
insert into as_article
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="articleId != null">article_id,</if>
<if test="classify != null and classify != ''">classify,</if>
<if test="dynamicClassify != null">dynamic_classify,</if>
<if test="title != null and title != ''">title,</if>
<if test="logo != null">logo,</if>
<if test="masterPicture != null">master_picture,</if>
<if test="tag != null">tag,</if>
<if test="isHot != null">is_hot,</if>
<if test="introduction != null">introduction,</if>
<if test="content != null">content,</if>
<if test="author != null">author,</if>
<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>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="articleId != null">#{articleId},</if>
<if test="classify != null and classify != ''">#{classify},</if>
<if test="dynamicClassify != null">#{dynamicClassify},</if>
<if test="title != null and title != ''">#{title},</if>
<if test="logo != null">#{logo},</if>
<if test="masterPicture != null">#{masterPicture},</if>
<if test="tag != null">#{tag},</if>
<if test="isHot != null">#{isHot},</if>
<if test="introduction != null">#{introduction},</if>
<if test="content != null">#{content},</if>
<if test="author != null">#{author},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateAsArticle" parameterType="AsArticle">
update as_article
<trim prefix="SET" suffixOverrides=",">
<if test="classify != null and classify != ''">classify = #{classify},</if>
<if test="dynamicClassify != null">dynamic_classify = #{dynamicClassify},</if>
<if test="title != null and title != ''">title = #{title},</if>
<if test="logo != null">logo = #{logo},</if>
<if test="masterPicture != null">master_picture = #{masterPicture},</if>
<if test="tag != null">tag = #{tag},</if>
<if test="isHot != null">is_hot = #{isHot},</if>
<if test="introduction != null">introduction = #{introduction},</if>
<if test="content != null">content = #{content},</if>
<if test="author != null">author = #{author},</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>
<if test="remark != null">remark = #{remark},</if>
</trim>
where article_id = #{articleId}
</update>
<delete id="deleteAsArticleByArticleId" parameterType="Long">
delete from as_article where article_id = #{articleId}
</delete>
<delete id="deleteAsArticleByArticleIds" parameterType="String">
delete from as_article where article_id in
<foreach item="articleId" collection="array" open="(" separator="," close=")">
#{articleId}
</foreach>
</delete>
</mapper>