Sfoglia il codice sorgente

feat(store): 添加合同管理功能模块

- 创建StoreContractController提供合同管理REST API接口
- 实现合同列表分页查询、详情查看、新增、更新、删除功能
- 添加合同签署功能及签署状态查询接口
- 创建StoreContractMapper数据访问层及对应的XML映射文件
- 定义StoreContractQueryDto查询参数对象和StoreContractVo视图对象
- 实现StoreContractService业务接口及StoreContractServiceImpl具体逻辑
- 支持按合同名称、状态、店铺ID等条件进行模糊查询
- 集成MyBatis-Plus分页插件实现高效的数据分页处理
fcw 2 mesi fa
parent
commit
c2e0c95b22

+ 93 - 0
alien-entity/src/main/java/shop/alien/entity/store/StoreContract.java

@@ -0,0 +1,93 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 合同表
+ *
+ * @author alien
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude
+@EqualsAndHashCode(callSuper = false)
+@TableName("store_contract")
+@ApiModel(value = "StoreContract对象", description = "合同表")
+public class StoreContract extends Model<StoreContract> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "店铺ID")
+    @TableField("store_id")
+    private Long storeId;
+
+    @ApiModelProperty(value = "商家店铺名称")
+    @TableField("store_name")
+    private String storeName;
+
+    @ApiModelProperty(value = "经营板块")
+    @TableField("business_segment")
+    private String businessSegment;
+
+    @ApiModelProperty(value = "商家姓名")
+    @TableField("merchant_name")
+    private String merchantName;
+
+    @ApiModelProperty(value = "联系电话")
+    @TableField("contact_phone")
+    private String contactPhone;
+
+    @ApiModelProperty(value = "签署状态(已签署,未签署,已到期)")
+    @TableField("signing_status")
+    private String signingStatus;
+
+    @ApiModelProperty(value = "合同URL")
+    @TableField("contract_url")
+    private String contractUrl;
+
+    @ApiModelProperty(value = "印章URL")
+    @TableField("seal_url")
+    private String sealUrl;
+
+    @ApiModelProperty(value = "签署时间")
+    @TableField("signing_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date signingTime;
+
+    @ApiModelProperty(value = "生效时间")
+    @TableField("effective_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date effectiveTime;
+
+    @ApiModelProperty(value = "到期时间")
+    @TableField("expiry_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date expiryTime;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "更新时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "删除标识, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+}
+

+ 35 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/StoreContractQueryDto.java

@@ -0,0 +1,35 @@
+package shop.alien.entity.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 合同查询DTO
+ *
+ * @author alien
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "StoreContractQueryDto对象", description = "合同查询DTO")
+public class StoreContractQueryDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "合同名称(模糊查询)")
+    private String contractName;
+
+    @ApiModelProperty(value = "合同状态(0:未签署, 1:已签署)")
+    private Integer status;
+
+    @ApiModelProperty(value = "店铺ID")
+    private Integer storeId;
+
+    @ApiModelProperty(value = "页码", required = true)
+    private Integer pageNum = 1;
+
+    @ApiModelProperty(value = "每页数量", required = true)
+    private Integer pageSize = 10;
+}
+

+ 31 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreContractVo.java

@@ -0,0 +1,31 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import shop.alien.entity.store.StoreContract;
+
+/**
+ * 合同 VO
+ *
+ * @author alien
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude
+@ApiModel(value = "StoreContractVo对象", description = "合同VO")
+public class StoreContractVo extends StoreContract {
+
+    @ApiModelProperty(value = "状态名称")
+    private String statusName;
+
+    @ApiModelProperty(value = "店铺名称")
+    private String storeName;
+
+    @ApiModelProperty(value = "签署人名称")
+    private String signedUserName;
+
+    private String status;
+}
+

+ 36 - 0
alien-entity/src/main/java/shop/alien/mapper/StoreContractMapper.java

@@ -0,0 +1,36 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import shop.alien.entity.store.StoreContract;
+import shop.alien.entity.store.vo.StoreContractVo;
+
+/**
+ * 合同 Mapper 接口
+ *
+ * @author alien
+ * @since 2025-01-XX
+ */
+@Mapper
+public interface StoreContractMapper extends BaseMapper<StoreContract> {
+
+    /**
+     * 分页查询合同列表
+     *
+     * @param page 分页对象
+     * @param contractName 合同名称(模糊查询)
+     * @param status 合同状态(0:未签署, 1:已签署)
+     * @param storeId 店铺ID
+     * @return 合同列表
+     */
+    IPage<StoreContractVo> selectContractPage(
+            Page<StoreContractVo> page,
+            @Param("contractName") String contractName,
+            @Param("status") Integer status,
+            @Param("storeId") Integer storeId
+    );
+}
+

