Ver código fonte

Merge branch 'dev' of http://gogs.gzzzyd.com/pangqijun/vending-machine-api into dev

LuoDLeo 7 meses atrás
pai
commit
4f033d26ca
29 arquivos alterados com 754 adições e 21 exclusões
  1. 7 2
      DockerfileTest
  2. 20 0
      src/main/java/org/springblade/common/config/LocalTimeDeserializer.java
  3. 48 0
      src/main/java/org/springblade/modules/api/controller/ApiMerchantUserController.java
  4. 21 0
      src/main/java/org/springblade/modules/api/controller/ApiShopController.java
  5. 58 4
      src/main/java/org/springblade/modules/api/controller/LoginController.java
  6. 49 0
      src/main/java/org/springblade/modules/api/request/MerchantRegisterRequest.java
  7. 5 0
      src/main/java/org/springblade/modules/auth/enums/UserEnum.java
  8. 2 0
      src/main/java/org/springblade/modules/auth/granter/PasswordTokenGranter.java
  9. 1 1
      src/main/java/org/springblade/modules/business/controller/ShopController.java
  10. 1 1
      src/main/java/org/springblade/modules/business/dto/ShopDTO.java
  11. 26 3
      src/main/java/org/springblade/modules/business/entity/Shop.java
  12. 1 1
      src/main/java/org/springblade/modules/business/mapper/ShopMapper.java
  13. 2 0
      src/main/java/org/springblade/modules/business/mapper/ShopMapper.xml
  14. 1 1
      src/main/java/org/springblade/modules/business/service/IShopService.java
  15. 1 1
      src/main/java/org/springblade/modules/business/service/impl/ShopServiceImpl.java
  16. 5 1
      src/main/java/org/springblade/modules/business/vo/ShopVO.java
  17. 1 1
      src/main/java/org/springblade/modules/business/wrapper/ShopWrapper.java
  18. 129 0
      src/main/java/org/springblade/modules/system/controller/UserMerchantController.java
  19. 34 0
      src/main/java/org/springblade/modules/system/dto/UserMerchantDTO.java
  20. 65 0
      src/main/java/org/springblade/modules/system/entity/UserMerchant.java
  21. 42 0
      src/main/java/org/springblade/modules/system/mapper/UserMerchantMapper.java
  22. 21 0
      src/main/java/org/springblade/modules/system/mapper/UserMerchantMapper.xml
  23. 48 0
      src/main/java/org/springblade/modules/system/service/IUserMerchantService.java
  24. 49 0
      src/main/java/org/springblade/modules/system/service/impl/UserMerchantServiceImpl.java
  25. 52 0
      src/main/java/org/springblade/modules/system/vo/UserMerchantVO.java
  26. 49 0
      src/main/java/org/springblade/modules/system/wrapper/UserMerchantWrapper.java
  27. 5 5
      src/main/java/sql/shop.menu.mysql
  28. 10 0
      src/main/java/sql/usermerchant.menu.mysql
  29. 1 0
      src/main/resources/application.yml

+ 7 - 2
DockerfileTest

@@ -1,7 +1,12 @@
-#FROM openjdk:8-jdk-alpine
-FROM java:8
+FROM frolvlad/alpine-java:jdk8-slim
+
 ENV LANG en_US.utf8
 ADD target/vend-api.jar /app.jar
 EXPOSE 8802
+
+RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+
+RUN echo 'Asia/Shanghai' >/etc/timezone
+
 # 运行jar包
 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=test","-Dfile.encoding=UTF-8","-jar","/app.jar"]

+ 20 - 0
src/main/java/org/springblade/common/config/LocalTimeDeserializer.java

@@ -0,0 +1,20 @@
+package org.springblade.common.config;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+
+import java.io.IOException;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+
+public class LocalTimeDeserializer extends JsonDeserializer<LocalTime> {
+
+    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
+
+    @Override
+    public LocalTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+        return LocalTime.parse(p.getValueAsString(), formatter);
+    }
+}

+ 48 - 0
src/main/java/org/springblade/modules/api/controller/ApiMerchantUserController.java

