x1ongzhu vor 6 Jahren
Ursprung
Commit
4c512406d8
30 geänderte Dateien mit 562 neuen und 43 gelöschten Zeilen
  1. 6 0
      pom.xml
  2. 10 0
      src/main/java/com/izouma/walkchina/bean/AppConstants.java
  3. 12 0
      src/main/java/com/izouma/walkchina/bean/Result.java
  4. 1 2
      src/main/java/com/izouma/walkchina/domain/City.java
  5. 1 2
      src/main/java/com/izouma/walkchina/domain/JourneyStage.java
  6. 58 0
      src/main/java/com/izouma/walkchina/domain/Message.java
  7. 1 2
      src/main/java/com/izouma/walkchina/domain/Province.java
  8. 45 0
      src/main/java/com/izouma/walkchina/domain/SystemVariable.java
  9. 56 0
      src/main/java/com/izouma/walkchina/domain/TeamMember.java
  10. 21 9
      src/main/java/com/izouma/walkchina/domain/UserFriend.java
  11. 14 0
      src/main/java/com/izouma/walkchina/domain/UserFriendKey.java
  12. 33 2
      src/main/java/com/izouma/walkchina/domain/UserInfo.java
  13. 1 2
      src/main/java/com/izouma/walkchina/domain/UserJourney.java
  14. 1 2
      src/main/java/com/izouma/walkchina/domain/WalkData.java
  15. 7 0
      src/main/java/com/izouma/walkchina/repo/MessageRepository.java
  16. 8 0
      src/main/java/com/izouma/walkchina/repo/SystemVariableRepository.java
  17. 14 0
      src/main/java/com/izouma/walkchina/repo/TeamMemberRepository.java
  18. 8 0
      src/main/java/com/izouma/walkchina/repo/UserFriendRepository.java
  19. 3 3
      src/main/java/com/izouma/walkchina/repo/UserInfoRepository.java
  20. 9 0
      src/main/java/com/izouma/walkchina/repo/WalkDataRepository.java
  21. 8 1
      src/main/java/com/izouma/walkchina/security/JwtTokenUtil.java
  22. 67 0
      src/main/java/com/izouma/walkchina/service/JourneyService.java
  23. 27 0
      src/main/java/com/izouma/walkchina/service/SystemVariableService.java
  24. 21 8
      src/main/java/com/izouma/walkchina/service/UserInfoService.java
  25. 16 6
      src/main/java/com/izouma/walkchina/service/WalkDataService.java
  26. 12 0
      src/main/java/com/izouma/walkchina/web/UserInfoController.java
  27. 3 4
      src/main/resources/application.yaml
  28. 41 0
      src/main/resources/logback-spring.xml
  29. 19 0
      src/test/java/com/izouma/walkchina/CommonTest.java
  30. 39 0
      src/test/java/com/izouma/walkchina/repo/WalkDataRepositoryTest.java

+ 6 - 0
pom.xml

@@ -110,6 +110,12 @@
             <version>6.0</version>
         </dependency>
 
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.10.3</version>
+        </dependency>
+
         <!--test dependency-->
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 10 - 0
src/main/java/com/izouma/walkchina/bean/AppConstants.java

@@ -0,0 +1,10 @@
+package com.izouma.walkchina.bean;
+
+public interface AppConstants {
+    double STEP_TO_DISTANCE_RATE = 1;  // 1步=多少米
+
+    public interface MessageType {
+        int NORMAL = 1;
+        int TEAM   = 2;
+    }
+}

+ 12 - 0
src/main/java/com/izouma/walkchina/bean/Result.java

