增加积分任务及操作员修改密码功能
diff --git a/backend/build.gradle b/backend/build.gradle
index ff5ab0b..631933b 100644
--- a/backend/build.gradle
+++ b/backend/build.gradle
@@ -74,7 +74,7 @@
     compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.9.1'
     compile group: 'log4j', name: 'log4j', version: '1.2.17'
 
-    compile group: 'com.supwisdom', name: 'payapi-sdk', version: '1.0.26-3-gde708e9'
+    compile group: 'com.supwisdom', name: 'payapi-sdk', version: '1.0.26-5-gf114ee1'
     
     implementation 'org.hamcrest:hamcrest:2.1'
 }
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java b/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java
index 8f0f157..21fc3a6 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java
@@ -22,9 +22,9 @@
   public static final String ARTICLE_STATUS_REVIEW = "review";
   public static final String ARTICLE_STATUS_REJECT = "reject";
 
-  public static final String POINTTASK_STATUS_UNDONE = "undone";
-  public static final String POINTTASK_STATUS_DONE = "done";
-  public static final String POINTTASK_STATUS_RECEIVED = "received";
+  public static final String POINTTASK_STATUS_UNDONE = "undone";//未完成
+  public static final String POINTTASK_STATUS_DONE = "done";//已完成未领取
+  public static final String POINTTASK_STATUS_RECEIVED = "received";//已完成已领取
 
   public static final String FEEDBACK_STATUS_DELETE = "delete";
   public static final String FEEDBACK_STATUS_TOREPLY = "toreply";
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt
index a731ac1..ae8b3fd 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt
@@ -96,10 +96,19 @@
     }
 
     override fun completePointTask(user: TBMobileUser, taskcode:String):JsonResult {
-        return if (taskcode == PointTaskCode.SIGN_IN.code) {
-            signInPointTask(user)
-        }else{
-            JsonResult.error(400,"未知的任务CODE")
+        return when (taskcode) {
+            PointTaskCode.SIGN_IN.code -> {
+                signInPointTask(user)
+            }
+            PointTaskCode.AUTH.code -> {
+                authPointTask(user)
+            }
+            PointTaskCode.CONSUME.code -> {
+                consumePointTask(user)
+            }
+            else -> {
+                JsonResult.error(400,"未知的任务CODE")
+            }
         }
     }
 
@@ -130,6 +139,55 @@
         return JsonResult.ok()
     }
 
+    fun consumePointTask(user: TBMobileUser):JsonResult{
+        val consumeResponse = userProxy.consumeTask(user.userid)
+        if (consumeResponse.retcode != 0) {
+            return JsonResult.error(400,"未完成首次消费不能领取积分")
+        }
+        val statusReponse = userProxy.getTaskStatus(user.userid, PointTaskCode.CONSUME.taskid)
+        if (statusReponse["retcode"] != 0) {
+            logger.error { "查询消费任务异常:${statusReponse["retmsg"]}" }
+            throw PortalBusinessException(statusReponse["retmsg"] as String)
+        }
+        val data = statusReponse["data"] as String
+        if (data.isNotEmpty()) {
+            return JsonResult.error(400,"已领取积分,不能重复领取")
+        }
+        val taskResponse = userProxy.userTask(UserTaskParam().apply {
+            this.userid = user.userid
+            this.taskid = PointTaskCode.CONSUME.taskid.toString()
+        })
+        if (taskResponse.retcode != 0) {
+            logger.error { "完成消费积分任务异常:${taskResponse.retmsg}" }
+            throw PortalBusinessException(taskResponse.retmsg)
+        }
+        return JsonResult.ok()
+    }
+
+    fun authPointTask(user: TBMobileUser):JsonResult{
+        if (user.userid.isNullOrEmpty()) {
+            return JsonResult.error(400,"未完成身份认证不能领取积分")
+        }
+        val statusReponse = userProxy.getTaskStatus(user.userid, PointTaskCode.AUTH.taskid)
+        if (statusReponse["retcode"] != 0) {
+            logger.error { "查询身份认证任务异常:${statusReponse["retmsg"]}" }
+            throw PortalBusinessException(statusReponse["retmsg"] as String)
+        }
+        val data = statusReponse["data"] as String
+        if (data.isNotEmpty()) {
+            return JsonResult.error(400,"已领取积分,不能重复领取")
+        }
+        val taskResponse = userProxy.userTask(UserTaskParam().apply {
+            this.userid = user.userid
+            this.taskid = PointTaskCode.AUTH.taskid.toString()
+        })
+        if (taskResponse.retcode != 0) {
+            logger.error { "完成身份认证积分任务异常:${taskResponse.retmsg}" }
+            throw PortalBusinessException(taskResponse.retmsg)
+        }
+        return JsonResult.ok()
+    }
+
     fun querySignInTaskStatus(user: TBMobileUser,list:ArrayList<PointTaskBean>,bean:PointTaskBean){
         bean.taskcode = PointTaskCode.SIGN_IN.code
         val lastTime = user.lastsignintime
@@ -147,15 +205,32 @@
         list.add(bean)
     }
 