@@ -0,0 +1,48 @@
+package org.springblade.modules.api.controller;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.modules.system.entity.User;
+import org.springblade.modules.system.entity.UserMerchant;
+import org.springblade.modules.system.service.IUserMerchantService;
+import org.springblade.modules.system.service.IUserService;
+import org.springblade.modules.system.vo.UserMerchantVO;
+import org.springframework.util.Assert;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Author pangqijun
+ * Date 2024/7/16
+ * Description
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping(CommonConstant.API_URL)
+@Api(value = "商家端", tags = "商家端用户接口")
+public class ApiMerchantUserController {
+
+    private final IUserMerchantService iUserMerchantService;
+    private final IUserService iUserService;
+
+    @GetMapping("/merchant/get")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "获取商家用户信息")
+    public R<UserMerchantVO> getMerchantUserInfo() {
+        User user = iUserService.getById(AuthUtil.getUserId());
+        Assert.notNull(user, "未查询到用户信息");
+        UserMerchantVO vo = iUserMerchantService.getByUserId(user.getId());
+        vo.setAvatar(user.getAvatar());
+        vo.setMerchantName(user.getName());
+        vo.setRealName(vo.getRealName());
+        vo.setPhone(user.getPhone());
+        return R.data(vo);
+    }
+}

+ 21 - 0
src/main/java/org/springblade/modules/api/controller/ApiShopController.java

@@ -1,12 +1,17 @@
 package org.springblade.modules.api.controller;
 
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
 import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.DistanceUtils;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.secure.utils.AuthUtil;
@@ -19,6 +24,7 @@ import org.springblade.modules.business.wrapper.ShopWrapper;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.util.List;
 
 @RestController
 @AllArgsConstructor
@@ -73,4 +79,19 @@ public class ApiShopController {
         return R.status(iShopService.removeByIds(Func.toLongList(ids)));
     }
 
+    /**
+     * 小程序查询所有门店,并返回距离
+     */
+    @GetMapping("/all")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "查询门店列表", notes = "经度纬度")
+    public R<List<ShopVO>> all(@ApiParam(value = "经度", required = true) @RequestParam Double longitude,
+                               @ApiParam(value = "纬度", required = true) @RequestParam Double latitude) {
+        List<Shop> pages = iShopService.list(Wrappers.lambdaQuery(Shop.class).eq(Shop::getBusinessStatus, 1));
+        List<ShopVO> shopVOS = ShopWrapper.build().listVO(pages);
+        for (ShopVO shopVO : shopVOS) {
+            shopVO.setDistance(DistanceUtils.getDistance(longitude, latitude, shopVO.getLongitude(), shopVO.getLatitude()));
+        }
+        return R.data(shopVOS);
+    }
 }

+ 58 - 4
src/main/java/org/springblade/modules/api/controller/LoginController.java

@@ -17,6 +17,7 @@
 package org.springblade.modules.api.controller;
 
 import cn.hutool.core.util.DesensitizedUtil;
+import cn.hutool.core.util.IdcardUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.PhoneUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -42,7 +43,9 @@ import org.springblade.core.sms.model.SmsCode;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.support.Kv;
 import org.springblade.core.tool.utils.*;
+import org.springblade.modules.api.request.MerchantRegisterRequest;
 import org.springblade.modules.auth.enums.UserEnum;
+import org.springblade.modules.auth.granter.PasswordTokenGranter;
 import org.springblade.modules.auth.provider.ITokenGranter;
 import org.springblade.modules.auth.provider.TokenGranterBuilder;
 import org.springblade.modules.auth.provider.TokenParameter;
@@ -56,6 +59,8 @@ import org.springblade.modules.resource.builder.sms.SmsBuilder;
 import org.springblade.modules.system.entity.User;
 import org.springblade.modules.system.entity.UserApp;
 import org.springblade.modules.system.entity.UserInfo;
+import org.springblade.modules.system.entity.UserMerchant;
+import org.springblade.modules.system.service.IUserMerchantService;
 import org.springblade.modules.system.service.IUserService;
 import org.springblade.modules.system.service.IUserWeChatService;
 import org.springframework.transaction.annotation.Transactional;
@@ -63,6 +68,7 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
 
 import static org.springblade.core.cache.constant.CacheConstant.USER_CACHE;
 import static org.springblade.modules.resource.utils.SmsUtil.VALIDATE_FAIL;