+ 84 - 0
alien-entity/src/main/resources/mapper/StoreContractMapper.xml

@@ -0,0 +1,84 @@
+<?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="shop.alien.mapper.StoreContractMapper">
+
+    <!-- 通用结果映射 -->
+    <resultMap id="BaseResultMap" type="shop.alien.entity.store.StoreContract">
+        <id column="id" property="id" />
+        <result column="store_id" property="storeId" />
+        <result column="store_name" property="storeName" />
+        <result column="business_segment" property="businessSegment" />
+        <result column="merchant_name" property="merchantName" />
+        <result column="contact_phone" property="contactPhone" />
+        <result column="signing_status" property="signingStatus" />
+        <result column="contract_url" property="contractUrl" />
+        <result column="seal_url" property="sealUrl" />
+        <result column="signing_time" property="signingTime" />
+        <result column="effective_time" property="effectiveTime" />
+        <result column="expiry_time" property="expiryTime" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_time" property="updatedTime" />
+        <result column="delete_flag" property="deleteFlag" />
+    </resultMap>
+
+    <!-- VO结果映射 -->
+    <resultMap id="StoreContractVoResultMap" type="shop.alien.entity.store.vo.StoreContractVo">
+        <id column="id" property="id" />
+        <result column="store_id" property="storeId" />
+        <result column="store_name" property="storeName" />
+        <result column="business_segment" property="businessSegment" />
+        <result column="merchant_name" property="merchantName" />
+        <result column="contact_phone" property="contactPhone" />
+        <result column="signing_status" property="signingStatus" />
+        <result column="contract_url" property="contractUrl" />
+        <result column="seal_url" property="sealUrl" />
+        <result column="signing_time" property="signingTime" />
+        <result column="effective_time" property="effectiveTime" />
+        <result column="expiry_time" property="expiryTime" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_time" property="updatedTime" />
+        <result column="delete_flag" property="deleteFlag" />
+    </resultMap>
+
+    <!-- 基础字段 -->
+    <sql id="Base_Column_List">
+        id, store_id, store_name, business_segment, merchant_name, contact_phone,
+        signing_status, contract_url, seal_url, signing_time, effective_time,
+        expiry_time, created_time, updated_time, delete_flag
+    </sql>
+
+    <!-- 分页查询合同列表 -->
+    <select id="selectContractPage" resultMap="StoreContractVoResultMap">
+        SELECT
+            cm.id,
+            cm.store_id,
+            cm.store_name,
+            cm.business_segment,
+            cm.merchant_name,
+            cm.contact_phone,
+            cm.signing_status,
+            cm.contract_url,
+            cm.seal_url,
+            cm.signing_time,
+            cm.effective_time,
+            cm.expiry_time,
+            cm.created_time,
+            cm.updated_time,
+            cm.delete_flag
+        FROM store_contract cm
+        WHERE cm.delete_flag = 0
+        <if test="contractName != null and contractName != ''">
+            AND cm.store_name LIKE CONCAT('%', #{contractName}, '%')
+        </if>
+        <if test="status != null">
+            AND cm.signing_status = #{status}
+        </if>
+        <if test="storeId != null">
+            AND cm.store_id = #{storeId}
+        </if>
+        ORDER BY cm.created_time DESC
+    </select>
+
+</mapper>

+ 128 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/controller/StoreContractController.java

@@ -0,0 +1,128 @@
+package shop.alien.storeplatform.controller;
+
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.StoreContract;
+import shop.alien.entity.store.dto.StoreContractQueryDto;
+import shop.alien.entity.store.vo.StoreContractVo;
+import shop.alien.storeplatform.service.StoreContractService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 合同管理控制器
+ *
+ * @author alien
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"商家端-合同管理"})
+@ApiSort(4)
+@CrossOrigin
+@RestController
+@RequestMapping("/contract")
+@RequiredArgsConstructor
+public class StoreContractController {
+
+    private final StoreContractService storeContractService;
+
+    @ApiOperation("分页查询合同列表")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/list")
+    public R<IPage<StoreContractVo>> getContractList(@RequestBody StoreContractQueryDto queryDto) {
+        log.info("StoreContractController.getContractList?queryDto={}", queryDto);
+        return storeContractService.getContractList(queryDto);
+    }
+
+    @ApiOperation("根据合同名称搜索合同列表(分页)")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query", required = false, defaultValue = "1"),
+            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "int", paramType = "query", required = false, defaultValue = "10"),
+            @ApiImplicitParam(name = "contractName", value = "合同名称(模糊查询)", dataType = "String", paramType = "query", required = false),
+            @ApiImplicitParam(name = "status", value = "合同状态(0:未签署, 1:已签署)", dataType = "int", paramType = "query", required = false),
+            @ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "int", paramType = "query", required = false)
+    })
+    @GetMapping("/list")
+    public R<IPage<StoreContractVo>> getContractListByQuery(
+            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
+            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
+            @RequestParam(value = "contractName", required = false) String contractName,
+            @RequestParam(value = "status", required = false) Integer status,
+            @RequestParam(value = "storeId", required = false) Integer storeId) {
+        log.info("StoreContractController.getContractListByQuery?pageNum={}, pageSize={}, contractName={}, status={}, storeId={}",
+                pageNum, pageSize, contractName, status, storeId);
+
+        StoreContractQueryDto queryDto = new StoreContractQueryDto();
+        queryDto.setPageNum(pageNum);
+        queryDto.setPageSize(pageSize);
+        queryDto.setContractName(contractName);
+        queryDto.setStatus(status);
+        queryDto.setStoreId(storeId);
+
+        return storeContractService.getContractList(queryDto);
+    }
+
+    @ApiOperation("查询合同详情")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "合同ID", dataType = "int", paramType = "query", required = true)
+    })
+    @GetMapping("/detail")
+    public R<StoreContractVo> getContractDetail(@RequestParam("id") Integer id) {
+        log.info("StoreContractController.getContractDetail?id={}", id);
+        return storeContractService.getContractDetail(id);
+    }
+
+    @ApiOperation("新增合同")
+    @ApiOperationSupport(order = 4)
+    @PostMapping("/add")
+    public R<StoreContract> addContract(@RequestBody StoreContract contract) {
+        log.info("StoreContractController.addContract?contract={}", contract);
+        return storeContractService.addContract(contract);
+    }
+
+    @ApiOperation("更新合同")
+    @ApiOperationSupport(order = 5)
+    @PostMapping("/update")
+    public R<StoreContract> updateContract(@RequestBody StoreContract contract) {
+        log.info("StoreContractController.updateContract?contract={}", contract);
+        return storeContractService.updateContract(contract);
+    }
+
+    @ApiOperation("签署合同")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "合同ID", dataType = "long", paramType = "query", required = true)
+    })
+    @PostMapping("/sign")
+    public R<Boolean> signContract(@RequestParam("id") Long id) {
+        log.info("StoreContractController.signContract?id={}", id);
+        return storeContractService.signContract(id);
+    }
+
+    @ApiOperation("删除合同")
+    @ApiOperationSupport(order = 7)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "合同ID", dataType = "int", paramType = "query", required = true)
+    })
+    @PostMapping("/delete")
+    public R<Boolean> deleteContract(@RequestParam("id") Integer id) {
+        log.info("StoreContractController.deleteContract?id={}", id);
+        return storeContractService.deleteContract(id);
+    }
+
+    @ApiOperation("获取合同签署状态")
+    @ApiOperationSupport(order = 8)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "store_id", value = "店铺ID", dataType = "int", paramType = "query", required = true)
+    })
+    @GetMapping("/signingStatus")
+    public R<String> getSigningStatus(@RequestParam("store_id") Integer storeId) {
+        log.info("StoreContractController.getSigningStatus?storeId={}", storeId);
+        return storeContractService.getSigningStatus(storeId);
+    }
+}
+

