From 0b6c174db343bb3b76c5deec566749f721997a74 Mon Sep 17 00:00:00 2001
From: lin <sbla5888@163.com>
Date: Tue, 12 Mar 2024 17:59:58 +0800
Subject: [PATCH] 从业人员信息录入

---
 src/main/java/org/springblade/modules/place/mapper/PlaceExtMapper.xml                      |   93 +++
 src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.java            |    8 
 src/main/java/org/springblade/common/config/WxPayConfig.java                               |  163 +++++
 src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java               |  248 ++++++++
 src/main/java/org/springblade/common/enums/wxpay/WxNotifyType.java                         |   30 +
 src/main/java/org/springblade/common/utils/HttpUtils.java                                  |   39 +
 pom.xml                                                                                    |   19 
 src/main/java/org/springblade/common/enums/OrderStatus.java                                |   49 +
 src/main/java/org/springblade/modules/place/controller/PlacePractitionerController.java    |   39 +
 src/main/java/org/springblade/modules/place/mapper/PlaceMapper.xml                         |    5 
 src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.xml             |  118 +++
 src/main/java/org/springblade/modules/place/service/impl/PlacePractitionerServiceImpl.java |   19 
 src/main/java/org/springblade/modules/place/entity/PlaceEntity.java                        |  230 +++----
 src/main/java/org/springblade/common/enums/PayType.java                                    |   24 
 src/main/java/org/springblade/modules/pay/service/IWxPayService.java                       |    8 
 src/main/java/org/springblade/modules/pay/controller/WxPayController.java                  |  105 +++
 src/main/java/org/springblade/modules/place/vo/PlacePractitionerVO.java                    |    4 
 src/main/java/org/springblade/common/enums/wxpay/WxTradeState.java                         |   34 +
 src/main/java/org/springblade/common/enums/wxpay/WxRefundStatus.java                       |   34 +
 src/main/java/org/springblade/modules/place/service/IPlacePractitionerService.java         |    1 
 src/main/java/org/springblade/common/utils/WechatPay2ValidatorForRequest.java              |  114 +++
 src/main/java/org/springblade/common/enums/wxpay/WxApiType.java                            |   65 ++
 src/main/java/org/springblade/modules/place/entity/PlaceExtEntity.java                     |  208 ++++--
 src/main/java/org/springblade/modules/place/entity/PlacePractitionerEntity.java            |  104 ++
 24 files changed, 1,513 insertions(+), 248 deletions(-)

diff --git a/pom.xml b/pom.xml
index 645b7fd..e647e17 100644
--- a/pom.xml
+++ b/pom.xml
@@ -195,11 +195,24 @@
             <version>1.13</version>
         </dependency>
         <!-- 微信支付 SDK-->
+<!--        <dependency>-->
+<!--            <groupId>com.github.binarywang</groupId>-->
+<!--            <artifactId>weixin-java-pay</artifactId>-->
+<!--            <version>4.4.9.B</version>-->
+<!--        </dependency>-->
+        <!-- 微信支付依赖 -->
         <dependency>
-            <groupId>com.github.binarywang</groupId>
-            <artifactId>weixin-java-pay</artifactId>
-            <version>4.4.9.B</version>
+            <groupId>com.github.wechatpay-apiv3</groupId>
+            <artifactId>wechatpay-apache-httpclient</artifactId>
+            <version>0.3.0</version>
         </dependency>
+        <!--微信支付 APIv2 SDK-->
+        <dependency>
+            <groupId>com.github.wxpay</groupId>
+            <artifactId>wxpay-sdk</artifactId>
+            <version>0.0.3</version>
+        </dependency>
+
         <!--xxl-job-core 相关依赖-->
         <dependency>
             <groupId>io.netty</groupId>
