diff --git a/pom.xml b/pom.xml index 5221a4c..0ae6ce7 100644 --- a/pom.xml +++ b/pom.xml @@ -52,6 +52,18 @@ + + + com.alibaba + dashscope-sdk-java + 2.10.1 + + + com.alipay.sdk + alipay-sdk-java + 4.35.37.ALL + + cn.smallbun.screw screw-core diff --git a/src/main/java/io/v/nutz/MainLauncher.java b/src/main/java/io/v/nutz/MainLauncher.java index 0ff262d..12361c2 100644 --- a/src/main/java/io/v/nutz/MainLauncher.java +++ b/src/main/java/io/v/nutz/MainLauncher.java @@ -977,11 +977,13 @@ public class MainLauncher { try { MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); ObjectName objectName = new ObjectName("com.alibaba.druid:type=MockDriver"); - if (mbeanServer.isRegistered(objectName)) + if (mbeanServer.isRegistered(objectName)) { mbeanServer.unregisterMBean(objectName); + } objectName = new ObjectName("com.alibaba.druid:type=DruidDriver"); - if (mbeanServer.isRegistered(objectName)) + if (mbeanServer.isRegistered(objectName)) { mbeanServer.unregisterMBean(objectName); + } } catch (Exception ex) { } } diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/controller/AlipayClientConfig.java b/src/main/java/io/v/nutz/zhgh/memberCost/controller/AlipayClientConfig.java new file mode 100644 index 0000000..7819815 --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/controller/AlipayClientConfig.java @@ -0,0 +1,22 @@ +package io.v.nutz.zhgh.memberCost.controller; + +/** + * @ClassName AlipayClientConfig + * @Description TODO + * @Author zhf + * @Date 2024/1/25 15:33 + */ +public interface AlipayClientConfig { + String serverUrl = "https://openapi.alipay.com/gateway.do"; + String appId = "2021004133670087"; + String sellerId = "2088002638762620"; + String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCEJBWNlUIY/2Tave1OtjTgvA21GZ5tdvZZD3jFmixIFTkEdZaRUpXCvlKuZ9heoL1IQwpbuOErJ4dM2f2Ju/Oc7QtUOjEOX6CnElR73KK5OSY8d8f5822LUOgp2zg5FHI6C7olYmjN4Nw26G6BGyqQBmWs4/sKzghKelEaH9AqkR8DZ+yOvuYtIg5KEvVixsM27TMhd6/3BuNXDIiQDVH9ZeQVb9IKuynZ6hnUJS0T4MkS41qehS1u8LgplGU5yvrNuUNeQtybADsiGHDNmNkl5lVt0QNh+N/lo56//duf5PJwh8ApDB22eXptiS6p321PSrYowy5VeFpHC07Tref9AgMBAAECggEAPQddXPKegGUT82LcgwnsCg9QVV/rp6rVw/Q9VyYJZZFHsCOO0rdNq4+zKBGWAL5ELWepFQuiEwhCmN/lFQPVU5i3LsNhfL31uLPiiQIxtVILssmvdmVTJpDLaOlyYgprZxubcUCuHsfHbSSURNSDJ9mMg/kXLLpTYfJ0Gpiuz7lkrMuAxncdz88Sp2r0O9k2T+TcnHFpRXHs+C/QAaa15EF18ieDSBLPkY0ti1R8J91LGAzDrjwcP7pNlq4u7TasZ7djv47ZFwQ3yjWoo13d9ab0MBYeQx9Grf5N+JGNf33YLyulQ0IshcuwNyB+RYhyWGjNmjnJdytzKRMOYSpPgQKBgQC6iqMPX+LGunyI+3T9l/AwAVWRJXzEHPflNxDYfQbicB5awlRixxH5T1qyZ46KZb/pBt01qDULXy0bEObVFSjAn1wXPzC9Fwb+BtVZUroYBTKV3tOAMpVCz2AAC34OZwG/3X//sRtW9Sr0Dr+yCcx8ULMiFS1BuCZfhSNXA516NQKBgQC1V+rge1pYKGnjtWqML4qJy4FEIDI4fSpGIizxumYDMxdXoUdNKoG2NHQkznHU4fIHJPVvIN/Tm82mfj2rhH9eFuu1FB8TL2soe5nPgzSJ9AmP7rZ7KBo3/SczvZqUEpii8+PjHu+Gx95BmgTzOFMnYz8xzitb4IBGTEGxVzavqQKBgCL28XFkS6FsOwOB/n+6Bu84kM1P9X7c3yo7lBC//pZa5ZWlbyPEpH3SffGKr5EJWVtYSgZQrQCgqle0Z0/xU14ngJ9q3LvUoR7kMQE5HGB8OOsWhRY2ZPvM2vWnMc2JSS6pWeCXVcSK164/RXcdlxKGHc15oq360lZ9Ig6hQtcxAoGAIYijd2V4HGtEwYXvsQKtlLOcMNPfVZDXu2Zgd0bnzFmrTFoXjE569A2ZGKFQbXRmxClydV1X5pKeIdagYtI6l1SXu8F/yZVwNGk+1R/HHGeTSRl0hyuwRYA7upaqOg2CSkfdcUdsNblKAUmQ9sUIo3T336bnX7MRJW6+iyO8ihkCgYBG8vG1fVUwPmqlRK+QanHxicR1+UyjRAN+aW6dgJUNMlC+tmPeHj21+WGkDdKPdhinHziLihLmzbmpwWSDwuGMMQPNQm8gSjiaqy1tWcP6XKDxjpG5biTzwEyHNuCIY6odS4HTeDOrrU4LvN6PxirN8xKBIpq+A2cgpGo+Mn4x+g=="; + String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjO/QUy+ujNBlToL6Kt8YjvTRGpEwmXjqc9pFe7GIORVkzBXP3F/UC/w5mPiwXhhyymXAe7bUwLANL/QMUZhvpjjCdLENtFWC9bd6hq3m2oHiTu0oicbzqCuaoQkzik2NybrNjuH+aYVi4RU0eNYpdewQoHHW+hbfxkSYUWmx7NF4SuG93edYlpc/G/ImdrweATLE0b6W9il4H/BxVUweCraPrispiOM8r6TN3fiIKUQRP15HKQo8Xsr4pMJzfi37I9aN8AThN/xBf6sual8IZZsH5hC3PS37LrYkXbUjt0dK5tqKl3SsZPjvvHGyz9b9JC225+0q09Y6B8/axOlihwIDAQAB"; + + /* String serverUrl = "https://openapi-sandbox.dl.alipaydev.com/gateway.do"; + String appId = "9021000134641646"; + String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCBFTF8qFbK+NiqUbKf1/jWHL/s0hfUXK6cyKwZCEXkEMZH1Lu6kZQl3kQye9Fsasawxn1vLmKz+OKjMiE+TdTytHDu5ULdLlSHN3bY1qf91i8L+RJfmZpb1p+NQOk9zImhhSauuk+itMkTC3bTiwwAkg/utOxkNB7YaynpAb3evhXnlX3LUVTHaMnCQFeV7ithh7CDKx0LPlxOpOvxnkWDBR3nsdcfjDqYNDVHXnUxEk0KQV4Ik6fA40+Gq/HXTByJolCSAaTk0OaH2ULp1RZAklWLqhiNEhytTZAlJUx8cSm36mm0c4jhgSXNdRz0Yi1BlPY9yxQGStpH5ue3+EfvAgMBAAECggEAda/D4Zp9HysIJyi7SZ6XwWaO2TSnAzfI/yq6NUxkpE1i6cSbr7rgrjHaTYiz5DvpkOw3GnHZDarhvtaKlopRl0JKIJSnhI6kBG/eDE6Q9Q4c8LaSONULdaXU6+z9ehmMddW28eDtkDNxi8qM+MuyEqcYnZMYXzdh1ADIQicTXArxo+9fpvlKUMNxOTO5LoOf0DtJg/xE1CD9PtWVc+l2G8S3+C52+RhfZ214YQdxwayMlvJQlWzLTbfzJCp8w4F2up1nJdwp7EY8k8xDUngEnG6BWm8ztWUVTTg7qp/+SC9yMTD2dl86wDkJt1lTtwcKaWxHYh2ZIn8a8+icHFykaQKBgQDgBEWAmuj0pgpny5Q0GRsUYPq42SwpN70u4rmD5UYFCeDHaKb4U3kyvA1V+1Tp0XWzFi7GU855h1n8dnQX64J3Vm4GfhftWwTJgB5ibbY53cZVEoV5nZe0bOO4hxxMdNy3BKjPovkT0REPpCkVas/RRLAFCdnvi6vmDkFxvv9JewKBgQCTgx9NZZCqSzzCJYpLTDOCitooOQmR8kAlgBiDCcHeH2wNVMh5O2Dl/OyTGauKUJFWIOSD8FXVTrNUbOEmx58msnS/+Mc5SnbEka5ptVEDp73gf6ctB+eZAMdO1kLsBT3iKnuyNa7pRyR/D2A692RHOTQZIvRHE1N+kM1r+iBPHQKBgCZRVLocxUAjrp/2eJE4wiMIO5qmuyEJwbhlW6ot634tJF+3jOfpD1AYToeoh+u+wk0xvCp8Z1LuTfwbHtyAkj5rcEJ4Cwu0h+sXmRro/USEpMokcuRMioh4H7OOmM6TJrW/fEiX7dbv6eUtBUH+lTGMeDdEahzJXUvqoFMegnhFAoGAa2eflRUMflIFzT7UMPsszjIXog3VoASJHETmlBK4q+ipHhPLXCoV5Z+BCaI5Op5rFBEjEcYeWQ/Slvgn/7p9cQmi5FxZgqdrTrjcC2/Pqx+pqxqHOMx2nvroI8jyNTOj2VchdaKM1qHMOw+Q+55Bz3IhMuQ2hMHXm2IHkEUw3SkCgYBjcqcWbJcq26L8yYVpU2JFzOvu7iHuV99TpEvF9Ym3cAcSNuoR5kGXzGS0MadYY87cd4HK9HvmXQmthLY14buKYxq27ZFfNbK/Auz8vk0Wbrm1Ym4Z1yMqClQqxKdr4hV29ijn1nPProRqgnVsGH3EtFmNxDfilZoVzh9ERaZe7w=="; + String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArhElUiFMpxqFCs+8zDHa4OVuhdWgKUUGVKgWnfLktPgy9mDZkuGPKk295k8ktWQSUZsnFvT8ikJIKdGYfbSWzlXvCAn6lDDDlsjfOJWMQ6zLmb9xygCih2OjwN5xt9QFIIthnWq8sOXpWvqmoRpIFQHolxxmvvCmUZ/VwK6mwgwU/yVvVypruQ/FGrJA70LAcJ764spWAMy/pWIoIs5UewOlJa3TAcZQIqRnjupL2/sI/TpIWFWF90a/rahwLfBgZ83VH7MA4Tl9uFLc3aeNFLllDF4X7lRdzaHIMYgUUKte9yvlDy5Ihrt+ssjsgdRhqLHvFn00u/g7BCvO5ZmIUwIDAQAB"; +*/ + +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/controller/AlipayClientController.java b/src/main/java/io/v/nutz/zhgh/memberCost/controller/AlipayClientController.java new file mode 100644 index 0000000..7270989 --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/controller/AlipayClientController.java @@ -0,0 +1,68 @@ +package io.v.nutz.zhgh.memberCost.controller; + +import io.v.nutz.zhgh.memberCost.service.AlipayService; +import lombok.extern.slf4j.Slf4j; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * @ClassName AlipayClientController + * @Description TODO + * @Author zhf + * @Date 2024/1/25 15:36 + */ +@IocBean +@Slf4j +@Ok("json:full") +@At("/mobile/memberCost/AlipayClient") +public class AlipayClientController { + + + @Inject + private AlipayService alipayService; + + + @At("/tradePagePay") + public String tradePagePay(String money, String paymentProjectId) throws Exception { + log.info("统一收单下单并支付接口调用"); + String formStr = alipayService.tradeCreate(money, paymentProjectId); + return formStr; + } + + @At("/tradeNotify") + @Ok("re") + public String tradeNotify(HttpServletRequest request) { + try { + Map params = new HashMap(); + Map requestParams = request.getParameterMap(); + for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) { + String name = (String) iter.next(); + String[] values = (String[]) requestParams.get(name); + String valueStr = ""; + for (int i = 0; i < values.length; i++) { + valueStr = (i == values.length - 1) ? valueStr + values[i] + : valueStr + values[i] + ","; + } + //乱码解决,这段代码在出现乱码时使用 + + valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); + + params.put(name, valueStr); + } + log.info("支付通知,正在执行,通知参数:{}"); + return alipayService.tradeNotify(params); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + } + +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/controller/mobile/MobileMemberCostListController.java b/src/main/java/io/v/nutz/zhgh/memberCost/controller/mobile/MobileMemberCostListController.java new file mode 100644 index 0000000..c3d1e43 --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/controller/mobile/MobileMemberCostListController.java @@ -0,0 +1,69 @@ +package io.v.nutz.zhgh.memberCost.controller.mobile; + +import io.v.nutz.base.annontation.ViReturn; +import io.v.nutz.web.commons.utils.ShiroUtil; +import io.v.nutz.zhgh.memberCost.service.MemberPaymentService; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +/** + * @ClassName MobileMemberCostListController + * @Description TODO + * @Author zhf + * @Date 2024/1/26 15:37 + */ +@IocBean +@Slf4j +@Ok("json:full") +@At("/mobile/memberCost/list") +public class MobileMemberCostListController { + + @Inject + private MemberPaymentService memberPaymentService; + + @At("") + @Ok("beetl:/mobile/memberCost/memberCostList.html") + public void index() { + } + + @At("/paySuccess") + @Ok("beetl:/mobile/memberCost/paySuccess.html") + public void paySuccess() { + } + + + @At + @ViReturn + public Object pageData(Integer memberActive) { + Sql sql = Sqls.create(""" + SELECT + mpi.*, + mpp.modeValue, + mpp.modeValueList, + mpp.selectMode, + mpp.projectName + FROM + member_payment_info mpi + LEFT JOIN member_payment_project mpp ON mpi.paymentProjectId = mpp.id + WHERE + mpi.userId = @userId + AND mpp.isDisabled =0 + and mpi.isPayment =@isPayment + """).setParam("userId", ShiroUtil.getUserId()).setParam("isPayment", memberActive); + + return memberPaymentService.listMap(sql); + } + + @At + @ViReturn + public Object getPayInfo(String id) { + return memberPaymentService.fetch(id); + } + + +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/controller/payment/MemberPaymentConfigController.java b/src/main/java/io/v/nutz/zhgh/memberCost/controller/payment/MemberPaymentConfigController.java new file mode 100644 index 0000000..7e4d016 --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/controller/payment/MemberPaymentConfigController.java @@ -0,0 +1,44 @@ +package io.v.nutz.zhgh.memberCost.controller.payment; + +import io.v.nutz.base.annontation.ViReturn; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentConfig; +import io.v.nutz.zhgh.memberCost.service.MemberPaymentService; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + + +@IocBean +@Slf4j +@Ok("json:full") +@At("/platform/member/payment/config") +public class MemberPaymentConfigController { + + @Inject + private MemberPaymentService memberPaymentService; + + @At("") + @Ok("beetl:/platform/memberCost/payment/config.html") + @RequiresPermissions("member.payment.config") + public void index() {} + + + @At + @ViReturn + public Object getPaymentConfig(){ + return memberPaymentService.getConfig(); + } + + + @At + @ViReturn + @RequiresPermissions("member.payment.config") + public Object doAddOrModify(MemberPaymentConfig memberPaymentConfig){ + System.out.println(memberPaymentConfig); + memberPaymentService.dao().insertOrUpdate(memberPaymentConfig); + return null; + } +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/controller/payment/MemberPaymentManageController.java b/src/main/java/io/v/nutz/zhgh/memberCost/controller/payment/MemberPaymentManageController.java new file mode 100644 index 0000000..4ad2167 --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/controller/payment/MemberPaymentManageController.java @@ -0,0 +1,261 @@ +package io.v.nutz.zhgh.memberCost.controller.payment; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import io.v.nutz.base.annontation.ViReturn; +import io.v.nutz.base.dao.CndPlus; +import io.v.nutz.base.query.PageForm; +import io.v.nutz.base.result.Result; +import io.v.nutz.sys.models.Sys_user; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentConfig; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentProject; +import io.v.nutz.zhgh.memberCost.service.MemberPaymentService; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.impl.NutTxDao; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; +import org.nutz.lang.Strings; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + + +@IocBean +@Slf4j +@Ok("json:full") +@At("/platform/member/payment/manage") +public class MemberPaymentManageController { + + @Inject + private MemberPaymentService memberPaymentService; + + @At("") + @Ok("beetl:/platform/memberCost/payment/manage.html") + @RequiresPermissions("member.payment.manage") + public void index() { + } + + + @At + @ViReturn + @RequiresPermissions("member.payment.manage") + public Object pageData(PageForm pageForm, + @Param(value = "year", required = false) String year, + @Param(value = "projectName", required = false) String projectName) { + Sql sql = Sqls.create("select project.*,IF((SELECT count(1) FROM member_payment_info WHERE paymentProjectId = project.id)>0,TRUE,FALSE) created from member_payment_project project $condition"); + CndPlus cnd = CndPlus.create(); + cnd.andEX("project.`year`", "=", year); + if (Strings.isNotBlank(projectName)) { + cnd.and(Cnd.likeEX("project.projectName", projectName)); + } +// cnd.desc("project.`year`"); + cnd.desc("project.createTime"); + sql.setCondition(cnd); + return memberPaymentService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + + /** + * 是否开启 + * + * @param id 项目Id + * @return + */ + @At + @ViReturn + @RequiresPermissions("member.payment.manage") + public Object openClosedProject(String id) { + //位运算 取反 + memberPaymentService.dao().update(MemberPaymentProject.class, + Chain.makeSpecial("isDisabled", "isDisabled ^ 1"), + Cnd.where("id", "=", id)); + return null; + } + + + /** + * 添加或修改缴费项目 + * + * @param paymentProject + * @return + */ + @At + @ViReturn + @RequiresPermissions("member.payment.manage") + public Object doSave(MemberPaymentProject paymentProject) { + memberPaymentService.insertOrUpdate(paymentProject); + return null; + } + + + /** + * 设置缴费人员 + * + * @param id 缴费项目Id + * @param isRenew 是否更行缴费人员 + * @return + */ + @At + @ViReturn + @RequiresPermissions("member.payment.manage") + public Object doSetPayment(String id, Boolean isRenew) { + //如果不是更新缴费人员,就删除该项目下的所有待缴费信息,再重新设置 + if (!isRenew) { + memberPaymentService.clear(Cnd.where("paymentProjectId", "=", id)); + } + + //获取缴费配置 + MemberPaymentConfig config = memberPaymentService.getConfig(); + List payStandards = config.getPayStandards(); + //缴费人员类型 + List personTypeList = new ArrayList<>(); + payStandards.forEach(v->{ + personTypeList.addAll(v.getPersonTypes()); + }); + + //获取所有有入会时间的会员 + List memberList = memberPaymentService.dao().query(Sys_user.class, Cnd.where("member", "=", 1).and("memberJoinTime","is not",null).and("personType","in",personTypeList)); + //获取该项目下的代缴人员 + List paymentUserIdList = memberPaymentService.query(Cnd.where("paymentProjectId", "=", id)).stream().map(MemberPaymentInfo::getUserId).collect(Collectors.toList()); + //过滤出需要新增到记录表中的人员 + List needInsertUserIds = memberList.stream().filter(v -> !paymentUserIdList.contains(v.getId())).collect(Collectors.toList()); + + //获取缴费项目 + MemberPaymentProject project = memberPaymentService.dao().fetch(MemberPaymentProject.class, id); + //该项目的缴费月份是几月到几月,转为数组,判断新入职教工应缴费几个月 + String[] strings = project.getPaymentMonth().substring(0, project.getPaymentMonth().length() - 1).split("-"); + DateTime beginDate = DateUtil.parse(project.getYear() + "-" + strings[0] + "-01"); + //获取月份的最后一天 + DateTime endDate = DateUtil.endOfMonth(DateUtil.parse(project.getYear() + "-" + strings[1] + "-01")); + + List memberPaymentInfos = new ArrayList<>(); + needInsertUserIds.forEach(v -> { + MemberPaymentInfo paymentInfo = new MemberPaymentInfo(); + //如果是新入职教工,计算需要缴纳的月数 + if (v.getMemberJoinTime().after(beginDate) && v.getMemberJoinTime().before(endDate)){ + long differMonth = DateUtil.betweenMonth(v.getMemberJoinTime(), endDate, false); + paymentInfo.setPaymentMonth(String.valueOf(differMonth)); + } else { + paymentInfo.setPaymentMonth(config.getPaidDuration()); + } + paymentInfo.setUserId(v.getId()); + paymentInfo.setLoginname(v.getLoginname()); + paymentInfo.setPaymentProjectId(id); + paymentInfo.setPayment(false); + memberPaymentInfos.add(paymentInfo); + }); + + if (memberPaymentInfos.size() < 500) { + memberPaymentService.insert(memberPaymentInfos); + } else { + List> splitList = CollectionUtil.split(memberPaymentInfos, 500); + NutTxDao nutTxDao = new NutTxDao(memberPaymentService.dao()).setDebug(true); + nutTxDao.beginRC(); + ExecutorService executorService = Executors.newWorkStealingPool(); + List> taskList = new ArrayList<>(); + for (List everyList : splitList) { + taskList.add(() -> nutTxDao.insert(everyList).size()); + } + List> futureList = null; + AtomicInteger atomicInteger = new AtomicInteger(); + try { + futureList = executorService.invokeAll(taskList); + for (Future future : futureList) { + atomicInteger.getAndAdd((Integer) future.get()); + } + if (atomicInteger.get() != memberPaymentInfos.size()) { + throw new RuntimeException("插入数据与期望数据条数不符"); + } + nutTxDao.commit(); + } catch (Exception e) { + nutTxDao.rollback(); + throw new RuntimeException(e); + } finally { + executorService.shutdown(); + } + } + return null; + } + + + /** + * 删除 + * + * @param id 项目Id + * @return + */ + @At + @RequiresPermissions("member.payment.manage") + @Aop(TransAop.READ_COMMITTED) + public Object doRemove(String id) { + int paymentCount = memberPaymentService.count(Cnd.where("paymentProjectId", "=", id).and("isPayment", "=", 1)); + if (paymentCount > 0) { + return Result.error().addMsg("该项目已有人完成缴费,请将缴费人员设置为未缴后再进行删除!"); + } + memberPaymentService.dao().clear(MemberPaymentProject.class, Cnd.where("id", "=", id)); + memberPaymentService.clear(Cnd.where("paymentProjectId", "=", id)); + return Result.success(); + } + + + /** + * 获取全部缴费项目 + * + * @param year + * @return + */ + @At + @ViReturn + @RequiresPermissions("member.payment.manage") + public Object getAllProject(String year) { + CndPlus cnd = CndPlus.create(); + cnd.and("isDisabled", "=", 0); + if (Strings.isNotBlank(year)) { + cnd.and("`year`", "=", year); + } + cnd.desc("createTime"); + cnd.desc("year"); + return memberPaymentService.dao().query(MemberPaymentProject.class, cnd); + } + + + @At("/findOne") + @ViReturn + public Object findOne(String id) { + return memberPaymentService.findOneProject(id); + } + + + @At + @ViReturn + @RequiresPermissions("member.payment.manage") + public Object isMonthCreatedByYear(@Param("year") String year, @Param("monthSelect") String monthSelect, @Param("id") String projectId) { + List nutMapList = Json.fromJsonAsList(NutMap.class, monthSelect); + for (NutMap nutMap : nutMapList) { + int count = memberPaymentService.dao().count(MemberPaymentProject.class, Cnd.where("`year`", "=", year).and("paymentMonth", "=", nutMap.getString("label"))); + nutMap.setv("code", count > 0 ? 1 : 0); + } + return nutMapList; + } + +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/controller/payment/MemberPaymentSummaryController.java b/src/main/java/io/v/nutz/zhgh/memberCost/controller/payment/MemberPaymentSummaryController.java new file mode 100644 index 0000000..0b60e6a --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/controller/payment/MemberPaymentSummaryController.java @@ -0,0 +1,338 @@ +package io.v.nutz.zhgh.memberCost.controller.payment; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.hutool.core.util.StrUtil; +import io.v.nutz.base.annontation.ViReturn; +import io.v.nutz.base.dao.CndPlus; +import io.v.nutz.base.query.PageForm; +import io.v.nutz.base.result.Result; +import io.v.nutz.base.utils.MsgApi; +import io.v.nutz.base.utils.Vi; +import io.v.nutz.base.utils.ViTool; +import io.v.nutz.sys.models.Sys_union; +import io.v.nutz.sys.services.SysUserService; +import io.v.nutz.web.commons.utils.ShiroUtil; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo; +import io.v.nutz.zhgh.memberCost.service.MemberPaymentService; +import io.v.nutz.zhgh.memberCost.template.MemberPaymentTemp; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.AdaptBy; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; +import org.nutz.mvc.upload.TempFile; +import org.nutz.mvc.upload.UploadAdaptor; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedOutputStream; +import java.math.BigDecimal; +import java.net.URLEncoder; +import java.text.DecimalFormat; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + + +@IocBean +@Slf4j +@Ok("json:full") +@At("/platform/member/payment/summary") +public class MemberPaymentSummaryController { + + @Inject + private MemberPaymentService memberPaymentService; + + @Inject + private SysUserService sysUserService; + + @Inject + private MsgApi msgApi; + + @At("") + @Ok("beetl:/platform/memberCost/payment/summary.html") + @RequiresPermissions("member.payment.summary") + public void index() { + } + + + public Sql dataSql(String pageOrderName, String pageOrderBy, String searchName, String searchKeyword, + String unionId, String unitId, String threeUnitId, String unionGroupId, + String personType, String userState, String paymentProjectId, String year, + String isPay) { + Sql sql = Sqls.create(""" + SELECT + mpi.*, + IF(mpi.isPayment = 1,'已缴费','未缴费') AS isPay, + mpp.projectName, + u.username, + u.sex, + u.member, + u.welfareMember, + u.personType, + u.userState, + u.unionname, + u.unionid, + u.unitname, + u.unitid, + u.threeUnitName, + u.threeUnitCode, + u.unionGroupName, + u.mobile, + u.birthday + FROM + `member_payment_info` mpi + LEFT JOIN `user` u ON u.id = mpi.userId + left join `member_payment_project` mpp on mpp.id = mpi.paymentProjectId + $condition + """); + CndPlus cnd = CndPlus.create(); + if (StrUtil.isNotBlank(searchName) && StrUtil.isNotBlank(searchKeyword)) { + cnd.and(Cnd.likeEX(searchName, searchKeyword)); + } + if (!ShiroUtil.hasAnyRoles("sysadmin,A06,H03")) { + if (ShiroUtil.hasRole("H04")) { + cnd.and("u.unionid", "=", Vi.getUnionId()); + } else { + cnd.and("u.unionGroupId", "in", io.v.nutz.web.commons.utils.ShiroUtil.getUnionGroupIds()); + } + } + cnd.andEX("mpp.`year`", "=", year); + cnd.andEX("mpi.paymentProjectId", "=", paymentProjectId); + if (Strings.isNotBlank(isPay) && !"null".equals(isPay)) { + cnd.andEX("mpi.isPayment", "=", "true".equals(isPay) ? 1 : 0); + } + cnd.andEX("u.unionid", "=", unionId); + cnd.andEX("u.unitid", "=", unitId); + cnd.andEX("u.threeUnitId", "=", threeUnitId); + cnd.andEX("u.unionGroupId", "=", unionGroupId); + cnd.andEX("u.personType", "=", personType); + cnd.andEX("u.userState", "=", userState); + cnd.groupBy("u.id"); + + if (StrUtil.isNotBlank(pageOrderName) && StrUtil.isNotBlank(pageOrderBy)) { + cnd.orderBy(pageOrderName, pageOrderBy.equalsIgnoreCase("ascending") ? "ASC" : "DESC"); + } else { + cnd.desc("mpi.isPayment"); + cnd.desc("mpi.paymentTime"); + cnd.asc("u.loginname"); + } + sql.setCondition(cnd); + return sql; + } + + + @At + @ViReturn + @RequiresPermissions("member.payment.summary") + public Object pageData(PageForm pageForm, + @Param(value = "unionId", required = false) String unionId, + @Param(value = "unitId", required = false) String unitId, + @Param(value = "unionGroupId", required = false) String unionGroupId, + @Param(value = "threeUnitId", required = false) String threeUnitId, + @Param(value = "personType", required = false) String personType, + @Param(value = "userState", required = false) String userState, + @Param(value = "paymentProjectId", required = false) String paymentProjectId, + @Param(value = "year", required = false) String year, + @Param(value = "isPay", required = false) String isPay) { + Sql sql = this.dataSql(pageForm.getPageOrderName(), pageForm.getPageOrderBy(), pageForm.getSearchName(), + pageForm.getSearchKeyword(), unionId, unitId, threeUnitId, unionGroupId, + personType, userState, paymentProjectId, year, isPay); + return memberPaymentService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + + @At + @ViReturn + @RequiresPermissions("member.payment.summary") + public Object modify(@Param("ids") String[] ids, String paymentMoney, boolean isPay, String remark) { + List idList = Arrays.asList(ids); + if (Lang.isNotEmpty(idList)) { + if (isPay) { + //未缴费设为已缴费 + memberPaymentService.update(Chain.make("paymentMoney", paymentMoney) + .add("remark", remark).add("isPayment", 1) + .add("paymentTime", new Date()), + Cnd.where("id", "in", idList)); + } else { + //已缴费设为未缴费 + memberPaymentService.update(Chain.make("paymentMoney", null) + .add("isPayment", 0).add("paymentTime", null), + Cnd.where("id", "in", idList)); + } + } + return null; + } + + @At + @ViReturn + @RequiresPermissions("member.payment.summary") + public Object doRemoveById(String id) { + memberPaymentService.delete(id); + return null; + } + + @At + @Ok("void") + @RequiresPermissions("member.payment.summary") + public void downloadImportTemp(HttpServletResponse response) { + try { + ViTool.excelResponse(response, "会员缴费导入模版.xlsx"); + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook sheets = ExcelExportUtil.exportExcel(exportParams, MemberPaymentTemp.class, new ArrayList<>()); + ServletOutputStream outputStream = response.getOutputStream(); + sheets.write(outputStream); + outputStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + @At + @RequiresPermissions("member.payment.summary") + @AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"}) + public Object doImport(TempFile file, String projectId) { + try { + List memberPaymentTempList = ExcelImportUtil.importExcel(file.getFile(), MemberPaymentTemp.class, new ImportParams()); + + List paymentUserList = memberPaymentService.query(Cnd.where("paymentProjectId", "=", projectId)); + Map infoMap = paymentUserList.stream().collect(Collectors.toMap(MemberPaymentInfo::getLoginname, v -> v)); + List errorInfos = new ArrayList<>(); + List needInsertList = new ArrayList<>(); + + //缴费比例 + BigDecimal paymentProportion = new BigDecimal("0.005"); + memberPaymentTempList.forEach(v -> { + if (infoMap.containsKey(v.getLoginname().trim())) { + if (Strings.isNotBlank(v.getPaymentBaseOne()) && Strings.isNotBlank(v.getPaymentBaseTwo())) { + MemberPaymentInfo memberPaymentInfo = infoMap.get(v.getLoginname().trim()); + memberPaymentInfo.setPayment(true); + memberPaymentInfo.setPaymentBaseOne(v.getPaymentBaseOne()); + memberPaymentInfo.setPaymentBaseTwo(v.getPaymentBaseTwo()); + + //缴费金额,精度计算 + DecimalFormat df = new DecimalFormat("#0.000"); + BigDecimal baseOne = new BigDecimal(v.getPaymentBaseOne()); + BigDecimal baseTwo = new BigDecimal(v.getPaymentBaseTwo()); + + String paymentMoney = df.format((baseOne.add(baseTwo)).multiply(paymentProportion)); + memberPaymentInfo.setPaymentMoney(paymentMoney); +// memberPaymentInfo.setPaymentTime(v.getPaymentTime() != null ? v.getPaymentTime() : new Date()); + memberPaymentInfo.setRemark(v.getRemark()); + memberPaymentInfo.setPaymentMethod("导入"); + needInsertList.add(memberPaymentInfo); + } else { + v.setResult("请填写该教职工的缴费数据!"); + errorInfos.add(v); + } + } else { + v.setResult("该教工可能不在此次缴费项目之中,请重新设置缴费人员或检查人员是否正确!"); + errorInfos.add(v); + } + }); + int i = 0; + if (Lang.isNotEmpty(needInsertList)) { + i = memberPaymentService.updateIgnoreNull(needInsertList); + } + + if (Lang.isNotEmpty(errorInfos)) { + NutMap nutMap = NutMap.NEW(); + nutMap.setv("totalCount", memberPaymentTempList.size()); + nutMap.setv("successCount", i); + nutMap.setv("errorCount", errorInfos.size()); + nutMap.setv("errorList", errorInfos.stream().map(v -> { + return NutMap.NEW().addv("工号", v.getLoginname()).addv("姓名", v.getUsername()).addv("错误原因", v.getResult()); + }).collect(Collectors.toList())); + return Result.success(nutMap); + } + return Result.success(); + } catch (Exception e) { + e.printStackTrace(); + return Result.error(); + } + } + + + @At + @Ok("void") + @RequiresPermissions("member.payment.summary") + public void doExport(@Param(value = "searchName", required = false) String searchName, + @Param(value = "searchKeyword", required = false) String searchKeyword, + @Param(value = "unionId", required = false) String unionId, + @Param(value = "unitId", required = false) String unitId, + @Param(value = "unionGroupId", required = false) String unionGroupId, + @Param(value = "threeUnitId", required = false) String threeUnitId, + @Param(value = "personType", required = false) String personType, + @Param(value = "userState", required = false) String userState, + @Param(value = "paymentProjectId", required = false) String paymentProjectId, + @Param(value = "year", required = false) String year, + @Param(value = "isPay", required = false) String isPay, + boolean isZip, HttpServletResponse response) { + Sql sql = this.dataSql(null, null, searchName, searchKeyword, unionId, unitId, threeUnitId, + unionGroupId, personType, userState, paymentProjectId, year, isPay); + + List list = memberPaymentService.listMap(sql); + NutMap nutMap = list.stream().findFirst().orElse(null); + + List unionIdList = memberPaymentService.dao().query(Sys_union.class, Cnd.NEW()); + try { + assert nutMap != null; + if (isZip) { + response.setContentType("application/octet-stream"); + response.setHeader("content-disposition", "attachment;filename=" + + URLEncoder.encode(nutMap.getString("projectName") + "缴费详情.zip", "UTF-8")); + ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream())); + for (Sys_union union : unionIdList) { + String fileName = union.getUnioncode() + union.getUnionname().replaceAll("/", "、") + "缴费记录表.xlsx"; + zipOutputStream.putNextEntry(new ZipEntry(fileName)); + List unionUserList = list.stream().filter(v -> Strings.isNotBlank(v.getString("unionid")) && v.getString("unionid").equals(union.getId())).collect(Collectors.toList()); + Workbook workbook = memberPaymentService.exportOrZip(unionUserList, response.getOutputStream()); + workbook.write(zipOutputStream); + zipOutputStream.closeEntry(); + response.flushBuffer(); + } + zipOutputStream.flush(); + zipOutputStream.close(); + } else { + ViTool.excelResponse(response, nutMap.getString("projectName") + "缴费详情表.xlsx"); + Workbook workbook = memberPaymentService.exportOrZip(list, response.getOutputStream()); + workbook.write(response.getOutputStream()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + + @At + @ViReturn + @RequiresPermissions("member.payment.summary") + public Object sendPaymentMsg(@Param(value = "id", required = false) String id) { + if (Strings.isNotBlank(id)) { + List paymentInfos = memberPaymentService.query(Cnd.where("isPayment", "=", 0)); +// msgApi.sendMsg(); + } else { + MemberPaymentInfo paymentInfo = memberPaymentService.fetch(id); +// msgApi.sendMsg(); + } + return null; + } +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/model/MemberPaymentConfig.java b/src/main/java/io/v/nutz/zhgh/memberCost/model/MemberPaymentConfig.java new file mode 100644 index 0000000..6f7b9de --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/model/MemberPaymentConfig.java @@ -0,0 +1,51 @@ +package io.v.nutz.zhgh.memberCost.model; + +import lombok.Data; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; +import org.nutz.lang.util.NutMap; + +import java.io.Serializable; +import java.util.List; + +@Data +@Table +public class MemberPaymentConfig { + + @Column + @Name + @Comment("ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @Comment("缴费标准") + @ColDefine(type = ColType.MYSQL_JSON) + private List payStandards; + + @Column + @Comment("未缴费退会时长") + @ColDefine(type = ColType.VARCHAR,width = 10) + private String unPaidExitDuration; + + @Column + @Comment("退会模式(1,。自动退会;2.人工退会)") + @ColDefine(type = ColType.VARCHAR,width = 10) + private String exitMode; + + @Column + @Comment("缴费时长(多久缴费一次)") + @ColDefine(type = ColType.VARCHAR,width = 10) + private String paidDuration; + + + @Data + public static class PayStandards implements Serializable { + private String payPersonnel; + private String payMode; + private List personTypes; + private String payModeValue; + private List payModeValueList; + } +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/model/MemberPaymentInfo.java b/src/main/java/io/v/nutz/zhgh/memberCost/model/MemberPaymentInfo.java new file mode 100644 index 0000000..a798ec0 --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/model/MemberPaymentInfo.java @@ -0,0 +1,90 @@ +package io.v.nutz.zhgh.memberCost.model; + +import lombok.Data; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.util.Date; + +@Data +@Table +public class MemberPaymentInfo { + + @Column + @Name + @Comment("ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @Comment("用户id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String userId; + + @Column + @Comment("工号") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String loginname; + + @Column + @Comment("缴费项目id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String paymentProjectId; + + @Column + @Comment("工资") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String wages; + + @Column + @Comment("是否缴费") + @ColDefine(type = ColType.BOOLEAN) + private boolean isPayment; + + @Column + @Comment("缴费基数1") + @ColDefine(type = ColType.VARCHAR,width = 32) + private String paymentBaseOne; + + @Column + @Comment("缴费基数2") + @ColDefine(type = ColType.VARCHAR,width = 32) + private String paymentBaseTwo; + + @Column + @Comment("缴费金额") + @ColDefine(type = ColType.VARCHAR,width = 32) + private String paymentMoney; + + @Column + @Comment("缴费日期") + @ColDefine(type = ColType.DATETIME) + private Date paymentTime; + + @Column + @Comment("备注") + @ColDefine(type = ColType.VARCHAR, width = 100) + private String remark; + + @Column + @Comment("支付记录Id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String payId; + + @Column + @Comment("支付宝记录Id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String tradeNo; + + @Column + @Comment("缴费方式") + @ColDefine(type = ColType.VARCHAR, width = 20) + private String paymentMethod; + + + @Column + @Comment("缴费月份") + @ColDefine(type = ColType.VARCHAR, width = 10) + private String paymentMonth; +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/model/MemberPaymentProject.java b/src/main/java/io/v/nutz/zhgh/memberCost/model/MemberPaymentProject.java new file mode 100644 index 0000000..a3ea16c --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/model/MemberPaymentProject.java @@ -0,0 +1,45 @@ +package io.v.nutz.zhgh.memberCost.model; + +import lombok.Data; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.util.Date; + +@Data +@Table +public class MemberPaymentProject { + + @Column + @Name + @Comment("ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @Comment("年度") + @ColDefine(type = ColType.VARCHAR, width = 4) + private String year; + + @Column + @Comment("项目名称") + @ColDefine(type = ColType.VARCHAR, width = 100) + private String projectName; + + @Column + @Comment("是否开启") + @ColDefine(type = ColType.BOOLEAN) + private boolean isDisabled; + + @Column + @Comment("创建时间") + @ColDefine(type = ColType.DATETIME) + private Date createTime; + + + @Column + @Comment("缴费月份") + @ColDefine(type = ColType.VARCHAR, width = 10) + private String paymentMonth; +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/service/AlipayService.java b/src/main/java/io/v/nutz/zhgh/memberCost/service/AlipayService.java new file mode 100644 index 0000000..32da08e --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/service/AlipayService.java @@ -0,0 +1,15 @@ +package io.v.nutz.zhgh.memberCost.service; + + +import io.v.nutz.base.service.ViService; + +import java.util.Map; + +public interface AlipayService extends ViService { + /** + * 支付宝开放平台接收 request请求对象后 + * @return + */ + String tradeCreate( String money, String paymentProjectId) throws Exception; + String tradeNotify(Map params) ; +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/service/MemberPaymentService.java b/src/main/java/io/v/nutz/zhgh/memberCost/service/MemberPaymentService.java new file mode 100644 index 0000000..7308adf --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/service/MemberPaymentService.java @@ -0,0 +1,20 @@ +package io.v.nutz.zhgh.memberCost.service; + +import io.v.nutz.base.service.ViService; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentConfig; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentProject; +import org.apache.poi.ss.usermodel.Workbook; +import org.nutz.lang.util.NutMap; + +import java.io.OutputStream; +import java.util.List; + +public interface MemberPaymentService extends ViService { + + MemberPaymentProject findOneProject(String id); + + Workbook exportOrZip(List list, OutputStream outputStream)throws Exception; + + MemberPaymentConfig getConfig(); +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/service/impl/AlipayNewServiceImpl.java b/src/main/java/io/v/nutz/zhgh/memberCost/service/impl/AlipayNewServiceImpl.java new file mode 100644 index 0000000..0dd726e --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/service/impl/AlipayNewServiceImpl.java @@ -0,0 +1,140 @@ +package io.v.nutz.zhgh.memberCost.service.impl; + +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayConstants; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.domain.AlipayTradeWapPayModel; +import com.alipay.api.internal.util.AlipaySignature; +import com.alipay.api.request.AlipayTradeWapPayRequest; +import com.alipay.api.response.AlipayTradeWapPayResponse; +import io.v.nutz.base.service.impl.ViServiceImpl; +import io.v.nutz.web.commons.utils.ShiroUtil; +import io.v.nutz.zhgh.memberCost.controller.AlipayClientConfig; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo; +import io.v.nutz.zhgh.memberCost.service.AlipayService; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.ioc.loader.annotation.IocBean; + +import java.util.Date; +import java.util.Map; + +/** + * @ClassName AlipayNewServiceImpl + * @Description TODO + * @Author zhf + * @Date 2024/1/25 15:38 + */ + +@Slf4j +@IocBean(args = {"refer:dao"}) +public class AlipayNewServiceImpl extends ViServiceImpl implements AlipayService { + public AlipayNewServiceImpl(Dao dao) { + super(dao); + } + + DefaultAlipayClient alipayClient = new DefaultAlipayClient(AlipayClientConfig.serverUrl, + AlipayClientConfig.appId, + AlipayClientConfig.privateKey, + AlipayConstants.FORMAT_JSON, + AlipayConstants.CHARSET_UTF8, + AlipayClientConfig.alipayPublicKey, + AlipayConstants.SIGN_TYPE_RSA2); + + @Override + public String tradeCreate(String money, String paymentProjectId) throws Exception { + String outTradeNo = String.valueOf(new Date().getTime()); + AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest(); + //支付宝公共参数 + request.setReturnUrl("http://sansi.ltd/mobile/memberCost/AlipayClient/tradeNotify"); + + + //面向对象封装业务参数 + AlipayTradeWapPayModel model = new AlipayTradeWapPayModel(); + model.setOutTradeNo(outTradeNo); + model.setTotalAmount(money); + model.setSubject("会员入会会费"); + model.setProductCode("QUICK_WAP_WAY"); + model.setSellerId(AlipayClientConfig.sellerId); + model.setTimeoutExpress("30m"); + model.setQuitUrl("http://sansi.ltd/mobile/memberCost/list"); + + request.setBizModel(model); + + //执行请求,调用支付宝 + AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "POST"); + if (response.isSuccess()) { + dao().update(MemberPaymentInfo.class, Chain.make("payId", outTradeNo), Cnd.where("paymentProjectId", "=", paymentProjectId) + .and("userId", "=", ShiroUtil.getUserId())); + log.info("调用成功,返回结果:[{}]", response.getBody()); + return response.getBody(); + } else { + log.info("调用失败!!"); + } + return null; + } + + @Override + public String tradeNotify(Map params) { + String total_amount = params.get("total_amount"); + String out_trade_no = params.get("out_trade_no"); + String trade_no = params.get("trade_no"); + +// + String result = "failure"; + try { + //异步通知验签 + boolean signVerified = AlipaySignature.rsaCheckV1(params, + AlipayClientConfig.alipayPublicKey, + AlipayConstants.CHARSET_UTF8, + AlipayConstants.SIGN_TYPE_RSA2); + if (!signVerified) { + // TODO 验签失败则记录异常日志,并在response中返回failure. + log.error("支付成功,异步通知验签失败!"); + return result; + } + log.info("支付成功,异步通知验签成功!"); + //TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验 + //1.验证out_trade_no 是否为商家系统中创建的订单号 + String outTradeNo = params.get("out_trade_no"); + if (!outTradeNo.equals(out_trade_no)) { + log.error("订单号不一致"); + return result; + } + //2.判断 total_amount 是否确实为该订单的实际金额 + String totalAmount = params.get("total_amount"); + if (!totalAmount.equals(total_amount)) { + log.error("订单的实际金额不一致"); + return result; + } + //3.校验通知中的 seller_id是否为 out_trade_no 这笔单据的对应的操作方 + String sellerId = params.get("seller_id"); + if (!sellerId.equals(AlipayClientConfig.sellerId)) { + log.error("商家PID校验失败"); + return result; + } + //4.验证 app_id 是否为该商家本身 + String appId = params.get("app_id"); + if (!appId.equals(AlipayClientConfig.appId)) { + log.error("app_id校验失败"); + return result; + } + + dao().update(MemberPaymentInfo.class, + Chain.make("isPayment", true) + .add("paymentMoney", total_amount) + .add("paymentTime", new Date()) + .add("tradeNo", trade_no), + Cnd.where("userId", "=", ShiroUtil.getUserId()).and("payId", "=", out_trade_no)); + + //TODO 处理自身业务 + result = "->:/mobile/memberCost/list/paySuccess"; + } catch (AlipayApiException e) { + e.printStackTrace(); + } + + return result; + } +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/service/impl/MemberPaymentServiceImpl.java b/src/main/java/io/v/nutz/zhgh/memberCost/service/impl/MemberPaymentServiceImpl.java new file mode 100644 index 0000000..74683db --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/service/impl/MemberPaymentServiceImpl.java @@ -0,0 +1,64 @@ +package io.v.nutz.zhgh.memberCost.service.impl; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import io.v.nutz.base.service.impl.ViServiceImpl; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentConfig; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentProject; +import io.v.nutz.zhgh.memberCost.service.MemberPaymentService; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.Workbook; +import org.nutz.dao.Dao; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; + +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@IocBean(args = {"refer:dao"}) +public class MemberPaymentServiceImpl extends ViServiceImpl implements MemberPaymentService { + public MemberPaymentServiceImpl(Dao dao) { + super(dao); + } + + @Override + public MemberPaymentProject findOneProject(String id) { + return dao().fetch(MemberPaymentProject.class, id); + } + + + @Override + public Workbook exportOrZip(List list, OutputStream outputStream) throws Exception { + List exportEntities = new ArrayList<>(); + exportEntities.add(new ExcelExportEntity("工号", "loginname", 20)); + exportEntities.add(new ExcelExportEntity("姓名", "username", 20)); +// exportEntities.add(new ExcelExportEntity("年度", "year", 20)); + exportEntities.add(new ExcelExportEntity("缴费项目", "projectName", 20)); + exportEntities.add(new ExcelExportEntity("性别", "sex", 20)); + exportEntities.add(new ExcelExportEntity("联系电话", "mobile", 20)); +// exportEntities.add(new ExcelExportEntity("身份证号", "idcard", 30)); + exportEntities.add(new ExcelExportEntity("在职状态", "userState", 20)); + exportEntities.add(new ExcelExportEntity("人员类型", "personType", 20)); + exportEntities.add(new ExcelExportEntity("所属工会", "unionname", 20)); + exportEntities.add(new ExcelExportEntity("所属单位", "unitname", 30)); + exportEntities.add(new ExcelExportEntity("是否缴费", "isPay", 10)); + exportEntities.add(new ExcelExportEntity("缴费金额", "paymentMoney", 10)); + exportEntities.add(new ExcelExportEntity("缴费时间", "paymentTime", 20)); + exportEntities.add(new ExcelExportEntity("备注", "remark", 30)); + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + exportParams.setHeight((short) 10); + return ExcelExportUtil.exportExcel(exportParams, exportEntities, list); + } + + + @Override + public MemberPaymentConfig getConfig() { + return dao().fetch(MemberPaymentConfig.class); + } +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/template/MemberPaymentTemp.java b/src/main/java/io/v/nutz/zhgh/memberCost/template/MemberPaymentTemp.java new file mode 100644 index 0000000..f1399b9 --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/memberCost/template/MemberPaymentTemp.java @@ -0,0 +1,31 @@ +package io.v.nutz.zhgh.memberCost.template; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +@Data +public class MemberPaymentTemp { + + @Excel(name = "工号") + String loginname; + + @Excel(name = "姓名") + String username; + + @Excel(name = "缴纳基数1") + String paymentBaseOne; + + @Excel(name = "缴纳基数2") + String paymentBaseTwo; + +// @Excel(name = "缴费金额") +// String paymentMoney; +// +// @Excel(name = "缴费日期") +// Date paymentTime; + + @Excel(name = "备注") + String remark; + + String result; +} diff --git a/src/main/resources/views/mobile/memberCost/memberCostList.html b/src/main/resources/views/mobile/memberCost/memberCostList.html new file mode 100644 index 0000000..ee3265b --- /dev/null +++ b/src/main/resources/views/mobile/memberCost/memberCostList.html @@ -0,0 +1,357 @@ + + + + +
+ + + + + +
+ + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
+ + + + + + + + + + + + +
+
+ +
+ + + + + + + + +
+ +
+ + + diff --git a/src/main/resources/views/mobile/memberCost/paySuccess.html b/src/main/resources/views/mobile/memberCost/paySuccess.html new file mode 100644 index 0000000..971062e --- /dev/null +++ b/src/main/resources/views/mobile/memberCost/paySuccess.html @@ -0,0 +1,134 @@ + + + +
+ +
+
+ + 支付成功 + 您已付款成功,请返回查看会费情况 +
+
+
+
¥{{total_amount}}
+
+ +
+
+ + 订单编号 + + {{out_trade_no}} + + + + 支付时间 + + {{timestamp}} + + +
+
+ + +
+ + + + + + diff --git a/src/main/resources/views/platform/memberCost/payment/config.html b/src/main/resources/views/platform/memberCost/payment/config.html new file mode 100644 index 0000000..d7154a5 --- /dev/null +++ b/src/main/resources/views/platform/memberCost/payment/config.html @@ -0,0 +1,221 @@ + + +
+ + +
+

缴费配置

+
+ + + + + + + + 添加 + + 说明:。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 说明:多长时间未缴纳会费则视为退会处理。 +
+
+ + + + + 自动退会 + 人工退会 + + + + + + + + + + + + + + +
+ 说明:多长时间缴费一次。 +
+
+
+ + + 保存 + + 提交 + + + +
+
+
+ + + diff --git a/src/main/resources/views/platform/memberCost/payment/manage.html b/src/main/resources/views/platform/memberCost/payment/manage.html new file mode 100644 index 0000000..264a496 --- /dev/null +++ b/src/main/resources/views/platform/memberCost/payment/manage.html @@ -0,0 +1,408 @@ + + + + +
+ + + + + + + +
+ + + diff --git a/src/main/resources/views/platform/memberCost/payment/summary.html b/src/main/resources/views/platform/memberCost/payment/summary.html new file mode 100644 index 0000000..5a2222b --- /dev/null +++ b/src/main/resources/views/platform/memberCost/payment/summary.html @@ -0,0 +1,489 @@ + + +
+ + + + + + + + + + + + + + + + +
+ + 取 消 + 确 定 + +
+
+ +
+ + + diff --git a/src/main/resources/views/platform/payment/config.html b/src/main/resources/views/platform/payment/config.html new file mode 100644 index 0000000..d7154a5 --- /dev/null +++ b/src/main/resources/views/platform/payment/config.html @@ -0,0 +1,221 @@ + + +
+ + +
+

缴费配置

+
+ + + + + + + + 添加 + + 说明:。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 说明:多长时间未缴纳会费则视为退会处理。 +
+
+ + + + + 自动退会 + 人工退会 + + + + + + + + + + + + + + +
+ 说明:多长时间缴费一次。 +
+
+
+ + + 保存 + + 提交 + + + +
+
+
+ + + diff --git a/src/main/resources/views/platform/payment/manage.html b/src/main/resources/views/platform/payment/manage.html new file mode 100644 index 0000000..264a496 --- /dev/null +++ b/src/main/resources/views/platform/payment/manage.html @@ -0,0 +1,408 @@ + + + + +
+ + + + + + + +
+ + + diff --git a/src/main/resources/views/platform/payment/summary.html b/src/main/resources/views/platform/payment/summary.html new file mode 100644 index 0000000..5a2222b --- /dev/null +++ b/src/main/resources/views/platform/payment/summary.html @@ -0,0 +1,489 @@ + + +
+ + + + + + + + + + + + + + + + +
+ + 取 消 + 确 定 + +
+
+ +
+ + +