+ 73 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/service/StoreContractService.java

@@ -0,0 +1,73 @@
+package shop.alien.storeplatform.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.StoreContract;
+import shop.alien.entity.store.dto.StoreContractQueryDto;
+import shop.alien.entity.store.vo.StoreContractVo;
+
+/**
+ * 合同服务接口
+ *
+ * @author alien
+ * @since 2025-01-XX
+ */
+public interface StoreContractService {
+
+    /**
+     * 分页查询合同列表
+     *
+     * @param queryDto 查询条件
+     * @return 分页结果
+     */
+    R<IPage<StoreContractVo>> getContractList(StoreContractQueryDto queryDto);
+
+    /**
+     * 根据ID查询合同详情
+     *
+     * @param id 合同ID
+     * @return 合同详情
+     */
+    R<StoreContractVo> getContractDetail(Integer id);
+
+    /**
+     * 新增合同
+     *
+     * @param contract 合同信息
+     * @return 操作结果
+     */
+    R<StoreContract> addContract(StoreContract contract);
+
+    /**
+     * 更新合同
+     *
+     * @param contract 合同信息
+     * @return 操作结果
+     */
+    R<StoreContract> updateContract(StoreContract contract);
+
+    /**
+     * 签署合同
+     *
+     * @param id 合同ID
+     * @return 操作结果
+     */
+    R<Boolean> signContract(Long id);
+
+    /**
+     * 删除合同(逻辑删除)
+     *
+     * @param id 合同ID
+     * @return 操作结果
+     */
+    R<Boolean> deleteContract(Integer id);
+
+    /**
+     * 获取合同的签署状态
+     *
+     * @param storeId 店铺ID
+     * @return 签署状态 (0:未签署, 1:已签署, 2:已到期)
+     */
+    R<String> getSigningStatus(Integer storeId);
+}
+

