From 71e7b5ed3dbf460a25dab697db241fc56c6c21c9 Mon Sep 17 00:00:00 2001 From: wenc000 <450292408@qq.com> Date: Tue, 20 Oct 2020 10:10:37 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud-manager-sms/pom.xml | 7 ++++ cloud-manager-sms/src/test/java/SmsTest.java | 36 ++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 cloud-manager-sms/src/test/java/SmsTest.java diff --git a/cloud-manager-sms/pom.xml b/cloud-manager-sms/pom.xml index 290396e..0b9ca5d 100644 --- a/cloud-manager-sms/pom.xml +++ b/cloud-manager-sms/pom.xml @@ -24,6 +24,13 @@ qcloudsms 1.0.6 + + + junit + junit + 4.12 + test + \ No newline at end of file diff --git a/cloud-manager-sms/src/test/java/SmsTest.java b/cloud-manager-sms/src/test/java/SmsTest.java new file mode 100644 index 0000000..6dfbacd --- /dev/null +++ b/cloud-manager-sms/src/test/java/SmsTest.java @@ -0,0 +1,36 @@ +import com.cm.manager.sms.config.properties.SmsDefaultProperties; +import com.cm.manager.sms.utils.DefaultSmsUtil; +import org.junit.Test; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: SmsTest + * @Description: 短信测试 + * @Author: WangGeng + * @Date: 2020/10/20 9:39 + * @Version: 1.0 + **/ +public class SmsTest { + + @Test + public void test() { + // 包头政法 btzfw + // 西藏日喀则 xzrkz + String account = "xzrkz"; + String password = "xzrkz123"; + String phone = "15147146676"; + StringBuilder contentSB = new StringBuilder("【山西腾狮科技】").append("测试短信"); + String url = "https://dx.ipyy.net/sms.aspx?action=send&userid=&account={account}&password={password}&mobile={mobile}&content={content}&sendTime=&extno={extno}"; + String[] paramArray = new String[]{ + account, + password, + phone, + contentSB.toString(), + phone + }; + DefaultSmsUtil.sendSms(url, paramArray); + } + +} From 781b42cbdc0ac8b6c6deb75f3e7f01f48ea5407b Mon Sep 17 00:00:00 2001 From: wenc000 <450292408@qq.com> Date: Wed, 21 Oct 2020 19:07:21 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/oauth/controller/routes/RouteController.java | 8 +++++++- .../cm/common/config/properties/SystemProperties.java | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/controller/routes/RouteController.java b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/controller/routes/RouteController.java index 805b585..1688c2c 100644 --- a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/controller/routes/RouteController.java +++ b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/controller/routes/RouteController.java @@ -5,6 +5,7 @@ import com.cm.common.config.properties.OauthProperties; import com.cm.common.config.properties.SystemProperties; import com.cm.common.exception.SearchException; import com.cm.common.pojo.bos.UserInfoBO; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @@ -37,7 +38,12 @@ public class RouteController { ModelAndView mv = new ModelAndView("index"); UserInfoBO userInfoBO = securityComponent.getCurrentUser(); mv.addObject("userUsername", userInfoBO.getUserUsername()); - mv.addObject("oauthServer", oauthProperties.getOauthServer()); + // 门户URL不存在,跳转统一用户 + if (StringUtils.isBlank(systemProperties.getPortalUrl())) { + mv.addObject("oauthServer", oauthProperties.getOauthServer()); + } else { + mv.addObject("oauthServer", systemProperties.getPortalUrl()); + } mv.addObject("title", systemProperties.getTitle()); return mv; } diff --git a/cloud-common/src/main/java/com/cm/common/config/properties/SystemProperties.java b/cloud-common/src/main/java/com/cm/common/config/properties/SystemProperties.java index 0a70e7c..3d9b85e 100644 --- a/cloud-common/src/main/java/com/cm/common/config/properties/SystemProperties.java +++ b/cloud-common/src/main/java/com/cm/common/config/properties/SystemProperties.java @@ -20,6 +20,7 @@ public class SystemProperties { private Integer port; private String url; private String title; + private String portalUrl; private String loginPageName; public Integer getPort() { @@ -46,6 +47,14 @@ public class SystemProperties { this.title = title; } + public String getPortalUrl() { + return portalUrl == null ? "" : portalUrl.trim(); + } + + public void setPortalUrl(String portalUrl) { + this.portalUrl = portalUrl; + } + public String getLoginPageName() { return loginPageName == null ? "" : loginPageName.trim(); } From b8700606aed133f4f8bb542cf382329d2f562348 Mon Sep 17 00:00:00 2001 From: wenc000 <450292408@qq.com> Date: Wed, 21 Oct 2020 19:07:57 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=9C=B0=E5=9B=BE?= =?UTF-8?q?=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud-common-plugin-map/pom.xml | 14 +- .../java/com/cm/plugin/map/dao/IGridDao.java | 100 ++++++++++++ .../com/cm/plugin/map/pojo/dto/GridDTO.java | 84 ++++++++++ .../cm/plugin/map/pojo/dto/GridPointDTO.java | 62 +++++++ .../plugin/map/pojo/dto/GridRelationDTO.java | 53 ++++++ .../cm/plugin/map/pojo/vo/GridPointVO.java | 62 +++++++ .../com/cm/plugin/map/pojo/vo/GridVO.java | 83 ++++++++++ .../cm/plugin/map/service/IGridService.java | 57 +++++++ .../map/service/impl/GridServiceImpl.java | 134 +++++++++++++++ .../resources/mybatis/mapper/grid-mapper.xml | 152 ++++++++++++++++++ .../templates/baidu/update-grid.html | 14 ++ 11 files changed, 814 insertions(+), 1 deletion(-) create mode 100644 cloud-common-plugin-map/src/main/java/com/cm/plugin/map/dao/IGridDao.java create mode 100644 cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridDTO.java create mode 100644 cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridPointDTO.java create mode 100644 cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridRelationDTO.java create mode 100644 cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/vo/GridPointVO.java create mode 100644 cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/vo/GridVO.java create mode 100644 cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/IGridService.java create mode 100644 cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/impl/GridServiceImpl.java create mode 100644 cloud-common-plugin-map/src/main/resources/mybatis/mapper/grid-mapper.xml create mode 100644 cloud-common-plugin-map/src/main/resources/templates/baidu/update-grid.html diff --git a/cloud-common-plugin-map/pom.xml b/cloud-common-plugin-map/pom.xml index b2c2a4f..5b50222 100644 --- a/cloud-common-plugin-map/pom.xml +++ b/cloud-common-plugin-map/pom.xml @@ -12,6 +12,18 @@ 地图插件,画网格 1.0.1-SNAPSHOT - + + + com.cm + cloud-common + 1.0.1-SNAPSHOT + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + + + + \ No newline at end of file diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/dao/IGridDao.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/dao/IGridDao.java new file mode 100644 index 0000000..d732edd --- /dev/null +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/dao/IGridDao.java @@ -0,0 +1,100 @@ +package com.cm.plugin.map.dao; + +import com.cm.common.exception.RemoveException; +import com.cm.common.exception.SaveException; +import com.cm.common.exception.SearchException; +import com.cm.plugin.map.pojo.dto.GridDTO; +import com.cm.plugin.map.pojo.dto.GridPointDTO; +import com.cm.plugin.map.pojo.dto.GridRelationDTO; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: IGridDao + * @Description: 网格业务 + * @Author: WangGeng + * @Date: 2020/10/21 11:16 + * @Version: 1.0 + **/ +@Repository +public interface IGridDao { + /** + * 保存网格 + * + * @param params + * @throws SaveException + */ + void saveGrid(Map params) throws SaveException; + + /** + * 保存网格关联关系 + * + * @param params + * @throws SaveException + */ + void saveGridRelation(Map params) throws SaveException; + + /** + * 保存网格点 + * + * @param params + * @throws SaveException + */ + void saveGridPoint(Map params) throws SaveException; + + /** + * 删除网格 + * + * @param params + * @throws RemoveException + */ + void deleteGrid(Map params) throws RemoveException; + + /** + * 删除网格点 + * + * @param params + * @throws RemoveException + */ + void deleteGridPoint(Map params) throws RemoveException; + + /** + * 删除网格关联关系 + * + * @param params + * @throws RemoveException + */ + void deleteGridRelation(Map params) throws RemoveException; + + /** + * 获取关联关系列表 + * + * @param params + * @return + * @throws SearchException + */ + List listGridRelation(Map params) throws SearchException; + + /** + * 获取网格列表(通过关联ID) + * + * @param areaId + * @return + * @throws SearchException + */ + List listGridByRelationId(String areaId) throws SearchException; + + /** + * 获取网格点列表(通过网格ID) + * + * @param gridId + * @return + * @throws SearchException + */ + List listPointByGridId(String gridId) throws SearchException; +} diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridDTO.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridDTO.java new file mode 100644 index 0000000..57fba7e --- /dev/null +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridDTO.java @@ -0,0 +1,84 @@ +package com.cm.plugin.map.pojo.dto; + +import com.cm.plugin.map.pojo.vo.GridPointVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: GridDTO + * @Description: 网格 + * @Author: WangGeng + * @Date: 2020/10/21 17:01 + * @Version: 1.0 + **/ +@ApiModel +public class GridDTO extends GridRelationDTO { + + @ApiModelProperty(name = "fillColor", value = "填充颜色") + private String fillColor; + @ApiModelProperty(name = "gridName", value = "网格名称") + private String gridName; + @ApiModelProperty(name = "relationIdArray", value = "关联ID列表") + private List relationIdArray; + @ApiModelProperty(name = "pointArray", value = "网格点列表") + private List pointArray; + + public String getFillColor() { + return fillColor == null ? "" : fillColor.trim(); + } + + public void setFillColor(String fillColor) { + this.fillColor = fillColor; + } + + public String getGridName() { + return gridName == null ? "" : gridName.trim(); + } + + public void setGridName(String gridName) { + this.gridName = gridName; + } + + public List getRelationIdArray() { + if (relationIdArray == null) { + return new ArrayList<>(); + } + return relationIdArray; + } + + public void setRelationIdArray(List relationIdArray) { + this.relationIdArray = relationIdArray; + } + + public List getPointArray() { + if (pointArray == null) { + return new ArrayList<>(); + } + return pointArray; + } + + public void setPointArray(List pointArray) { + this.pointArray = pointArray; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"fillColor\":\"") + .append(fillColor).append('\"'); + sb.append(",\"gridName\":\"") + .append(gridName).append('\"'); + sb.append(",\"relationIdArray\":") + .append(relationIdArray); + sb.append(",\"pointArray\":") + .append(pointArray); + sb.append('}'); + return sb.toString(); + } +} diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridPointDTO.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridPointDTO.java new file mode 100644 index 0000000..29bb376 --- /dev/null +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridPointDTO.java @@ -0,0 +1,62 @@ +package com.cm.plugin.map.pojo.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: BaiduGridPointVO + * @Description: 百度地图网格点 + * @Author: WangGeng + * @Date: 2020/10/21 11:02 + * @Version: 1.0 + **/ +@ApiModel +public class GridPointDTO { + + @ApiModelProperty(name = "gridId", value = "网格ID") + private String gridId; + @ApiModelProperty(name = "lng", value = "经度") + private String lng; + @ApiModelProperty(name = "lat", value = "纬度") + private String lat; + + public String getGridId() { + return gridId == null ? "" : gridId.trim(); + } + + public void setGridId(String gridId) { + this.gridId = gridId; + } + + public String getLng() { + return lng == null ? "" : lng.trim(); + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat == null ? "" : lat.trim(); + } + + public void setLat(String lat) { + this.lat = lat; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"gridId\":\"") + .append(gridId).append('\"'); + sb.append(",\"lng\":\"") + .append(lng).append('\"'); + sb.append(",\"lat\":\"") + .append(lat).append('\"'); + sb.append('}'); + return sb.toString(); + } +} diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridRelationDTO.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridRelationDTO.java new file mode 100644 index 0000000..ed31a49 --- /dev/null +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/dto/GridRelationDTO.java @@ -0,0 +1,53 @@ +package com.cm.plugin.map.pojo.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: GridRelationDTO + * @Description: 网格关联 + * @Author: WangGeng + * @Date: 2020/10/21 12:11 + * @Version: 1.0 + **/ +@ApiModel +public class GridRelationDTO implements Serializable { + + private static final long serialVersionUID = 9159203095930603288L; + @ApiModelProperty(name = "gridId", value = "网格ID") + private String gridId; + @ApiModelProperty(name = "relationId", value = "关联ID") + private String relationId; + + public String getGridId() { + return gridId == null ? "" : gridId.trim(); + } + + public void setGridId(String gridId) { + this.gridId = gridId; + } + + public String getRelationId() { + return relationId == null ? "" : relationId.trim(); + } + + public void setRelationId(String relationId) { + this.relationId = relationId; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"gridId\":\"") + .append(gridId).append('\"'); + sb.append(",\"relationId\":\"") + .append(relationId).append('\"'); + sb.append('}'); + return sb.toString(); + } +} diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/vo/GridPointVO.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/vo/GridPointVO.java new file mode 100644 index 0000000..48f7503 --- /dev/null +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/vo/GridPointVO.java @@ -0,0 +1,62 @@ +package com.cm.plugin.map.pojo.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: BaiduGridPointVO + * @Description: 百度地图网格点 + * @Author: WangGeng + * @Date: 2020/10/21 11:02 + * @Version: 1.0 + **/ +@ApiModel +public class GridPointVO { + + @ApiModelProperty(name = "gridId", value = "网格ID") + private String gridId; + @ApiModelProperty(name = "lng", value = "经度") + private String lng; + @ApiModelProperty(name = "lat", value = "纬度") + private String lat; + + public String getGridId() { + return gridId == null ? "" : gridId.trim(); + } + + public void setGridId(String gridId) { + this.gridId = gridId; + } + + public String getLng() { + return lng == null ? "" : lng.trim(); + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat == null ? "" : lat.trim(); + } + + public void setLat(String lat) { + this.lat = lat; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"gridId\":\"") + .append(gridId).append('\"'); + sb.append(",\"lng\":\"") + .append(lng).append('\"'); + sb.append(",\"lat\":\"") + .append(lat).append('\"'); + sb.append('}'); + return sb.toString(); + } +} diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/vo/GridVO.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/vo/GridVO.java new file mode 100644 index 0000000..15afacd --- /dev/null +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/pojo/vo/GridVO.java @@ -0,0 +1,83 @@ +package com.cm.plugin.map.pojo.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: BaiduGridVO + * @Description: 百度地图网格 + * @Author: WangGeng + * @Date: 2020/10/21 11:02 + * @Version: 1.0 + **/ +@ApiModel +public class GridVO { + + @ApiModelProperty(name = "fillColor", value = "填充颜色") + private String fillColor; + @ApiModelProperty(name = "gridName", value = "网格名称") + private String gridName; + @ApiModelProperty(name = "relationIdArray", value = "关联ID列表") + private List relationIdArray; + @ApiModelProperty(name = "pointArray", value = "网格点列表") + private List pointArray; + + public String getFillColor() { + return fillColor == null ? "" : fillColor.trim(); + } + + public void setFillColor(String fillColor) { + this.fillColor = fillColor; + } + + public String getGridName() { + return gridName == null ? "" : gridName.trim(); + } + + public void setGridName(String gridName) { + this.gridName = gridName; + } + + public List getRelationIdArray() { + if (relationIdArray == null) { + return new ArrayList<>(); + } + return relationIdArray; + } + + public void setRelationIdArray(List relationIdArray) { + this.relationIdArray = relationIdArray; + } + + public List getPointArray() { + if (pointArray == null) { + return new ArrayList<>(); + } + return pointArray; + } + + public void setPointArray(List pointArray) { + this.pointArray = pointArray; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"fillColor\":\"") + .append(fillColor).append('\"'); + sb.append(",\"gridName\":") + .append(gridName); + sb.append(",\"relationIdArray\":") + .append(relationIdArray); + sb.append(",\"pointArray\":") + .append(pointArray); + sb.append('}'); + return sb.toString(); + } +} diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/IGridService.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/IGridService.java new file mode 100644 index 0000000..2b8ec44 --- /dev/null +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/IGridService.java @@ -0,0 +1,57 @@ +package com.cm.plugin.map.service; + +import com.cm.common.exception.RemoveException; +import com.cm.common.exception.SearchException; +import com.cm.plugin.map.pojo.dto.GridDTO; +import com.cm.plugin.map.pojo.dto.GridRelationDTO; +import com.cm.plugin.map.pojo.vo.GridVO; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: IGridService + * @Description: 网格业务 + * @Author: WangGeng + * @Date: 2020/10/21 11:14 + * @Version: 1.0 + **/ +public interface IGridService { + + /** + * 保存网格并返回ID + * + * @param gridVO + * @return + * @throws Exception + */ + void saveGrid(GridVO gridVO) throws Exception; + + /** + * 通过关联关系删除网格 + * + * @param relationId + * @throws RemoveException + */ + void deleteGridByRelationId(String relationId) throws RemoveException; + + /** + * 获取网格关系列表 + * + * @param relationId + * @return + * @throws SearchException + */ + List listGridRelationByRelationId(String relationId) throws SearchException; + + /** + * 获取网格列表(通过关联ID) + * @param areaId + * @return + * @throws SearchException + */ + List listGridByRelationId(String areaId) throws SearchException; +} diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/impl/GridServiceImpl.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/impl/GridServiceImpl.java new file mode 100644 index 0000000..bfaa290 --- /dev/null +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/impl/GridServiceImpl.java @@ -0,0 +1,134 @@ +package com.cm.plugin.map.service.impl; + +import com.cm.common.base.AbstractService; +import com.cm.common.exception.RemoveException; +import com.cm.common.exception.SearchException; +import com.cm.common.utils.HashMapUtil; +import com.cm.common.utils.UUIDUtil; +import com.cm.plugin.map.dao.IGridDao; +import com.cm.plugin.map.pojo.dto.GridDTO; +import com.cm.plugin.map.pojo.dto.GridPointDTO; +import com.cm.plugin.map.pojo.dto.GridRelationDTO; +import com.cm.plugin.map.pojo.vo.GridPointVO; +import com.cm.plugin.map.pojo.vo.GridVO; +import com.cm.plugin.map.service.IGridService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: GridServiceImpl + * @Description: 网格业务 + * @Author: WangGeng + * @Date: 2020/10/21 11:14 + * @Version: 1.0 + **/ +@Service +public class GridServiceImpl extends AbstractService implements IGridService { + + @Autowired + private IGridDao gridDao; + + @Override + public void saveGrid(GridVO gridVO) throws Exception { + String gridId = UUIDUtil.getUUID(); + List relationIdArray = gridVO.getRelationIdArray(); + List pointArray = gridVO.getPointArray(); + // 保存网格 + Map params = HashMapUtil.beanToMap(gridVO); + params.put("gridId", gridId); + params.remove("relationIdArray"); + params.remove("pointArray"); + setSaveInfo(params); + gridDao.saveGrid(params); + // 保存拓展属性 + saveRelationIdArray(gridId, relationIdArray); + savePointArray(gridId, pointArray); + } + + @Override + public void deleteGridByRelationId(String relationId) throws RemoveException { + List gridRelationDTOs = listGridRelationByRelationId(relationId); + if (gridRelationDTOs.isEmpty()) { + return; + } + List gridIds = new ArrayList<>(); + for (GridRelationDTO gridRelationDTO : gridRelationDTOs) { + gridIds.add(gridRelationDTO.getGridId()); + } + Map params = getHashMap(2); + params.put("gridIds", gridIds); + // 删除网格 + gridDao.deleteGrid(params); + // 删除网格点 + gridDao.deleteGridPoint(params); + // 删除关联关系 + params.clear(); + params.put("relationId", relationId); + gridDao.deleteGridRelation(params); + } + + @Override + public List listGridRelationByRelationId(String relationId) throws SearchException { + Map params = getHashMap(2); + params.put("relationId", relationId); + return gridDao.listGridRelation(params); + } + + @Override + public List listGridByRelationId(String areaId) throws SearchException { + List gridDTOs = gridDao.listGridByRelationId(areaId); + if (gridDTOs.isEmpty()) { + return gridDTOs; + } + for (GridDTO gridDTO : gridDTOs) { + List gridPointDTOs = gridDao.listPointByGridId(gridDTO.getGridId()); + gridDTO.setPointArray(gridPointDTOs); + } + return gridDTOs; + } + + /** + * 保存关联关系 + * + * @param gridId + * @param relationIdArray + */ + private void saveRelationIdArray(String gridId, List relationIdArray) { + if (relationIdArray == null || relationIdArray.isEmpty()) { + return; + } + Map params = getHashMap(4); + params.put("gridId", gridId); + for (String relationId : relationIdArray) { + params.put("relationId", relationId); + gridDao.saveGridRelation(params); + } + } + + /** + * 保存网格点 + * + * @param gridId + * @param pointArray + */ + private void savePointArray(String gridId, List pointArray) { + if (pointArray == null || pointArray.isEmpty()) { + return; + } + Map params = getHashMap(4); + params.put("gridId", gridId); + for (GridPointVO gridPointVO : pointArray) { + params.put("lng", gridPointVO.getLng()); + params.put("lat", gridPointVO.getLat()); + gridDao.saveGridPoint(params); + } + } + +} diff --git a/cloud-common-plugin-map/src/main/resources/mybatis/mapper/grid-mapper.xml b/cloud-common-plugin-map/src/main/resources/mybatis/mapper/grid-mapper.xml new file mode 100644 index 0000000..717cba8 --- /dev/null +++ b/cloud-common-plugin-map/src/main/resources/mybatis/mapper/grid-mapper.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO map_grid( + grid_id, + grid_name, + fill_color, + gmt_create, + creator, + gmt_modified, + modifier, + is_delete + ) VALUES( + #{gridId}, + #{gridName}, + #{fillColor}, + #{gmtCreate}, + #{creator}, + #{gmtModified}, + #{modifier}, + #{isDelete} + ) + + + + + INSERT INTO map_grid_relation( + grid_id, + relation_id + ) VALUES( + #{gridId}, + #{relationId} + ) + + + + + DELETE FROM + map_grid + WHERE + + grid_id IN + + #{gridIds[${index}]} + + + + + + + DELETE FROM + map_grid_point + WHERE + + grid_id IN + + #{gridIds[${index}]} + + + + + + + DELETE FROM + map_grid_relation + WHERE + + relation_id = #{relationId} + + + + + + INSERT INTO map_grid_point( + grid_id, + lng, + lat + ) VALUES( + #{gridId}, + #{lng}, + #{lat} + ) + + + + + + + + + + + + \ No newline at end of file diff --git a/cloud-common-plugin-map/src/main/resources/templates/baidu/update-grid.html b/cloud-common-plugin-map/src/main/resources/templates/baidu/update-grid.html new file mode 100644 index 0000000..c2bfcb5 --- /dev/null +++ b/cloud-common-plugin-map/src/main/resources/templates/baidu/update-grid.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file From 25185405c3f765b0741b5d54fa3e8fb4ee88c7e4 Mon Sep 17 00:00:00 2001 From: wenc000 <450292408@qq.com> Date: Fri, 23 Oct 2020 18:05:48 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/cm/plugin/map/dao/IGridDao.java | 28 ++++++++++++--- .../cm/plugin/map/service/IGridService.java | 16 +++++++-- .../map/service/impl/GridServiceImpl.java | 36 +++++++++++++++++-- .../resources/mybatis/mapper/grid-mapper.xml | 36 +++++++++++++++++++ 4 files changed, 106 insertions(+), 10 deletions(-) diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/dao/IGridDao.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/dao/IGridDao.java index d732edd..2d8431b 100644 --- a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/dao/IGridDao.java +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/dao/IGridDao.java @@ -81,20 +81,38 @@ public interface IGridDao { List listGridRelation(Map params) throws SearchException; /** - * 获取网格列表(通过关联ID) + * 获取网格列表 * - * @param areaId + * @param relationId 关联ID * @return * @throws SearchException */ - List listGridByRelationId(String areaId) throws SearchException; + List listGridByRelationId(String relationId) throws SearchException; /** - * 获取网格点列表(通过网格ID) + * 获取网格点列表 * - * @param gridId + * @param gridId 网格ID * @return * @throws SearchException */ List listPointByGridId(String gridId) throws SearchException; + + /** + * 获取网格点列表 + * + * @param relationIds 关联ID列表 + * @return + * @throws SearchException + */ + List listGridByRelationIds(List relationIds) throws SearchException; + + /** + * 获取网格点列表 + * + * @param gridIds 网格ID列表 + * @return + * @throws SearchException + */ + List listPointByGridIds(List gridIds) throws SearchException; } diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/IGridService.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/IGridService.java index 2b8ec44..c6345c7 100644 --- a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/IGridService.java +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/IGridService.java @@ -48,10 +48,20 @@ public interface IGridService { List listGridRelationByRelationId(String relationId) throws SearchException; /** - * 获取网格列表(通过关联ID) - * @param areaId + * 获取网格列表 + * + * @param relationId 关联ID * @return * @throws SearchException */ - List listGridByRelationId(String areaId) throws SearchException; + List listGridByRelationId(String relationId) throws SearchException; + + /** + * 获取网格列表 + * + * @param relationIds 关联ID列表 + * @return + * @throws SearchException + */ + List listGridByRelationIds(List relationIds) throws SearchException; } diff --git a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/impl/GridServiceImpl.java b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/impl/GridServiceImpl.java index bfaa290..82f1b12 100644 --- a/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/impl/GridServiceImpl.java +++ b/cloud-common-plugin-map/src/main/java/com/cm/plugin/map/service/impl/GridServiceImpl.java @@ -1,5 +1,6 @@ package com.cm.plugin.map.service.impl; +import com.alibaba.druid.util.StringUtils; import com.cm.common.base.AbstractService; import com.cm.common.exception.RemoveException; import com.cm.common.exception.SearchException; @@ -82,8 +83,8 @@ public class GridServiceImpl extends AbstractService implements IGridService { } @Override - public List listGridByRelationId(String areaId) throws SearchException { - List gridDTOs = gridDao.listGridByRelationId(areaId); + public List listGridByRelationId(String relationId) throws SearchException { + List gridDTOs = gridDao.listGridByRelationId(relationId); if (gridDTOs.isEmpty()) { return gridDTOs; } @@ -94,6 +95,37 @@ public class GridServiceImpl extends AbstractService implements IGridService { return gridDTOs; } + @Override + public List listGridByRelationIds(List relationIds) throws SearchException { + if (relationIds == null && relationIds.size() == 0) { + return new ArrayList<>(); + } + List gridDTOs = gridDao.listGridByRelationIds(relationIds); + if (gridDTOs.isEmpty()) { + return gridDTOs; + } + List gridIds = new ArrayList<>(); + for (GridDTO gridDTO : gridDTOs) { + gridIds.add(gridDTO.getGridId()); + } + // 获取所有点 + List gridPointDTOs = gridDao.listPointByGridIds(gridIds); + if (gridPointDTOs.isEmpty()) { + return gridDTOs; + } + // 构建所有点 + for (GridDTO gridDTO : gridDTOs) { + List pointArray = new ArrayList<>(); + for (GridPointDTO gridPointDTO : gridPointDTOs) { + if (StringUtils.equals(gridDTO.getGridId(), gridPointDTO.getGridId())) { + pointArray.add(gridPointDTO); + } + } + gridDTO.setPointArray(pointArray); + } + return gridDTOs; + } + /** * 保存关联关系 * diff --git a/cloud-common-plugin-map/src/main/resources/mybatis/mapper/grid-mapper.xml b/cloud-common-plugin-map/src/main/resources/mybatis/mapper/grid-mapper.xml index 717cba8..8c47965 100644 --- a/cloud-common-plugin-map/src/main/resources/mybatis/mapper/grid-mapper.xml +++ b/cloud-common-plugin-map/src/main/resources/mybatis/mapper/grid-mapper.xml @@ -137,6 +137,27 @@ t2.relation_id = #{_parameter} + + + + + \ No newline at end of file From d460eb504fda5f1e083c62012bd704b54f956c1c Mon Sep 17 00:00:00 2001 From: wenc000 <450292408@qq.com> Date: Mon, 26 Oct 2020 10:55:50 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/cm/common/plugin/IApiConsts.java | 8 + .../controller/apis/user/UserController.java | 58 ++- .../oauth/service/user/IUserService.java | 40 +- .../service/user/impl/UserServiceImpl.java | 33 +- .../user/select-department-user.html | 478 ++++++++++++------ 5 files changed, 420 insertions(+), 197 deletions(-) diff --git a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/IApiConsts.java b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/IApiConsts.java index b82c6e4..c47ead3 100644 --- a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/IApiConsts.java +++ b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/IApiConsts.java @@ -182,5 +182,13 @@ public interface IApiConsts { * 获取所在部门用户列表(通过职位ID列表) */ String LIST_USER_DEPARTMENT_RESOURCE_BY_POSITION_IDS = "%s/resource/user/listuserdepartmentresourcebypositionids"; + /** + * 组织部门人员分页列表 + */ + String LIST_SELECT_DEPARTMENT_USER = "%s/resource/user/listselectdepartmentuser/%s"; + /** + * 通过id列表获取用户ID + */ + String LIST_PAGE_SELECT_DEPARTMENT_USER = "%s/resource/user/listpageselectdepartmentuser/%s"; } diff --git a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/controller/apis/user/UserController.java b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/controller/apis/user/UserController.java index 0e21b82..177dc76 100644 --- a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/controller/apis/user/UserController.java +++ b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/controller/apis/user/UserController.java @@ -11,13 +11,16 @@ import com.cm.common.exception.SearchException; import com.cm.common.exception.UpdateException; import com.cm.common.plugin.oauth.service.user.IUserService; import com.cm.common.plugin.pojo.bos.UserResourceBO; +import com.cm.common.pojo.ListPage; import com.cm.common.result.ErrorResult; import com.cm.common.result.SuccessResult; import com.cm.common.result.SuccessResultList; import io.swagger.annotations.*; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -87,18 +90,6 @@ public class UserController extends AbstractController { return userService.listPositionUsers(params); } - @ApiOperation(value = "通过用户ID获取用户列表", notes = "通过用户ID获取用户列表接口") - @ApiImplicitParams({ - @ApiImplicitParam(name = "userIds", value = "用不ID列表", paramType = "path") - }) - @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) - @GetMapping("listuserbyids/{userIds}") - public JSONArray listUserByIds(@PathVariable("userIds") String userIds) throws AccessTokenException, SearchException { - Map params = getParams(); - params.put("userIds", userIds); - return userService.listUserByIds(params); - } - @ApiOperation(value = "全部用户列表", notes = "全部用户列表接口") @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) @GetMapping("listallusers") @@ -189,4 +180,47 @@ public class UserController extends AbstractController { return userService.listPageUserSimple(params); } + @ApiOperation(value = "组织部门人员列表", notes = "组织部门人员列表接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "departmentId", value = "部门ID", paramType = "path"), + @ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("listselectdepartmentuser/{departmentId}") + public JSONArray listSelectDepartmentUser(@PathVariable("departmentId") String departmentId) throws SearchException { + return userService.listSelectDepartmentUser(departmentId); + } + + @ApiOperation(value = "组织部门人员分页列表", notes = "组织部门人员分页列表接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "departmentId", value = "部门ID", paramType = "path"), + @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"), + @ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"), + @ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query", dataType = "String"), + @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"), + @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "String") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("listpageselectdepartmentuser/{departmentId}") + public JSONObject listPageSelectDepartmentUser(@PathVariable("departmentId") String departmentId, ListPage page) throws SearchException { + Map params = requestParams(); + page.setParams(params); + return userService.listPageSelectDepartmentUserByDepartmentId(departmentId, page); + } + + @ApiOperation(value = "通过ID列表获取用户列表", notes = "通过ID列表获取用户列表接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "userIds", value = "用户ID列表,用下划线分隔,如:1_2_3", paramType = "body") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @PostMapping("listuserbyids") + public JSONArray listUserByIds(@RequestBody Map params) throws SearchException, ParamsException { + if (params.get("selectedUserIds") == null || StringUtils.isBlank(params.get("selectedUserIds").toString())) { + throw new ParamsException("用户列表不能为空"); + } + params.put("userIds", params.get("selectedUserIds")); + params.remove("selectedUserIds"); + return userService.listUserByIds(params); + } + } \ No newline at end of file diff --git a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/service/user/IUserService.java b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/service/user/IUserService.java index 46b446d..fb8488c 100644 --- a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/service/user/IUserService.java +++ b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/service/user/IUserService.java @@ -6,6 +6,7 @@ import com.cm.common.exception.AccessTokenException; import com.cm.common.exception.SearchException; import com.cm.common.plugin.pojo.bos.UserResourceBO; import com.cm.common.plugin.pojo.bos.user.UserDepartmentResourceBO; +import com.cm.common.pojo.ListPage; import com.cm.common.result.SuccessResult; import com.cm.common.result.SuccessResultList; import org.aspectj.lang.annotation.DeclareError; @@ -68,17 +69,6 @@ public interface IUserService { @Deprecated JSONArray listPositionUsers(Map params) throws AccessTokenException, SearchException; - /** - * 通过id列表获取用户ID - * - * @param params - * @return - * @throws AccessTokenException - * @throws SearchException - */ - @Deprecated - JSONArray listUserByIds(Map params) throws AccessTokenException, SearchException; - /** * 全部用户 * @@ -331,4 +321,32 @@ public interface IUserService { */ List listUserDepartmentResourceByPositionIds(List positionIds) throws SearchException; + /** + * 获取选择的部门用户(插件用) + * + * @param params + * @return + * @throws SearchException + */ + JSONArray listSelectDepartmentUser(String departmentId) throws AccessTokenException, SearchException; + + /** + * 组织部门人员分页列表(插件用) + * + * @param departmentId + * @param page + * @return + * @throws SearchException + */ + JSONObject listPageSelectDepartmentUserByDepartmentId(String departmentId, ListPage page) throws AccessTokenException, SearchException; + + /** + * 通过id列表获取用户ID(插件用) + * + * @param params + * @return + * @throws AccessTokenException + * @throws SearchException + */ + JSONArray listUserByIds(Map params) throws AccessTokenException, SearchException; } diff --git a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/service/user/impl/UserServiceImpl.java b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/service/user/impl/UserServiceImpl.java index 80af27c..ff149db 100644 --- a/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/service/user/impl/UserServiceImpl.java +++ b/cloud-common-plugin-oauth/src/main/java/com/cm/common/plugin/oauth/service/user/impl/UserServiceImpl.java @@ -13,6 +13,7 @@ import com.cm.common.plugin.oauth.token.ClientTokenManager; import com.cm.common.plugin.pojo.bos.UserResourceBO; import com.cm.common.plugin.pojo.bos.user.UserDepartmentResourceBO; import com.cm.common.plugin.utils.RestTemplateUtil; +import com.cm.common.pojo.ListPage; import com.cm.common.result.SuccessResult; import com.cm.common.result.SuccessResultList; import org.apache.commons.lang3.StringUtils; @@ -71,13 +72,6 @@ public class UserServiceImpl extends AbstractService implements IUserService { return JSONArray.parseArray(result); } - @Override - public JSONArray listUserByIds(Map params) throws AccessTokenException, SearchException { - String result = restTemplateUtil.doPostForm(String.format(IApiConsts.LIST_USER_BY_ID, apiPathProperties.getUserCenter()), params); - searchResourceResult(result, "获取人员列表失败"); - return JSONArray.parseArray(result); - } - @Override public JSONArray listAllUsers(Map params) throws AccessTokenException, SearchException { String result = restTemplateUtil.doPostForm(String.format(IApiConsts.LIST_ALL_USER, apiPathProperties.getUserCenter()), params); @@ -380,4 +374,29 @@ public class UserServiceImpl extends AbstractService implements IUserService { searchResourceResult(result, "获取人员信息失败"); return JSONArray.parseArray(result, UserDepartmentResourceBO.class); } + + @Override + public JSONArray listSelectDepartmentUser(String departmentId) throws SearchException { + Map params = getHashMap(2); + params.put(IApiConsts.ACCESS_TOKEN, ClientTokenManager.getInstance().getClientToken().getAccessToken()); + String result = restTemplateUtil.doGetFormNormal(String.format(IApiConsts.LIST_SELECT_DEPARTMENT_USER, apiPathProperties.getUserCenter(), departmentId), params); + searchResourceResult(result, "获取组织部门人员列表失败"); + return JSONArray.parseArray(result); + } + + @Override + public JSONObject listPageSelectDepartmentUserByDepartmentId(String departmentId, ListPage page) throws SearchException { + page.getParams().put(IApiConsts.ACCESS_TOKEN, ClientTokenManager.getInstance().getClientToken().getAccessToken()); + String result = restTemplateUtil.doGetFormNormal(String.format(IApiConsts.LIST_PAGE_SELECT_DEPARTMENT_USER, apiPathProperties.getUserCenter(), departmentId), page.getParams()); + searchResourceResult(result, "获取组织部门人员分页列表失败"); + return JSONObject.parseObject(result); + } + + @Override + public JSONArray listUserByIds(Map params) throws AccessTokenException, SearchException { + params.put(IApiConsts.ACCESS_TOKEN, ClientTokenManager.getInstance().getClientToken().getAccessToken()); + String result = restTemplateUtil.doPostFormNormal(String.format(IApiConsts.LIST_USER_BY_ID, apiPathProperties.getUserCenter()), params); + searchResourceResult(result, "获取人员列表失败"); + return JSONArray.parseArray(result); + } } diff --git a/cloud-common-plugin-oauth/src/main/resources/templates/user/select-department-user.html b/cloud-common-plugin-oauth/src/main/resources/templates/user/select-department-user.html index eaedeee..9b77e11 100644 --- a/cloud-common-plugin-oauth/src/main/resources/templates/user/select-department-user.html +++ b/cloud-common-plugin-oauth/src/main/resources/templates/user/select-department-user.html @@ -1,193 +1,337 @@ - - - - - - - - - - - - - - -
-
-
-
-
-
-
    + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    -
    -
    -