@@ -87,6 +93,7 @@ public class LoginController extends BladeController {
 	private final JwtProperties jwtProperties;
 	private final UserAppService userAppService;
 	private final IUserWeChatService userWeChatService;
+	private final IUserMerchantService iUserMerchantService;
 
 	@ApiLog("用户注册")
 	@PostMapping("/user-register")
@@ -155,6 +162,7 @@ public class LoginController extends BladeController {
 			userScores.setDataType(1);
 			userScores.setDataRemarks(dataRemarks);
 			userScoresService.save(userScores);
+
 			//修改用户信誉积分
 			UserApp userAppUpdate = new UserApp();
 			userAppUpdate.setId(userAppQuery.getId());
@@ -195,17 +203,16 @@ public class LoginController extends BladeController {
 						  @ApiParam(value = "微信小程序code") @RequestParam(required = false) String code) {
 
 		String tenantId = WebUtil.getRequest().getHeader(TokenUtil.TENANT_HEADER_KEY);
-		String grantType = WebUtil.getRequest().getParameter("grant_type");
 		String refreshToken = WebUtil.getRequest().getParameter("refresh_token");
 		String userType = Func.toStr(WebUtil.getRequest().getHeader(TokenUtil.USER_TYPE_HEADER_KEY), UserEnum.APP.getName());
 		TokenParameter tokenParameter = new TokenParameter();
 		tokenParameter.getArgs().set("tenantId", tenantId)
 			.set("username", username)
-			.set("password", DigestUtil.md5Hex(password))
-			.set("grantType", grantType)
+			.set("password", password)
+			.set("grantType", PasswordTokenGranter.GRANT_TYPE)
 			.set("refreshToken", refreshToken)
 			.set("userType", userType);
-		ITokenGranter granter = TokenGranterBuilder.getGranter(grantType);
+		ITokenGranter granter = TokenGranterBuilder.getGranter(PasswordTokenGranter.GRANT_TYPE);
 		UserInfo userInfo = granter.grant(tokenParameter);
 		if (userInfo == null || userInfo.getUser() == null) {
 			return R.fail("用户名或密码不正确");
@@ -322,6 +329,53 @@ public class LoginController extends BladeController {
 		return R.success("退出成功");
 	}
 
+	@ApiLog("商家注册")
+	@PostMapping("/merchant-register")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "商家注册", notes = "商家注册")
+	@Transactional
+	public R<Void> merchantRegister(@Valid @RequestBody MerchantRegisterRequest request) {
+		if (!PhoneUtil.isPhone(request.getPhone())){
+			return R.fail("请输入正确的手机号!");
+		}
+		if (!IdcardUtil.isValidCard(request.getIdCard())) {
+			return R.fail("请输入正确的身份证号!");
+		}
+		if (!request.getPassword().equals(request.getRePassword())) {
+			return R.fail("密码不一致");
+		}
+		User query1 = userService.getOne(Wrappers.<User>query().lambda().eq(User::getAccount, request.getPhone()));
+		if (query1 != null){
+			return R.fail("手机号已注册!");
+		}
+		boolean flg = captchaCode(request.getPhone(), request.getCaptchaId(), request.getCaptchaCode());
+		if (!flg){
+			return R.fail(VALIDATE_FAIL);
+		}
+		String tenantId = WebUtil.getRequest().getHeader(TokenUtil.TENANT_HEADER_KEY);
+		User user = new User();
+		user.setAccount(request.getPhone());
+		user.setPhone(request.getPhone());
+		user.setTenantId(tenantId);
+		user.setUserType(UserEnum.MERCHANT.getCategory());
+		user.setPassword(DigestUtil.encrypt(request.getPassword()));
+		user.setName(request.getMerchantName());
+		user.setRealName(request.getName());
+		userService.save(user);
+
+		UserMerchant userMerchant = new UserMerchant();
+		userMerchant.setUserId(user.getId());
+		userMerchant.setAddress(request.getAddress());
+		userMerchant.setIdCard(request.getIdCard());
+		userMerchant.setBusinessLicence(request.getBusinessLicence());
+		userMerchant.setParentId(0L);
+		iUserMerchantService.save(userMerchant);
+
+		return R.success("注册成功");
+	}
+
+
+
 	private boolean captchaCode(String phone, String captchaId, String captchaCode){
 		String key = "blade:sms::captcha:" + phone + ":" + captchaId;
 		String cache = bladeRedis.get(key);

+ 49 - 0
src/main/java/org/springblade/modules/api/request/MerchantRegisterRequest.java

@@ -0,0 +1,49 @@
+package org.springblade.modules.api.request;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class MerchantRegisterRequest {
+    @NotBlank(message = "身份证号不能为空")
+    @ApiModelProperty(value = "身份证号")
+    private String idCard;
+
+    @NotBlank(message = "营业执照不能为空")
+    @ApiModelProperty(value = "营业执照")
+    private String businessLicence;
+
+    @NotBlank(message = "地址不能为空")
+    @ApiModelProperty(value = "地址")
+    private String address;
+
+    @NotBlank(message = "手机号不能为空")
+    @ApiModelProperty(value = "手机号")
+    private String phone;
+
+    @NotBlank(message = "姓名不能为空")
+    @ApiModelProperty(value = "姓名")
+    private String name;
+
+    @NotBlank(message = "商户名称不能为空")
+    @ApiModelProperty(value = "商户名称")
+    private String merchantName;
+
+    @NotBlank(message = "密码不能为空")
+    @ApiModelProperty(value = "密码")
+    private String password;
+
+    @NotBlank(message = "确认密码不能为空")
+    @ApiModelProperty(value = "确认密码")
+    private String rePassword;
+
+    @NotBlank(message = "验证码不能为空")
+    @ApiModelProperty(value = "验证码")
+    private String captchaCode;
+
+    @NotBlank(message = "验证ID不能为空")
+    @ApiModelProperty(value = "验证ID, 发送验证码返回的ID")
+    private String captchaId;
+}

+ 5 - 0
src/main/java/org/springblade/modules/auth/enums/UserEnum.java

@@ -42,6 +42,11 @@ public enum UserEnum {
 	 * other
 	 */
 	OTHER("other", 3),
+
+	/**
+	 * 商家
+	 */
+	MERCHANT("merchant", 4),
 	;
 
 	final String name;

+ 2 - 0
src/main/java/org/springblade/modules/auth/granter/PasswordTokenGranter.java

@@ -92,6 +92,8 @@ public class PasswordTokenGranter implements ITokenGranter {
 				userInfo = userService.userInfo(tenantId, username, DigestUtil.hex(password), UserEnum.WEB);
 			} else if (userType.equals(UserEnum.APP.getName())) {
 				userInfo = userService.userInfo(tenantId, username, DigestUtil.hex(password), UserEnum.APP);
+			} else if (userType.equals(UserEnum.MERCHANT.getName())) {
+				userInfo = userService.userInfo(tenantId, username, DigestUtil.hex(password), UserEnum.MERCHANT);
 			} else {
 				userInfo = userService.userInfo(tenantId, username, DigestUtil.hex(password), UserEnum.OTHER);
 			}

+ 1 - 1
src/main/java/org/springblade/modules/business/controller/ShopController.java

@@ -40,7 +40,7 @@ import org.springblade.core.boot.ctrl.BladeController;
  * 门店表 控制器
  *
  * @author BladeX
- * @since 2024-07-15
+ * @since 2024-07-16
  */
 @RestController
 @AllArgsConstructor

+ 1 - 1
src/main/java/org/springblade/modules/business/dto/ShopDTO.java

@@ -24,7 +24,7 @@ import lombok.EqualsAndHashCode;
  * 门店表数据传输对象实体类
  *
  * @author BladeX
- * @since 2024-07-15
+ * @since 2024-07-16
  */
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 26 - 3
src/main/java/org/springblade/modules/business/entity/Shop.java

@@ -1,19 +1,24 @@
 package org.springblade.modules.business.entity;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import org.springblade.common.base.BaseEntity;
 import com.baomidou.mybatisplus.annotation.TableName;
+import java.time.LocalTime;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import org.springblade.common.config.LocalTimeDeserializer;
 
 import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 
 /**
  * 门店表实体类
  *
  * @author zzyd
- * @since 2024-07-15
+ * @since 2024-07-16
  */
 @Data
 @TableName("t_shop")
@@ -26,33 +31,37 @@ public class Shop extends BaseEntity {
 	/**
 	* 门店名称
 	*/
-	@NotBlank(message = "请输入门店名称")
 	@ApiModelProperty(value = "门店名称")
+	@NotBlank(message = "门店名称不能为空")
 	private String storeName;
 	/**
 	* 门店图片
 	*/
+	@NotBlank(message = "门店图片不能为空")
 	@ApiModelProperty(value = "门店图片")
 	private String storeImage;
 	/**
 	* 门店地址
 	*/
+	@NotBlank(message = "门店地址不能为空")
 	@ApiModelProperty(value = "门店地址")
 	private String address;
 	/**
 	* 经度
 	*/
+	@NotNull(message = "经度不能为空")
 	@ApiModelProperty(value = "经度")
 	private Double longitude;
 	/**
 	* 纬度
 	*/
+	@NotNull(message = "纬度不能为空")
 	@ApiModelProperty(value = "纬度")
 	private Double latitude;
 	/**
 	* 所属商家id
 	*/
-	@ApiModelProperty(value = "所属商家id", hidden = true)
+	@ApiModelProperty(value = "所属商家id")
 	private Long merchantId;
 	/**
 	* 店长姓名
@@ -74,6 +83,20 @@ public class Shop extends BaseEntity {
 	*/
 	@ApiModelProperty(value = "营业执照")
 	private String businessLicence;
+	/**
+	* 营业开始时间
+	*/
+	@JsonDeserialize(using = LocalTimeDeserializer.class)
+	@ApiModelProperty(value = "营业开始时间")
+	@JsonFormat(pattern = "HH:mm")
+	private LocalTime openingHours;
+	/**
+	* 营业结束时间
+	*/
+	@JsonFormat(pattern = "HH:mm")
+	@JsonDeserialize(using = LocalTimeDeserializer.class)
+	@ApiModelProperty(value = "营业结束时间")
+	private LocalTime closingHours;
 
 
 }

+ 1 - 1
src/main/java/org/springblade/modules/business/mapper/ShopMapper.java

@@ -26,7 +26,7 @@ import java.util.List;
  * 门店表 Mapper 接口
  *
  * @author BladeX
- * @since 2024-07-15
+ * @since 2024-07-16
  */
 public interface ShopMapper extends BaseMapper<Shop> {
 

+ 2 - 0
src/main/java/org/springblade/modules/business/mapper/ShopMapper.xml

@@ -20,6 +20,8 @@
         <result column="manager_phone" property="managerPhone"/>
         <result column="business_status" property="businessStatus"/>
         <result column="business_licence" property="businessLicence"/>
+        <result column="opening_hours" property="openingHours"/>
+        <result column="closing_hours" property="closingHours"/>
     </resultMap>
 
 

+ 1 - 1
src/main/java/org/springblade/modules/business/service/IShopService.java

@@ -25,7 +25,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
  * 门店表 服务类
  *
  * @author BladeX
- * @since 2024-07-15
+ * @since 2024-07-16
  */
 public interface IShopService extends IService<Shop> {
 

+ 1 - 1
src/main/java/org/springblade/modules/business/service/impl/ShopServiceImpl.java

@@ -28,7 +28,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
  * 门店表 服务实现类
  *
  * @author BladeX
- * @since 2024-07-15
+ * @since 2024-07-16
  */
 @Service
 public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {

+ 5 - 1
src/main/java/org/springblade/modules/business/vo/ShopVO.java

@@ -25,7 +25,7 @@ import io.swagger.annotations.ApiModel;
  * 门店表视图实体类
  *
  * @author BladeX
- * @since 2024-07-15
+ * @since 2024-07-16
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -33,4 +33,8 @@ import io.swagger.annotations.ApiModel;
 public class ShopVO extends Shop {
 	private static final long serialVersionUID = 1L;
 
+	/**
+	 * 距离
+	 */
+	private double distance;
 }

+ 1 - 1
src/main/java/org/springblade/modules/business/wrapper/ShopWrapper.java

@@ -26,7 +26,7 @@ import java.util.Objects;
  * 门店表包装类,返回视图层所需的字段
  *
  * @author BladeX
- * @since 2024-07-15
+ * @since 2024-07-16
  */
 public class ShopWrapper extends BaseEntityWrapper<Shop, ShopVO>  {
 

+ 129 - 0
src/main/java/org/springblade/modules/system/controller/UserMerchantController.java

@@ -0,0 +1,129 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+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.Func;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestParam;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.modules.system.entity.UserMerchant;
+import org.springblade.modules.system.vo.UserMerchantVO;
+import org.springblade.modules.system.wrapper.UserMerchantWrapper;
+import org.springblade.modules.system.service.IUserMerchantService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ * 商家用户表 控制器
+ *
+ * @author BladeX
+ * @since 2024-07-16
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("system/usermerchant")
+@Api(value = "商家用户表", tags = "商家用户表接口")
+public class UserMerchantController extends BladeController {
+
+	private final IUserMerchantService userMerchantService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入userMerchant")
+	public R<UserMerchantVO> detail(UserMerchant userMerchant) {
+		UserMerchant detail = userMerchantService.getOne(Condition.getQueryWrapper(userMerchant));
+		return R.data(UserMerchantWrapper.build().entityVO(detail));
+	}
+
+	/**
+	 * 分页 商家用户表
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入userMerchant")
+	public R<IPage<UserMerchantVO>> list(UserMerchant userMerchant, Query query) {
+		IPage<UserMerchant> pages = userMerchantService.page(Condition.getPage(query), Condition.getQueryWrapper(userMerchant));
+		return R.data(UserMerchantWrapper.build().pageVO(pages));
+	}
+
+
+	/**
+	 * 自定义分页 商家用户表
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入userMerchant")
+	public R<IPage<UserMerchantVO>> page(UserMerchantVO userMerchant, Query query) {
+		IPage<UserMerchantVO> pages = userMerchantService.selectUserMerchantPage(Condition.getPage(query), userMerchant);
+		return R.data(pages);
+	}
+
+	/**
+	 * 新增 商家用户表
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入userMerchant")
+	public R save(@Valid @RequestBody UserMerchant userMerchant) {
+		return R.status(userMerchantService.save(userMerchant));
+	}
+
+	/**
+	 * 修改 商家用户表
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入userMerchant")
+	public R update(@Valid @RequestBody UserMerchant userMerchant) {
+		return R.status(userMerchantService.updateById(userMerchant));
+	}
+
+	/**
+	 * 新增或修改 商家用户表
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入userMerchant")
+	public R submit(@Valid @RequestBody UserMerchant userMerchant) {
+		return R.status(userMerchantService.saveOrUpdate(userMerchant));
+	}
+
+	
+	/**
+	 * 删除 商家用户表
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(userMerchantService.removeByIds(Func.toLongList(ids)));
+	}
+
+	
+}

+ 34 - 0
src/main/java/org/springblade/modules/system/dto/UserMerchantDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.dto;
+
+import org.springblade.modules.system.entity.UserMerchant;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 商家用户表数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2024-07-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class UserMerchantDTO extends UserMerchant {
+	private static final long serialVersionUID = 1L;
+
+}

+ 65 - 0
src/main/java/org/springblade/modules/system/entity/UserMerchant.java

@@ -0,0 +1,65 @@
+package org.springblade.modules.system.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import org.springblade.common.base.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * 商家用户表实体类
+ *
+ * @author zzyd
+ * @since 2024-07-16
+ */
+@Data
+@TableName("blade_user_merchant")
+@ApiModel(value = "UserMerchant对象", description = "商家用户表")
+public class UserMerchant implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	@JsonSerialize(using = ToStringSerializer.class)
+	@TableId(value = "id", type = IdType.ASSIGN_ID)
+	@ApiModelProperty(value = "主键")
+	protected Long id;
+	/**
+	* 用户id
+	*/
+	@ApiModelProperty(value = "用户id")
+	private Long userId;
+	/**
+	* 身份证号
+	*/
+	@ApiModelProperty(value = "身份证号")
+	private String idCard;
+	/**
+	* 营业执照
+	*/
+	@ApiModelProperty(value = "营业执照")
+	private String businessLicence;
+	/**
+	* 地址
+	*/
+	@ApiModelProperty(value = "地址")
+	private String address;
+	/**
+	* 父id
+	*/
+	@ApiModelProperty(value = "父id")
+	private Long parentId;
+	/**
+	* 授权菜单
+	*/
+	@ApiModelProperty(value = "授权菜单")
+	private String authMenu;
+
+
+}

+ 42 - 0
src/main/java/org/springblade/modules/system/mapper/UserMerchantMapper.java

@@ -0,0 +1,42 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.mapper;
+
+import org.springblade.modules.system.entity.UserMerchant;
+import org.springblade.modules.system.vo.UserMerchantVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 商家用户表 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2024-07-16
+ */
+public interface UserMerchantMapper extends BaseMapper<UserMerchant> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param userMerchant
+	 * @return
+	 */
+	List<UserMerchantVO> selectUserMerchantPage(IPage page, UserMerchantVO userMerchant);
+
+}

+ 21 - 0
src/main/java/org/springblade/modules/system/mapper/UserMerchantMapper.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.modules.system.mapper.UserMerchantMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="userMerchantResultMap" type="org.springblade.modules.system.entity.UserMerchant">
+        <result column="id" property="id"/>
+        <result column="user_id" property="userId"/>
+        <result column="id_card" property="idCard"/>
+        <result column="business_licence" property="businessLicence"/>
+        <result column="address" property="address"/>
+        <result column="parent_id" property="parentId"/>
+        <result column="auth_menu" property="authMenu"/>
+    </resultMap>
+
+
+    <select id="selectUserMerchantPage" resultMap="userMerchantResultMap">
+        select * from blade_user_merchant where is_delete = 0
+    </select>
+
+</mapper>

+ 48 - 0
src/main/java/org/springblade/modules/system/service/IUserMerchantService.java

@@ -0,0 +1,48 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.service;
+
+import org.springblade.modules.system.entity.UserMerchant;
+import org.springblade.modules.system.vo.UserMerchantVO;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 商家用户表 服务类
+ *
+ * @author BladeX
+ * @since 2024-07-16
+ */
+public interface IUserMerchantService extends IService<UserMerchant> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param userMerchant
+	 * @return
+	 */
+	IPage<UserMerchantVO> selectUserMerchantPage(IPage<UserMerchantVO> page, UserMerchantVO userMerchant);
+
+	/**
+	 * 根据用户id查询商户信息
+	 * @param userId 用户id
+	 * @return UserMerchantVO
+	 */
+	UserMerchantVO getByUserId(Long userId);
+
+}

+ 49 - 0
src/main/java/org/springblade/modules/system/service/impl/UserMerchantServiceImpl.java

@@ -0,0 +1,49 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.springblade.modules.system.entity.UserMerchant;
+import org.springblade.modules.system.vo.UserMerchantVO;
+import org.springblade.modules.system.mapper.UserMerchantMapper;
+import org.springblade.modules.system.service.IUserMerchantService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.modules.system.wrapper.UserMerchantWrapper;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 商家用户表 服务实现类
+ *
+ * @author BladeX
+ * @since 2024-07-16
+ */
+@Service
+public class UserMerchantServiceImpl extends ServiceImpl<UserMerchantMapper, UserMerchant> implements IUserMerchantService {
+
+	@Override
+	public IPage<UserMerchantVO> selectUserMerchantPage(IPage<UserMerchantVO> page, UserMerchantVO userMerchant) {
+		return page.setRecords(baseMapper.selectUserMerchantPage(page, userMerchant));
+	}
+
+	@Override
+	public UserMerchantVO getByUserId(Long userId) {
+		UserMerchant one = getOne(Wrappers.lambdaQuery(UserMerchant.class).eq(UserMerchant::getUserId, userId));
+		return UserMerchantWrapper.build().entityVO(one);
+	}
+
+}

+ 52 - 0
src/main/java/org/springblade/modules/system/vo/UserMerchantVO.java

@@ -0,0 +1,52 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.vo;
+
+import org.springblade.modules.system.entity.UserMerchant;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * 商家用户表视图实体类
+ *
+ * @author BladeX
+ * @since 2024-07-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "UserMerchantVO对象", description = "商家用户表")
+public class UserMerchantVO extends UserMerchant {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 商户名称
+	 */
+	private String merchantName;
+	/**
+	 * 姓名
+	 */
+	private String realName;
+	/**
+	 * 头像
+	 */
+	private String avatar;
+	/**
+	 * 手机
+	 */
+	private String phone;
+}

+ 49 - 0
src/main/java/org/springblade/modules/system/wrapper/UserMerchantWrapper.java

@@ -0,0 +1,49 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.wrapper;
+
+import org.springblade.core.mp.support.BaseEntityWrapper;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.modules.system.entity.UserMerchant;
+import org.springblade.modules.system.vo.UserMerchantVO;
+import java.util.Objects;
+
+/**
+ * 商家用户表包装类,返回视图层所需的字段
+ *
+ * @author BladeX
+ * @since 2024-07-16
+ */
+public class UserMerchantWrapper extends BaseEntityWrapper<UserMerchant, UserMerchantVO>  {
+
+	public static UserMerchantWrapper build() {
+		return new UserMerchantWrapper();
+ 	}
+
+	@Override
+	public UserMerchantVO entityVO(UserMerchant userMerchant) {
+		UserMerchantVO userMerchantVO = Objects.requireNonNull(BeanUtil.copy(userMerchant, UserMerchantVO.class));
+
+		//User createUser = UserCache.getUser(userMerchant.getCreateUser());
+		//User updateUser = UserCache.getUser(userMerchant.getUpdateUser());
+		//userMerchantVO.setCreateUserName(createUser.getName());
+		//userMerchantVO.setUpdateUserName(updateUser.getName());
+
+		return userMerchantVO;
+	}
+
+}

+ 5 - 5
src/main/java/sql/shop.menu.mysql

@@ -1,10 +1,10 @@
 INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
-VALUES ('1812844618044239878', 1123598815738675201, 'shop', '门店信息', 'menu', '/business/shop', NULL, 1, 1, 0, 1, NULL, 0);
+VALUES ('1813037051004706823', 1123598815738675201, 'shop', '门店信息', 'menu', '/business/shop', NULL, 1, 1, 0, 1, NULL, 0);
 INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
-VALUES ('1812844618044239879', '1812844618044239878', 'shop_add', '新增', 'add', '/business/shop/add', 'plus', 1, 2, 1, 1, NULL, 0);
+VALUES ('1813037051004706824', '1813037051004706823', 'shop_add', '新增', 'add', '/business/shop/add', 'plus', 1, 2, 1, 1, NULL, 0);
 INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
-VALUES ('1812844618044239880', '1812844618044239878', 'shop_edit', '修改', 'edit', '/business/shop/edit', 'form', 2, 2, 2, 1, NULL, 0);
+VALUES ('1813037051004706825', '1813037051004706823', 'shop_edit', '修改', 'edit', '/business/shop/edit', 'form', 2, 2, 2, 1, NULL, 0);
 INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
-VALUES ('1812844618044239881', '1812844618044239878', 'shop_delete', '删除', 'delete', '/api/business/shop/remove', 'delete', 3, 2, 3, 1, NULL, 0);
+VALUES ('1813037051004706826', '1813037051004706823', 'shop_delete', '删除', 'delete', '/api/business/shop/remove', 'delete', 3, 2, 3, 1, NULL, 0);
 INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
-VALUES ('1812844618044239882', '1812844618044239878', 'shop_view', '查看', 'view', '/business/shop/view', 'file-text', 4, 2, 2, 1, NULL, 0);
+VALUES ('1813037051004706827', '1813037051004706823', 'shop_view', '查看', 'view', '/business/shop/view', 'file-text', 4, 2, 2, 1, NULL, 0);

+ 10 - 0
src/main/java/sql/usermerchant.menu.mysql

@@ -0,0 +1,10 @@
+INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
+VALUES ('1813060589279272967', 1123598815738675201, 'usermerchant', '商家用户表', 'menu', '/system/usermerchant', NULL, 1, 1, 0, 1, NULL, 0);
+INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
+VALUES ('1813060589279272968', '1813060589279272967', 'usermerchant_add', '新增', 'add', '/system/usermerchant/add', 'plus', 1, 2, 1, 1, NULL, 0);
+INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
+VALUES ('1813060589279272969', '1813060589279272967', 'usermerchant_edit', '修改', 'edit', '/system/usermerchant/edit', 'form', 2, 2, 2, 1, NULL, 0);
+INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
+VALUES ('1813060589279272970', '1813060589279272967', 'usermerchant_delete', '删除', 'delete', '/api/system/usermerchant/remove', 'delete', 3, 2, 3, 1, NULL, 0);
+INSERT INTO `blade_menu`(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`)
+VALUES ('1813060589279272971', '1813060589279272967', 'usermerchant_view', '查看', 'view', '/system/usermerchant/view', 'file-text', 4, 2, 2, 1, NULL, 0);

+ 1 - 0
src/main/resources/application.yml

@@ -245,6 +245,7 @@ blade:
       - /blade-test/**
       - /v1/ads-list
       - /v1/user-register
+      - /v1/merchant-register
       - /v1/login_account
       - /v1/login/wx-auth
       - /v1/login_phone