-    fun queryAuthTaskStatus(user: TBMobileUser,list:ArrayList<PointTaskBean>,bean:PointTaskBean){
+    fun queryAuthTaskStatus(user: TBMobileUser,list:ArrayList<PointTaskBean>,bean:PointTaskBean,lasttime:Any?){
         bean.taskcode = PointTaskCode.AUTH.code
-        bean.status = PortalConstant.POINTTASK_STATUS_DONE
+        bean.status = PortalConstant.POINTTASK_STATUS_UNDONE
+        if (lasttime != null) {
+            bean.status = PortalConstant.POINTTASK_STATUS_RECEIVED
+        } else {
+            if (!user.userid.isNullOrEmpty()) {
+                bean.status = PortalConstant.POINTTASK_STATUS_DONE
+            }
+        }
         list.add(bean)
     }
 
-    fun queryConsumeTaskStatus(user: TBMobileUser,list:ArrayList<PointTaskBean>,bean:PointTaskBean){
+    fun queryConsumeTaskStatus(user: TBMobileUser,list:ArrayList<PointTaskBean>,bean:PointTaskBean,lasttime:Any?){
         bean.taskcode = PointTaskCode.CONSUME.code
-        bean.status = PortalConstant.POINTTASK_STATUS_DONE
+        bean.status = PortalConstant.POINTTASK_STATUS_UNDONE
+        if (lasttime != null) {
+            bean.status = PortalConstant.POINTTASK_STATUS_RECEIVED
+        } else {
+            if (!user.userid.isNullOrEmpty()) {
+                val consumeResponse = userProxy.consumeTask(user.userid)
+                if (consumeResponse.retcode == 0) {
+                    bean.status = PortalConstant.POINTTASK_STATUS_DONE
+                }
+            }
+        }
         list.add(bean)
     }
 
@@ -165,14 +240,18 @@
         list.add(bean)
     }
 
+    @Suppress("UNCHECKED_CAST")
     override fun queryPointTaskStatus(user: TBMobileUser): List<PointTaskBean>? {
         val result = ArrayList<PointTaskBean>()
-        val taskResponse = userProxy.tPointsTaskNoPage
+        var userid = ""
+        if (!StringUtil.isEmpty(user.userid)) {
+            userid = user.userid!!
+        }
+        val taskResponse = userProxy.getTPointsTaskNoPage(userid)
         if (taskResponse["retcode"] != 0) {
             logger.error { "查询积分任务异常" }
             throw PortalBusinessException("查询积分任务异常")
         }
-        @Suppress("UNCHECKED_CAST")
         val data = taskResponse["data"] as ArrayList<LinkedHashMap<String,Any>>
         data.forEach {
             val taskid =  it["taskid"] as Int
@@ -180,15 +259,16 @@
                 this.points = it["taskpoints"] as Int
                 this.taskname = it["taskname"] as String
             }
+            val lasttime = it["lasttime"]
             when (taskid) {
                 PointTaskCode.SIGN_IN.taskid -> {
                     querySignInTaskStatus(user,result,bean)
                 }
                 PointTaskCode.AUTH.taskid -> {
-                    queryAuthTaskStatus(user,result,bean)
+                    queryAuthTaskStatus(user,result,bean,lasttime)
                 }
                 PointTaskCode.CONSUME.taskid -> {
-                    queryConsumeTaskStatus(user,result,bean)
+                    queryConsumeTaskStatus(user,result,bean,lasttime)
                 }
                 PointTaskCode.EXCHANGE.taskid -> {
                     queryExchangeTaskStatus(user,result,bean)
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
index 5e10bf5..23d7284 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
@@ -4,6 +4,7 @@
 import com.supwisdom.dlpay.api.service.UploadPicService
 import com.supwisdom.dlpay.framework.core.JwtConfig
 import com.supwisdom.dlpay.framework.core.JwtTokenUtil
+import com.supwisdom.dlpay.framework.domain.TOperator
 import com.supwisdom.dlpay.framework.redisrepo.ApiJwtRepository
 import com.supwisdom.dlpay.framework.service.OperatorDetailService
 import com.supwisdom.dlpay.framework.service.SystemUtilService
@@ -19,6 +20,7 @@
 import org.springframework.http.HttpStatus
 import org.springframework.http.ResponseEntity
 import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
 import org.springframework.web.bind.annotation.*
 import org.springframework.web.multipart.MultipartHttpServletRequest
 import java.util.regex.Pattern
@@ -67,6 +69,33 @@
         return ResponseEntity.ok().body(JsonResult.ok())
     }
 
+    @RequestMapping("user/updatepwd")
+    fun updatePwd(@RequestHeader("Authorization") auth: String?,
+                  curpwd: String, newpwd: String, renewpwd: String): ResponseEntity<Any> {
+        if (auth == null) {
+            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build()
+        }
+        val p = SecurityContextHolder.getContext().authentication
+        val oper = operatorDetailService.findByOperid(p.name)
+        val encoder = BCryptPasswordEncoder()
+        if (!encoder.matches(curpwd, oper.password)) {
+            return ResponseEntity.ok().body(JsonResult.error("当前密码错误"))
+        }
+        if (newpwd != renewpwd) {
+            return ResponseEntity.ok().body(JsonResult.error("两次密码不一致"))
+        }
+        if (newpwd.length < 6 || newpwd.length > 20) {
+            return ResponseEntity.ok().body(JsonResult.error("密码必须为6-20个字符"))
+        }
+        oper.operpwd = encoder.encode(newpwd)
+        operatorDetailService.saveOper(oper)
+        val jwt = auth.substring(jwtConfig.tokenHeader.length)
+        val claims = JwtTokenUtil(jwtConfig).verifyToken(jwt)
+        SecurityContextHolder.clearContext()
+        apiJwtRepository.deleteById(claims[ReservedClaimNames.JWT_ID].toString())
+        return ResponseEntity.ok().body(JsonResult.ok())
+    }
+
     @RequestMapping("/user/info")
     fun getUserInfo(): JsonResult? {
         return try {
@@ -89,6 +118,39 @@
 
     }
 
+    @RequestMapping("/user/updateinfo")
+    fun updateUserInfo(@RequestBody bean:TOperator): JsonResult?{
+        return try {
+            val p = SecurityContextHolder.getContext().authentication
+            val oper = operatorDetailService.findByOperid(p.name)
+            oper.opername = bean.opername
+            oper.mobile = bean.mobile
+            oper.email = bean.email
+            operatorDetailService.saveOper(oper)
+            return JsonResult.ok()
+        } catch (e: Exception) {
+            logger.error { e.message }
+            JsonResult.error("修改用户个人资料异常")
+        }
+    }
+
+    @RequestMapping("/user/data")
+    fun getUserData(): JsonResult? {
+        return try {
+            val p = SecurityContextHolder.getContext().authentication
+            val oper = operatorDetailService.findByOperid(p.name)
+            val data = HashMap<String, String?>()
+            data["opername"] = oper.opername
+            data["opercode"] = oper.opercode
+            data["mobile"] = oper.mobile
+            data["email"] = oper.email
+            JsonResult.ok().put("data", data)
+        } catch (e: Exception) {
+            logger.error { e.message }
+            JsonResult.error("查询用户个人信息异常")
+        }
+
+    }
     @RequestMapping("/user/resource")
     fun getUserResource(): JsonResult? {
         return try {
@@ -194,7 +256,7 @@
         if (map["retcode"] == "1") {
             return JsonResult.error("图片上传失败!")
         }
-        return JsonResult.ok().put("data",map)
+        return JsonResult.ok().put("data", map)
     }
 
     @RequestMapping("/column/all")
@@ -427,7 +489,7 @@
 
     @RequestMapping(value = ["/advisory/switchdisplay/{advisoryid}"], method = [RequestMethod.POST])
     fun switchAdvisoryDisplay(@PathVariable(value = "advisoryid") advisoryid: String,
-                      @RequestParam(value = "value") value: String): JsonResult? {
+                              @RequestParam(value = "value") value: String): JsonResult? {
         return try {
             val result = advisoryService.switchDisplay(advisoryid, value)
             JsonResult.ok().put("result", result)
@@ -484,7 +546,7 @@
      */
     @RequestMapping(value = ["/outlets/switchopen/{outletsno}"], method = [RequestMethod.POST])
     fun switchOutletsOpen(@PathVariable(value = "outletsno") outletsno: String,
-                              @RequestParam(value = "value") value: String): JsonResult? {
+                          @RequestParam(value = "value") value: String): JsonResult? {
         return try {
             val result = outletsService.switchOpen(outletsno, value)
             JsonResult.ok().put("result", result)