change - add电、水实时数据

change - update 计量设备信息
main
zhouhy 4 months ago
parent 1bad8a04aa
commit 351696c5bc

@ -50,7 +50,7 @@ public class EmsBaseMonitorInfoController extends BaseController
*
* */
@PostMapping("/monitorInfoTree")
public AjaxResult getMonitorInfoTree(EmsBaseMonitorInfo baseMonitorInfo) {
public AjaxResult getMonitorInfoTree(@RequestBody EmsBaseMonitorInfo baseMonitorInfo) {
List<TreeSelects> list = emsBaseMonitorInfoService.selectBaseMonitorInfoTreeList(baseMonitorInfo);
return success(list);
}

@ -42,7 +42,7 @@ public class EmsBaseMonitorInfo extends BaseEntity
@Excel(name = "计量设备状态", readConverterExp = "0=启用,1=停用")
private Long monitorStatus;
/** 采集设备编号 */
/** 采集设备编号F */
@Excel(name = "采集设备编号")
private String collectDeviceId;

@ -0,0 +1,106 @@
package com.os.ems.record.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
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.os.common.annotation.Log;
import com.os.common.core.controller.BaseController;
import com.os.common.core.domain.AjaxResult;
import com.os.common.enums.BusinessType;
import com.os.ems.record.domain.EmsRecordWaterInstant;
import com.os.ems.record.service.IEmsRecordWaterInstantService;
import com.os.common.utils.poi.ExcelUtil;
import com.os.common.core.page.TableDataInfo;
/**
* Controller
*
* @author Yinq
* @date 2024-05-14
*/
@RestController
@RequestMapping("/ems/record/recordWaterInstant")
public class EmsRecordWaterInstantController extends BaseController
{
@Autowired
private IEmsRecordWaterInstantService emsRecordWaterInstantService;
/**
*
*/
@PreAuthorize("@ss.hasPermi('ems/record:recordWaterInstant:list')")
@GetMapping("/list")
public TableDataInfo list(EmsRecordWaterInstant emsRecordWaterInstant)
{
startPage();
List<EmsRecordWaterInstant> list = emsRecordWaterInstantService.selectEmsRecordWaterInstantList(emsRecordWaterInstant);
return getDataTable(list);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ems/record:recordWaterInstant:export')")
@Log(title = "水实时数据", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, EmsRecordWaterInstant emsRecordWaterInstant)
{
List<EmsRecordWaterInstant> list = emsRecordWaterInstantService.selectEmsRecordWaterInstantList(emsRecordWaterInstant);
ExcelUtil<EmsRecordWaterInstant> util = new ExcelUtil<EmsRecordWaterInstant>(EmsRecordWaterInstant.class);
util.exportExcel(response, list, "水实时数据数据");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ems/record:recordWaterInstant:query')")
@GetMapping(value = "/{objId}")
public AjaxResult getInfo(@PathVariable("objId") Long objId)
{
return success(emsRecordWaterInstantService.selectEmsRecordWaterInstantByObjId(objId));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ems/record:recordWaterInstant:add')")
@Log(title = "水实时数据", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody EmsRecordWaterInstant emsRecordWaterInstant)
{
emsRecordWaterInstant.setCreateBy(getUsername());
return toAjax(emsRecordWaterInstantService.insertEmsRecordWaterInstant(emsRecordWaterInstant));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ems/record:recordWaterInstant:edit')")
@Log(title = "水实时数据", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody EmsRecordWaterInstant emsRecordWaterInstant)
{
emsRecordWaterInstant.setUpdateBy(getUsername());
return toAjax(emsRecordWaterInstantService.updateEmsRecordWaterInstant(emsRecordWaterInstant));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('ems/record:recordWaterInstant:remove')")
@Log(title = "水实时数据", businessType = BusinessType.DELETE)
@DeleteMapping("/{objIds}")
public AjaxResult remove(@PathVariable Long[] objIds)
{
return toAjax(emsRecordWaterInstantService.deleteEmsRecordWaterInstantByObjIds(objIds));
}
}

@ -28,12 +28,26 @@ public class EmsRecordDnbInstant extends BaseEntity {
@Excel(name = "计量设备编号")
private String monitorId;
/**
* Code
*/
@Excel(name = "计量设备名称")
private String monitorCode;
/**
*
*/
@Excel(name = "计量设备名称")
private String monitorName;
/**
*
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "采集时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date collectTime;
private String beginCollectTime;
private String endCollectTime;
/**
* A
@ -78,6 +92,9 @@ public class EmsRecordDnbInstant extends BaseEntity {
@Excel(name = "记录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date recordTime;
private String beginRecordTime;
private String endRecordTime;
/**
*
*/
@ -108,6 +125,67 @@ public class EmsRecordDnbInstant extends BaseEntity {
@Excel(name = "采集方式", readConverterExp = "0=自动,1=手动")
private Long collectType;
//统计单元id
private String workUnitCode;
public String getBeginRecordTime() {
return beginRecordTime;
}
public String getMonitorCode() {
return monitorCode;
}
public void setMonitorCode(String monitorCode) {
this.monitorCode = monitorCode;
}
public void setBeginRecordTime(String beginRecordTime) {
this.beginRecordTime = beginRecordTime;
}
public String getEndRecordTime() {
return endRecordTime;
}
public void setEndRecordTime(String endRecordTime) {
this.endRecordTime = endRecordTime;
}
public String getBeginCollectTime() {
return beginCollectTime;
}
public void setBeginCollectTime(String beginCollectTime) {
this.beginCollectTime = beginCollectTime;
}
public String getEndCollectTime() {
return endCollectTime;
}
public void setEndCollectTime(String endCollectTime) {
this.endCollectTime = endCollectTime;
}
public String getWorkUnitCode() {
return workUnitCode;
}
public void setWorkUnitCode(String workUnitCode) {
this.workUnitCode = workUnitCode;
}
public String getMonitorName() {
return monitorName;
}
public void setMonitorName(String monitorName) {
this.monitorName = monitorName;
}
public void setObjId(Long objId) {
this.objId = objId;
}

@ -0,0 +1,182 @@
package com.os.ems.record.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.os.common.annotation.Excel;
import com.os.common.core.domain.BaseEntity;
/**
* ems_record_water_instant
*
* @author Yinq
* @date 2024-05-14
*/
public class EmsRecordWaterInstant extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** */
private Long objId;
/** 计量设备编号 */
@Excel(name = "计量设备编号")
private String monitorId;
/** 计量设备编号 */
@Excel(name = "计量设备名称")
private String monitorName;
private String monitorCode;
/** 采集时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "采集时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date collectTime;
private String beginTime;
private String endTime;
/** 瞬时流量 */
@Excel(name = "瞬时流量")
private Long fluxFlow;
/** 累计流量 */
@Excel(name = "累计流量")
private Long waterFlow;
/** 记录时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "记录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date recordTime;
private String beginRecordTime;
private String endRecordTime;
/** 采集方式0自动 1手动 */
@Excel(name = "采集方式", readConverterExp = "0=自动,1=手动")
private Long collectType;
public String getMonitorCode() {
return monitorCode;
}
public void setMonitorCode(String monitorCode) {
this.monitorCode = monitorCode;
}
public String getBeginRecordTime() {
return beginRecordTime;
}
public void setBeginRecordTime(String beginRecordTime) {
this.beginRecordTime = beginRecordTime;
}
public String getEndRecordTime() {
return endRecordTime;
}
public void setEndRecordTime(String endRecordTime) {
this.endRecordTime = endRecordTime;
}
public String getBeginTime() {
return beginTime;
}
public void setBeginTime(String beginTime) {
this.beginTime = beginTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public String getMonitorName() {
return monitorName;
}
public void setMonitorName(String monitorName) {
this.monitorName = monitorName;
}
public void setObjId(Long objId)
{
this.objId = objId;
}
public Long getObjId()
{
return objId;
}
public void setMonitorId(String monitorId)
{
this.monitorId = monitorId;
}
public String getMonitorId()
{
return monitorId;
}
public void setCollectTime(Date collectTime)
{
this.collectTime = collectTime;
}
public Date getCollectTime()
{
return collectTime;
}
public void setFluxFlow(Long fluxFlow)
{
this.fluxFlow = fluxFlow;
}
public Long getFluxFlow()
{
return fluxFlow;
}
public void setWaterFlow(Long waterFlow)
{
this.waterFlow = waterFlow;
}
public Long getWaterFlow()
{
return waterFlow;
}
public void setRecordTime(Date recordTime)
{
this.recordTime = recordTime;
}
public Date getRecordTime()
{
return recordTime;
}
public void setCollectType(Long collectType)
{
this.collectType = collectType;
}
public Long getCollectType()
{
return collectType;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("objId", getObjId())
.append("monitorId", getMonitorId())
.append("collectTime", getCollectTime())
.append("fluxFlow", getFluxFlow())
.append("waterFlow", getWaterFlow())
.append("recordTime", getRecordTime())
.append("collectType", getCollectType())
.toString();
}
}

@ -0,0 +1,61 @@
package com.os.ems.record.mapper;
import java.util.List;
import com.os.ems.record.domain.EmsRecordWaterInstant;
/**
* Mapper
*
* @author Yinq
* @date 2024-05-14
*/
public interface EmsRecordWaterInstantMapper
{
/**
*
*
* @param objId
* @return
*/
public EmsRecordWaterInstant selectEmsRecordWaterInstantByObjId(Long objId);
/**
*
*
* @param emsRecordWaterInstant
* @return
*/
public List<EmsRecordWaterInstant> selectEmsRecordWaterInstantList(EmsRecordWaterInstant emsRecordWaterInstant);
/**
*
*
* @param emsRecordWaterInstant
* @return
*/
public int insertEmsRecordWaterInstant(EmsRecordWaterInstant emsRecordWaterInstant);
/**
*
*
* @param emsRecordWaterInstant
* @return
*/
public int updateEmsRecordWaterInstant(EmsRecordWaterInstant emsRecordWaterInstant);
/**
*
*
* @param objId
* @return
*/
public int deleteEmsRecordWaterInstantByObjId(Long objId);
/**
*
*
* @param objIds
* @return
*/
public int deleteEmsRecordWaterInstantByObjIds(Long[] objIds);
}

@ -0,0 +1,61 @@
package com.os.ems.record.service;
import java.util.List;
import com.os.ems.record.domain.EmsRecordWaterInstant;
/**
* Service
*
* @author Yinq
* @date 2024-05-14
*/
public interface IEmsRecordWaterInstantService
{
/**
*
*
* @param objId
* @return
*/
public EmsRecordWaterInstant selectEmsRecordWaterInstantByObjId(Long objId);
/**
*
*
* @param emsRecordWaterInstant
* @return
*/
public List<EmsRecordWaterInstant> selectEmsRecordWaterInstantList(EmsRecordWaterInstant emsRecordWaterInstant);
/**
*
*
* @param emsRecordWaterInstant
* @return
*/
public int insertEmsRecordWaterInstant(EmsRecordWaterInstant emsRecordWaterInstant);
/**
*
*
* @param emsRecordWaterInstant
* @return
*/
public int updateEmsRecordWaterInstant(EmsRecordWaterInstant emsRecordWaterInstant);
/**
*
*
* @param objIds
* @return
*/
public int deleteEmsRecordWaterInstantByObjIds(Long[] objIds);
/**
*
*
* @param objId
* @return
*/
public int deleteEmsRecordWaterInstantByObjId(Long objId);
}

@ -0,0 +1,93 @@
package com.os.ems.record.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.os.ems.record.mapper.EmsRecordWaterInstantMapper;
import com.os.ems.record.domain.EmsRecordWaterInstant;
import com.os.ems.record.service.IEmsRecordWaterInstantService;
/**
* Service
*
* @author Yinq
* @date 2024-05-14
*/
@Service
public class EmsRecordWaterInstantServiceImpl implements IEmsRecordWaterInstantService
{
@Autowired
private EmsRecordWaterInstantMapper emsRecordWaterInstantMapper;
/**
*
*
* @param objId
* @return
*/
@Override
public EmsRecordWaterInstant selectEmsRecordWaterInstantByObjId(Long objId)
{
return emsRecordWaterInstantMapper.selectEmsRecordWaterInstantByObjId(objId);
}
/**
*
*
* @param emsRecordWaterInstant
* @return
*/
@Override
public List<EmsRecordWaterInstant> selectEmsRecordWaterInstantList(EmsRecordWaterInstant emsRecordWaterInstant)
{
return emsRecordWaterInstantMapper.selectEmsRecordWaterInstantList(emsRecordWaterInstant);
}
/**
*
*
* @param emsRecordWaterInstant
* @return
*/
@Override
public int insertEmsRecordWaterInstant(EmsRecordWaterInstant emsRecordWaterInstant)
{
return emsRecordWaterInstantMapper.insertEmsRecordWaterInstant(emsRecordWaterInstant);
}
/**
*
*
* @param emsRecordWaterInstant
* @return
*/
@Override
public int updateEmsRecordWaterInstant(EmsRecordWaterInstant emsRecordWaterInstant)
{
return emsRecordWaterInstantMapper.updateEmsRecordWaterInstant(emsRecordWaterInstant);
}
/**
*
*
* @param objIds
* @return
*/
@Override
public int deleteEmsRecordWaterInstantByObjIds(Long[] objIds)
{
return emsRecordWaterInstantMapper.deleteEmsRecordWaterInstantByObjIds(objIds);
}
/**
*
*
* @param objId
* @return
*/
@Override
public int deleteEmsRecordWaterInstantByObjId(Long objId)
{
return emsRecordWaterInstantMapper.deleteEmsRecordWaterInstantByObjId(objId);
}
}

@ -7,6 +7,8 @@
<resultMap type="EmsRecordDnbInstant" id="EmsRecordDnbInstantResult">
<result property="objId" column="obj_id"/>
<result property="monitorId" column="monitor_id"/>
<result property="monitorName" column="monitor_name"/>
<result property="monitorCode" column="monitor_code"/>
<result property="collectTime" column="collect_time"/>
<result property="vA" column="v_a"/>
<result property="vB" column="v_b"/>
@ -23,48 +25,55 @@
</resultMap>
<sql id="selectEmsRecordDnbInstantVo">
select obj_id,
monitor_id,
collect_time,
v_a,
v_b,
v_c,
i_a,
i_b,
i_c,
record_time,
glys,
zxyg,
active_power,
reactive_power,
collect_type
from ems_record_dnb_instant
select RDI.obj_id,
RDI.monitor_id,
BMI.monitor_name,
BMI.monitor_code,
RDI.collect_time,
RDI.v_a,
RDI.v_b,
RDI.v_c,
RDI.i_a,
RDI.i_b,
RDI.i_c,
RDI.record_time,
RDI.glys,
RDI.zxyg,
RDI.active_power,
RDI.reactive_power,
RDI.collect_type
from ems_record_dnb_instant as RDI
left join ems_base_monitor_info as BMI
on RDI.monitor_id = BMI.obj_id
</sql>
<select id="selectEmsRecordDnbInstantList" parameterType="EmsRecordDnbInstant"
resultMap="EmsRecordDnbInstantResult">
<include refid="selectEmsRecordDnbInstantVo"/>
<where>
<if test="monitorId != null and monitorId != ''">and monitor_id = #{monitorId}</if>
<if test="collectTime != null ">and collect_time = #{collectTime}</if>
<if test="vA != null ">and v_a = #{vA}</if>
<if test="vB != null ">and v_b = #{vB}</if>
<if test="vC != null ">and v_c = #{vC}</if>
<if test="iA != null ">and i_a = #{iA}</if>
<if test="iB != null ">and i_b = #{iB}</if>
<if test="iC != null ">and i_c = #{iC}</if>
<if test="recordTime != null ">and record_time = #{recordTime}</if>
<if test="glys != null ">and glys = #{glys}</if>
<if test="zxyg != null ">and zxyg = #{zxyg}</if>
<if test="activePower != null ">and active_power = #{activePower}</if>
<if test="reactivePower != null ">and reactive_power = #{reactivePower}</if>
<if test="collectType != null ">and collect_type = #{collectType}</if>
<if test="objId != null and objId != ''">and RDI.obj_id = #{objId}</if>
<if test="monitorId != null and monitorId != ''">and RDI.monitor_id = #{monitorId}</if>
<if test="beginCollectTime != null ">and RDI.collect_time >= #{beginCollectTime}</if>
<if test="endCollectTime != null ">and #{endCollectTime} >= RDI.collect_time</if>
<if test="vA != null ">and RDI.v_a = #{vA}</if>
<if test="vB != null ">and RDI.v_b = #{vB}</if>
<if test="vC != null ">and RDI.v_c = #{vC}</if>
<if test="iA != null ">and RDI.i_a = #{iA}</if>
<if test="iB != null ">and RDI.i_b = #{iB}</if>
<if test="iC != null ">and RDI.i_c = #{iC}</if>
<if test="beginRecordTime != null ">and RDI.record_time >= #{beginRecordTime}</if>
<if test="endRecordTime != null ">and #{endRecordTime} >= RDI.record_time</if>
<if test="glys != null ">and RDI.glys = #{glys}</if>
<if test="zxyg != null ">and RDI.zxyg = #{zxyg}</if>
<if test="activePower != null ">and RDI.active_power = #{activePower}</if>
<if test="reactivePower != null ">and RDI.reactive_power = #{reactivePower}</if>
<if test="collectType != null ">and RDI.collect_type = #{collectType}</if>
</where>
</select>
<select id="selectEmsRecordDnbInstantByObjId" parameterType="Long" resultMap="EmsRecordDnbInstantResult">
<include refid="selectEmsRecordDnbInstantVo"/>
where obj_id = #{objId}
where RDI.obj_id = #{objId}
</select>
<insert id="insertEmsRecordDnbInstant" parameterType="EmsRecordDnbInstant" useGeneratedKeys="true"

@ -0,0 +1,98 @@
<?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.os.ems.record.mapper.EmsRecordWaterInstantMapper">
<resultMap type="EmsRecordWaterInstant" id="EmsRecordWaterInstantResult">
<result property="objId" column="obj_id"/>
<result property="monitorId" column="monitor_id"/>
<result property="monitorCode" column="monitor_code"/>
<result property="monitorName" column="monitor_name"/>
<result property="collectTime" column="collect_time"/>
<result property="fluxFlow" column="flux_flow"/>
<result property="waterFlow" column="water_flow"/>
<result property="recordTime" column="record_time"/>
<result property="collectType" column="collect_type"/>
</resultMap>
<sql id="selectEmsRecordWaterInstantVo">
select RWI.obj_id,
RWI.monitor_id,
RWI.collect_time,
RWI.flux_flow,
RWI.water_flow,
RWI.record_time,
RWI.collect_type,
BMI.monitor_name,
BMI.monitor_code
from ems_record_water_instant RWI
left join ems_base_monitor_info BMI on RWI.monitor_id = BMI.obj_id
</sql>
<select id="selectEmsRecordWaterInstantList" parameterType="EmsRecordWaterInstant"
resultMap="EmsRecordWaterInstantResult">
<include refid="selectEmsRecordWaterInstantVo"/>
<where>
<if test="objId != null and objId != ''">and RWI.obj_id = #{objId}</if>
<if test="monitorId != null and monitorId != ''">and RWI.monitor_id = #{monitorId}</if>
<if test="beginTime !=null" > and RWI.collect_time>=#{beginTime}</if>
<if test="endTime !=null" > and #{endTime} >= RWI.collect_time</if>
<if test="fluxFlow != null ">and RWI.flux_flow = #{fluxFlow}</if>
<if test="waterFlow != null ">and RWI.water_flow = #{waterFlow}</if>
<if test="beginRecordTime != null ">and RWI.record_time >= #{beginRecordTime}</if>
<if test="endRecordTime != null ">and #{endRecordTime} >= RWI.record_time</if>
<if test="collectType != null ">and RWI.collect_type = #{collectType}</if>
</where>
</select>
<select id="selectEmsRecordWaterInstantByObjId" parameterType="Long" resultMap="EmsRecordWaterInstantResult">
<include refid="selectEmsRecordWaterInstantVo"/>
where RWI.obj_id = #{objId}
</select>
<insert id="insertEmsRecordWaterInstant" parameterType="EmsRecordWaterInstant" useGeneratedKeys="true"
keyProperty="objId">
insert into ems_record_water_instant
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="monitorId != null">monitor_id,</if>
<if test="collectTime != null">collect_time,</if>
<if test="fluxFlow != null">flux_flow,</if>
<if test="waterFlow != null">water_flow,</if>
<if test="recordTime != null">record_time,</if>
<if test="collectType != null">collect_type,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="monitorId != null">#{monitorId},</if>
<if test="collectTime != null">#{collectTime},</if>
<if test="fluxFlow != null">#{fluxFlow},</if>
<if test="waterFlow != null">#{waterFlow},</if>
<if test="recordTime != null">#{recordTime},</if>
<if test="collectType != null">#{collectType},</if>
</trim>
</insert>
<update id="updateEmsRecordWaterInstant" parameterType="EmsRecordWaterInstant">
update ems_record_water_instant
<trim prefix="SET" suffixOverrides=",">
<if test="monitorId != null">monitor_id = #{monitorId},</if>
<if test="collectTime != null">collect_time = #{collectTime},</if>
<if test="fluxFlow != null">flux_flow = #{fluxFlow},</if>
<if test="waterFlow != null">water_flow = #{waterFlow},</if>
<if test="recordTime != null">record_time = #{recordTime},</if>
<if test="collectType != null">collect_type = #{collectType},</if>
</trim>
where obj_id = #{objId}
</update>
<delete id="deleteEmsRecordWaterInstantByObjId" parameterType="Long">
delete from ems_record_water_instant where obj_id = #{objId}
</delete>
<delete id="deleteEmsRecordWaterInstantByObjIds" parameterType="String">
delete from ems_record_water_instant where obj_id in
<foreach item="objId" collection="array" open="(" separator="," close=")">
#{objId}
</foreach>
</delete>
</mapper>
Loading…
Cancel
Save