commit 0d04141af82a1d49de7344190cdb5afa8a0d569a
Author: 15989082884@163.com <15989082884@163.com>
Date: Tue Jun 6 12:01:14 2023 +0800
first init
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..1d605f6
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,78 @@
+
+
+ 4.0.0
+
+ org.example
+ jsl_crm_xlt_sync
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.4
+
+
+
+ 8
+ 8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.24
+
+
+ mysql
+ mysql-connector-java
+ 8.0.15
+
+
+ com.microsoft.sqlserver
+ mssql-jdbc
+ 8.4.1.jre8
+
+
+ org.noear
+ wood
+ 1.0.7
+
+
+ junit
+ junit
+ 4.13.1
+ compile
+
+
+ org.apache.commons
+ commons-lang3
+ 3.7
+
+
+
+
+ serve
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 2.6.4
+
+
+
+
+
diff --git a/src/main/java/com/qs/Application.java b/src/main/java/com/qs/Application.java
new file mode 100644
index 0000000..1a50d52
--- /dev/null
+++ b/src/main/java/com/qs/Application.java
@@ -0,0 +1,46 @@
+package com.qs;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import java.util.TimeZone;
+
+/**
+ * @author YenHex
+ * @since 2023/3/16
+ */
+@EnableAsync
+@EnableScheduling
+@EnableCaching
+@SpringBootApplication
+public class Application extends SpringBootServletInitializer {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class,args);
+ }
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ super.onStartup(servletContext);
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
+ return builder.sources(Application.class);
+ }
+
+ @PostConstruct
+ void started() {
+ TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
+ }
+
+
+}
diff --git a/src/main/java/com/qs/controller/SyncController.java b/src/main/java/com/qs/controller/SyncController.java
new file mode 100644
index 0000000..481f389
--- /dev/null
+++ b/src/main/java/com/qs/controller/SyncController.java
@@ -0,0 +1,51 @@
+package com.qs.controller;
+
+import com.qs.crm.BmsChannelSync;
+import com.qs.crm.BmsPointSync;
+import com.qs.crm.BmsSupplierSync;
+import com.qs.dto.R;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@Slf4j
+@AllArgsConstructor
+@RestController
+@RequestMapping("sync")
+public class SyncController {
+
+ private BmsSupplierSync supplierSync;
+ private BmsChannelSync channelSync;
+ private BmsPointSync pointSync;
+
+ @GetMapping("/syncAll")
+ public String syncAll() throws Exception {
+ supplierSync.syncSupplier();
+ channelSync.syncChannel();
+ pointSync.syncPoint();
+ return new String("1");
+ }
+
+ @GetMapping("/syncSupplier")
+ public String syncSupplier() throws Exception {
+ supplierSync.syncSupplier();
+ return new String("1");
+ }
+
+ @GetMapping("/syncChannel")
+ public String syncChannel() throws Exception {
+ channelSync.syncChannel();
+ return new String("1");
+ }
+
+ @GetMapping("/syncPoint")
+ public String syncPoint() throws Exception {
+ pointSync.syncPoint();
+ return new String("1");
+ }
+}
diff --git a/src/main/java/com/qs/crm/BmsChannelSync.java b/src/main/java/com/qs/crm/BmsChannelSync.java
new file mode 100644
index 0000000..3edac16
--- /dev/null
+++ b/src/main/java/com/qs/crm/BmsChannelSync.java
@@ -0,0 +1,105 @@
+package com.qs.crm;
+
+import com.qs.crm.entity.BmsChannel;
+import com.qs.crm.entity.BmsSupplierChannel;
+import com.qs.crm.xltentity.XltChannel;
+import com.qs.crm.xltentity.XltChannelDealer;
+import com.qs.util.DateUtils;
+import org.noear.wood.DbContext;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Component
+public class BmsChannelSync {
+
+ @Value("${xlt.url}")
+ String xltUrl;
+ @Value("${xlt.user}")
+ String xltUser;
+ @Value("${xlt.pass}")
+ String xltPass;
+
+ @Value("${jsl.url}")
+ String jslUrl;
+ @Value("${jsl.user}")
+ String jslUser;
+ @Value("${jsl.pass}")
+ String jslPass;
+
+ public DbContext getJslDbContext(){
+ return new DbContext("test",jslUrl,jslUser,jslPass);
+ }
+
+ public DbContext getXltDbContext(){
+ return new DbContext("xlt",xltUrl,xltUser,xltPass);
+ }
+
+ public void syncChannel() throws Exception {
+ DbContext jslDb = getJslDbContext();
+ DbContext xltDb = getXltDbContext();
+
+ Date day = DateUtils.nextDay(-30);
+
+ List channelList = xltDb.sql("SELECT t.name as channeltype ,s.* FROM DealerSystem s LEFT JOIN emp_quDaoTwo t on s.quDaoTwo = t.id WHERE s.isval = '0' and addDate>=?",day).getList(XltChannel.class);
+
+ List channels = new ArrayList<>();
+ for(XltChannel a:channelList){
+
+ if(jslDb.sql("select * from bms_channel where del_flag=0 and channel_code =? ",a.getNumber()).getList(BmsChannel.class).size()>0){
+ continue;
+ }
+
+ BmsChannel channel = new BmsChannel();
+ channel.setChannelCode(a.getNumber());
+ channel.setChannelName(a.getName());
+ channel.setChannelType(a.getChanneltype());
+ channel.setTenantId("001");
+ channel.setDelFlag("0");
+ channel.setCostFlag(1);
+// channels.add(channel);
+ Long channelId = jslDb.table("bms_channel").setEntity(channel).insert();
+ System.out.println(a.getNumber());
+
+ List channelDealers = xltDb.sql("select d.*,c.dealerNumber as dealer_number from emp_system_dealer d left join DealerConnTable c on d.dealer_id = c.id where d.system_id = ?",a.getId()).getList(XltChannelDealer.class);
+ if(channelDealers.size()>0) {
+ for (XltChannelDealer b : channelDealers) {
+
+ Long supId = (Long)jslDb.sql("select * from bms_supplier where del_flag=0 and code = ?",b.getDealer_number()).getMap().get("id");
+ if(supId==null){
+ System.out.println("缺少客户:"+a.getNumber());
+ continue;
+ }
+
+ if(jslDb.sql("select * from bms_supplier_channel where del_flag=0 and channel_id=? and supplier_id=?",
+ channelId,supId).getList(BmsSupplierChannel.class).size()>0){
+ continue;
+ }
+
+ BmsSupplierChannel supplierChannel = new BmsSupplierChannel();
+ supplierChannel.setChannelId(channelId);
+ supplierChannel.setSupplierId(supId);
+ supplierChannel.setTenantId("001");
+ supplierChannel.setDelFlag("0");
+ jslDb.table("bms_supplier_channel").setEntity(supplierChannel).insert();
+ }
+ }
+ };
+
+ System.out.println(channels.size());
+ }
+
+ public void syncChannelDealer() throws Exception {
+ DbContext jslDb = getJslDbContext();
+ DbContext xltDb = getXltDbContext();
+
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ new BmsChannelSync().syncChannel();
+ }
+}
diff --git a/src/main/java/com/qs/crm/BmsPointSync.java b/src/main/java/com/qs/crm/BmsPointSync.java
new file mode 100644
index 0000000..d1fcf98
--- /dev/null
+++ b/src/main/java/com/qs/crm/BmsPointSync.java
@@ -0,0 +1,128 @@
+package com.qs.crm;
+
+import com.qs.crm.entity.BmsChannel;
+import com.qs.crm.entity.BmsChannelPoint;
+import com.qs.crm.entity.BmsRegion2;
+import com.qs.crm.entity.BmsSupplierChannel;
+import com.qs.crm.xltentity.XltChannel;
+import com.qs.crm.xltentity.XltChannelDealer;
+import com.qs.crm.xltentity.XltPoint;
+import com.qs.util.DateUtils;
+import org.noear.wood.DbContext;
+import org.noear.wood.utils.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Component
+public class BmsPointSync {
+
+ @Value("${xlt.url}")
+ String xltUrl;
+ @Value("${xlt.user}")
+ String xltUser;
+ @Value("${xlt.pass}")
+ String xltPass;
+
+ @Value("${jsl.url}")
+ String jslUrl;
+ @Value("${jsl.user}")
+ String jslUser;
+ @Value("${jsl.pass}")
+ String jslPass;
+
+ public DbContext getJslDbContext(){
+ return new DbContext("test",jslUrl,jslUser,jslPass);
+ }
+
+ public DbContext getXltDbContext(){
+ return new DbContext("xlt",xltUrl,xltUser,xltPass);
+ }
+
+ public void syncPoint() throws Exception {
+ DbContext jslDb = getJslDbContext();
+ DbContext xltDb = getXltDbContext();
+
+ Date day = DateUtils.nextDay(-10);
+
+
+ String sql ="select w1.id,w1.number_,w1.name,xiancheng,chengshi,shengfen,w1.cashRegister as cash_register,w1.area as shop_area,w1.floor '店面层数',w1.xihuaDiDui '同品类地堆数',d2.number as channel_code,w1.sysId as sys_id " +
+ ",xihuaArer '同品类面积',xihuaDuanJia '同品类端架数',dentifriceShelf '同品类货架节数(各产品)',contactP,w3.phone,w3.email,w3.mobileTel " +
+ ",w1.addDate,w1.address,w1.dingWei_address,w2.WDTypeName as type_name ,wl.WDLevelName as level_name,d2.name sysName,d3.dealerNumber,d3.dealerName,d1.city,d4.province " +
+ "from emp_system_dealer e1 " +
+ "inner join DealerSystem d2 on e1.system_id = d2.id " +
+ "inner join WangDian w1 on d2.id = w1.sysId " +
+ "left join DealerConnTable d3 on e1.dealer_id = d3.id " +
+ "left join DealerCity d1 on d3.cid = d1.id " +
+ "left join DealerProvince d4 on d1.pid = d4.id " +
+ "left join DealerArea d5 on d5.id = d4.aid " +
+ "left join WDType w2 on w1.type = w2.id " +
+ "left join WDContact w3 on w1.id = w3.WDID " +
+ "left join WDLevel wl on w1.wdlevel = wl.id " +
+ "where w1.isval = 0 and d5.id = ? ";
+
+ String id = "40288a73601f131601602b0fbe010074";
+
+ List pointList = xltDb.sql(sql,id).getList(XltPoint.class);
+
+ for(XltPoint a:pointList) {
+
+ List points = jslDb.sql("select * from bms_channel_point where del_flag=0 and point_code = ?",a.getNumber_()).getList(BmsChannelPoint.class);
+ if(points.size()>0){
+ continue;
+ }
+
+ List channelList = jslDb.sql("select * from bms_channel where del_flag=0 and channel_code =? ",a.getChannel_code()).getList(BmsChannel.class);
+
+ if(channelList.size()==0){
+ continue;
+ }
+
+ BmsChannelPoint point = new BmsChannelPoint();
+ point.setChannelId(channelList.get(0).getId());
+ point.setChannelName(channelList.get(0).getChannelName());
+ point.setPointCode(a.getNumber_());
+ point.setPointName(a.getName());
+ if(a.getShop_area()!=null) {
+ point.setShopArea(a.getShop_area().toString());
+ }
+ point.setCountCheckstand(a.getCash_register());
+ point.setPointLevel(a.getLevel_name());
+ point.setPointType(a.getType_name());
+ point.setAddress(a.getAddress());
+ point.setTenantId("001");
+ point.setCostFlag(1);
+ point.setDelFlag("0");
+
+// BmsRegion2 region2 = jslDb.sql("select * from bms_region2 where del_flag=0 and name = ?",a.getXiancheng()).getItem(BmsRegion2.class);
+// if(region2==null || StringUtils.isEmpty(region2.getPathIds())){
+// System.out.println(a.getName());
+// }else{
+// String[] regionPath = region2.getPathIds().split("_");
+// if(regionPath.length!=3){
+// System.out.println(a.getName());
+// }else{
+// point.setBizRegionId(region2.getId());
+// point.setBizRegionPathIds(region2.getPathIds());
+// point.setBizRegionPath(region2.getPathNames());
+// }
+// }
+
+ jslDb.table("bms_channel_point").setEntity(point).insert();
+ }
+ }
+
+ public void syncChannelDealer() throws Exception {
+ DbContext jslDb = getJslDbContext();
+ DbContext xltDb = getXltDbContext();
+
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ new BmsPointSync().syncPoint();
+ }
+}
diff --git a/src/main/java/com/qs/crm/BmsSupplierSync.java b/src/main/java/com/qs/crm/BmsSupplierSync.java
new file mode 100644
index 0000000..055bd0b
--- /dev/null
+++ b/src/main/java/com/qs/crm/BmsSupplierSync.java
@@ -0,0 +1,158 @@
+package com.qs.crm;
+
+import com.qs.crm.entity.*;
+import com.qs.crm.xltentity.XltChannel;
+import com.qs.crm.xltentity.XltChannelDealer;
+import com.qs.crm.xltentity.XltDealer;
+import com.qs.crm.xltentity.XltDealerUser;
+import com.qs.util.DateUtils;
+import org.noear.wood.DbContext;
+import org.noear.wood.utils.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Component
+public class BmsSupplierSync {
+
+ @Value("${xlt.url}")
+ String xltUrl;
+ @Value("${xlt.user}")
+ String xltUser;
+ @Value("${xlt.pass}")
+ String xltPass;
+
+ @Value("${jsl.url}")
+ String jslUrl;
+ @Value("${jsl.user}")
+ String jslUser;
+ @Value("${jsl.pass}")
+ String jslPass;
+
+ public DbContext getJslDbContext(){
+ return new DbContext("test",jslUrl,jslUser,jslPass);
+ }
+
+ public DbContext getXltDbContext(){
+ return new DbContext("xlt",xltUrl,xltUser,xltPass);
+ }
+
+ public void syncSupplier() throws Exception {
+ DbContext jslDb = getJslDbContext();
+ DbContext xltDb = getXltDbContext();
+
+ Date day = DateUtils.nextDay(-10);
+
+ String sql =
+ "select d1.id,d1.address,d1.dealerName as dealer_name,d1.dealerNumber as dealer_number,d.districtName as district_name " +
+ "from DealerConnTable d1 " +
+ "left join District d on d.id = d1.xian where d1.addDate >= ?";
+ List dealerList = xltDb.sql(sql,day).getList(XltDealer.class);
+
+
+ for(XltDealer dealer:dealerList){
+ List supplierList = jslDb.sql("select * from bms_supplier where del_flag=0 and code = ?",dealer.getDealer_number()).getList(BmsSupplier.class);
+ if(supplierList.size()>0){
+ BmsSupplier supplier = supplierList.get(0);
+
+ if(supplier.getOtherUserIds()!=null && supplier.getOtherUserIds().length()>0){
+ continue;
+ }
+// 更新客户负责人
+ List dealerUsers = xltDb.sql("select f.*,e.numNo as num_no from franKHEMP f left join Employee e on f.KHEmp_ID=e.ID where fran_number=?",dealer.getDealer_number()).getList(XltDealerUser.class);
+ List sysUsers = new ArrayList<>();
+ for(XltDealerUser xltuser:dealerUsers){
+ List users = jslDb.sql("select * from sys_user where del_flag=0 and code = ?",xltuser.getNum_no()).getList(SysUser.class);
+ if(users.size()==0){
+ continue;
+ }
+ sysUsers.add(users.get(0));
+ }
+ if(sysUsers.size()>0){
+ List userNames = sysUsers.stream().map(a->a.getName()).distinct().collect(Collectors.toList());
+ List userCodes = sysUsers.stream().map(a->a.getCode()).distinct().collect(Collectors.toList());
+ List userIds = sysUsers.stream().map(a->a.getId()).distinct().collect(Collectors.toList());
+ supplier.setOtherUserIds(userIds.stream().collect(Collectors.joining(",")));
+ supplier.setOtherUserCodes(userCodes.stream().collect(Collectors.joining(",")));
+ supplier.setOtherUserNames(userNames.stream().collect(Collectors.joining(",")));
+
+ jslDb.table("bms_supplier").set("other_user_ids",supplier.getOtherUserIds())
+ .set("other_user_names",supplier.getOtherUserNames())
+ .set("other_user_codes",supplier.getOtherUserCodes())
+ .whereEq("id",supplier.getId()).update();
+ }
+ }else{
+
+// 新增客户
+ System.out.println(dealer.getDealer_number());
+ System.out.println(dealer.getDealer_name());
+
+ BmsSupplier bmsSupplier = new BmsSupplier();
+ bmsSupplier.setCode(dealer.getDealer_number());
+ bmsSupplier.setName(dealer.getDealer_name());
+ bmsSupplier.setTenantId("001");
+ bmsSupplier.setDelFlag(false);
+ bmsSupplier.setCostFlag(1);
+ bmsSupplier.setInitCurAmount(BigDecimal.ZERO);
+ bmsSupplier.setInitHisAmount(BigDecimal.ZERO);
+ bmsSupplier.setStopFlag(0);
+ bmsSupplier.setPid(0L);
+ bmsSupplier.setAddress(dealer.getAddress());
+
+ //付责人
+
+ List dealerUsers = xltDb.sql("select f.*,e.numNo as num_no from franKHEMP f left join Employee e on f.KHEmp_ID=e.ID where fran_number=?",dealer.getDealer_number()).getList(XltDealerUser.class);
+ List sysUsers = new ArrayList<>();
+ for(XltDealerUser xltuser:dealerUsers){
+ List users = jslDb.sql("select * from sys_user where del_flag=0 and code = ?",xltuser.getNum_no()).getList(SysUser.class);
+ if(users.size()==0){
+ continue;
+ }
+ sysUsers.add(users.get(0));
+ }
+ if(sysUsers.size()>0){
+ List userNames = sysUsers.stream().map(a->a.getName()).distinct().collect(Collectors.toList());
+ List userCodes = sysUsers.stream().map(a->a.getCode()).distinct().collect(Collectors.toList());
+ List userIds = sysUsers.stream().map(a->a.getId()).distinct().collect(Collectors.toList());
+ bmsSupplier.setOtherUserIds(userIds.stream().collect(Collectors.joining(",")));
+ bmsSupplier.setOtherUserCodes(userCodes.stream().collect(Collectors.joining(",")));
+ bmsSupplier.setOtherUserNames(userNames.stream().collect(Collectors.joining(",")));
+ }
+
+ //区域
+ BmsRegion2 region2 = jslDb.sql("select * from bms_region2 where del_flag=0 and name = ?",dealer.getDistrict_name()).getItem(BmsRegion2.class);
+ if(region2==null || StringUtils.isEmpty(region2.getPathIds())){
+ System.out.println(dealer.getDealer_name());
+ }else{
+ String[] regionPath = region2.getPathIds().split("_");
+
+ if(regionPath.length!=3){
+ System.out.println(dealer.getDealer_name());
+ }else{
+ bmsSupplier.setRegion2First(regionPath[0]);
+ bmsSupplier.setRegion2Second(regionPath[1]);
+ bmsSupplier.setRegion2Third(regionPath[2]);
+ bmsSupplier.setRegion2Last(regionPath[2]);
+ }
+ }
+
+ Long supplierId = jslDb.table("bms_supplier").setEntity(bmsSupplier).insert();
+
+
+ jslDb.table("bms_supplier").set("path_ids","0_"+supplierId).whereEq("id",supplierId).update();
+// bmsSupplier.setPathIds("");
+ System.out.println(dealer.getDealer_name());
+ }
+ }
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ new BmsSupplierSync().syncSupplier();
+ }
+}
diff --git a/src/main/java/com/qs/crm/entity/BmsChannel.java b/src/main/java/com/qs/crm/entity/BmsChannel.java
new file mode 100644
index 0000000..cf24770
--- /dev/null
+++ b/src/main/java/com/qs/crm/entity/BmsChannel.java
@@ -0,0 +1,67 @@
+package com.qs.crm.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 渠道 实体类
+ * @author YenHex
+ * @since 2022-11-07
+ */
+@Data
+public class BmsChannel implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private Long id;
+
+ /** 渠道编码 */
+ private String channelCode;
+
+ /** 渠道名称 */
+ private String channelName;
+
+ /** 渠道类型(读取数据字典) */
+ private String channelType;
+
+ /** 备注 */
+ private String remark;
+
+ /** 创建时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime createTime;
+
+ /** 最后更新时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime updateTime;
+
+ /** 所属租户 */
+ @JsonIgnore
+ @JsonProperty
+ private String tenantId;
+
+ /** 逻辑删除标记(0:显示;1:隐藏) */
+ @JsonIgnore
+ @JsonProperty
+ private String delFlag;
+
+ /** 创建人 */
+ private String createBy;
+
+ /** 更新人 */
+ private String updateBy;
+
+ /** 可投放费用标识 */
+ private Integer costFlag;
+
+}
+
diff --git a/src/main/java/com/qs/crm/entity/BmsChannelPoint.java b/src/main/java/com/qs/crm/entity/BmsChannelPoint.java
new file mode 100644
index 0000000..30b9584
--- /dev/null
+++ b/src/main/java/com/qs/crm/entity/BmsChannelPoint.java
@@ -0,0 +1,120 @@
+package com.qs.crm.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 渠道站点 实体类
+ * @author YenHex
+ * @since 2022-11-07
+ */
+@Data
+public class BmsChannelPoint implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private Long id;
+
+ /** 渠道名称 */
+ private Long channelId;
+
+ private String channelName;
+
+ /** 站点编码 */
+ private String pointCode;
+
+ /** 站点名称 */
+ private String pointName;
+
+ /** 店铺面积 */
+ private String shopArea;
+
+ /** 收银台数量 */
+ private Integer countCheckstand;
+
+ /** 站点等级(读取字典值) */
+ private String pointLevel;
+
+ /** 站点类型(读取字典值) */
+ private String pointType;
+
+ /** 详细地址 */
+ private String address;
+
+ /** 销售区域id */
+ private String saleRegionId;
+
+ /** 销售区域 */
+ private String saleRegionPath;
+
+ private String saleRegionPathIds;
+
+ /** 行政区域id */
+ private String bizRegionId;
+
+ /** 行政区域 */
+ private String bizRegionPath;
+
+ private String bizRegionPathIds;
+
+ /** 纬度 */
+ private String localX;
+
+ /** 经度 */
+ private String localY;
+
+ /** 地图地址 */
+ private String mapAddress;
+
+ /** 备注 */
+ private String remark;
+
+ /** 图片多张用句号隔开 */
+ private String[] photos;
+
+ /** 创建时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+ @JsonSerialize(using = LocalDateTimeSerializer.class)
+ private LocalDateTime createTime;
+
+ /** 最后更新时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+ @JsonSerialize(using = LocalDateTimeSerializer.class)
+ private LocalDateTime updateTime;
+
+ /** 所属租户 */
+ @JsonIgnore
+ @JsonProperty
+ private String tenantId;
+
+ /** 逻辑删除标记(0:显示;1:隐藏) */
+ @JsonIgnore
+ @JsonProperty
+ private String delFlag;
+
+ /** 可投放费用标识 */
+ private Integer costFlag;
+
+ /** 创建人 */
+ private String createBy;
+
+ /** 更新人 */
+ private String updateBy;
+
+}
+
diff --git a/src/main/java/com/qs/crm/entity/BmsRegion2.java b/src/main/java/com/qs/crm/entity/BmsRegion2.java
new file mode 100644
index 0000000..23494a7
--- /dev/null
+++ b/src/main/java/com/qs/crm/entity/BmsRegion2.java
@@ -0,0 +1,70 @@
+package com.qs.crm.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 区域档案 实体类
+ * @author YenHex
+ * @since 2022-10-10
+ */
+@Data
+public class BmsRegion2 implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private String id;
+
+ /** 名称 */
+ private String name;
+
+ /** 编码 */
+ private String code;
+
+ /** 父级ID */
+ private String pid;
+
+ /** 层级 */
+ private Integer level;
+
+ /** 祖级id */
+ private String pathIds;
+
+ /** 祖级id */
+ private String pathNames;
+
+ /** 创建时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime createTime;
+
+ /** 创建人 */
+ private String createBy;
+
+ /** 更新时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime updateTime;
+
+ /** 更新人 */
+ private String updateBy;
+
+ /** 租户id */
+ @JsonIgnore
+ @JsonProperty
+ private String tenantId;
+
+ /** 删除标识 */
+ @JsonIgnore
+ @JsonProperty
+ private Boolean delFlag;
+}
+
diff --git a/src/main/java/com/qs/crm/entity/BmsSupplier.java b/src/main/java/com/qs/crm/entity/BmsSupplier.java
new file mode 100644
index 0000000..534f5b8
--- /dev/null
+++ b/src/main/java/com/qs/crm/entity/BmsSupplier.java
@@ -0,0 +1,150 @@
+package com.qs.crm.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 供应商 实体类
+ * @author YenHex
+ * @since 2022-10-11
+ */
+@Data
+public class BmsSupplier implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private Long id;
+
+ /** 一级区域ID */
+ private String regionFirst;
+
+ /** 二级区域ID */
+ private String regionSecond;
+
+ /** 三级区域ID */
+ private String regionThird;
+
+ /** 四级区域ID */
+ private String regionFourthly;
+
+ /** 最子级区域ID */
+ private String regionLast;
+
+ /** 行政一级区域ID */
+ private String region2First;
+
+ /** 行政二级区域ID */
+ private String region2Second;
+
+ /** 行政三级区域ID */
+ private String region2Third;
+
+ /** 行政四级区域ID */
+ private String region2Fourthly;
+
+ /** 行政最子级区域ID */
+ private String region2Last;
+
+ /** 详细地址 */
+ private String address;
+
+ /** 名称 */
+ private String name;
+
+ /** 客户编码 */
+ private String code;
+
+ /** 父级id */
+ private Long pid;
+
+ private String pathIds;
+
+ private String parentCode;
+
+ /** 负责人 */
+ private String userId;
+
+ /** 负责人 */
+ private String userCode;
+
+ /** 负责人 */
+ private String userName;
+
+ private String otherUserIds;
+
+ private String otherUserNames;
+
+ private String otherUserCodes;
+
+ /** 停用 */
+ private Integer stopFlag;
+
+ /** 所属账套 */
+ private String belong;
+
+ /** 创建时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime createTime;
+
+ /** 创建人 */
+ private String createBy;
+
+ /** 更新时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime updateTime;
+
+ /** 更新人 */
+ private String updateBy;
+
+ /** 租户id */
+ @JsonIgnore
+ @JsonProperty
+ private String tenantId;
+
+ /** 删除标识 */
+ @JsonIgnore
+ @JsonProperty
+ private Boolean delFlag;
+
+ /** 初始化当前欠费 */
+ private BigDecimal initCurAmount;
+
+ /** 初始化欠费(历史记录) */
+ private BigDecimal initHisAmount;
+
+ /** 可投放费用标识 */
+ private Integer costFlag;
+
+
+ public List listBizRegionIds(){
+ List list = new ArrayList<>();
+ list.add(this.getRegion2First());
+ list.add(this.getRegion2Second());
+ list.add(this.getRegion2Third());
+ list.add(this.getRegion2Fourthly());
+ return list;
+ }
+
+ public List listSaleRegionIds(){
+ List list = new ArrayList<>();
+ list.add(this.getRegionFirst());
+ list.add(this.getRegionSecond());
+ list.add(this.getRegionThird());
+ list.add(this.getRegionFourthly());
+ return list;
+ }
+
+}
+
diff --git a/src/main/java/com/qs/crm/entity/BmsSupplierChannel.java b/src/main/java/com/qs/crm/entity/BmsSupplierChannel.java
new file mode 100644
index 0000000..8b01881
--- /dev/null
+++ b/src/main/java/com/qs/crm/entity/BmsSupplierChannel.java
@@ -0,0 +1,58 @@
+package com.qs.crm.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 客户渠道关系 实体类
+ * @author YenHex
+ * @since 2022-11-03
+ */
+@Data
+public class BmsSupplierChannel implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private Long id;
+
+ /** 渠道id */
+ private Long channelId;
+
+ /** 客户id */
+ private Long supplierId;
+
+ /** 创建时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime createTime;
+
+ /** 最后更新时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime updateTime;
+
+ /** 所属租户 */
+ @JsonIgnore
+ @JsonProperty
+ private String tenantId;
+
+ /** 逻辑删除标记(0:显示;1:隐藏) */
+ @JsonIgnore
+ @JsonProperty
+ private String delFlag;
+
+ /** 创建人 */
+ private String createBy;
+
+ /** 更新人 */
+ private String updateBy;
+
+}
+
diff --git a/src/main/java/com/qs/crm/entity/SysUser.java b/src/main/java/com/qs/crm/entity/SysUser.java
new file mode 100644
index 0000000..2b9b14f
--- /dev/null
+++ b/src/main/java/com/qs/crm/entity/SysUser.java
@@ -0,0 +1,106 @@
+package com.qs.crm.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 系统用户 实体类
+ * @author YenHex
+ * @since 2022-03-01
+ */
+@Data
+public class SysUser implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private String id;
+
+ /** 手机号 */
+ private String mobile;
+
+ /** 账号 */
+ private String account;
+
+ /** 昵称 */
+ private String name;
+
+ /** 编号/工号 */
+ private String code;
+
+ /** 密码 */
+ private String password;
+
+ /** 头像 */
+ private String icon;
+
+ /** 部门ID */
+ private String deptId;
+
+
+ /** 入职/复职日期 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
+ private LocalDate servingDate;
+
+ /** 离职或上一次离职的日期 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
+ private LocalDate servingLeaveDate;
+
+ /** 是否销售人员 */
+ private Integer salesFlag;
+
+ /** 身份证号码 */
+ private String identityNo;
+
+ /** 备注 */
+ private String remark;
+
+
+ /** 登陆客户端标识:android,ios */
+ private String appClient;
+
+ /** app推送token */
+ private String appToken;
+
+ /** 致远登陆账户 */
+ private String syAccount;
+
+ /** 致远用户id */
+ private String syUserId;
+
+
+ /** 创建时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime createTime;
+
+ /** 创建人 */
+ private String createBy;
+
+ /** 更新时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime updateTime;
+
+ /** 更新人 */
+ private String updateBy;
+
+ /** 删除标识 */
+ @JsonIgnore
+ private Boolean delFlag;
+
+ /** 校区id */
+ @JsonIgnore
+ private String tenantId;
+
+}
+
diff --git a/src/main/java/com/qs/crm/xltentity/XltChannel.java b/src/main/java/com/qs/crm/xltentity/XltChannel.java
new file mode 100644
index 0000000..3e4dd6c
--- /dev/null
+++ b/src/main/java/com/qs/crm/xltentity/XltChannel.java
@@ -0,0 +1,67 @@
+package com.qs.crm.xltentity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 渠道 实体类
+ * @author YenHex
+ * @since 2022-11-07
+ */
+@Data
+public class XltChannel implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private String id;
+
+ /** 渠道编码 */
+ private String number;
+
+ /** 渠道名称 */
+ private String name;
+
+ /** 渠道类型(读取数据字典) */
+ private String channeltype;
+
+ /** 备注 */
+ private String remark;
+
+ /** 创建时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime createTime;
+
+ /** 最后更新时间 */
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private LocalDateTime updateTime;
+
+ /** 所属租户 */
+ @JsonIgnore
+ @JsonProperty
+ private String tenantId;
+
+ /** 逻辑删除标记(0:显示;1:隐藏) */
+ @JsonIgnore
+ @JsonProperty
+ private String delFlag;
+
+ /** 创建人 */
+ private String createBy;
+
+ /** 更新人 */
+ private String updateBy;
+
+ /** 可投放费用标识 */
+ private Integer costFlag;
+
+}
+
diff --git a/src/main/java/com/qs/crm/xltentity/XltChannelDealer.java b/src/main/java/com/qs/crm/xltentity/XltChannelDealer.java
new file mode 100644
index 0000000..a8b276b
--- /dev/null
+++ b/src/main/java/com/qs/crm/xltentity/XltChannelDealer.java
@@ -0,0 +1,34 @@
+package com.qs.crm.xltentity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 渠道 实体类
+ * @author YenHex
+ * @since 2022-11-07
+ */
+@Data
+public class XltChannelDealer implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private String id;
+
+ /** 渠道ID */
+ private String system_id;
+
+ /** 客户ID */
+ private String dealer_id;
+
+ private String dealer_number;
+
+}
+
diff --git a/src/main/java/com/qs/crm/xltentity/XltDealer.java b/src/main/java/com/qs/crm/xltentity/XltDealer.java
new file mode 100644
index 0000000..c8c3b45
--- /dev/null
+++ b/src/main/java/com/qs/crm/xltentity/XltDealer.java
@@ -0,0 +1,31 @@
+package com.qs.crm.xltentity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 渠道 实体类
+ * @author YenHex
+ * @since 2022-11-07
+ */
+@Data
+public class XltDealer implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private String id;
+
+ /** 详细地址 */
+ private String address;
+
+ /** 名称 */
+ private String dealer_name;
+
+ /** 客户编码 */
+ private String dealer_number;
+
+ private String district_name;
+}
+
diff --git a/src/main/java/com/qs/crm/xltentity/XltDealerUser.java b/src/main/java/com/qs/crm/xltentity/XltDealerUser.java
new file mode 100644
index 0000000..755813e
--- /dev/null
+++ b/src/main/java/com/qs/crm/xltentity/XltDealerUser.java
@@ -0,0 +1,27 @@
+package com.qs.crm.xltentity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 渠道 实体类
+ * @author YenHex
+ * @since 2022-11-07
+ */
+@Data
+public class XltDealerUser implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** 客户编码 */
+ private String fran_number;
+
+ /** 用户user */
+ private String khemp_id;
+
+ private String num_no;
+
+ private String name;
+}
+
diff --git a/src/main/java/com/qs/crm/xltentity/XltPoint.java b/src/main/java/com/qs/crm/xltentity/XltPoint.java
new file mode 100644
index 0000000..6505d9d
--- /dev/null
+++ b/src/main/java/com/qs/crm/xltentity/XltPoint.java
@@ -0,0 +1,43 @@
+package com.qs.crm.xltentity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 渠道 实体类
+ * @author YenHex
+ * @since 2022-11-07
+ */
+@Data
+public class XltPoint implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** id */
+ private String id;
+
+ /** 详细地址 */
+ private String address;
+
+ /** 名称 */
+ private String name;
+
+ /** 客户编码 */
+ private String number_;
+
+ private Double shop_area;
+
+ private Integer cash_register;
+
+ private String xiancheng;
+
+ private String sys_id;
+
+ private String type_name;
+
+ private String level_name;
+
+ private String channel_code;
+}
+
diff --git a/src/main/java/com/qs/dto/R.java b/src/main/java/com/qs/dto/R.java
new file mode 100644
index 0000000..7aaf9e4
--- /dev/null
+++ b/src/main/java/com/qs/dto/R.java
@@ -0,0 +1,125 @@
+package com.qs.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 统一返回封装
+ * 1.替代旧版的ViewResult
+ * 2.支持SmartDoc
+ * @author JcYen
+ * @date 2021/4/22
+ * @version 2.0
+ */
+@Getter
+@Setter
+public class R implements Serializable {
+
+ public R(int status, String msg) {
+ this.status = status;
+ this.msg = msg;
+ }
+
+ public R(int status, String msg, T data) {
+ this.status = status;
+ this.msg = msg;
+ this.data = data;
+ }
+
+ /**
+ * 状态码
+ */
+ private Integer status;
+
+ /**
+ * 信息
+ */
+ private String msg;
+
+ /**
+ * 数据
+ */
+ private T data;
+
+ public static final int SUCCESS_STATUS = 200;
+ public static final int LOGOUT_STATUS = 401;
+ public static final int FORBIDDEN_STATUS = 403;
+ public static final int NOT_FOUND_STATUS = 434;
+ public static final int FAILED_STATUS = 500;
+
+ public static final String SUCCESS_TIPS = "操作成功";
+ public static final String FAILED_TIPS = "操作失败";
+ public static final String FAILED_TIPS_2 = "业务操作失败";
+ public static final String LOGOUT_TIPS = "登录无效";
+ public static final String FORBIDDEN_TIPS = "无权限访问";
+ public static final String NOT_FOUND_TIPS = "数据不存在或被移除";
+
+ public static R ok() {
+ return new R(SUCCESS_STATUS,SUCCESS_TIPS,null);
+ }
+
+ public static R ok(String msg) {
+ return new R<>(SUCCESS_STATUS,msg,null);
+ }
+
+ public static R ok(TYPE data) {
+ return new R<>(SUCCESS_STATUS,SUCCESS_TIPS,data);
+ }
+
+ public static R ok(TYPE data,String message) {
+ return new R<>(SUCCESS_STATUS,message,data);
+ }
+
+ public static R isTrue(Boolean bool){
+ if(bool==null|| !bool){
+ return error();
+ }
+ return ok();
+ }
+
+ public static R isTrue(Boolean bool, String message){
+ if(bool==null|| !bool){
+ return error(message);
+ }
+ return ok(null,message);
+ }
+
+
+ public static R isNotNull(TYPE object){
+ if(object==null){
+ return error();
+ }
+ return ok(object,SUCCESS_TIPS);
+ }
+
+ public static R> isOk(Boolean rs){
+ if(rs==null){
+ return error();
+ }
+ return ok();
+ }
+
+ public static R> isOk(Boolean rs,String errMsg){
+ if(rs==null){
+ return error(errMsg);
+ }
+ return ok();
+ }
+
+ public static R error(String message) {
+ return new R<>(FAILED_STATUS,message,null);
+ }
+
+ public static R error() {
+ return new R<>(FAILED_STATUS,FAILED_TIPS,null);
+ }
+
+ public static R error2() {
+ return new R<>(FAILED_STATUS,FAILED_TIPS_2,null);
+ }
+
+
+}
diff --git a/src/main/java/com/qs/dto/SimpleKeyValue.java b/src/main/java/com/qs/dto/SimpleKeyValue.java
new file mode 100644
index 0000000..058e1c6
--- /dev/null
+++ b/src/main/java/com/qs/dto/SimpleKeyValue.java
@@ -0,0 +1,23 @@
+package com.qs.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @author YenHex
+ * @since 2022/3/7
+ */
+@Data
+@AllArgsConstructor
+public class SimpleKeyValue {
+
+ /** 键 */
+ private String label;
+
+ /** 值 */
+ private T value;
+
+ /** 说明 */
+ private String remark;
+
+}
diff --git a/src/main/java/com/qs/dto/TreeLongNode.java b/src/main/java/com/qs/dto/TreeLongNode.java
new file mode 100644
index 0000000..07c7b26
--- /dev/null
+++ b/src/main/java/com/qs/dto/TreeLongNode.java
@@ -0,0 +1,30 @@
+package com.qs.dto;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 树节点
+ * @author YenHex
+ * @since 2022/3/1
+ */
+@Data
+public class TreeLongNode {
+ protected Long id;
+ protected Long parentId;
+ private Integer sort;
+ protected List children = new ArrayList<>();
+
+ public void addChildren(TreeLongNode treeNode) {
+ children.add(treeNode);
+ }
+
+ public List getChildren() {
+ if(children.size()<=0){
+ return null;
+ }
+ return children;
+ }
+}
diff --git a/src/main/java/com/qs/dto/TreeNode.java b/src/main/java/com/qs/dto/TreeNode.java
new file mode 100644
index 0000000..86ee301
--- /dev/null
+++ b/src/main/java/com/qs/dto/TreeNode.java
@@ -0,0 +1,30 @@
+package com.qs.dto;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 树节点
+ * @author YenHex
+ * @since 2022/3/1
+ */
+@Data
+public class TreeNode {
+ protected String id;
+ protected String parentId;
+ private Integer sort;
+ protected List children = new ArrayList<>();
+
+ public void addChildren(TreeNode treeNode) {
+ children.add(treeNode);
+ }
+
+ public List getChildren() {
+ if(children.size()<=0){
+ return null;
+ }
+ return children;
+ }
+}
diff --git a/src/main/java/com/qs/task/TestTask.java b/src/main/java/com/qs/task/TestTask.java
new file mode 100644
index 0000000..375bb82
--- /dev/null
+++ b/src/main/java/com/qs/task/TestTask.java
@@ -0,0 +1,34 @@
+package com.qs.task;
+
+import com.qs.crm.BmsChannelSync;
+import com.qs.crm.BmsPointSync;
+import com.qs.crm.BmsSupplierSync;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author YenHex
+ * @since 2023/3/16
+ */
+@Slf4j
+@Component
+public class TestTask {
+
+ private BmsSupplierSync supplierSync;
+ private BmsChannelSync channelSync;
+ private BmsPointSync pointSync;
+
+ @Scheduled(cron = "* * 2 * * ?")
+ public void test(){
+ try {
+ supplierSync.syncSupplier();
+ channelSync.syncChannel();
+ pointSync.syncPoint();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/main/java/com/qs/test/ChartAxisColumn.java b/src/main/java/com/qs/test/ChartAxisColumn.java
new file mode 100644
index 0000000..d9d548e
--- /dev/null
+++ b/src/main/java/com/qs/test/ChartAxisColumn.java
@@ -0,0 +1,21 @@
+package com.qs.test;
+
+import lombok.Data;
+
+/**
+ * @author YenHex
+ * @since 2023/2/17
+ */
+@Data
+public class ChartAxisColumn {
+
+ /** 列Id */
+ Long columnId;
+
+ /** 列名 */
+ String columnName;
+
+ /** 系列坐标值合计 */
+ Double total;
+
+}
diff --git a/src/main/java/com/qs/test/ChartDataVo.java b/src/main/java/com/qs/test/ChartDataVo.java
new file mode 100644
index 0000000..781a6dd
--- /dev/null
+++ b/src/main/java/com/qs/test/ChartDataVo.java
@@ -0,0 +1,24 @@
+package com.qs.test;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author YenHex
+ * @since 2023/2/17
+ */
+@Data
+public class ChartDataVo {
+
+ /**
+ * 列(饼状图的主要参数)
+ */
+ List axisColumns;
+
+ /**
+ * 系列
+ */
+ List seriesItem;
+
+}
diff --git a/src/main/java/com/qs/test/ChartGroupItem.java b/src/main/java/com/qs/test/ChartGroupItem.java
new file mode 100644
index 0000000..040aee1
--- /dev/null
+++ b/src/main/java/com/qs/test/ChartGroupItem.java
@@ -0,0 +1,18 @@
+package com.qs.test;
+
+import lombok.Data;
+
+/**
+ * @author YenHex
+ * @since 2023/2/17
+ */
+@Data
+public class ChartGroupItem {
+
+ /** 组id */
+ private Long groupId;
+
+ /** 组名 */
+ private String groupName;
+
+}
diff --git a/src/main/java/com/qs/test/ChartSeriesItem.java b/src/main/java/com/qs/test/ChartSeriesItem.java
new file mode 100644
index 0000000..22f4e89
--- /dev/null
+++ b/src/main/java/com/qs/test/ChartSeriesItem.java
@@ -0,0 +1,31 @@
+package com.qs.test;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author YenHex
+ * @since 2023/2/17
+ */
+@Data
+public class ChartSeriesItem {
+
+ /** 列Id */
+ Long columnId;
+
+ /** 列名 */
+ String columnName;
+
+ /** 组id */
+ private Long groupId;
+
+ /** 组名 */
+ private String groupName;
+
+ /**
+ * 值列表(列对应axisColumns)
+ */
+ List values;
+
+}
diff --git a/src/main/java/com/qs/test/PrintChart.java b/src/main/java/com/qs/test/PrintChart.java
new file mode 100644
index 0000000..15ae489
--- /dev/null
+++ b/src/main/java/com/qs/test/PrintChart.java
@@ -0,0 +1,25 @@
+package com.qs.test;
+
+/**
+ * @author YenHex
+ * @since 2023/2/17
+ */
+public class PrintChart {
+
+
+ public static void main(String[] args) {
+ //eg. 统计1-6年纪每个班年纪学生柱状图
+ for (int i = 1; i < 7; i++) {
+ ChartSeriesItem seriesItem = new ChartSeriesItem();
+ seriesItem.setColumnId(new Long(i));
+ seriesItem.setColumnName("小学"+i+"年级");
+ for (int j = 0; j < 2; j++) {
+ if(j==0){
+
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/src/main/java/com/qs/util/DateUtils.java b/src/main/java/com/qs/util/DateUtils.java
new file mode 100644
index 0000000..af655a4
--- /dev/null
+++ b/src/main/java/com/qs/util/DateUtils.java
@@ -0,0 +1,506 @@
+package com.qs.util;
+
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+
+public class DateUtils {
+
+ /**
+ * 仅显示年月日,例如 2015-08-11.
+ */
+ public static final String DATE_FORMAT = "yyyy-MM-dd";
+ /**
+ * 显示年月日时分秒,例如 2015-08-11 09:51:53.
+ */
+ public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+ /**
+ * 仅显示时分秒,例如 09:51:53.
+ */
+ public static final String TIME_FORMAT = "HH:mm:ss";
+
+ /**
+ * 每天的毫秒数 8640000.
+ */
+ public static final long MILLISECONDS_PER_DAY = 86400000L;
+
+ /**
+ * 每周的天数.
+ */
+ public static final long DAYS_PER_WEEK = 7L;
+
+ /**
+ * 每小时毫秒数.
+ */
+ public static final long MILLISECONDS_PER_HOUR = 3600000L;
+
+ /**
+ * 每分钟秒数.
+ */
+ public static final long SECONDS_PER_MINUTE = 60L;
+
+ /**
+ * 每小时秒数.
+ */
+ public static final long SECONDS_PER_HOUR = 3600L;
+
+ /**
+ * 每天秒数.
+ */
+ public static final long SECONDS_PER_DAY = 86400L;
+
+ /**
+ * 每个月秒数,默认每月30天.
+ */
+ public static final long SECONDS_PER_MONTH = 2592000L;
+
+ /**
+ * 每年秒数,默认每年365天.
+ */
+ public static final long SECONDS_PER_YEAR = 31536000L;
+
+ /**
+ * 常用的时间格式.
+ */
+ private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd",
+ "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" };
+
+ /**
+ * 得到当前日期字符串.
+ * @return String 日期字符串,例如2015-08-11
+ * @since 1.0
+ */
+ public static String getDate() {
+ return getDate(DateUtils.DATE_FORMAT);
+ }
+
+ /**
+ * 得到当前时间字符串.
+ * @return String 时间字符串,例如 09:51:53
+ * @since 1.0
+ */
+ public static String getTime() {
+ return formatDate(new Date(), DateUtils.TIME_FORMAT);
+ }
+
+ /**
+ * 得到当前日期和时间字符串.
+ * @return String 日期和时间字符串,例如 2015-08-11 09:51:53
+ * @since 1.0
+ */
+ public static String getDateTime() {
+ return formatDate(new Date(), DateUtils.DATETIME_FORMAT);
+ }
+
+ /**
+ * 获取当前时间指定格式下的字符串.
+ * @param pattern
+ * 转化后时间展示的格式,例如"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"等
+ * @return String 格式转换之后的时间字符串.
+ * @since 1.0
+ */
+ public static String getDate(String pattern) {
+ return DateFormatUtils.format(new Date(), pattern);
+ }
+
+ /**
+ * 获取指定日期的字符串格式.
+ * @param date 需要格式化的时间,不能为空
+ * @param pattern 时间格式,例如"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"等
+ * @return String 格式转换之后的时间字符串.
+ * @since 1.0
+ */
+ public static String getDate(Date date, String pattern) {
+ return DateFormatUtils.format(date, pattern);
+ }
+
+ /**
+ * 获取日期时间字符串,默认格式为(yyyy-MM-dd).
+ * @param date 需要转化的日期时间
+ * @param pattern 时间格式,例如"yyyy-MM-dd" "HH:mm:ss" "E"等
+ * @return String 格式转换后的时间字符串
+ * @since 1.0
+ */
+ public static String formatDate(Date date, Object... pattern) {
+ String formatDate = null;
+ if (pattern != null && pattern.length > 0) {
+ formatDate = DateFormatUtils.format(date, pattern[0].toString());
+ } else {
+ formatDate = DateFormatUtils.format(date, DateUtils.DATE_FORMAT);
+ }
+ return formatDate;
+ }
+
+ /**
+ * 获取当前年份字符串.
+ * @return String 当前年份字符串,例如 2015
+ * @since 1.0
+ */
+ public static String getYear() {
+ return formatDate(new Date(), "yyyy");
+ }
+
+ /**
+ * 获取当前月份字符串.
+ * @return String 当前月份字符串,例如 08
+ * @since 1.0
+ */
+ public static String getMonth() {
+ return formatDate(new Date(), "MM");
+ }
+
+ /**
+ * 获取当前天数字符串.
+ * @return String 当前天数字符串,例如 11
+ * @since 1.0
+ */
+ public static String getDay() {
+ return formatDate(new Date(), "dd");
+ }
+
+ /**
+ * 获取当前星期字符串.
+ * @return String 当前星期字符串,例如星期二
+ * @since 1.0
+ */
+ public static String getWeek() {
+ return formatDate(new Date(), "E");
+ }
+
+ /**
+ * 将日期型字符串转换为日期格式.
+ * 支持的日期字符串格式包括"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
+ * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm"
+ * @param str
+ * @return Date
+ * @since 1.0
+ */
+ public static Date parseDate(Object str) {
+ if (str == null) {
+ return null;
+ }
+ try {
+ return org.apache.commons.lang3.time.DateUtils.parseDate(str.toString(), parsePatterns);
+ } catch (ParseException e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取当前日期与指定日期相隔的天数.
+ * @param date 给定的日期
+ * @return long 日期间隔天数,正数表示给定日期在当前日期之前,负数表示在当前日期之后
+ * @since 1.0
+ */
+ public static long pastDays(Date date) {
+ // 将指定日期转换为yyyy-MM-dd格式
+ date = DateUtils.parseDate(DateUtils.formatDate(date, DateUtils.DATE_FORMAT));
+ // 当前日期转换为yyyy-MM-dd格式
+ Date currentDate = DateUtils.parseDate(DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT));
+ long t=0;
+ if(date!=null&¤tDate!=null){
+ t = (currentDate.getTime() - date.getTime()) / DateUtils.MILLISECONDS_PER_DAY;
+ }
+ return t;
+ }
+
+ /**
+ * 获取当前日期指定天数之后的日期.
+ * @param num 相隔天数
+ * @return Date 日期
+ * @since 1.0
+ */
+ public static Date nextDay(int num) {
+ Calendar curr = Calendar.getInstance();
+ curr.set(Calendar.DAY_OF_MONTH, curr.get(Calendar.DAY_OF_MONTH) + num);
+ return curr.getTime();
+ }
+
+ /**
+ * 获取当前日期指定月数之后的日期.
+ * @param num 间隔月数
+ * @return Date 日期
+ * @since 1.0
+ */
+ public static Date nextMonth(int num) {
+ Calendar curr = Calendar.getInstance();
+ curr.set(Calendar.MONTH, curr.get(Calendar.MONTH) + num);
+ return curr.getTime();
+ }
+
+ /**
+ * 获取当前日期指定年数之后的日期.
+ * @param num 间隔年数
+ * @return Date 日期
+ * @since 1.0
+ */
+ public static Date nextYear(int num) {
+ Calendar curr = Calendar.getInstance();
+ curr.set(Calendar.YEAR, curr.get(Calendar.YEAR) + num);
+ return curr.getTime();
+ }
+
+ /**
+ * 将 Date 日期转化为 Calendar 类型日期.
+ * @param date 给定的时间,若为null,则默认为当前时间
+ * @return Calendar Calendar对象
+ * @since 1.0
+ */
+ public static Calendar getCalendar(Date date) {
+ Calendar calendar = Calendar.getInstance();
+ // calendar.setFirstDayOfWeek(Calendar.SUNDAY);//每周从周日开始
+ // calendar.setMinimalDaysInFirstWeek(1); // 设置每周最少为1天
+ if (date != null) {
+ calendar.setTime(date);
+ }
+ return calendar;
+ }
+
+ /**
+ * 计算两个日期之间相差天数.
+ * @param start 计算开始日期
+ * @param end 计算结束日期
+ * @return long 相隔天数
+ * @since 1.0
+ */
+ public static long getDaysBetween(Date start, Date end) {
+ // 将指定日期转换为yyyy-MM-dd格式
+ start = DateUtils.parseDate(DateUtils.formatDate(start, DateUtils.DATE_FORMAT));
+ // 当前日期转换为yyyy-MM-dd格式
+ end = DateUtils.parseDate(DateUtils.formatDate(end, DateUtils.DATE_FORMAT));
+
+ long diff=0;
+ if(start!=null&&end!=null) {
+ diff = (end.getTime() - start.getTime()) / DateUtils.MILLISECONDS_PER_DAY;
+ }
+ return diff;
+ }
+
+ /**
+ * 计算两个日期之前相隔多少周.
+ * @param start 计算开始时间
+ * @param end 计算结束时间
+ * @return long 相隔周数,向下取整
+ * @since 1.0
+ */
+ public static long getWeeksBetween(Date start, Date end) {
+ return getDaysBetween(start, end) / DateUtils.DAYS_PER_WEEK;
+ }
+
+ /**
+ * 获取与指定日期间隔给定天数的日期.
+ * @param specifiedDay 给定的字符串格式日期,支持的日期字符串格式包括"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss",
+ * "yyyy-MM-dd HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss",
+ * "yyyy/MM/dd HH:mm"
+ * @param num 间隔天数
+ * @return String 间隔指定天数之后的日期
+ * @since 1.0
+ */
+ public static String getSpecifiedDayAfter(String specifiedDay, int num) {
+ Date specifiedDate = parseDate(specifiedDay);
+ Calendar c = Calendar.getInstance();
+ c.setTime(specifiedDate);
+ int day = c.get(Calendar.DATE);
+ c.set(Calendar.DATE, day + num);
+ String dayAfter = formatDate(c.getTime(), DateUtils.DATE_FORMAT);
+ return dayAfter;
+ }
+
+ /**
+ * 计算两个日期之前间隔的小时数.
+ *
+ * @param date1
+ * 结束时间
+ * @param date2
+ * 开始时间
+ * @return String 相差的小时数,保留一位小数
+ * @since 1.0
+ */
+ public static String dateMinus(Date date1, Date date2) {
+ if (date1 == null || date2 == null) {
+ return "0";
+ }
+ Long r = date1.getTime() - date2.getTime();
+ DecimalFormat df = new DecimalFormat("#.0");
+ double result = r * 1.0 / DateUtils.MILLISECONDS_PER_HOUR;
+ return df.format(result);
+ }
+
+ /**
+ * 获取当前季度 .
+ *
+ * @return Integer 当前季度数
+ * @since 1.0
+ */
+ public static Integer getCurrentSeason() {
+ Calendar calendar = Calendar.getInstance();
+ Integer month = calendar.get(Calendar.MONTH) + 1;
+ int season = 0;
+ if (month >= 1 && month <= 3) {
+ season = 1;
+ } else if (month >= 4 && month <= 6) {
+ season = 2;
+ } else if (month >= 7 && month <= 9) {
+ season = 3;
+ } else if (month >= 10 && month <= 12) {
+ season = 4;
+ }
+ return season;
+ }
+
+ /**
+ * 将以秒为单位的时间转换为其他单位.
+ *
+ * @param seconds
+ * 秒数
+ * @return String 例如 16分钟前、2小时前、3天前、4月前、5年前等
+ * @since 1.0
+ */
+ public static String getIntervalBySeconds(long seconds) {
+ StringBuffer buffer = new StringBuffer();
+ if (seconds < SECONDS_PER_MINUTE) {
+ buffer.append(seconds).append("秒前");
+ } else if (seconds < SECONDS_PER_HOUR) {
+ buffer.append(seconds / SECONDS_PER_MINUTE).append("分钟前");
+ } else if (seconds < SECONDS_PER_DAY) {
+ buffer.append(seconds / SECONDS_PER_HOUR).append("小时前");
+ } else if (seconds < SECONDS_PER_MONTH) {
+ buffer.append(seconds / SECONDS_PER_DAY).append("天前");
+ } else if (seconds < SECONDS_PER_YEAR) {
+ buffer.append(seconds / SECONDS_PER_MONTH).append("月前");
+ } else {
+ buffer.append(seconds / DateUtils.SECONDS_PER_YEAR).append("年前");
+ }
+ return buffer.toString();
+ }
+
+ /**
+ *
+ * getNowTimeBefore(记录时间相当于目前多久之前)
+ *
+ * @param seconds
+ * 秒
+ * @return
+ * @exception @since
+ * 1.0
+ * @author rlliu
+ */
+ public static String getNowTimeBefore(long seconds) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("上传于");
+ if (seconds < 3600) {
+ buffer.append((long) Math.floor(seconds / 60.0)).append("分钟前");
+ } else if (seconds < 86400) {
+ buffer.append((long) Math.floor(seconds / 3600.0)).append("小时前");
+ } else if (seconds < 604800) {
+ buffer.append((long) Math.floor(seconds / 86400.0)).append("天前");
+ } else if (seconds < 2592000) {
+ buffer.append((long) Math.floor(seconds / 604800.0)).append("周前");
+ } else if (seconds < 31104000) {
+ buffer.append((long) Math.floor(seconds / 2592000.0)).append("月前");
+ } else {
+ buffer.append((long) Math.floor(seconds / 31104000.0)).append("年前");
+ }
+ return buffer.toString();
+ }
+
+ /**
+ *
+ * getMonthsBetween(查询两个日期相隔的月份)
+ *
+ * @param startDate 开始日期1 (格式yyyy-MM-dd)
+ * @param endDate 截止日期2 (格式yyyy-MM-dd)
+ * @return
+ */
+ public static int getMonthsBetween(String startDate, String endDate) {
+ Calendar c1 = Calendar.getInstance();
+ Calendar c2 = Calendar.getInstance();
+ c1.setTime(DateUtils.parseDate(startDate));
+ c2.setTime(DateUtils.parseDate(endDate));
+ int year = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
+ int month = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
+ return Math.abs(year * 12 + month);
+ }
+
+ /**
+ *
+ * getDayOfWeek(获取当前日期是星期几)
+ *
+ * @param dateStr 日期
+ * @return 星期几
+ */
+ public static String getDayOfWeek(String dateStr) {
+ String[] weekOfDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
+ Date date = parseDate(dateStr);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ int num = calendar.get(Calendar.DAY_OF_WEEK) - 1;
+ return weekOfDays[num];
+ }
+
+ /**
+ * sns 格式 如几秒前,几分钟前,几小时前,几天前,几个月前,几年后, ... 精细,类如某个明星几秒钟之前发表了一篇微博
+ *
+ * @param createTime
+ * @return
+ */
+ public static String snsFormat(long createTime) {
+ long now = System.currentTimeMillis() / 1000;
+ long differ = now - createTime / 1000;
+ String dateStr = "";
+ if (differ <= 60) {
+ dateStr = "刚刚";
+ } else if (differ <= 3600) {
+ dateStr = (differ / 60) + "分钟前";
+ } else if (differ <= 3600 * 24) {
+ dateStr = (differ / 3600) + "小时前";
+ } else if (differ <= 3600 * 24 * 30) {
+ dateStr = (differ / (3600 * 24)) + "天前";
+ } else {
+ Date date = new Date(createTime);
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ dateStr = sdf.format(date);
+ }
+ return dateStr;
+ }
+
+ /**
+ * 得到UTC时间,类型为字符串,格式为"yyyy-MM-dd HH:mm"
+ * 如果获取失败,返回null
+ * @return
+ */
+ public static String getUTCTimeStr() {
+ StringBuffer UTCTimeBuffer = new StringBuffer();
+ // 1、取得本地时间:
+ Calendar cal = Calendar.getInstance() ;
+ // 2、取得时间偏移量:
+ int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET);
+ // 3、取得夏令时差:
+ int dstOffset = cal.get(java.util.Calendar.DST_OFFSET);
+ // 4、从本地时间里扣除这些差量,即可以取得UTC时间:
+ cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));
+ int year = cal.get(Calendar.YEAR);
+ int month = cal.get(Calendar.MONTH)+1;
+ int day = cal.get(Calendar.DAY_OF_MONTH);
+ int hour = cal.get(Calendar.HOUR_OF_DAY);
+ int minute = cal.get(Calendar.MINUTE);
+ UTCTimeBuffer.append(year).append("-").append(month).append("-").append(day) ;
+ UTCTimeBuffer.append(" ").append(hour).append(":").append(minute) ;
+ try{
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+ sdf.parse(UTCTimeBuffer.toString()) ;
+ return UTCTimeBuffer.toString() ;
+ }catch(ParseException e)
+ {
+ e.printStackTrace() ;
+ }
+ return null ;
+ }
+}
diff --git a/src/main/java/com/qs/util/StringUtils.java b/src/main/java/com/qs/util/StringUtils.java
new file mode 100644
index 0000000..552eaf7
--- /dev/null
+++ b/src/main/java/com/qs/util/StringUtils.java
@@ -0,0 +1,125 @@
+package com.qs.util;
+
+import lombok.experimental.UtilityClass;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+/**
+ * @author YenHex
+ * @since 2022/2/28
+ */
+@UtilityClass
+public class StringUtils {
+
+ /** 订单号生成(NEW) **/
+ private static final AtomicInteger SEQ = new AtomicInteger(1000);
+ private static final AtomicInteger SEQ2 = new AtomicInteger(10001);
+ private static final DateTimeFormatter DF_FMT_PREFIX = DateTimeFormatter.ofPattern("yyMMddHHmmssSS");
+ private static ZoneId ZONE_ID = ZoneId.of("Asia/Shanghai");
+
+ public static String generateOrderNo(){
+ LocalDateTime dataTime = LocalDateTime.now(ZONE_ID);
+ if(SEQ.intValue()>9990){
+ SEQ.getAndSet(1000);
+ }
+ return dataTime.format(DF_FMT_PREFIX)+SEQ.getAndIncrement();
+ }
+
+ public static Long genShortLong(){
+ String id = genShortId();
+ return Long.parseLong(id);
+ }
+
+ public static String genShortId() {
+ // 2 位 年份的后两位 22001 后五位走随机 每天清一次缓存 99999 10
+ StringBuilder idSb = new StringBuilder();
+ /// 年份后两位 和 一年中的第几天
+ LocalDate now = LocalDate.now();
+ String year = now.getYear() + "";
+ year = year.substring(2);
+ String day = now.getDayOfYear() + "";
+ /// 补0
+ if (day.length() < 3) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = day.length(); i < 3; i++) {
+ sb.append("0");
+ }
+ day = sb.append(day).toString();
+ }
+ idSb.append(year).append(day);
+ /// 后五位补随机数
+ if(SEQ2.intValue()>9999900){
+ SEQ2.getAndSet(1000001);
+ }
+ idSb.append(SEQ2.getAndIncrement());
+ return idSb.toString();
+ }
+
+ public static void main(String[] args) {
+
+ for (int i = 0; i < 100; i++) {
+ //System.out.println(genShortId());
+ System.out.println(generateOrderNo());
+ }
+ }
+
+ public static String getUrlByList(List> list,String param){
+ StringBuilder sb = new StringBuilder();
+ for (Object val : list) {
+ sb.append("&"+param+"="+val);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 格式化
+ * @param exp 含{}的表达式
+ * @param params 参数(注意跳过空值)
+ * @return
+ */
+ public static String format(String exp,String... params){
+ StringBuilder builder = new StringBuilder(exp);
+ int idx_p = 0;
+ while (hasText(builder,"{}")){
+ int idx = builder.indexOf("{}");
+ if(idx_p splitIdString(String ids){
+ if(ids==null){
+ return null;
+ }
+ if(ids.contains(",")){
+ String[] idsA= ids.split(",");
+ return Arrays.asList(idsA);
+ }
+ return Arrays.asList(ids);
+ }
+
+ public static List splitIdLong(String ids){
+ List strs = splitIdString(ids);
+ if(strs!=null){
+ return strs.stream().map(a->Long.parseLong(a)).collect(Collectors.toList());
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..50c8902
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,28 @@
+#Spring配置
+spring:
+ servlet:
+ multipart:
+ max-file-size: 100MB
+ max-request-size: 160MB
+#服务配置
+server:
+ port: 8061
+ servlet:
+ context-path: /
+# 日志配置
+logging:
+ level:
+ ROOT: info
+ com.qs: debug
+ org.springframework: info
+ java.io: warn
+
+jsl:
+# url: jdbc:mysql://192.168.0.9:3306/jsl_mall_qs_test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
+ url: jdbc:mysql://183.56.249.148:3306/jsl_cost_base?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
+ user: root
+ pass: '@Jsl2282125'
+xlt:
+ url: jdbc:sqlserver://rm-wz93l107hc277n9ieco.sqlserver.rds.aliyuncs.com:3433;DatabaseName=xiaolutong
+ user: qs_db_user
+ pass: Aa135246
\ No newline at end of file