@@ -20,6 +20,12 @@ public class Result {
     private Object  data;
     private Object  error;
 
+    public static Result ok() {
+        Result result = new Result();
+        result.setSuccess(true);
+        return result;
+    }
+
     public static Result ok(Object data) {
         Result result = new Result();
         result.setSuccess(true);
@@ -27,6 +33,7 @@ public class Result {
         return result;
     }
 
+
     public static Result error(int code, Object error) {
         Result result = new Result();
         result.setSuccess(false);
@@ -38,4 +45,9 @@ public class Result {
     public static Result error(Object error) {
         return error(-1, error);
     }
+
+    public static Result error() {
+        return error(null);
+    }
+
 }

+ 1 - 2
src/main/java/com/izouma/walkchina/domain/City.java

@@ -18,10 +18,9 @@ import java.util.Date;
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
-@EqualsAndHashCode(callSuper = true)
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @EntityListeners(AuditingEntityListener.class)
-public class City extends BaseEntity {
+public class City {
     @Id
     private Long id;
 

+ 1 - 2
src/main/java/com/izouma/walkchina/domain/JourneyStage.java

@@ -22,11 +22,10 @@ import java.util.List;
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
-@EqualsAndHashCode(callSuper = true)
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @Where(clause = "active = 1")
 @EntityListeners(AuditingEntityListener.class)
-public class JourneyStage extends BaseEntity implements Serializable {
+public class JourneyStage implements Serializable {
 
     private static final long serialVersionUID = 3520261464947638374L;
 

+ 58 - 0
src/main/java/com/izouma/walkchina/domain/Message.java

@@ -0,0 +1,58 @@
+package com.izouma.walkchina.domain;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.izouma.walkchina.bean.AppConstants;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.annotations.Where;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@Where(clause = "active = 1")
+@EntityListeners(AuditingEntityListener.class)
+public class Message {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    private Long userId;
+
+    private String content;
+
+    @Builder.Default
+    private Integer type = AppConstants.MessageType.NORMAL;
+
+    @Column(columnDefinition = "bit default 0", nullable = false)
+    @Builder.Default
+    private Boolean isRead = false;
+
+    @Column(columnDefinition = "bit default 1", nullable = false)
+    @Builder.Default
+    public Boolean active = true;
+
+    @CreatedBy
+    private String createdBy;
+
+    @CreatedDate
+    private Date createdAt;
+
+    @LastModifiedBy
+    private String modifiedBy;
+
+    @LastModifiedDate
+    private Date modifiedAt;
+}

+ 1 - 2
src/main/java/com/izouma/walkchina/domain/Province.java

@@ -18,10 +18,9 @@ import java.util.Date;
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
-@EqualsAndHashCode(callSuper = true)
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @EntityListeners(AuditingEntityListener.class)
-public class Province extends BaseEntity {
+public class Province {
     @Id
     private Long id;
 

+ 45 - 0
src/main/java/com/izouma/walkchina/domain/SystemVariable.java

@@ -0,0 +1,45 @@
+package com.izouma.walkchina.domain;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@EntityListeners(AuditingEntityListener.class)
+public class SystemVariable {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    private String name;
+
+    private String value;
+
+    @CreatedBy
+    private String createdBy;
+
+    @CreatedDate
+    private Date createdAt;
+
+    @LastModifiedBy
+    private String modifiedBy;
+
+    @LastModifiedDate
+    private Date modifiedAt;
+}

+ 56 - 0
src/main/java/com/izouma/walkchina/domain/TeamMember.java

@@ -0,0 +1,56 @@
+package com.izouma.walkchina.domain;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.annotations.Where;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@Where(clause = "active = 1")
+@EntityListeners(AuditingEntityListener.class)
+public class TeamMember {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    private Long userId;
+
+    private Long leader;
+
+    @Temporal(TemporalType.DATE)
+    private Date startDate;
+
+    @Temporal(TemporalType.DATE)
+    private Date endDate;
+
+    @Column(columnDefinition = "bit default 1", nullable = false)
+    @Builder.Default
+    public Boolean active = true;
+
+    @CreatedBy
+    private String createdBy;
+
+    @CreatedDate
+    private Date createdAt;
+
+    @LastModifiedBy
+    private String modifiedBy;
+
+    @LastModifiedDate
+    private Date modifiedAt;
+}

+ 21 - 9
src/main/java/com/izouma/walkchina/domain/BaseEntity.java → src/main/java/com/izouma/walkchina/domain/UserFriend.java

@@ -1,23 +1,35 @@
 package com.izouma.walkchina.domain;
 
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.Setter;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 import org.springframework.data.annotation.CreatedBy;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedBy;
 import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
-import javax.persistence.EntityListeners;
-import javax.persistence.MappedSuperclass;
+import javax.persistence.*;
 import java.util.Date;
 
-@Getter(AccessLevel.PUBLIC)
-@Setter(AccessLevel.PUBLIC)
-@MappedSuperclass
+@Entity
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@JsonInclude(JsonInclude.Include.NON_NULL)
 @EntityListeners(AuditingEntityListener.class)
-class BaseEntity {
+@IdClass(UserFriendKey.class)
+public class UserFriend {
+
+    @Id
+    private Long userId;
+
+    @Id
+    private Long friendId;
+
     @CreatedBy
     private String createdBy;
 

+ 14 - 0
src/main/java/com/izouma/walkchina/domain/UserFriendKey.java

@@ -0,0 +1,14 @@
+package com.izouma.walkchina.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class UserFriendKey implements Serializable {
+    private static final long serialVersionUID = -2193777760224400194L;
+
+    private Long userId;
+
+    private Long friendId;
+}

+ 33 - 2
src/main/java/com/izouma/walkchina/domain/UserInfo.java

@@ -4,6 +4,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import lombok.*;
 import org.hibernate.annotations.Where;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -11,6 +15,7 @@ import org.springframework.security.core.userdetails.UserDetails;
 
 import javax.persistence.*;
 import javax.validation.constraints.Email;
+import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -20,11 +25,10 @@ import java.util.Date;
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
-@EqualsAndHashCode(callSuper = true)
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @Where(clause = "active = 1")
 @EntityListeners(AuditingEntityListener.class)
-public class UserInfo extends BaseEntity implements UserDetails {
+public class UserInfo implements UserDetails {
 
     private static final long serialVersionUID = 6392705780780532944L;
 
@@ -59,6 +63,21 @@ public class UserInfo extends BaseEntity implements UserDetails {
 
     private String city;
 
+    @Column(columnDefinition = "bigint(19) default 0", nullable = false)
+    @Builder.Default
+    private Long totalSteps = 0L;
+
+    @Column(columnDefinition = "int(10) default 0", nullable = false)
+    @Builder.Default
+    private Integer walkCities = 0;
+
+    @Column(columnDefinition = "int(10) default 1", nullable = false)
+    @Builder.Default
+    private Integer level = 1;
+
+    @Column(length = 10, precision = 2)
+    private BigDecimal coin;
+
     @Column(columnDefinition = "integer default 0")
     private Integer sex;
 
@@ -66,6 +85,18 @@ public class UserInfo extends BaseEntity implements UserDetails {
     @Builder.Default
     public Boolean active = true;
 
+    @CreatedBy
+    private String createdBy;
+
+    @CreatedDate
+    private Date createdAt;
+
+    @LastModifiedBy
+    private String modifiedBy;
+
+    @LastModifiedDate
+    private Date modifiedAt;
+
     private String sessionKey;
 
     @JsonInclude

+ 1 - 2
src/main/java/com/izouma/walkchina/domain/UserJourney.java

@@ -19,11 +19,10 @@ import java.util.List;
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
-@EqualsAndHashCode(callSuper = true)
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @Where(clause = "active = 1")
 @EntityListeners(AuditingEntityListener.class)
-public class UserJourney extends BaseEntity {
+public class UserJourney {
 
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)

+ 1 - 2
src/main/java/com/izouma/walkchina/domain/WalkData.java

@@ -17,11 +17,10 @@ import java.util.Date;
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
-@EqualsAndHashCode(callSuper = true)
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @Where(clause = "active = 1")
 @EntityListeners(AuditingEntityListener.class)
-public class WalkData extends BaseEntity {
+public class WalkData {
 
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)

+ 7 - 0
src/main/java/com/izouma/walkchina/repo/MessageRepository.java

@@ -0,0 +1,7 @@
+package com.izouma.walkchina.repo;
+
+import com.izouma.walkchina.domain.Message;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface MessageRepository extends JpaRepository<Message, Long> {
+}

+ 8 - 0
src/main/java/com/izouma/walkchina/repo/SystemVariableRepository.java

@@ -0,0 +1,8 @@
+package com.izouma.walkchina.repo;
+
+import com.izouma.walkchina.domain.SystemVariable;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface SystemVariableRepository extends JpaRepository<SystemVariable, Long> {
+    SystemVariable findByName(String name);
+}

+ 14 - 0
src/main/java/com/izouma/walkchina/repo/TeamMemberRepository.java

@@ -0,0 +1,14 @@
+package com.izouma.walkchina.repo;
+
+import com.izouma.walkchina.domain.TeamMember;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.Date;
+import java.util.List;
+
+public interface TeamMemberRepository extends JpaRepository<TeamMember, Long> {
+
+    @Query("select t from TeamMember t where t.leader = ?1 and t.startDate >= ?2 and t.endDate <= ?2")
+    List<TeamMember> findUserTeamMembers(Long leader, Date date);
+}

+ 8 - 0
src/main/java/com/izouma/walkchina/repo/UserFriendRepository.java

@@ -0,0 +1,8 @@
+package com.izouma.walkchina.repo;
+
+import com.izouma.walkchina.domain.UserFriend;
+import com.izouma.walkchina.domain.UserFriendKey;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserFriendRepository extends JpaRepository<UserFriend, UserFriendKey> {
+}

+ 3 - 3
src/main/java/com/izouma/walkchina/repo/UserInfoRepository.java

@@ -3,8 +3,8 @@ package com.izouma.walkchina.repo;
 import com.izouma.walkchina.domain.UserInfo;
 import org.springframework.data.jpa.repository.JpaRepository;
 
-import java.util.Optional;
-
 public interface UserInfoRepository extends JpaRepository<UserInfo, Long> {
-    Optional<UserInfo> findByOpenId(String openId);
+    UserInfo findByOpenId(String openId);
+
+    UserInfo findByUsername(String username);
 }

+ 9 - 0
src/main/java/com/izouma/walkchina/repo/WalkDataRepository.java

@@ -2,9 +2,18 @@ package com.izouma.walkchina.repo;
 
 import com.izouma.walkchina.domain.WalkData;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.Date;
 
 public interface WalkDataRepository extends JpaRepository<WalkData, Long> {
     WalkData findByUserIdAndDate(Long userId, Date date);
+
+    @Modifying
+    @Transactional
+    @Query(value = "UPDATE user_info SET total_steps = (SELECT SUM(steps) FROM walk_data WHERE user_id = ?1 AND walk_data.active = 1) WHERE id = ?1", nativeQuery = true)
+    int updateUserSteps(Long userId);
+
 }

+ 8 - 1
src/main/java/com/izouma/walkchina/security/JwtTokenUtil.java

@@ -3,6 +3,7 @@ package com.izouma.walkchina.security;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.stereotype.Component;
@@ -61,7 +62,10 @@ public class JwtTokenUtil implements Serializable {
     //3. According to JWS Compact Serialization(https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-3.1)
     //   compaction of the JWT to a URL-safe string
     private String doGenerateToken(Map<String, Object> claims, String subject) {
-        return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
+        return Jwts.builder()
+                .setClaims(claims)
+                .setSubject(subject)
+                .setIssuedAt(new Date(System.currentTimeMillis()))
                 .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
                 .signWith(SignatureAlgorithm.HS512, secret).compact();
     }
@@ -69,6 +73,9 @@ public class JwtTokenUtil implements Serializable {
     //validate token
     public Boolean validateToken(String token, UserDetails userDetails) {
         final String username = getUsernameFromToken(token);
+        if (StringUtils.isEmpty(username) || userDetails == null) {
+            return false;
+        }
         return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
     }
 }

+ 67 - 0
src/main/java/com/izouma/walkchina/service/JourneyService.java

@@ -1,8 +1,75 @@
 package com.izouma.walkchina.service;
 
+import com.izouma.walkchina.bean.AppConstants;
+import com.izouma.walkchina.domain.*;
+import com.izouma.walkchina.exception.ServiceException;
+import com.izouma.walkchina.repo.*;
+import org.joda.time.Days;
+import org.joda.time.LocalDate;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Date;
+import java.util.List;
+
 @Service
 public class JourneyService {
+    @Autowired
+    private UserJourneyRepository  userJourneyRepository;
+    @Autowired
+    private JourneyStageRepository journeyStageRepository;
+    @Autowired
+    private WalkDataRepository     walkDataRepository;
+    @Autowired
+    private TeamMemberRepository   teamMemberRepository;
+    @Autowired
+    private MessageRepository      messageRepository;
+
+    public void updateUserJourney(Long userId, Date date) {
+        UserJourney userJourney = userJourneyRepository.findByUserId(userId);
+        if (userJourney == null) {
+            throw new ServiceException("无数据");
+        }
+        List<JourneyStage> stageList = journeyStageRepository.findAllByJourneyIdOrderById(userJourney.getId());
+        if (stageList.size() == 0) {
+            throw new ServiceException("无数据");
+        }
+        JourneyStage latestStage = stageList.get(stageList.size() - 1);
+        if (latestStage.getProgress() != 1) {
+
+        }
+        Long steps = 0L;
+        WalkData walkData = walkDataRepository.findByUserIdAndDate(userId, date);
+        if (walkData != null) {
+            steps += walkData.getSteps();
+        }
+        List<TeamMember> teamMembers = teamMemberRepository.findUserTeamMembers(userId, date);
+        for (TeamMember teamMember : teamMembers) {
+            WalkData w = walkDataRepository.findByUserIdAndDate(teamMember.getUserId(), date);
+            if (w != null) {
+                steps += w.getSteps();
+            }
+        }
+        latestStage.setSteps(steps);
+        double progress = steps * AppConstants.STEP_TO_DISTANCE_RATE / latestStage.getDistance();
+        progress = progress > 1 ? 1 : progress;
+        latestStage.setProgress(progress);
+        journeyStageRepository.save(latestStage);
+
+        if (progress == 1) {
+            Message msg = Message.builder()
+                    .userId(userId)
+                    .content("你正在从 " + latestStage.getOrigin().getName()
+                            + " 向 " + latestStage.getDestination().getName()
+                            + " 前进,你今日步数"
+                            + (walkData != null ? walkData.getSteps() : 0)
+                            + "步,已行走" + calcDays(latestStage.getCreatedAt(), new Date()))
+                    .build();
+            messageRepository.save(msg);
+        }
+    }
 
+    private int calcDays(Date start, Date end) {
+        return Days.daysBetween(LocalDate.fromDateFields(start), LocalDate.fromDateFields(end)).getDays();
+    }
 }

+ 27 - 0
src/main/java/com/izouma/walkchina/service/SystemVariableService.java

@@ -0,0 +1,27 @@
+package com.izouma.walkchina.service;
+
+import com.izouma.walkchina.domain.SystemVariable;
+import com.izouma.walkchina.exception.ServiceException;
+import com.izouma.walkchina.repo.SystemVariableRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+public class SystemVariableService {
+    @Autowired
+    private SystemVariableRepository systemVariableRepository;
+
+    public String getStringVariable(String name) {
+        log.info("getStringVariable {}", name);
+        SystemVariable variable = systemVariableRepository.findByName(name);
+        if (variable == null) {
+            log.error("systemVariable {} is null", name);
+            throw new ServiceException("不存在");
+        }
+        return variable.getValue();
+    }
+
+
+}

+ 21 - 8
src/main/java/com/izouma/walkchina/service/UserInfoService.java

@@ -3,8 +3,10 @@ package com.izouma.walkchina.service;
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
+import com.izouma.walkchina.domain.UserFriend;
 import com.izouma.walkchina.domain.UserInfo;
 import com.izouma.walkchina.exception.ServiceException;
+import com.izouma.walkchina.repo.UserFriendRepository;
 import com.izouma.walkchina.repo.UserInfoRepository;
 import com.izouma.walkchina.service.storage.StorageService;
 import lombok.extern.slf4j.Slf4j;
@@ -25,18 +27,18 @@ import java.util.UUID;
 @Slf4j
 public class UserInfoService implements UserDetailsService {
     @Autowired
-    private UserInfoRepository userInfoRepository;
+    private UserInfoRepository   userInfoRepository;
     @Autowired
-    private WxMaService        wxMaService;
+    private WxMaService          wxMaService;
     @Autowired
-    private StorageService     storageService;
+    private StorageService       storageService;
+    @Autowired
+    private UserFriendRepository userFriendRepository;
 
     @Override
     public UserInfo loadUserByUsername(String username) {
         log.info("loadUserByUsername {}", username);
-        UserInfo userInfo = new UserInfo();
-        userInfo.setUsername(username);
-        return userInfoRepository.findOne(Example.of(userInfo)).orElse(null);
+        return userInfoRepository.findByUsername(username);
     }
 
     public UserInfo registerByUserPwd(String username, String password) {
@@ -57,7 +59,7 @@ public class UserInfoService implements UserDetailsService {
             WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(code);
             String openId = result.getOpenid();
             String sessionKey = result.getSessionKey();
-            UserInfo userInfo = userInfoRepository.findByOpenId(openId).orElse(null);
+            UserInfo userInfo = userInfoRepository.findByOpenId(openId);
             if (userInfo != null) {
                 userInfo.setSessionKey(sessionKey);
                 return userInfoRepository.save(userInfo);
@@ -87,7 +89,7 @@ public class UserInfoService implements UserDetailsService {
 
         // 解密用户信息
         WxMaUserInfo wxUserInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
-        UserInfo userInfo = userInfoRepository.findByOpenId(wxUserInfo.getOpenId()).orElse(null);
+        UserInfo userInfo = userInfoRepository.findByOpenId(wxUserInfo.getOpenId());
 
         String avatarUrl = "https://microball.oss-cn-hangzhou.aliyuncs.com/awesomeAdmin/user.png";
         try {
@@ -130,4 +132,15 @@ public class UserInfoService implements UserDetailsService {
 
         throw new ServiceException("获取用户信息失败");
     }
+
+    public void saveFriend(Long userId1, Long userId2) {
+        try {
+            userFriendRepository.save(UserFriend.builder().userId(userId1).friendId(userId2).build());
+        } catch (Exception ignored) {
+        }
+        try {
+            userFriendRepository.save(UserFriend.builder().userId(userId2).friendId(userId1).build());
+        } catch (Exception ignored) {
+        }
+    }
 }

+ 16 - 6
src/main/java/com/izouma/walkchina/service/WalkDataService.java

@@ -7,13 +7,16 @@ import com.izouma.walkchina.domain.WalkData;
 import com.izouma.walkchina.exception.ServiceException;
 import com.izouma.walkchina.repo.UserInfoRepository;
 import com.izouma.walkchina.repo.WalkDataRepository;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
 
 @Service
+@Slf4j
 public class WalkDataService {
     @Autowired
     private WxMaService        wxMaService;
@@ -23,20 +26,27 @@ public class WalkDataService {
     private UserInfoRepository userInfoRepository;
 
     public void saveWalkData(Long userId, String encryptedData, String iv) {
+        log.info("saveWalkData\nuserId:{}\nencryptedData:{}\niv:{}", userId, encryptedData, iv);
         UserInfo userInfo = userInfoRepository.findById(userId).orElse(null);
         if (userInfo == null) {
+            log.error("user {} is null", userId);
             throw new ServiceException("用户不存在");
         }
         String sessionKey = userInfo.getSessionKey();
         List<WxMaRunStepInfo> wxMaRunStepInfoList = wxMaService.getRunService().getRunStepInfo(sessionKey, encryptedData, iv);
         for (WxMaRunStepInfo stepInfo : wxMaRunStepInfoList) {
-            WalkData walkData = walkDataRepository.findByUserIdAndDate(userId, new Date(stepInfo.getTimestamp()));
-            if (walkData == null) {
-                walkData = new WalkData();
+            SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
+            if (fmt.format(new Date(stepInfo.getTimestamp() * 1000)).equals(fmt.format(new Date()))) {
+                WalkData walkData = walkDataRepository.findByUserIdAndDate(userId, new Date(stepInfo.getTimestamp() * 1000));
+                if (walkData == null) {
+                    walkData = new WalkData();
+                }
+                walkData.setDate(new Date(stepInfo.getTimestamp() * 1000));
+                walkData.setSteps(Long.valueOf(stepInfo.getStep()));
+                walkData.setUserId(userId);
+                walkDataRepository.save(walkData);
             }
-            walkData.setDate(new Date(stepInfo.getTimestamp() * 1000));
-            walkData.setSteps(Long.valueOf(stepInfo.getStep()));
-            walkDataRepository.save(walkData);
         }
+        walkDataRepository.updateUserSteps(userId);
     }
 }

+ 12 - 0
src/main/java/com/izouma/walkchina/web/UserInfoController.java

@@ -72,4 +72,16 @@ public class UserInfoController {
         }
         return Result.error("获取用户信息失败,请稍后再试");
     }
+
+    @GetMapping("/saveFriend")
+    public Result saveFriend(@RequestParam("userId") Long userId) {
+        try {
+            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+            UserInfo userInfo = (UserInfo) authentication.getPrincipal();
+            userInfoService.saveFriend(userId, userInfo.getId());
+            return Result.ok();
+        } catch (Exception ignored) {
+        }
+        return Result.error();
+    }
 }

+ 3 - 4
src/main/resources/application.yaml

@@ -12,7 +12,6 @@ spring:
   jpa:
     database: MySQL
     database_platform: org.hibernate.dialect.MySQL5InnoDBDialect
-    show_sql: true
     hibernate:
       ddl_auto: update
     properties:
@@ -53,7 +52,7 @@ aliyun:
 spring:
   profiles: dev
   datasource:
-    url: jdbc:mysql://120.55.131.232:3306/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
+    url: jdbc:mysql://120.55.131.232:3306/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
 storage:
   local_path: /upload/
 aliyun:
@@ -64,7 +63,7 @@ aliyun:
 spring:
   profiles: test
   datasource:
-    url: jdbc:mysql://rdsave1o67m1ido6gwp6.mysql.rds.aliyuncs.com/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
+    url: jdbc:mysql://rdsave1o67m1ido6gwp6.mysql.rds.aliyuncs.com/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
 aliyun:
   oss_end_point: oss-cn-hangzhou-internal.aliyuncs.com
 
@@ -73,6 +72,6 @@ aliyun:
 spring:
   profiles: prod
   datasource:
-    url: jdbc:mysql://rdsave1o67m1ido6gwp6.mysql.rds.aliyuncs.com/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
+    url: jdbc:mysql://rdsave1o67m1ido6gwp6.mysql.rds.aliyuncs.com/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
 aliyun:
   oss_end_point: oss-cn-hangzhou-internal.aliyuncs.com

+ 41 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
+
+    <springProfile name="dev">
+        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+            <encoder>
+                <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            </encoder>
+        </appender>
+        <root level="INFO">
+            <appender-ref ref="CONSOLE"/>
+        </root>
+        <logger name="org.hibernate.SQL" level="DEBUG"/>
+        <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/>
+        <logger name="org.springframework.jdbc.core.JdbcTemplate" level="DEBUG"/>
+        <logger name="org.springframework.jdbc.core.StatementCreatorUtils" level="TRACE"/>
+    </springProfile>
+
+    <springProfile name="prod">
+        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+            <encoder>
+                <pattern>${FILE_LOG_PATTERN}</pattern>
+            </encoder>
+            <file>app.log</file>
+            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+                <fileNamePattern>app.log.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
+                <maxFileSize>10MB</maxFileSize>
+                <maxHistory>60</maxHistory>
+            </rollingPolicy>
+        </appender>
+        <root level="INFO">
+            <appender-ref ref="FILE"/>
+        </root>
+        <logger name="org.hibernate.SQL" level="DEBUG"/>
+        <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/>
+        <logger name="org.springframework.jdbc.core.JdbcTemplate" level="DEBUG"/>
+        <logger name="org.springframework.jdbc.core.StatementCreatorUtils" level="TRACE"/>
+    </springProfile>
+
+</configuration>

+ 19 - 0
src/test/java/com/izouma/walkchina/CommonTest.java

@@ -0,0 +1,19 @@
+package com.izouma.walkchina;
+
+import org.joda.time.Days;
+import org.joda.time.LocalDate;
+import org.junit.Test;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class CommonTest {
+    @Test
+    public void testDays() throws ParseException {
+        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        fmt.parse("2019-07-15 17:58:35");
+        System.out.println(Days.daysBetween(LocalDate.fromDateFields(fmt.parse("2019-07-15 17:58:35")),
+                LocalDate.fromDateFields(new Date())).getDays());
+    }
+}

+ 39 - 0
src/test/java/com/izouma/walkchina/repo/WalkDataRepositoryTest.java

@@ -0,0 +1,39 @@
+package com.izouma.walkchina.repo;
+
+import com.izouma.walkchina.domain.WalkData;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class WalkDataRepositoryTest {
+    @Autowired
+    private WalkDataRepository walkDataRepository;
+
+    @Test
+    public void testSaveWalkData() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(new Date());
+        calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+        WalkData walkData = WalkData.builder()
+                .active(true)
+                .createdAt(new Date())
+                .modifiedAt(calendar.getTime())
+                .build();
+        walkDataRepository.save(walkData);
+        System.out.println(new Date());
+    }
+
+    @Test
+    public void testUpdateTotalSteps() {
+        walkDataRepository.updateUserSteps(665L);
+    }
+
+}