diff --git a/src/main/java/org/springblade/common/config/WxPayConfig.java b/src/main/java/org/springblade/common/config/WxPayConfig.java
new file mode 100644
index 0000000..1c018b4
--- /dev/null
+++ b/src/main/java/org/springblade/common/config/WxPayConfig.java
@@ -0,0 +1,163 @@
+package org.springblade.common.config;
+
+import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
+import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
+import com.wechat.pay.contrib.apache.httpclient.auth.ScheduledUpdateCertificatesVerifier;
+import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
+import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
+import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.io.FileInputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+
+
+//@Configuration
+// @PropertySource("classpath:wxpay.properties") //读取配置文件
+//@ConfigurationProperties(prefix = "wxpay") //读取wxpay节点
+@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
+@Slf4j
+public class WxPayConfig {
+
+	// 商户号
+	private String mchId;
+
+	// 商户API证书序列号
+	private String mchSerialNo;
+
+	// 商户私钥文件
+	private String privateKeyPath;
+
+	private String privateCertPath;
+
+	// APIv3密钥
+	private String apiV3Key;
+
+	// APPID
+	private String appid;
+
+	// 微信服务器地址
+	private String domain;
+
+	// 接收结果通知地址
+	private String notifyDomain;
+
+	// APIv2密钥
+	private String partnerKey;
+
+	/**
+	 * 获取商户的私钥文件
+	 *
+	 * @param filename
+	 * @return
+	 */
+	private PrivateKey getPrivateKey(String filename) {
+
+		try {
+			// FileInputStream fileInputStream = new FileInputStream(filename);
+			// log.info("文件内容:" + fileInputStream);
+			return PemUtil.loadPrivateKey(getFileInputStream(filename));
+		} catch (Exception e) {
+			log.info("私钥文件不存在", e);
+			throw new RuntimeException("私钥文件不存在", e);
+		}
+	}
+
+
+	/**
+	 * 获取商户的文件
+	 *
+	 * @param filename
+	 * @return
+	 */
+	public static FileInputStream getFileInputStream(String filename) {
+
+		try {
+			FileInputStream fileInputStream = new FileInputStream(filename);
+			return fileInputStream;
+		} catch (Exception e) {
+			log.info("读取文件不存在", e);
+			throw new RuntimeException("读取文件不存在", e);
+		}
+	}
+
+	/**
+	 * 获取商户的文件
+	 *
+	 * @return
+	 */
+	// @Bean
+	// public KeyStore keyStore() {
+	// 	try {
+	// 		InputStream certStream = WxPayConfig.class.getClassLoader().getResourceAsStream(privateCertPath);
+	// 		KeyStore ks = KeyStore.getInstance("PKCS12");
+	// 		ks.load(certStream, mchId.toCharArray());
+	// 		return ks;
+	// 	} catch (Exception e) {
+	// 		log.info("读取文件不存在", e);
+	// 		throw new RuntimeException("读取文件不存在", e);
+	// 	}
+	// }
+
+
+	/**
+	 * 获取签名验证器
+	 *
+	 * @return
+	 */
+//	@Bean
+	public ScheduledUpdateCertificatesVerifier getVerifier(String privateKeyPath, String mchSerialNo, String mchId, String apiV3Key) {
+
+		log.info("获取签名验证器");
+
+		//获取商户私钥
+		PrivateKey privateKey = getPrivateKey(privateKeyPath);
+
+		//私钥签名对象
+		PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);
+
+		//身份认证对象
+		WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);
+
+		// 使用定时更新的签名验证器,不需要传入证书
+		ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
+			wechatPay2Credentials,
+			apiV3Key.getBytes(StandardCharsets.UTF_8));
+
+		return verifier;
+	}
+
+
+	/**
+	 * 获取http请求对象
+	 *
+	 * @param verifier
+	 * @return
+	 */
+//	@Bean(name = "wxPayClient")
+	public CloseableHttpClient getWxPayClient(String privateKeyPath, String mchSerialNo, String mchId, String apiV3Key) {
+
+		log.info("获取httpClient");
+
+		//获取商户私钥
+		PrivateKey privateKey = getPrivateKey(privateKeyPath);
+
+		WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
+			.withMerchant(mchId, mchSerialNo, privateKey)
+			.withValidator(new WechatPay2Validator(getVerifier(privateKeyPath, mchSerialNo, mchId, apiV3Key)));
+		// ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient
+
+		// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
+		CloseableHttpClient httpClient = builder.build();
+
+		return httpClient;
+	}
+
+
+}
diff --git a/src/main/java/org/springblade/common/enums/OrderStatus.java b/src/main/java/org/springblade/common/enums/OrderStatus.java
new file mode 100644
index 0000000..538c938
--- /dev/null
+++ b/src/main/java/org/springblade/common/enums/OrderStatus.java
@@ -0,0 +1,49 @@
+package org.springblade.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public enum OrderStatus {
+    /**
+     * 未支付
+     */
+    NOTPAY("未支付"),
+
+
+    /**
+     * 支付成功
+     */
+    SUCCESS("支付成功"),
+
+    /**
+     * 已关闭
+     */
+    CLOSED("超时已关闭"),
+
+    /**
+     * 已取消
+     */
+    CANCEL("用户已取消"),
+
+    /**
+     * 退款中
+     */
+    REFUND_PROCESSING("退款中"),
+
+    /**
+     * 已退款
+     */
+    REFUND_SUCCESS("已退款"),
+
+    /**
+     * 退款异常
+     */
+    REFUND_ABNORMAL("退款异常");
+
+    /**
+     * 类型
+     */
+    private final String type;
+}
diff --git a/src/main/java/org/springblade/common/enums/PayType.java b/src/main/java/org/springblade/common/enums/PayType.java
new file mode 100644
index 0000000..9066612
--- /dev/null
+++ b/src/main/java/org/springblade/common/enums/PayType.java
@@ -0,0 +1,24 @@
+package org.springblade.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public enum PayType {
+    /**
+     * 微信
+     */
+    WXPAY("微信"),
+
+
+    /**
+     * 支付宝
+     */
+    ALIPAY("支付宝");
+
+    /**
+     * 类型
+     */
+    private final String type;
+}
diff --git a/src/main/java/org/springblade/common/enums/wxpay/WxApiType.java b/src/main/java/org/springblade/common/enums/wxpay/WxApiType.java
new file mode 100644
index 0000000..4f2d7bc
--- /dev/null
+++ b/src/main/java/org/springblade/common/enums/wxpay/WxApiType.java
@@ -0,0 +1,65 @@
+package org.springblade.common.enums.wxpay;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public enum WxApiType {
+
+	/**
+	 * Native下单
+	 */
+	NATIVE_PAY("/v3/pay/transactions/native"),
+
+	/**
+	 * Native下单
+	 */
+	NATIVE_PAY_V2("/pay/unifiedorder"),
+
+	/**
+	 * JSAPI下单
+	 */
+	JSAPI_PAY("/v3/pay/transactions/jsapi"),
+
+	/**
+	 * sendredpack 发送红包
+	 */
+	SENDREDPACK_PAY("/mmpaymkttransfers/sendredpack"),
+
+	/**
+	 * 查询订单
+	 */
+	ORDER_QUERY_BY_NO("/v3/pay/transactions/out-trade-no/%s"),
+
+	/**
+	 * 关闭订单
+	 */
+	CLOSE_ORDER_BY_NO("/v3/pay/transactions/out-trade-no/%s/close"),
+
+	/**
+	 * 申请退款
+	 */
+	DOMESTIC_REFUNDS("/v3/refund/domestic/refunds"),
+
+	/**
+	 * 查询单笔退款
+	 */
+	DOMESTIC_REFUNDS_QUERY("/v3/refund/domestic/refunds/%s"),
+
+	/**
+	 * 申请交易账单
+	 */
+	TRADE_BILLS("/v3/bill/tradebill"),
+
+	/**
+	 * 申请资金账单
+	 */
+	FUND_FLOW_BILLS("/v3/bill/fundflowbill");
+
+
+	/**
+	 * 类型
+	 */
+	private final String type;
+}
diff --git a/src/main/java/org/springblade/common/enums/wxpay/WxNotifyType.java b/src/main/java/org/springblade/common/enums/wxpay/WxNotifyType.java
new file mode 100644
index 0000000..b0f4825
--- /dev/null
+++ b/src/main/java/org/springblade/common/enums/wxpay/WxNotifyType.java
@@ -0,0 +1,30 @@
+package org.springblade.common.enums.wxpay;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public enum WxNotifyType {
+
+	/**
+	 * 支付通知
+	 */
+	NATIVE_NOTIFY("/wxPay/native/notify"),
+
+	/**
+	 * 支付通知
+	 */
+	NATIVE_NOTIFY_V2("/wxPayV2/native/notify"),
+
+
+	/**
+	 * 退款结果通知
+	 */
+	REFUND_NOTIFY("/wxPay/refunds/notify");
+
+	/**
+	 * 类型
+	 */
+	private final String type;
+}
diff --git a/src/main/java/org/springblade/common/enums/wxpay/WxRefundStatus.java b/src/main/java/org/springblade/common/enums/wxpay/WxRefundStatus.java
new file mode 100644
index 0000000..6be0b51
--- /dev/null
+++ b/src/main/java/org/springblade/common/enums/wxpay/WxRefundStatus.java
@@ -0,0 +1,34 @@
+package org.springblade.common.enums.wxpay;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public enum WxRefundStatus {
+
+    /**
+     * 退款成功
+     */
+    SUCCESS("SUCCESS"),
+
+    /**
+     * 退款关闭
+     */
+    CLOSED("CLOSED"),
+
+    /**
+     * 退款处理中
+     */
+    PROCESSING("PROCESSING"),
+
+    /**
+     * 退款异常
+     */
+    ABNORMAL("ABNORMAL");
+
+    /**
+     * 类型
+     */
+    private final String type;
+}
diff --git a/src/main/java/org/springblade/common/enums/wxpay/WxTradeState.java b/src/main/java/org/springblade/common/enums/wxpay/WxTradeState.java
new file mode 100644
index 0000000..22d5b62
--- /dev/null
+++ b/src/main/java/org/springblade/common/enums/wxpay/WxTradeState.java
@@ -0,0 +1,34 @@
+package org.springblade.common.enums.wxpay;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public enum WxTradeState {
+
+    /**
+     * 支付成功
+     */
+    SUCCESS("SUCCESS"),
+
+    /**
+     * 未支付
+     */
+    NOTPAY("NOTPAY"),
+
+    /**
+     * 已关闭
+     */
+    CLOSED("CLOSED"),
+
+    /**
+     * 转入退款
+     */
+    REFUND("REFUND");
+
+    /**
+     * 类型
+     */
+    private final String type;
+}
diff --git a/src/main/java/org/springblade/common/utils/HttpUtils.java b/src/main/java/org/springblade/common/utils/HttpUtils.java
new file mode 100644
index 0000000..e1fde41
--- /dev/null
+++ b/src/main/java/org/springblade/common/utils/HttpUtils.java
@@ -0,0 +1,39 @@
+package org.springblade.common.utils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.BufferedReader;
+import java.io.IOException;
+
+
+public class HttpUtils {
+
+    /**
+     * 将通知参数转化为字符串
+     * @param request
+     * @return
+     */
+    public static String readData(HttpServletRequest request) {
+        BufferedReader br = null;
+        try {
+            StringBuilder result = new StringBuilder();
+            br = request.getReader();
+            for (String line; (line = br.readLine()) != null; ) {
+                if (result.length() > 0) {
+                    result.append("\n");
+                }
+                result.append(line);
+            }
+            return result.toString();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/springblade/common/utils/WechatPay2ValidatorForRequest.java b/src/main/java/org/springblade/common/utils/WechatPay2ValidatorForRequest.java
new file mode 100644
index 0000000..ee2210f
--- /dev/null
+++ b/src/main/java/org/springblade/common/utils/WechatPay2ValidatorForRequest.java
@@ -0,0 +1,114 @@
+package org.springblade.common.utils;
+
+
+import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.time.DateTimeException;
+import java.time.Duration;
+import java.time.Instant;
+
+import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.*;
+
+/**
+ * @author xy-peng
+ */
+public class WechatPay2ValidatorForRequest {
+
+    protected static final Logger log = LoggerFactory.getLogger(WechatPay2ValidatorForRequest.class);
+    /**
+     * 应答超时时间,单位为分钟
+     */
+    protected static final long RESPONSE_EXPIRED_MINUTES = 5;
+    protected final Verifier verifier;
+    protected final String requestId;
+    protected final String body;
+
+
+    public WechatPay2ValidatorForRequest(Verifier verifier, String requestId, String body) {
+        this.verifier = verifier;
+        this.requestId = requestId;
+        this.body = body;
+    }
+
+    protected static IllegalArgumentException parameterError(String message, Object... args) {
+        message = String.format(message, args);
+        return new IllegalArgumentException("parameter error: " + message);
+    }
+
+    protected static IllegalArgumentException verifyFail(String message, Object... args) {
+        message = String.format(message, args);
+        return new IllegalArgumentException("signature verify fail: " + message);
+    }
+
+    public final boolean validate(HttpServletRequest request) throws IOException {
+        try {
+            //处理请求参数
+            validateParameters(request);
+
+            //构造验签名串
+            String message = buildMessage(request);
+
+            String serial = request.getHeader(WECHAT_PAY_SERIAL);
+            String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
+
+            //验签
+            if (!verifier.verify(serial, message.getBytes(StandardCharsets.UTF_8), signature)) {
+                throw verifyFail("serial=[%s] message=[%s] sign=[%s], request-id=[%s]",
+                        serial, message, signature, requestId);
+            }
+        } catch (IllegalArgumentException e) {
+            log.warn(e.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    protected final void validateParameters(HttpServletRequest request) {
+
+        // NOTE: ensure HEADER_WECHAT_PAY_TIMESTAMP at last
+        String[] headers = {WECHAT_PAY_SERIAL, WECHAT_PAY_SIGNATURE, WECHAT_PAY_NONCE, WECHAT_PAY_TIMESTAMP};
+
+        String header = null;
+        for (String headerName : headers) {
+            header = request.getHeader(headerName);
+            if (header == null) {
+                throw parameterError("empty [%s], request-id=[%s]", headerName, requestId);
+            }
+        }
+
+        //判断请求是否过期
+        String timestampStr = header;
+        try {
+            Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestampStr));
+            // 拒绝过期请求
+            if (Duration.between(responseTime, Instant.now()).abs().toMinutes() >= RESPONSE_EXPIRED_MINUTES) {
+                throw parameterError("timestamp=[%s] expires, request-id=[%s]", timestampStr, requestId);
+            }
+        } catch (DateTimeException | NumberFormatException e) {
+            throw parameterError("invalid timestamp=[%s], request-id=[%s]", timestampStr, requestId);
+        }
+    }
+
+    protected final String buildMessage(HttpServletRequest request) throws IOException {
+        String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
+        String nonce = request.getHeader(WECHAT_PAY_NONCE);
+        return timestamp + "\n"
+                + nonce + "\n"
+                + body + "\n";
+    }
+
+    protected final String getResponseBody(CloseableHttpResponse response) throws IOException {
+        HttpEntity entity = response.getEntity();
+        return (entity != null && entity.isRepeatable()) ? EntityUtils.toString(entity) : "";
+    }
+
+}
diff --git a/src/main/java/org/springblade/modules/pay/controller/WxPayController.java b/src/main/java/org/springblade/modules/pay/controller/WxPayController.java
index 9a9cece..016e4c6 100644
--- a/src/main/java/org/springblade/modules/pay/controller/WxPayController.java
+++ b/src/main/java/org/springblade/modules/pay/controller/WxPayController.java
@@ -1,23 +1,33 @@
 package org.springblade.modules.pay.controller;
 
-import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
-import com.github.binarywang.wxpay.constant.WxPayConstants;
+import com.google.gson.Gson;
+import com.wechat.pay.contrib.apache.httpclient.auth.ScheduledUpdateCertificatesVerifier;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.common.config.WxPayConfig;
+import org.springblade.common.utils.HttpUtils;
+import org.springblade.common.utils.WechatPay2ValidatorForRequest;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.tool.api.R;
 import org.springblade.modules.pay.entity.WxPayInfo;
 import org.springblade.modules.pay.service.IWxPayService;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.Map;
 
 @RestController
 @AllArgsConstructor
 @RequestMapping("/wxpay")
 @Api(value = "微信支付接口", tags = "微信支付接口")
 public class WxPayController extends BladeController {
+
+	private static final Logger logger = LoggerFactory.getLogger(WxPayController.class);
 
 	private IWxPayService wxPayService;
 
@@ -38,12 +48,91 @@
 
 	/**
 	 * 获取openId
+	 *
 	 * @param code
 	 * @return
 	 */
 	@PostMapping("getOpenId")
-	public R getOpenId(String code){
-		 return R.data(wxPayService.getOpenId(code));
+	public R getOpenId(String code) {
+		return R.data(wxPayService.getOpenId(code));
 	}
 
+	/**
+	 * jsapi下单
+	 *
+	 * @param productId
+	 * @return
+	 * @throws Exception
+	 */
+	@ApiOperation("调用jsapi统一下单API")
+	@GetMapping("/jsapiPay")
+	public R jsapiPay(@RequestParam("productId") Long productId) throws Exception {
+
+		logger.info("发起支付请求 v3");
+
+		//返回支付二维码连接和订单号
+		Map<String, String> map = wxPayService.jsapiPay(productId);
+
+		return R.data(map);
+	}
+
+	/**
+	 * 支付通知
+	 * 微信支付通过支付通知接口将用户支付成功消息通知给商户
+	 */
+	@ApiOperation("支付通知")
+	@PostMapping("/native/notify")
+	public String nativeNotify(HttpServletRequest request, HttpServletResponse response) {
+
+		Gson gson = new Gson();
+		Map<String, String> map = new HashMap<>();//应答对象
+
+		try {
+
+			//处理通知参数
+			String body = HttpUtils.readData(request);
+			Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
+			String requestId = (String) bodyMap.get("id");
+			logger.info("支付通知的id ===> {}", requestId);
+			logger.info("支付通知的完整数据 ===> {}", body);
+			//int a = 9 / 0;
+			ScheduledUpdateCertificatesVerifier verifier = new WxPayConfig().getVerifier("111", "111", "111", "111");
+			//签名的验证
+			WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
+				= new WechatPay2ValidatorForRequest(verifier, requestId, body);
+			if (!wechatPay2ValidatorForRequest.validate(request)) {
+				logger.error("通知验签失败");
+				//失败应答
+				response.setStatus(500);
+				map.put("code", "ERROR");
+				map.put("message", "通知验签失败");
+				return gson.toJson(map);
+			}
+			logger.info("通知验签成功");
+
+			//处理订单
+			wxPayService.processOrder(bodyMap);
+
+			//应答超时
+			//模拟接收微信端的重复通知
+			// TimeUnit.SECONDS.sleep(5);
+
+			//成功应答
+			response.setStatus(200);
+			map.put("code", "SUCCESS");
+			map.put("message", "成功");
+			return gson.toJson(map);
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			//失败应答
+			response.setStatus(500);
+			map.put("code", "ERROR");
+			map.put("message", "失败");
+			return gson.toJson(map);
+		}
+
+	}
+
+
 }
diff --git a/src/main/java/org/springblade/modules/pay/service/IWxPayService.java b/src/main/java/org/springblade/modules/pay/service/IWxPayService.java
index c078e9c..bac42f4 100644
--- a/src/main/java/org/springblade/modules/pay/service/IWxPayService.java
+++ b/src/main/java/org/springblade/modules/pay/service/IWxPayService.java
@@ -3,6 +3,10 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.springblade.modules.pay.entity.WxPayInfo;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.Map;
+
 public interface IWxPayService extends IService<WxPayInfo> {
 
 	/**
@@ -11,4 +15,8 @@
 	 * @return
 	 */
     Object getOpenId(String code);
+
+	Map<String, String> jsapiPay(Long productId) throws IOException;
+
+	void processOrder(Map<String, Object> bodyMap) throws GeneralSecurityException;
 }
diff --git a/src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java b/src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java
index 206c764..08b67fe 100644
--- a/src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java
+++ b/src/main/java/org/springblade/modules/pay/service/impl/WxPayServiceImpl.java
@@ -1,25 +1,261 @@
 package org.springblade.modules.pay.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.wxpay.sdk.WXPayUtil;
+import com.google.gson.Gson;
+import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
+import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.common.enums.OrderStatus;
+import org.springblade.common.enums.wxpay.WxApiType;
+import org.springblade.common.enums.wxpay.WxNotifyType;
+import org.springblade.modules.pay.controller.WxPayController;
 import org.springblade.modules.pay.entity.WxPayInfo;
 import org.springblade.modules.pay.mapper.WxPayMapper;
 import org.springblade.modules.pay.service.IWxPayService;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.*;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
 @Service
 public class WxPayServiceImpl extends ServiceImpl<WxPayMapper,WxPayInfo> implements IWxPayService {
 
 	private final String  MINI_PROGRAM_APP_ID = "wx41aa8a5d2e565a05";
+	private static final Logger logger = LoggerFactory.getLogger(WxPayServiceImpl.class);
+
+	private final ReentrantLock lock = new ReentrantLock();
 
 	@Override
 	public Object getOpenId(String code) {
-
-
-
-
-
-
 		return null;
 	}
+
+	@Override
+	public Map<String, String> jsapiPay(Long productId) throws IOException {
+
+		String prepayId = "";
+		//生成订单
+//		OrderInfo orderInfo = orderInfoService.createOrderByProductId(productId);
+
+
+		logger.info("调用统一下单API");
+
+//		//调用统一下单API
+//		HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxApiType.JSAPI_PAY.getType()));
+//
+//		// 请求body参数
+//
+//		Gson gson = new Gson();
+//		Map paramsMap = new HashMap();
+//		paramsMap.put("appid", wxPayConfig.getAppid());
+//		paramsMap.put("mchid", wxPayConfig.getMchId());
+//		paramsMap.put("description", orderInfo.getTitle());
+//		paramsMap.put("out_trade_no", orderInfo.getOrderNo());
+//		paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.NATIVE_NOTIFY.getType()));
+//
+//		Map amountMap = new HashMap();
+//		amountMap.put("total", orderInfo.getTotalFee());
+//		amountMap.put("currency", "CNY");
+//
+//		paramsMap.put("amount", amountMap);
+//
+//		Map payerMap = new HashMap();
+//		payerMap.put("openid", "oSX3G6OUuGaKJbWzSHUpPbzgtDXo");
+//
+//		paramsMap.put("payer", payerMap);
+//
+//		//将参数转换成json字符串
+//		String jsonParams = gson.toJson(paramsMap);
+//		logger.info("请求参数 ===> {}" + jsonParams);
+//
+//		StringEntity entity = new StringEntity(jsonParams, "utf-8");
+//		entity.setContentType("application/json");
+//		httpPost.setEntity(entity);
+//		httpPost.setHeader("Accept", "application/json");
+//
+//		//完成签名并执行请求
+//		CloseableHttpResponse response = wxPayClient.execute(httpPost);
+//
+//		try {
+//			String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
+//			int statusCode = response.getStatusLine().getStatusCode();//响应状态码
+//			if (statusCode == 200) { //处理成功
+//				logger.info("成功, 返回结果 = " + bodyAsString);
+//			} else if (statusCode == 204) { //处理成功,无返回Body
+//				logger.info("成功");
+//			} else {
+//				logger.info("jszpi下单失败,响应码 = " + statusCode + ",返回结果 = " + bodyAsString);
+//				throw new IOException("request failed");
+//			}
+//			//响应结果
+//			Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
+//			//预支付交易会话标识
+//			prepayId = resultMap.get("prepay_id");
+//
+//			//返回预支付交易会话标识
+//			// 组装前端预下单参数
+//			/** 返回给前端所需要的数据 */
+//			SortedMap<String, String> payMap = new TreeMap<>();
+//			String nonceStr = WXPayUtil.generateNonceStr();
+//			String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
+//			payMap.put("appId", wxPayConfig.getAppid());
+//			payMap.put("timeStamp", timestamp);
+//			payMap.put("nonceStr", nonceStr);
+//			payMap.put("signType", "RSA");
+//			payMap.put("package", "prepay_id=" + prepayId);
+//			String paySign = getSign(wxPayConfig.getAppid(), prepayId, timestamp, nonceStr);
+//			payMap.put("paySign", paySign);
+//			logger.info("返回参数 ===> {}" + gson.toJson(payMap));
+//			return payMap;
+//		} finally {
+//			response.close();
+//		}
+		return null;
+	}
+
+	@Override
+	public void processOrder(Map<String, Object> bodyMap) throws GeneralSecurityException {
+		logger.info("处理订单");
+
+		//解密报文
+		String plainText = decryptFromResource(bodyMap);
+
+		//将明文转换成map
+		Gson gson = new Gson();
+		HashMap plainTextMap = gson.fromJson(plainText, HashMap.class);
+		String orderNo = (String) plainTextMap.get("out_trade_no");
+
+
+        /*在对业务数据进行状态检查和处理之前,
+        要采用数据锁进行并发控制,
+        以避免函数重入造成的数据混乱*/
+		//尝试获取锁:
+		// 成功获取则立即返回true,获取失败则立即返回false。不必一直等待锁的释放
+//		if (lock.tryLock()) {
+//			try {
+//				//处理重复的通知
+//				//接口调用的幂等性:无论接口被调用多少次,产生的结果是一致的。
+//				String orderStatus = orderInfoService.getOrderStatus(orderNo);
+//				if (!OrderStatus.NOTPAY.getType().equals(orderStatus)) {
+//					return;
+//				}
+//
+//				//模拟通知并发
+//				try {
+//					TimeUnit.SECONDS.sleep(5);
+//				} catch (InterruptedException e) {
+//					e.printStackTrace();
+//				}
+//
+//				//更新订单状态
+//				orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.SUCCESS);
+//
+//				//记录支付日志
+//				paymentInfoService.createPaymentInfo(plainText);
+//			} finally {
+//				//要主动释放锁
+//				lock.unlock();
+//			}
+//		}
+	}
+
+	/**
+	 * 通过prepay_id获取签名
+	 *
+	 * @param appid
+	 * @param prepay_id
+	 * @param timestamp
+	 * @param nonceStr
+	 * @return
+	 * @throws IOException
+	 * @throws SignatureException
+	 * @throws NoSuchAlgorithmException
+	 * @throws InvalidKeyException
+	 */
+	String getSign(String appid, String prepay_id, String timestamp, String nonceStr) throws IOException, SignatureException, NoSuchAlgorithmException, InvalidKeyException {
+		//从下往上依次生成
+		String message = getSignStr(appid, timestamp, nonceStr, "prepay_id=" + prepay_id);
+		//签名
+		String signature = sign(message.getBytes("utf-8"));
+		return signature;
+	}
+
+	String sign(byte[] message) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException {
+		//签名方式
+		Signature sign = Signature.getInstance("SHA256withRSA");
+		//私钥,通过MyPrivateKey来获取,这是个静态类可以接调用方法 ,需要的是_key.pem文件的绝对路径配上文件名
+//		sign.initSign(getPrivateKey(wxPayConfig.getPrivateKeyPath()));
+		sign.update(message);
+
+		return Base64.getEncoder().encodeToString(sign.sign());
+	}
+
+	/**
+	 * 按照前端签名文档规范进行排序
+	 *
+	 * @param appId
+	 * @param timeStamp
+	 * @param nonceStr
+	 * @param packageValue
+	 * @return
+	 */
+	private String getSignStr(String appId, String timeStamp, String nonceStr, String packageValue) {
+		return String.format("%s\n%s\n%s\n%s\n", appId, timeStamp, nonceStr, packageValue);
+	}
+
+	private PrivateKey getPrivateKey(String filename) {
+
+		try {
+			FileInputStream fileInputStream = new FileInputStream(filename);
+			logger.info("文件内容:" + fileInputStream);
+			return PemUtil.loadPrivateKey(fileInputStream);
+		} catch (Exception e) {
+			logger.info("私钥文件不存在", e);
+			throw new RuntimeException("私钥文件不存在", e);
+		}
+	}
+
+	/**
+	 * 对称解密
+	 *
+	 * @param bodyMap
+	 * @return
+	 */
+	private String decryptFromResource(Map<String, Object> bodyMap) throws GeneralSecurityException {
+
+		logger.info("密文解密");
+
+		//通知数据
+		Map<String, String> resourceMap = (Map) bodyMap.get("resource");
+		//数据密文
+		String ciphertext = resourceMap.get("ciphertext");
+		//随机串
+		String nonce = resourceMap.get("nonce");
+		//附加数据
+		String associatedData = resourceMap.get("associated_data");
+
+		logger.info("密文 ===> {}", ciphertext);
+//		AesUtil aesUtil = new AesUtil(wxPayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8));
+//		String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
+//			nonce.getBytes(StandardCharsets.UTF_8),
+//			ciphertext);
+
+//		logger.info("明文 ===> {}", plainText);
+
+//		return plainText;
+		return null;
+	}
+
 }
diff --git a/src/main/java/org/springblade/modules/place/controller/PlacePractitionerController.java b/src/main/java/org/springblade/modules/place/controller/PlacePractitionerController.java
index c17bcfa..de84090 100644
--- a/src/main/java/org/springblade/modules/place/controller/PlacePractitionerController.java
+++ b/src/main/java/org/springblade/modules/place/controller/PlacePractitionerController.java
@@ -21,12 +21,15 @@
 import io.swagger.annotations.ApiParam;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
+
 import javax.validation.Valid;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springframework.web.bind.annotation.*;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -35,6 +38,8 @@
 import org.springblade.modules.place.wrapper.PlacePractitionerWrapper;
 import org.springblade.modules.place.service.IPlacePractitionerService;
 import org.springblade.core.boot.ctrl.BladeController;
+
+import java.util.Date;
 
 /**
  * 场所从业人员 控制器
@@ -46,7 +51,7 @@
 @AllArgsConstructor
 @RequestMapping("blade-placePractitioner/placePractitioner")
 @Api(value = "场所从业人员", tags = "场所从业人员接口")
-public class PlacePractitionerController{
+public class PlacePractitionerController {
 
 	private final IPlacePractitionerService placePractitionerService;
 
@@ -60,6 +65,7 @@
 		PlacePractitionerEntity detail = placePractitionerService.getOne(Condition.getQueryWrapper(placePractitioner));
 		return R.data(PlacePractitionerWrapper.build().entityVO(detail));
 	}
+
 	/**
 	 * 场所从业人员 分页
 	 */
@@ -89,6 +95,13 @@
 	@ApiOperationSupport(order = 4)
 	@ApiOperation(value = "新增", notes = "传入placePractitioner")
 	public R save(@Valid @RequestBody PlacePractitionerEntity placePractitioner) {
+		if (StringUtils.isNotBlank(placePractitioner.getIdCard())) {
+			// 从身份证号获取出生日期
+			String birthDateStr = placePractitioner.getIdCard().substring(6, 14);
+			// 解析出生日期字符串为日期对象
+			Date birthDate = DateUtil.parse(birthDateStr, "yyyyMMdd");
+			placePractitioner.setBirthday(birthDate);
+		}
 		return R.status(placePractitionerService.save(placePractitioner));
 	}
 
@@ -99,6 +112,13 @@
 	@ApiOperationSupport(order = 5)
 	@ApiOperation(value = "修改", notes = "传入placePractitioner")
 	public R update(@Valid @RequestBody PlacePractitionerEntity placePractitioner) {
+		if (StringUtils.isNotBlank(placePractitioner.getIdCard())) {
+			// 从身份证号获取出生日期
+			String birthDateStr = placePractitioner.getIdCard().substring(6, 14);
+			// 解析出生日期字符串为日期对象
+			Date birthDate = DateUtil.parse(birthDateStr, "yyyyMMdd");
+			placePractitioner.setBirthday(birthDate);
+		}
 		return R.status(placePractitionerService.updateById(placePractitioner));
 	}
 
@@ -109,6 +129,13 @@
 	@ApiOperationSupport(order = 6)
 	@ApiOperation(value = "新增或修改", notes = "传入placePractitioner")
 	public R submit(@Valid @RequestBody PlacePractitionerEntity placePractitioner) {
+		if (StringUtils.isNotBlank(placePractitioner.getIdCard())) {
+			// 从身份证号获取出生日期
+			String birthDateStr = placePractitioner.getIdCard().substring(6, 14);
+			// 解析出生日期字符串为日期对象
+			Date birthDate = DateUtil.parse(birthDateStr, "yyyyMMdd");
+			placePractitioner.setBirthday(birthDate);
+		}
 		return R.status(placePractitionerService.saveOrUpdate(placePractitioner));
 	}
 
@@ -122,5 +149,15 @@
 		return R.status(placePractitionerService.removeByIds(Func.toLongList(ids)));
 	}
 
+	/**
+	 * 统计少数民族和未成年数量
+	 */
+	@PostMapping("/countByType")
+	@ApiOperationSupport(order = 8)
+	@ApiOperation(value = "统计少数民族和未成年数量", notes = "")
+	public R countByType() {
+		return R.data(placePractitionerService.countByType());
+	}
+
 
 }
diff --git a/src/main/java/org/springblade/modules/place/entity/PlaceEntity.java b/src/main/java/org/springblade/modules/place/entity/PlaceEntity.java
index 0de558c..7f88fa0 100644
--- a/src/main/java/org/springblade/modules/place/entity/PlaceEntity.java
+++ b/src/main/java/org/springblade/modules/place/entity/PlaceEntity.java
@@ -43,186 +43,158 @@
 public class PlaceEntity implements Serializable {
 	private static final long serialVersionUID = 1L;
 
-	/**
-	 * 主键
-	 */
-	@JsonSerialize(using = ToStringSerializer.class)
-	@ApiModelProperty("主键id")
+	/** 主键id */
+	@ApiModelProperty(value = "主键ID", example = "")
 	@TableId(value = "id", type = IdType.ASSIGN_ID)
 	private Long id;
 
-	/**
-	 * 门牌地址编码
-	 */
-	@ApiModelProperty(value = "门牌地址编码")
+	/** 门牌地址编码 */
+	@ApiModelProperty(value = "门牌地址编码", example = "")
+	@TableField("house_code")
 	private String houseCode;
-	/**
-	 * 门牌地址编码绑定
-	 */
-	@ApiModelProperty(value = "门牌地址编码绑定")
+
+	/** 门牌地址编号绑定 */
+	@ApiModelProperty(value = "门牌地址编号绑定", example = "")
+	@TableField("house_code_binds")
 	private String houseCodeBinds;
 
-	/**
-	 * 楼栋编码
-	 */
-	@ApiModelProperty(value = "楼栋编码")
+	/** 楼栋编码 */
+	@ApiModelProperty(value = "楼栋编码", example = "")
+	@TableField("building_code")
 	private String buildingCode;
 
-	/**
-	 * 场所负责人(关联用户表信息user_id)
-	 */
-	@ApiModelProperty(value = "场所负责人(关联用户表信息user_id)")
-	@JsonSerialize(using = ToStringSerializer.class)
+	/** 场所负责人(关联用户表信息) */
+	@ApiModelProperty(value = "场所负责人(关联用户表信息)", example = "")
+	@TableField("principal_user_id")
 	private Long principalUserId;
 
-	/**
-	 * 场所负责人
-	 */
-	@ApiModelProperty(value = "场所负责人")
-	@JsonSerialize(using = ToStringSerializer.class)
+	/** 场所负责人姓名 */
+	@ApiModelProperty(value = "场所负责人姓名", example = "")
+	@TableField("principal")
 	private String principal;
 
+	/** 场所负责人联系方式 */
+	@ApiModelProperty(value = "场所负责人联系方式", example = "")
+	@TableField("principal_phone")
+	private String principalPhone;
 
 	/** 场所负责人身份证号 */
 	@ApiModelProperty(value = "场所负责人身份证号", example = "")
 	@TableField("principal_id_card")
 	private String principalIdCard;
 
-	/**
-	 * 场所负责人联系电话
-	 */
-	@ApiModelProperty(value = "场所负责人联系电话")
-	@JsonSerialize(using = ToStringSerializer.class)
-	private String principalPhone;
-
-	/**
-	 * 场所名称
-	 */
-	@ApiModelProperty(value = "场所名称")
+	/** 场所名称 */
+	@ApiModelProperty(value = "场所名称", example = "")
+	@TableField("place_name")
 	private String placeName;
-	/**
-	 * 经度
-	 */
-	@ApiModelProperty(value = "经度")
+
+	/** 经度 */
+	@ApiModelProperty(value = "经度", example = "")
+	@TableField("lng")
 	private String lng;
-	/**
-	 * 纬度
-	 */
-	@ApiModelProperty(value = "纬度")
+
+	/** 纬度 */
+	@ApiModelProperty(value = "纬度", example = "")
+	@TableField("lat")
 	private String lat;
-	/**
-	 * 位置
-	 */
-	@ApiModelProperty(value = "位置")
+
+	/** 位置 */
+	@ApiModelProperty(value = "位置", example = "")
+	@TableField("location")
 	private String location;
-	/**
-	 * 场所照片
-	 */
-	@ApiModelProperty(value = "场所照片")
+
+	/** 场所照片 */
+	@ApiModelProperty(value = "场所照片", example = "")
+	@TableField("image_urls")
 	private String imageUrls;
 
-	/**
-	 * 网格编号
-	 */
-	@ApiModelProperty(value = "网格编号")
+	/** 网格id */
+	@ApiModelProperty(value = "网格id", example = "")
+	@TableField("grid_id")
+	private Integer gridId;
+
+	/** 网格编号 */
+	@ApiModelProperty(value = "网格编号", example = "")
+	@TableField("grid_code")
 	private String gridCode;
 
-	/**
-	 * 警务网格编号
-	 */
-	@ApiModelProperty(value = "警务网格编号")
+	/** 警务网格编号 */
+	@ApiModelProperty(value = "警务网格编号", example = "")
+	@TableField("jw_grid_code")
 	private String jwGridCode;
 
-	/**
-	 * 状态  1:待完善  2:已完善
-	 */
-	@ApiModelProperty(value = "状态  1:待完善  2:已完善")
-	private Integer status;
-
-	/**
-	 * 来源 1:地址总表  2:国控采集  3:商超
-	 */
-	@ApiModelProperty(value = "来源 1:地址总表  2:国控采集 3:商超")
+	/** 来源 1:地址总表  2:国控采集 3:商超 */
+	@ApiModelProperty(value = "来源 1:地址总表  2:国控采集 3:商超", example = "")
+	@TableField("source")
 	private Integer source;
 
-	/**
-	 * 是否现场采集  1:是  2:否
-	 */
-	@ApiModelProperty(value = "是否现场采集  1:是  2:否")
+	/** 状态  1:待完善  2:已完善 */
+	@ApiModelProperty(value = "状态  1:待完善  2:已完善", example = "")
+	@TableField("status")
+	private Integer status;
+
+	/** 是否现场采集  1:是  2:否 */
+	@ApiModelProperty(value = "是否现场采集  1:是  2:否", example = "")
+	@TableField("is_scene")
 	private Integer isScene;
 
-	/**
-	 * 是否九小场所  1:是 2:否
-	 */
-	@ApiModelProperty(value = "是否九小场所  1:是 2:否")
+	/** 是否九小场所  1:是 2:否 */
+	@ApiModelProperty(value = "是否九小场所  1:是 2:否", example = "")
+	@TableField("is_nine")
 	private Integer isNine;
 
-	/**
-	 * 九小场所类型 字典 nineType
-	 */
-	@ApiModelProperty(value = "九小场所类型")
+	/** 九小场所类型 业务字典:nineType */
+	@ApiModelProperty(value = "九小场所类型 业务字典:nineType", example = "")
+	@TableField("nine_type")
 	private Integer nineType;
 
-	/**
-	 * 是否阵地  1:是 2:否
-	 */
-	@ApiModelProperty(value = "是否阵地  1:是 2:否")
+	/** 是否阵地  1:是 2:否 */
+	@ApiModelProperty(value = "是否阵地  1:是 2:否", example = "")
+	@TableField("is_front")
 	private Integer isFront;
 
-	/**
-	 * 阵地类型 字典 frontType
-	 */
-	@ApiModelProperty(value = "阵地类型")
+	/** 阵地类型 业务字典:frontType */
+	@ApiModelProperty(value = "阵地类型 业务字典:frontType", example = "")
+	@TableField("front_type")
 	private Integer frontType;
 
-	/**
-	 * 创建人
-	 */
-	@JsonSerialize(using = ToStringSerializer.class)
-	@ApiModelProperty("创建人")
-	@TableField(fill = FieldFill.INSERT)
+	/** 创建人 */
+	@ApiModelProperty(value = "创建人", example = "")
+	@TableField("create_user")
 	private Long createUser;
 
-	/**
-	 * 创建时间
-	 */
-	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@ApiModelProperty("创建时间")
-	@TableField(fill = FieldFill.INSERT)
+	/** 创建时间 */
+	@ApiModelProperty(value = "创建时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField(value = "create_time",fill = FieldFill.INSERT)
 	private Date createTime;
 
-	/**
-	 * 更新人
-	 */
-	@JsonSerialize(using = ToStringSerializer.class)
-	@ApiModelProperty("更新人")
-	@TableField(fill = FieldFill.INSERT_UPDATE)
+	/** 更新人 */
+	@ApiModelProperty(value = "更新人", example = "")
+	@TableField("update_user")
 	private Long updateUser;
 
-	/**
-	 * 更新时间
-	 */
-	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@ApiModelProperty("更新时间")
-	@TableField(fill = FieldFill.INSERT_UPDATE)
+	/** 更新时间 */
+	@ApiModelProperty(value = "更新时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField(value = "update_time",fill = FieldFill.UPDATE)
 	private Date updateTime;
 
-	/**
-	 * 备注
-	 */
-	@ApiModelProperty(value = "备注")
+	/** 备注 */
+	@ApiModelProperty(value = "备注", example = "")
+	@TableField("remark")
 	private String remark;
 
-	@ApiModelProperty(value = "小区编码")
+	/** 是否删除 0:否  1:是 */
+	@ApiModelProperty(value = "是否删除 0:否  1:是", example = "")
+	@TableField("is_deleted")
+	private Integer isDeleted;
+
+	/** 小区编码 */
+	@ApiModelProperty(value = "小区编码", example = "")
+	@TableField("aoi_code")
 	private String aoiCode;
 
-	/**
-	 * 是否删除
-	 */
-	@TableLogic
-	@ApiModelProperty("是否已删除 0:否  1:是")
-	private Integer isDeleted;
+
 
 }
diff --git a/src/main/java/org/springblade/modules/place/entity/PlaceExtEntity.java b/src/main/java/org/springblade/modules/place/entity/PlaceExtEntity.java
index f906ccb..22aeeb1 100644
--- a/src/main/java/org/springblade/modules/place/entity/PlaceExtEntity.java
+++ b/src/main/java/org/springblade/modules/place/entity/PlaceExtEntity.java
@@ -49,102 +49,156 @@
 	@ApiModelProperty("主键id")
 	@TableId(value = "id", type = IdType.ASSIGN_ID)
 	private Long id;
-//
-//	/**
-//	 * 任务id
-//	 */
-//	@ApiModelProperty(value = "任务id")
-//	private Long taskId;
 
-	/**
-	 * 场所ID
-	 */
-	@ApiModelProperty(value = "场所ID")
+	/** 场所ID */
+	@ApiModelProperty(value = "场所ID", example = "")
+	@TableField("place_id")
 	private Long placeId;
-	/**
-	 * 营业执照图片URLS
-	 */
-	@ApiModelProperty(value = "营业执照图片URLS")
+
+	/** 营业执照图片URLS */
+	@ApiModelProperty(value = "营业执照图片URLS", example = "")
+	@TableField("image_urls")
 	private String imageUrls;
 
-	/**
-	 * 法人信息
-	 */
-	@ApiModelProperty(value = "法人信息")
+	/** 法人信息 */
+	@ApiModelProperty(value = "法人信息", example = "")
+	@TableField("legal_person")
 	private String legalPerson;
-	/**
-	 * 法人电话
-	 */
-	@ApiModelProperty(value = "法人电话")
+
+	/** 法人电话 */
+	@ApiModelProperty(value = "法人电话", example = "")
+	@TableField("legal_tel")
 	private String legalTel;
-	/**
-	 * 场所平面图URLS
-	 */
-	@ApiModelProperty(value = "场所平面图URLS")
+
+	/** 场所平面图URLS */
+	@ApiModelProperty(value = "场所平面图URLS", example = "")
+	@TableField("plan_image_urls")
 	private String planImageUrls;
 
-	/**
-	 * 确认用户ID
-	 */
-	@ApiModelProperty(value = "确认用户ID")
-	@JsonSerialize(using = ToStringSerializer.class)
+	/** 审核确认人用户id */
+	@ApiModelProperty(value = "审核确认人用户id", example = "")
+	@TableField("confirm_user_id")
 	private Long confirmUserId;
-	/**
-	 * 确认时间
-	 */
-	@ApiModelProperty(value = "确认时间")
-	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	private Date confirmTime;
-	/**
-	 * 确认标记 1:待审核  2:审核通过  3:审核不通过 4:待完善(地址表数据,无场所负责人)
-	 */
-	@ApiModelProperty(value = "确认标记 1:待审核  2:审核通过  3:审核不通过 4:待完善")
+
+	/** 确认标记 1:待审核  2:审核通过  3:审核不通过 4:待完善 */
+	@ApiModelProperty(value = "确认标记 1:待审核  2:审核通过  3:审核不通过 4:待完善", example = "")
+	@TableField("confirm_flag")
 	private Integer confirmFlag;
-	/**
-	 * 确认意见
-	 */
-	@ApiModelProperty(value = "确认意见")
+
+	/** 审核确认时间 */
+	@ApiModelProperty(value = "审核确认时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("confirm_time")
+	private Date confirmTime;
+
+	/** 审核意见 */
+	@ApiModelProperty(value = "审核意见", example = "")
+	@TableField("confirm_notion")
 	private String confirmNotion;
 
-	/**
-	 * 创建人
-	 */
-	@JsonSerialize(using = ToStringSerializer.class)
-	@ApiModelProperty("创建人")
-	@TableField(fill = FieldFill.INSERT)
+	/** 创建人 */
+	@ApiModelProperty(value = "创建人", example = "")
+	@TableField("create_user")
 	private Long createUser;
 
-	/**
-	 * 创建时间
-	 */
-	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@ApiModelProperty("创建时间")
-	@TableField(fill = FieldFill.INSERT)
+	/** 创建时间 */
+	@ApiModelProperty(value = "创建时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("create_time")
 	private Date createTime;
 
-	/**
-	 * 更新人
-	 */
-	@JsonSerialize(using = ToStringSerializer.class)
-	@ApiModelProperty("更新人")
-	@TableField(fill = FieldFill.INSERT_UPDATE)
+	/** 更新人 */
+	@ApiModelProperty(value = "更新人", example = "")
+	@TableField("update_user")
 	private Long updateUser;
 
-	/**
-	 * 更新时间
-	 */
-	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	@ApiModelProperty("更新时间")
-	@TableField(fill = FieldFill.INSERT_UPDATE)
+	/** 更新时间 */
+	@ApiModelProperty(value = "更新时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("update_time")
 	private Date updateTime;
 
-	/**
-	 * 是否删除
-	 */
-	@TableLogic
-	@ApiModelProperty("是否已删除 0:否  1:是")
+	/** 是否删除 0:否  1:是 */
+	@ApiModelProperty(value = "是否删除 0:否  1:是", example = "")
+	@TableField("is_deleted")
 	private Integer isDeleted;
+
+	/** 法人现住地址 */
+	@ApiModelProperty(value = "法人现住地址", example = "")
+	@TableField("legal_temp_address")
+	private String legalTempAddress;
+
+	/** 法人年龄 */
+	@ApiModelProperty(value = "法人年龄", example = "")
+	@TableField("legal_age")
+	private Integer legalAge;
+
+	/** 法人性别 */
+	@ApiModelProperty(value = "法人性别", example = "")
+	@TableField("legal_gender")
+	private Integer legalGender;
+
+	/** 法人身份证 */
+	@ApiModelProperty(value = "法人身份证", example = "")
+	@TableField("legal_id_card")
+	private String legalIdCard;
+
+	/** 法人证件类型,业务字典  cardType */
+	@ApiModelProperty(value = "法人证件类型,业务字典  cardType", example = "")
+	@TableField("legal_card_type")
+	private String legalCardType;
+
+	/** 法人户籍地址 */
+	@ApiModelProperty(value = "法人户籍地址", example = "")
+	@TableField("legal_registered_address")
+	private String legalRegisteredAddress;
+
+	/** 法人岗位性质 */
+	@ApiModelProperty(value = "法人岗位性质", example = "")
+	@TableField("legal_job_nature")
+	private String legalJobNature;
+
+	/** 法人微信号 */
+	@ApiModelProperty(value = "法人微信号", example = "")
+	@TableField("legal_wx_account")
+	private String legalWxAccount;
+
+
+	/** 生日 */
+	@ApiModelProperty(value = "生日", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField("birthday")
+	private Date birthday;
+
+	/** 民族 */
+	@ApiModelProperty(value = "民族", example = "")
+	@TableField("ethnicity")
+	private Integer ethnicity;
+
+	/** 工作单位(就职单位) */
+	@ApiModelProperty(value = "工作单位(就职单位)", example = "")
+	@TableField("employer")
+	private String employer;
+
+	/** 房东名字 */
+	@ApiModelProperty(value = "房东名字", example = "")
+	@TableField("landlord_name")
+	private String landlordName;
+
+	/** 房东手机号 */
+	@ApiModelProperty(value = "房东手机号", example = "")
+	@TableField("landlord_phone")
+	private String landlordPhone;
+
+	/** 房东微信号 */
+	@ApiModelProperty(value = "房东微信号", example = "")
+	@TableField("landlord_wx_account")
+	private String landlordWxAccount;
+
+	/** 房东身份证号 */
+	@ApiModelProperty(value = "房东身份证号", example = "")
+	@TableField("landlord_id_card")
+	private String landlordIdCard;
+
+
 }
diff --git a/src/main/java/org/springblade/modules/place/entity/PlacePractitionerEntity.java b/src/main/java/org/springblade/modules/place/entity/PlacePractitionerEntity.java
index f723bd6..8384c31 100644
--- a/src/main/java/org/springblade/modules/place/entity/PlacePractitionerEntity.java
+++ b/src/main/java/org/springblade/modules/place/entity/PlacePractitionerEntity.java
@@ -16,9 +16,8 @@
  */
 package org.springblade.modules.place.entity;
 
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import lombok.Data;
@@ -28,6 +27,7 @@
 import org.springblade.core.tenant.mp.TenantEntity;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * 场所从业人员 实体类
@@ -48,25 +48,91 @@
 	@TableId(value = "id", type = IdType.ASSIGN_ID)
 	private Long id;
 
-	/**
-	 * 场所ID
-	 */
-	@ApiModelProperty(value = "场所ID")
+	/** 场所ID */
+	@ApiModelProperty(value = "场所ID", example = "")
+	@TableField("place_id")
 	private Long placeId;
-	/**
-	 * 姓名
-	 */
-	@ApiModelProperty(value = "姓名")
+
+	/** 姓名 */
+	@ApiModelProperty(value = "姓名", example = "")
+	@TableField("name")
 	private String name;
-	/**
-	 * 电话
-	 */
-	@ApiModelProperty(value = "电话")
+
+	/** 电话 */
+	@ApiModelProperty(value = "电话", example = "")
+	@TableField("telephone")
 	private String telephone;
-	/**
-	 * 暂住地
-	 */
-	@ApiModelProperty(value = "暂住地")
+
+	/** 现住地址 */
+	@ApiModelProperty(value = "现住地址", example = "")
+	@TableField("temp_address")
 	private String tempAddress;
 
+	/** 年龄 */
+	@ApiModelProperty(value = "年龄", example = "")
+	@TableField("age")
+	private Integer age;
+
+	/** 性别 */
+	@ApiModelProperty(value = "性别", example = "")
+	@TableField("gender")
+	private Integer gender;
+
+	/** 身份证 */
+	@ApiModelProperty(value = "身份证", example = "")
+	@TableField("id_card")
+	private String idCard;
+
+	/** 证件类型,业务字典  cardType */
+	@ApiModelProperty(value = "证件类型,业务字典  cardType", example = "")
+	@TableField("card_type")
+	private String cardType;
+
+	/** 工作单位(就职单位) */
+	@ApiModelProperty(value = "工作单位(就职单位)", example = "")
+	@TableField("employer")
+	private String employer;
+
+	/** 户籍地址 */
+	@ApiModelProperty(value = "户籍地址", example = "")
+	@TableField("registered_address")
+	private String registeredAddress;
+
+	/** 岗位性质 */
+	@ApiModelProperty(value = "岗位性质", example = "")
+	@TableField("job_nature")
+	private String jobNature;
+
+	/** 从业人员的照片 */
+	@ApiModelProperty(value = "从业人员的照片", example = "")
+	@TableField("employer_img")
+	private String employerImg;
+
+	/** 微信号 */
+	@ApiModelProperty(value = "微信号", example = "")
+	@TableField("wx_account")
+	private String wxAccount;
+
+	/** 创建时间 */
+	@ApiModelProperty(value = "创建时间", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@TableField(value = "create_time",fill = FieldFill.INSERT)
+	private Date createTime;
+	/** 生日 */
+	@ApiModelProperty(value = "生日", example = "")
+	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+	@TableField("birthday")
+	private Date birthday;
+
+	/** 民族 */
+	@ApiModelProperty(value = "民族", example = "")
+	@TableField("ethnicity")
+	private Integer ethnicity;
+
+	/** 民族 */
+	@ApiModelProperty(value = "0:否1:是", example = "")
+	@TableField("is_deleted")
+	private Integer isDeleted;
+
+
 }
diff --git a/src/main/java/org/springblade/modules/place/mapper/PlaceExtMapper.xml b/src/main/java/org/springblade/modules/place/mapper/PlaceExtMapper.xml
index b6e9864..6a54d39 100644
--- a/src/main/java/org/springblade/modules/place/mapper/PlaceExtMapper.xml
+++ b/src/main/java/org/springblade/modules/place/mapper/PlaceExtMapper.xml
@@ -194,5 +194,98 @@
           and jpe.place_id = #{placeExt.placeId}
     </select>
 
+    <resultMap type="org.springblade.modules.place.dto.PlaceExtDTO" id="JczzPlaceExtDTOResult">
+        <result property="id"    column="id"    />
+        <result property="placeId"    column="place_id"    />
+        <result property="imageUrls"    column="image_urls"    />
+        <result property="legalPerson"    column="legal_person"    />
+        <result property="legalTel"    column="legal_tel"    />
+        <result property="planImageUrls"    column="plan_image_urls"    />
+        <result property="confirmUserId"    column="confirm_user_id"    />
+        <result property="confirmFlag"    column="confirm_flag"    />
+        <result property="confirmTime"    column="confirm_time"    />
+        <result property="confirmNotion"    column="confirm_notion"    />
+        <result property="createUser"    column="create_user"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateUser"    column="update_user"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="isDeleted"    column="is_deleted"    />
+        <result property="legalTempAddress"    column="legal_temp_address"    />
+        <result property="legalAge"    column="legal_age"    />
+        <result property="legalGender"    column="legal_gender"    />
+        <result property="legalIdCard"    column="legal_id_card"    />
+        <result property="legalCardType"    column="legal_card_type"    />
+        <result property="legalRegisteredAddress"    column="legal_registered_address"    />
+        <result property="legalJobNature"    column="legal_job_nature"    />
+        <result property="legalWxAccount"    column="legal_wx_account"    />
+        <result property="birthday"    column="birthday"    />
+        <result property="ethnicity"    column="ethnicity"    />
+        <result property="employer"    column="employer"    />
+    </resultMap>
+
+    <sql id="selectJczzPlaceExt">
+        select
+            id,
+            place_id,
+            image_urls,
+            legal_person,
+            legal_tel,
+            plan_image_urls,
+            confirm_user_id,
+            confirm_flag,
+            confirm_time,
+            confirm_notion,
+            create_user,
+            create_time,
+            update_user,
+            update_time,
+            is_deleted,
+            legal_temp_address,
+            legal_age,
+            legal_gender,
+            legal_id_card,
+            legal_card_type,
+            legal_registered_address,
+            legal_job_nature,
+            legal_wx_account
+        from
+            jczz_place_ext
+    </sql>
+
+<!--    <select id="selectJczzPlaceExtById" parameterType="long" resultMap="JczzPlaceExtDTOResult">-->
+<!--        <include refid="selectJczzPlaceExt"/>-->
+<!--        where-->
+<!--        id = #{id}-->
+<!--    </select>-->
+
+<!--    <select id="selectJczzPlaceExtList" parameterType="jczzplaceext.dto.JczzPlaceExtDTO" resultMap="JczzPlaceExtDTOResult">-->
+<!--        <include refid="selectJczzPlaceExt"/>-->
+<!--        <where>-->
+<!--            <if test="id != null "> and id = #{id}</if>-->
+<!--            <if test="placeId != null "> and place_id = #{placeId}</if>-->
+<!--            <if test="imageUrls != null  and imageUrls != ''"> and image_urls = #{imageUrls}</if>-->
+<!--            <if test="legalPerson != null  and legalPerson != ''"> and legal_person = #{legalPerson}</if>-->
+<!--            <if test="legalTel != null  and legalTel != ''"> and legal_tel = #{legalTel}</if>-->
+<!--            <if test="planImageUrls != null  and planImageUrls != ''"> and plan_image_urls = #{planImageUrls}</if>-->
+<!--            <if test="confirmUserId != null "> and confirm_user_id = #{confirmUserId}</if>-->
+<!--            <if test="confirmFlag != null "> and confirm_flag = #{confirmFlag}</if>-->
+<!--            <if test="confirmTime != null "> and confirm_time = #{confirmTime}</if>-->
+<!--            <if test="confirmNotion != null  and confirmNotion != ''"> and confirm_notion = #{confirmNotion}</if>-->
+<!--            <if test="createUser != null "> and create_user = #{createUser}</if>-->
+<!--            <if test="createTime != null "> and create_time = #{createTime}</if>-->
+<!--            <if test="updateUser != null "> and update_user = #{updateUser}</if>-->
+<!--            <if test="updateTime != null "> and update_time = #{updateTime}</if>-->
+<!--            <if test="isDeleted != null "> and is_deleted = #{isDeleted}</if>-->
+<!--            <if test="legalTempAddress != null  and legalTempAddress != ''"> and legal_temp_address = #{legalTempAddress}</if>-->
+<!--            <if test="legalAge != null "> and legal_age = #{legalAge}</if>-->
+<!--            <if test="legalGender != null "> and legal_gender = #{legalGender}</if>-->
+<!--            <if test="legalIdCard != null  and legalIdCard != ''"> and legal_id_card = #{legalIdCard}</if>-->
+<!--            <if test="legalCardType != null  and legalCardType != ''"> and legal_card_type = #{legalCardType}</if>-->
+<!--            <if test="legalRegisteredAddress != null  and legalRegisteredAddress != ''"> and legal_registered_address = #{legalRegisteredAddress}</if>-->
+<!--            <if test="legalJobNature != null  and legalJobNature != ''"> and legal_job_nature = #{legalJobNature}</if>-->
+<!--            <if test="legalWxAccount != null  and legalWxAccount != ''"> and legal_wx_account = #{legalWxAccount}</if>-->
+<!--        </where>-->
+<!--    </select>-->
+
 
 </mapper>
diff --git a/src/main/java/org/springblade/modules/place/mapper/PlaceMapper.xml b/src/main/java/org/springblade/modules/place/mapper/PlaceMapper.xml
index 27451bb..4e725c9 100644
--- a/src/main/java/org/springblade/modules/place/mapper/PlaceMapper.xml
+++ b/src/main/java/org/springblade/modules/place/mapper/PlaceMapper.xml
@@ -657,17 +657,20 @@
     <resultMap type="org.springblade.modules.place.dto.PlaceDTO" id="PlaceDTOResult">
         <result property="id"    column="id"    />
         <result property="houseCode"    column="house_code"    />
+        <result property="houseCodeBinds"    column="house_code_binds"    />
         <result property="buildingCode"    column="building_code"    />
         <result property="principalUserId"    column="principal_user_id"    />
         <result property="principal"    column="principal"    />
-        <result property="principalIdCard"    column="principal_id_card"    />
         <result property="principalPhone"    column="principal_phone"    />
+        <result property="principalIdCard"    column="principal_id_card"    />
         <result property="placeName"    column="place_name"    />
         <result property="lng"    column="lng"    />
         <result property="lat"    column="lat"    />
         <result property="location"    column="location"    />
         <result property="imageUrls"    column="image_urls"    />
+        <result property="gridId"    column="grid_id"    />
         <result property="gridCode"    column="grid_code"    />
+        <result property="jwGridCode"    column="jw_grid_code"    />
         <result property="source"    column="source"    />
         <result property="status"    column="status"    />
         <result property="isScene"    column="is_scene"    />
diff --git a/src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.java b/src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.java
index 0bfc9e1..a989395 100644
--- a/src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.java
+++ b/src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.java
@@ -16,6 +16,7 @@
  */
 package org.springblade.modules.place.mapper;
 
+import liquibase.pro.packaged.S;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.modules.place.entity.PlacePractitionerEntity;
 import org.springblade.modules.place.vo.PlacePractitionerVO;
@@ -40,5 +41,12 @@
 	 */
 	List<PlacePractitionerVO> selectPlacePractitionerPage(IPage page,@Param("placePractitioner") PlacePractitionerVO placePractitioner);
 
+	/**
+	 * 统计数据
+	 * @param type
+	 * @return
+	 */
+	Integer selectPlaceCountByType(@Param("type") Integer type);
+
 
 }
diff --git a/src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.xml b/src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.xml
index 3dffc37..bbf9e44 100644
--- a/src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.xml
+++ b/src/main/java/org/springblade/modules/place/mapper/PlacePractitionerMapper.xml
@@ -4,10 +4,120 @@
 
     <!--自定义分页查询-->
     <select id="selectPlacePractitionerPage" resultType="org.springblade.modules.place.vo.PlacePractitionerVO">
-        select * from jczz_place_practitioner where 1=1
-        <if test="placePractitioner.placeId!=null">
-            and place_id = #{placePractitioner.placeId}
-        </if>
+        SELECT
+        *
+        FROM
+        jczz_place_practitioner jpp
+        LEFT JOIN jczz_place jp ON jp.id = jpp.place_id
+        LEFT JOIN jczz_place_poi_label jppl on jppl.place_id = jp.id and type = 3
+        LEFT JOIN jczz_category jc on jc.category_no = jppl.poi_code
+        <where>
+            <if test="placePractitioner.id != null ">and jpp.id = #{placePractitioner.id}</if>
+            <if test="placePractitioner.placeId != null ">and jpp.place_id = #{placePractitioner.placeId}</if>
+            <if test="placePractitioner.name != null  and placePractitioner.name != ''">and jpp.name =
+                #{placePractitioner.name}
+            </if>
+            <if test="placePractitioner.telephone != null  and placePractitioner.telephone != ''">and jpp.telephone =
+                #{placePractitioner.telephone}
+            </if>
+            <if test="placePractitioner.tempAddress != null  and placePractitioner.tempAddress != ''">and jpp.temp_address =
+                #{placePractitioner.tempAddress}
+            </if>
+            <if test="placePractitioner.age != null ">and jpp.age = #{placePractitioner.age}</if>
+            <if test="placePractitioner.gender != null ">and jpp.gender = #{placePractitioner.gender}</if>
+            <if test="placePractitioner.idCard != null  and placePractitioner.idCard != ''">and jpp.id_card =
+                #{placePractitioner.idCard}
+            </if>
+            <if test="placePractitioner.cardType != null  and placePractitioner.cardType != ''">and jpp.card_type =
+                #{placePractitioner.cardType}
+            </if>
+            <if test="placePractitioner.employer != null  and placePractitioner.employer != ''">and jpp.employer =
+                #{placePractitioner.employer}
+            </if>
+            <if test="placePractitioner.registeredAddress != null  and placePractitioner.registeredAddress != ''">and
+                jpp.registered_address = #{placePractitioner.registeredAddress}
+            </if>
+            <if test="placePractitioner.jobNature != null  and placePractitioner.jobNature != ''">and jpp.job_nature =
+                #{placePractitioner.jobNature}
+            </if>
+            <if test="placePractitioner.employerImg != null  and placePractitioner.employerImg != ''">and jpp.employer_img =
+                #{placePractitioner.employerImg}
+            </if>
+            <if test="placePractitioner.wxAccount != null  and placePractitioner.wxAccount != ''">and jpp.wx_account =
+                #{placePractitioner.wxAccount}
+            </if>
+            <if test="placePractitioner.createTime != null ">and jpp.create_time = #{placePractitioner.createTime}</if>
+            <if test="placePractitioner.birthday != null ">and jpp.birthday = #{placePractitioner.birthday}</if>
+            <if test="placePractitioner.ethnicity != null ">and jpp.ethnicity = #{placePractitioner.ethnicity}</if>
+
+            <if test="placePractitioner.type == 1">
+                and (YEAR(CURDATE()) - YEAR(jpp.birthday)) &lt; 18
+            </if>
+            <if test="placePractitioner.type == 2">
+                and jpp.ethnicity != 1
+            </if>
+            <if test="placePractitioner.type == 3">
+                and (((YEAR(CURDATE()) - YEAR(jpp.birthday)) &lt; 18) or ( jpp.ethnicity != 1))
+                and jc.category_no in (180202,180201)
+            </if>
+            and jpp.is_deleted = 0
+        </where>
+    </select>
+
+
+    <resultMap type="org.springblade.modules.place.dto.PlacePractitionerDTO" id="JczzPlacePractitionerDTOResult">
+        <result property="id" column="id"/>
+        <result property="placeId" column="place_id"/>
+        <result property="name" column="name"/>
+        <result property="telephone" column="telephone"/>
+        <result property="tempAddress" column="temp_address"/>
+        <result property="age" column="age"/>
+        <result property="gender" column="gender"/>
+        <result property="idCard" column="id_card"/>
+        <result property="cardType" column="card_type"/>
+        <result property="employer" column="employer"/>
+        <result property="registeredAddress" column="registered_address"/>
+        <result property="jobNature" column="job_nature"/>
+        <result property="employerImg" column="employer_img"/>
+        <result property="wxAccount" column="wx_account"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
+
+    <sql id="selectJczzPlacePractitioner">
+        select id,
+               place_id,
+               name,
+               telephone,
+               temp_address,
+               age,
+               gender,
+               id_card,
+               card_type,
+               employer,
+               registered_address,
+               job_nature,
+               employer_img,
+               wx_account,
+               create_time,
+               birthday,
+               ethnicity
+        from jczz_place_practitioner
+    </sql>
+
+    <select id="selectPlaceCountByType" parameterType="long" resultType="integer">
+        select
+        count(1)
+        from
+        jczz_place_practitioner
+        <where>
+            <if test="type == 1">
+                and (YEAR(CURDATE()) - YEAR(birthday)) &lt; 18
+            </if>
+            <if test="type == 2">
+                and ethnicity != 1
+            </if>
+            and is_deleted = 0
+        </where>
     </select>
 
 
diff --git a/src/main/java/org/springblade/modules/place/service/IPlacePractitionerService.java b/src/main/java/org/springblade/modules/place/service/IPlacePractitionerService.java
index 7550764..8b79c57 100644
--- a/src/main/java/org/springblade/modules/place/service/IPlacePractitionerService.java
+++ b/src/main/java/org/springblade/modules/place/service/IPlacePractitionerService.java
@@ -40,4 +40,5 @@
 	IPage<PlacePractitionerVO> selectPlacePractitionerPage(IPage<PlacePractitionerVO> page, PlacePractitionerVO placePractitioner);
 
 
+    Object countByType();
 }
diff --git a/src/main/java/org/springblade/modules/place/service/impl/PlacePractitionerServiceImpl.java b/src/main/java/org/springblade/modules/place/service/impl/PlacePractitionerServiceImpl.java
index 079de89..0ce0566 100644
--- a/src/main/java/org/springblade/modules/place/service/impl/PlacePractitionerServiceImpl.java
+++ b/src/main/java/org/springblade/modules/place/service/impl/PlacePractitionerServiceImpl.java
@@ -17,6 +17,7 @@
 package org.springblade.modules.place.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.common.constant.CommonConstant;
 import org.springblade.modules.place.entity.PlacePractitionerEntity;
 import org.springblade.modules.place.vo.PlacePractitionerVO;
 import org.springblade.modules.place.mapper.PlacePractitionerMapper;
@@ -24,6 +25,9 @@
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * 场所从业人员 服务实现类
@@ -40,4 +44,19 @@
 	}
 
 
+	/**
+	 * 统计少数民族和未成年数量
+	 * @return
+	 */
+	@Override
+	public Object countByType() {
+		// 未成年数量
+		Integer minors = baseMapper.selectPlaceCountByType(CommonConstant.NUMBER_ONE);
+		// 少数民族
+		Integer nationalMinority = baseMapper.selectPlaceCountByType(CommonConstant.NUMBER_TWO);
+		Map<String, Integer> resultMap = new HashMap<>();
+		resultMap.put("minors",minors);
+		resultMap.put("nationalMinority",nationalMinority);
+		return resultMap;
+	}
 }
diff --git a/src/main/java/org/springblade/modules/place/vo/PlacePractitionerVO.java b/src/main/java/org/springblade/modules/place/vo/PlacePractitionerVO.java
index faa452a..fc5c0f0 100644
--- a/src/main/java/org/springblade/modules/place/vo/PlacePractitionerVO.java
+++ b/src/main/java/org/springblade/modules/place/vo/PlacePractitionerVO.java
@@ -16,6 +16,7 @@
  */
 package org.springblade.modules.place.vo;
 
+import io.swagger.annotations.ApiModelProperty;
 import org.springblade.modules.place.entity.PlacePractitionerEntity;
 import org.springblade.core.tool.node.INode;
 import lombok.Data;
@@ -32,4 +33,7 @@
 public class PlacePractitionerVO extends PlacePractitionerEntity {
 	private static final long serialVersionUID = 1L;
 
+	@ApiModelProperty(value = "类型1:未成年 2:少数民族 3:包含1和2", example = "")
+	private Integer type;
+
 }

--
Gitblit v1.9.3