diff --git a/project/.idea/.gitignore b/project/.idea/.gitignore
new file mode 100644
index 0000000..35410ca
--- /dev/null
+++ b/project/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/project/.idea/compiler.xml b/project/.idea/compiler.xml
new file mode 100644
index 0000000..223bafe
--- /dev/null
+++ b/project/.idea/compiler.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/.idea/dataSources.xml b/project/.idea/dataSources.xml
new file mode 100644
index 0000000..d0c0ef6
--- /dev/null
+++ b/project/.idea/dataSources.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ mysql.8
+ true
+ com.mysql.cj.jdbc.Driver
+ jdbc:mysql://localhost:3306
+
+
+
+
+
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/project/.idea/encodings.xml b/project/.idea/encodings.xml
new file mode 100644
index 0000000..8b47faa
--- /dev/null
+++ b/project/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/.idea/jarRepositories.xml b/project/.idea/jarRepositories.xml
new file mode 100644
index 0000000..abb532a
--- /dev/null
+++ b/project/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/.idea/misc.xml b/project/.idea/misc.xml
new file mode 100644
index 0000000..94ace4f
--- /dev/null
+++ b/project/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/.idea/modules.xml b/project/.idea/modules.xml
new file mode 100644
index 0000000..a0733a5
--- /dev/null
+++ b/project/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/.idea/project.iml b/project/.idea/project.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/project/.idea/project.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/.idea/uiDesigner.xml b/project/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/project/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/project/.idea/vcs.xml b/project/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/project/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/jiaqingjiayi/src/main/java/com/cj/jiaqingjiayi/controller/SpecificationsController.java b/project/jiaqingjiayi/src/main/java/com/cj/jiaqingjiayi/controller/SpecificationsController.java
new file mode 100644
index 0000000..fdb5021
--- /dev/null
+++ b/project/jiaqingjiayi/src/main/java/com/cj/jiaqingjiayi/controller/SpecificationsController.java
@@ -0,0 +1,152 @@
+package com.cj.jiaqingjiayi.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+import com.cj.jiaqingjiayi.common.BaseResponse;
+import com.cj.jiaqingjiayi.common.ErrorCode;
+import com.cj.jiaqingjiayi.common.ResultUtils;
+import com.cj.jiaqingjiayi.exception.BusinessException;
+import com.cj.jiaqingjiayi.exception.ThrowUtils;
+import com.cj.jiaqingjiayi.model.domain.Business;
+import com.cj.jiaqingjiayi.model.domain.Specifications;
+
+import com.cj.jiaqingjiayi.model.domain.SpecificationsCommodities;
+import com.cj.jiaqingjiayi.model.request.attribute.AttributeAddRequest;
+import com.cj.jiaqingjiayi.model.request.attribute.AttributeUpdateRequest;
+import com.cj.jiaqingjiayi.model.request.specifications.SpecificationsAddRequest;
+import com.cj.jiaqingjiayi.model.request.specifications.SpecificationsMyQueryRequest;
+import com.cj.jiaqingjiayi.model.request.specifications.SpecificationsQueryRequest;
+import com.cj.jiaqingjiayi.model.request.specifications.SpecificationsUpdateRequest;
+import com.cj.jiaqingjiayi.model.vo.SpecificationsVO;
+import com.cj.jiaqingjiayi.service.*;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.transaction.annotation.Transactional;
+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 javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/specifications")
+public class SpecificationsController {
+
+ @Resource
+ private SpecificationsService specificationsService;
+
+ @Resource
+ private SpecificationsCommoditiesService specificationsCommoditiesService;
+
+ @Resource
+ private BusinessService businessService;
+
+ @Resource
+ private AttributeService attributeService;
+
+ @Resource
+ private UserService userService;
+
+ /**
+ * 添加规格
+ * @param specificationsAddRequest 添加请求体
+ * @param request 网络请求
+ * @return 是否成功
+ */
+ @PostMapping("/add")
+ @Transactional(rollbackFor = Exception.class)
+ public BaseResponse addSpecifications(@RequestBody SpecificationsAddRequest specificationsAddRequest, HttpServletRequest request){
+ //判断是否为商家
+ userService.isBusiness(request);
+
+ if (specificationsAddRequest == null) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR);
+ }
+
+ Specifications specifications = new Specifications();
+ BeanUtils.copyProperties(specificationsAddRequest,specifications);
+ //校验请求体
+ specificationsService.validSpecifications(specifications, false);
+ //添加规格和属性
+ List attributeAddRequests = specificationsAddRequest.getAttributeAddRequests();
+ Boolean aBoolean = specificationsService.addSpecifications(specifications, attributeAddRequests, request);
+ ThrowUtils.throwIf(!aBoolean, ErrorCode.OPERATION_ERROR);
+ return ResultUtils.success(true);
+ }
+
+ /**·
+ * 更新规格
+ * @param specificationsUpdateRequest 更新请求体
+ * @param request 网络请求
+ * @return 是否成功
+ */
+ @PostMapping("/update")
+ @Transactional(rollbackFor = Exception.class)
+ public BaseResponse updateSpecifications(@RequestBody SpecificationsUpdateRequest specificationsUpdateRequest, HttpServletRequest request) {
+ //判断是否为商家
+ userService.isBusiness(request);
+
+ if (specificationsUpdateRequest == null) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR);
+ }
+
+ Specifications specifications = new Specifications();
+ BeanUtils.copyProperties(specificationsUpdateRequest,specifications);
+ //校验
+ specificationsService.validSpecifications(specifications,true);
+
+ //更新规格和属性
+ List attributeUpdateRequests = specificationsUpdateRequest.getAttributeUpdateRequests();
+ Boolean aBoolean = specificationsService.updateSpecifications(specifications, attributeUpdateRequests, request);
+ ThrowUtils.throwIf(!aBoolean, ErrorCode.OPERATION_ERROR);
+ return ResultUtils.success(true);
+ }
+
+ /**
+ * 根据菜品id获取规格脱敏信息
+ * @param specificationsMyQueryRequest 请求体
+ * @return 脱敏列表
+ */
+ @PostMapping("/list/specificationsVOByComId")
+ public BaseResponse> specificationsVOByComId(@RequestBody SpecificationsMyQueryRequest specificationsMyQueryRequest) {
+ if (specificationsMyQueryRequest == null) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR);
+ }
+ Long commoditiesId = specificationsMyQueryRequest.getId();
+ //根据id获取中间表数据
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("commoditiesId",commoditiesId);
+ List list = specificationsCommoditiesService.list(queryWrapper);
+ //根据中间表数据中的规格获取规格信息和属性
+ return ResultUtils.success(specificationsCommoditiesService.getSpecificationsAddAttribute(list));
+ }
+
+ /**
+ * 获取脱敏列表
+ * @param specificationsQueryRequest 前端请求
+ * @param request 网络请求
+ * @return 脱敏列表
+ */
+ @PostMapping("/list/specificationsVO")
+ public BaseResponse> specificationsVOList(@RequestBody SpecificationsQueryRequest specificationsQueryRequest, HttpServletRequest request) {
+ //获取商家id
+ Business loginBusiness = businessService.getLoginBusiness(request);
+ Long businessId = loginBusiness.getId();
+ //获取商家的规格表
+ String specificationsName = specificationsQueryRequest.getSpecificationsName();
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.like(StringUtils.isNotBlank(specificationsName), "specificationsName", specificationsName);
+ queryWrapper.eq("businessId",businessId);
+ List list = specificationsService.list(queryWrapper);
+ //对规格信息脱敏
+ List specificationsVO = specificationsService.getSpecificationsVO(list);
+ //获取各规格的属性脱敏信息
+ return ResultUtils.success(attributeService.getBySpecificationsVoId(specificationsVO));
+ }
+}
diff --git a/project/jiaqingjiayi/src/main/java/com/cj/jiaqingjiayi/model/request/manicurist/ManicuristAddRequest.java b/project/jiaqingjiayi/src/main/java/com/cj/jiaqingjiayi/model/request/manicurist/ManicuristAddRequest.java
new file mode 100644
index 0000000..a7eb16b
--- /dev/null
+++ b/project/jiaqingjiayi/src/main/java/com/cj/jiaqingjiayi/model/request/manicurist/ManicuristAddRequest.java
@@ -0,0 +1,55 @@
+package com.cj.jiaqingjiayi.model.request.manicurist;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+public class ManicuristAddRequest implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1396365359119727782L;
+
+ /**
+ * 美甲师姓名
+ */
+ private String name;
+
+ /**
+ * 性别
+ */
+ private Integer gender;
+
+ /**
+ * 美甲师联系电话
+ */
+ private String phone;
+
+ /**
+ * 美甲师电子邮件
+ */
+ private String email;
+
+ /**
+ * 美甲师的专长(如法式美甲、彩绘等)
+ */
+ private String specialties;
+
+ /**
+ * 认证编号
+ */
+ private String certification_number;
+
+ /**
+ * 发证机构
+ */
+ private String issuing_authority;
+
+ /**
+ * 证书文件的存储路径或链接
+ */
+ private String certificate_path;
+
+}