+ 243 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/StoreContractServiceImpl.java

@@ -0,0 +1,243 @@
+package shop.alien.storeplatform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.StoreContract;
+import shop.alien.entity.store.dto.StoreContractQueryDto;
+import shop.alien.entity.store.vo.StoreContractVo;
+import shop.alien.mapper.StoreContractMapper;
+import shop.alien.storeplatform.service.StoreContractService;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 合同服务实现类
+ *
+ * @author alien
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@Transactional
+public class StoreContractServiceImpl implements StoreContractService {
+
+    private final StoreContractMapper storeContractMapper;
+
+    @Override
+    public R<IPage<StoreContractVo>> getContractList(StoreContractQueryDto queryDto) {
+        try {
+            log.info("StoreContractServiceImpl.getContractList?queryDto={}", queryDto);
+
+            // 构建分页对象
+            Page<StoreContractVo> page = new Page<>(queryDto.getPageNum(), queryDto.getPageSize());
+
+            // 执行分页查询
+            IPage<StoreContractVo> result = storeContractMapper.selectContractPage(
+                    page,
+                    queryDto.getContractName(),
+                    queryDto.getStatus(),
+                    queryDto.getStoreId()
+            );
+
+            // 设置状态名称
+            for (StoreContractVo vo : result.getRecords()) {
+                if (vo.getStatus() != null) {
+                    vo.setStatusName(vo.getStatus());
+                }
+            }
+
+            return R.data(result);
+        } catch (Exception e) {
+            log.error("StoreContractServiceImpl.getContractList ERROR: {}", e.getMessage(), e);
+            return R.fail("查询合同列表失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public R<StoreContractVo> getContractDetail(Integer id) {
+        try {
+            log.info("StoreContractServiceImpl.getContractDetail?id={}", id);
+
+            StoreContract contract = storeContractMapper.selectById(id);
+            if (contract == null) {
+                return R.fail("合同不存在");
+            }
+
+            StoreContractVo vo = new StoreContractVo();
+            BeanUtils.copyProperties(contract, vo);
+
+            // 设置状态名称
+            if (vo.getSigningStatus() != null) {
+                vo.setStatusName(vo.getSigningStatus());
+            }
+
+            return R.data(vo);
+        } catch (Exception e) {
+            log.error("StoreContractServiceImpl.getContractDetail ERROR: {}", e.getMessage(), e);
+            return R.fail("查询合同详情失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public R<StoreContract> addContract(StoreContract contract) {
+        try {
+            log.info("StoreContractServiceImpl.addContract?contract={}", contract);
+
+            // 设置默认值
+            if (contract.getSigningStatus() == null) {
+                contract.setSigningStatus("未签署"); // 默认未签署
+            }
+            if (contract.getDeleteFlag() == null) {
+                contract.setDeleteFlag(0);
+            }
+            contract.setCreatedTime(new Date());
+
+            int result = storeContractMapper.insert(contract);
+            if (result > 0) {
+                return R.data(contract);
+            }
+            return R.fail("新增合同失败");
+        } catch (Exception e) {
+            log.error("StoreContractServiceImpl.addContract ERROR: {}", e.getMessage(), e);
+            return R.fail("新增合同失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public R<StoreContract> updateContract(StoreContract contract) {
+        try {
+            log.info("StoreContractServiceImpl.updateContract?contract={}", contract);
+
+            if (contract.getId() == null) {
+                return R.fail("合同ID不能为空");
+            }
+
+            contract.setUpdatedTime(new Date());
+            int result = storeContractMapper.updateById(contract);
+            if (result > 0) {
+                StoreContract updated = storeContractMapper.selectById(contract.getId());
+                return R.data(updated);
+            }
+            return R.fail("更新合同失败");
+        } catch (Exception e) {
+            log.error("StoreContractServiceImpl.updateContract ERROR: {}", e.getMessage(), e);
+            return R.fail("更新合同失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public R<Boolean> signContract(Long id) {
+        try {
+            log.info("StoreContractServiceImpl.signContract?id={}", id);
+
+            StoreContract contract = storeContractMapper.selectById(id);
+            if (contract == null) {
+                return R.fail("合同不存在");
+            }
+
+            if ("已签署".equals(contract.getSigningStatus())) {
+                return R.fail("合同已签署,无需重复签署");
+            }
+
+            // 更新合同状态为已签署
+            StoreContract updateContract = new StoreContract();
+            updateContract.setId(id);
+            updateContract.setSigningStatus("已签署");
+            updateContract.setSigningTime(new Date());
+            updateContract.setUpdatedTime(new Date());
+
+            int result = storeContractMapper.updateById(updateContract);
+            if (result > 0) {
+                return R.success("合同签署成功");
+            }
+            return R.fail("合同签署失败");
+        } catch (Exception e) {
+            log.error("StoreContractServiceImpl.signContract ERROR: {}", e.getMessage(), e);
+            return R.fail("合同签署失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public R<Boolean> deleteContract(Integer id) {
+        try {
+            log.info("StoreContractServiceImpl.deleteContract?id={}", id);
+
+            StoreContract contract = storeContractMapper.selectById(id);
+            if (contract == null) {
+                return R.fail("合同不存在");
+            }
+
+            // 逻辑删除
+            StoreContract updateContract = new StoreContract();
+            updateContract.setDeleteFlag(1);
+            updateContract.setUpdatedTime(new Date());
+
+            int result = storeContractMapper.updateById(updateContract);
+            if (result > 0) {
+                return R.success("删除合同成功");
+            }
+            return R.fail("删除合同失败");
+        } catch (Exception e) {
+            log.error("StoreContractServiceImpl.deleteContract ERROR: {}", e.getMessage(), e);
+            return R.fail("删除合同失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public R<String> getSigningStatus(Integer storeId) {
+        try {
+            log.info("StoreContractServiceImpl.getSigningStatus?storeId={}", storeId);
+
+            if (storeId == null) {
+                return R.fail("店铺ID不能为空");
+            }
+
+            // 根据店铺ID查询最新的合同(按创建时间倒序)
+            List<StoreContract> contracts = storeContractMapper.selectList(
+                    new LambdaQueryWrapper<StoreContract>()
+                            .eq(StoreContract::getStoreId, storeId.longValue())
+                            .eq(StoreContract::getDeleteFlag, 0)
+                            .orderByDesc(StoreContract::getCreatedTime)
+                            .last("LIMIT 1")
+            );
+
+            if (contracts == null || contracts.isEmpty()) {
+                return R.fail("该店铺暂无合同");
+            }
+
+            StoreContract contract = contracts.get(0);
+            String signingStatus = contract.getSigningStatus();
+            // 将字符串状态转换为数字:已签署=1, 未签署=0, 已到期=2
+            Integer statusValue = null;
+            if (signingStatus != null) {
+                switch (signingStatus) {
+                    case "已签署":
+                        statusValue = 1;
+                        break;
+                    case "未签署":
+                        statusValue = 0;
+                        break;
+                    case "已到期":
+                        statusValue = 2;
+                        break;
+                    default:
+                        statusValue = 0;
+                }
+            }
+            return R.data(signingStatus);
+        } catch (Exception e) {
+            log.error("StoreContractServiceImpl.getSigningStatus ERROR: {}", e.getMessage(), e);
+            return R.fail("获取签署状态失败: " + e.getMessage());
+        }
+    }
+}
+