diff --git a/yudao-module-cms/yudao-module-cms-biz/src/main/java/cn/iocoder/yudao/module/cms/service/extContract/ExtContractService.java b/yudao-module-cms/yudao-module-cms-biz/src/main/java/cn/iocoder/yudao/module/cms/service/extContract/ExtContractService.java
new file mode 100644
index 000000000..f457c5f6d
--- /dev/null
+++ b/yudao-module-cms/yudao-module-cms-biz/src/main/java/cn/iocoder/yudao/module/cms/service/extContract/ExtContractService.java
@@ -0,0 +1,63 @@
+package cn.iocoder.yudao.module.cms.service.extcontract;
+
+
+import cn.iocoder.yudao.module.cms.controller.admin.extContract.vo.ExtContractPageReqVO;
+import cn.iocoder.yudao.module.cms.controller.admin.extContract.vo.ExtContractRespVO;
+import cn.iocoder.yudao.module.cms.controller.admin.extContract.vo.ExtContractSaveReqVO;
+import jakarta.validation.*;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import java.math.BigDecimal;
+
+/**
+ * 外部合同 Service 接口
+ *
+ * @author 管理员
+ */
+public interface ExtContractService {
+
+    /**
+     * 创建外部合同
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createExtContract(@Valid ExtContractSaveReqVO createReqVO);
+
+    /**
+     * 更新外部合同
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateExtContract(@Valid ExtContractSaveReqVO updateReqVO);
+
+    /**
+     * 删除外部合同
+     *
+     * @param id 编号
+     */
+    void deleteExtContract(Long id);
+
+    /**
+     * 获得外部合同
+     *
+     * @param id 编号
+     * @return 外部合同
+     */
+    ExtContractRespVO getExtContract(Long id);
+
+    /**
+     * 获得外部合同分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 外部合同分页
+     */
+    PageResult<ExtContractRespVO> getExtContractPage(ExtContractPageReqVO pageReqVO);
+
+    /**
+     * 合同总金额
+     * @param id
+     * @return
+     */
+    BigDecimal getContractAmount(Long id);
+}
\ No newline at end of file
diff --git a/yudao-module-cms/yudao-module-cms-biz/src/main/java/cn/iocoder/yudao/module/cms/service/extContract/ExtContractServiceImpl.java b/yudao-module-cms/yudao-module-cms-biz/src/main/java/cn/iocoder/yudao/module/cms/service/extContract/ExtContractServiceImpl.java
new file mode 100644
index 000000000..95d79bdc6
--- /dev/null
+++ b/yudao-module-cms/yudao-module-cms-biz/src/main/java/cn/iocoder/yudao/module/cms/service/extContract/ExtContractServiceImpl.java
@@ -0,0 +1,145 @@
+package cn.iocoder.yudao.module.cms.service.extcontract;
+
+import cn.iocoder.yudao.module.cms.controller.admin.extContract.vo.ExtContractPageReqVO;
+import cn.iocoder.yudao.module.cms.controller.admin.extContract.vo.ExtContractRespVO;
+import cn.iocoder.yudao.module.cms.controller.admin.extContract.vo.ExtContractSaveReqVO;
+import cn.iocoder.yudao.module.cms.dal.dataobject.customerCompany.CustomerCompanyDO;
+import cn.iocoder.yudao.module.cms.dal.dataobject.extContract.ExtContractDO;
+import cn.iocoder.yudao.module.cms.dal.mysql.customerCompany.CustomerCompanyMapper;
+import cn.iocoder.yudao.module.cms.dal.mysql.extContract.ExtContractMapper;
+import cn.iocoder.yudao.module.pms.api.ProjectApi;
+import cn.iocoder.yudao.module.pms.api.project.dto.ProjectDetailRespDTO;
+import cn.iocoder.yudao.module.pms.api.project.dto.ProjectRespDTO;
+import org.springframework.stereotype.Service;
+import jakarta.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.cms.enums.ErrorCodeConstants.EXT_CONTRACT_NOT_EXISTS;
+
+/**
+ * 外部合同 Service 实现类
+ *
+ * @author 管理员
+ */
+@Service
+@Validated
+public class ExtContractServiceImpl implements ExtContractService {
+
+    @Resource
+    private ExtContractMapper extContractMapper;
+
+    @Resource
+    private ProjectApi projectApi;
+
+    @Resource
+    private CustomerCompanyMapper customerCompanyMapper;
+
+
+    @Override
+    public Long createExtContract(ExtContractSaveReqVO createReqVO) {
+        // 插入
+        ExtContractDO extContract = BeanUtils.toBean(createReqVO, ExtContractDO.class);
+        extContractMapper.insert(extContract);
+        // 返回
+        return extContract.getId();
+    }
+
+    @Override
+    public void updateExtContract(ExtContractSaveReqVO updateReqVO) {
+        //校验
+        Long id = updateReqVO.getId();
+        validateExtContractExists(id);
+        // 更新
+        ExtContractDO updateObj = BeanUtils.toBean(updateReqVO, ExtContractDO.class);
+        extContractMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteExtContract(Long id) {
+        // 校验存在
+        validateExtContractExists(id);
+        // 删除
+        extContractMapper.deleteById(id);
+    }
+
+    private void validateExtContractExists(Long id) {
+        if (extContractMapper.selectById(id) == null) {
+            throw exception(EXT_CONTRACT_NOT_EXISTS);
+        }
+    }
+
+    //        需要联表查询
+    //        1.项目编号 pms_project 直接 √
+    //        2.主控部门(跟踪部门) pms_project找到的是id 需要联表 √
+    //        3.项目经理 pms_project找到的是id 需要联表 √
+    //        4.客户公司名称 pms_project 联表 √
+    //        5.合同总金额 √
+    //        6.合同商议提示(和分包提示不一样)
+    @Override
+    public ExtContractRespVO getExtContract(Long id) {
+        ExtContractDO extContractDO = extContractMapper.selectById(id);
+        Long projectId = extContractDO.getProjectId();
+        Long customerCompanyId = extContractDO.getCustomerCompanyId();
+        ExtContractRespVO extContractRespVO = BeanUtils.toBean(extContractDO, ExtContractRespVO.class);
+
+
+        ProjectRespDTO project = projectApi.getProject(projectId);
+        extContractRespVO.setCode(project.getCode());
+
+
+        ProjectDetailRespDTO projectDetail = projectApi.getProjectDetailById(projectId);
+        extContractRespVO.setTrackingDep(projectDetail.getTrackingDepName());
+        extContractRespVO.setProjectManager(projectDetail.getProjectManagerName());
+
+        //用客户公司id查询
+        CustomerCompanyDO customerCompanyDO = customerCompanyMapper.selectById(customerCompanyId);
+        String name = customerCompanyDO.getName();
+        extContractRespVO.setCustomerCompanyName(name);
+
+
+        //合同总金额
+        BigDecimal contractAmount = getContractAmount(id);
+        extContractRespVO.setAmount(contractAmount);
+
+
+        return extContractRespVO;
+    }
+
+    @Override
+    public PageResult<ExtContractRespVO> getExtContractPage(ExtContractPageReqVO pageReqVO) {
+
+        PageResult<ExtContractDO> extContractDOPageResult = extContractMapper.selectPage(pageReqVO);
+        List<ExtContractDO> excontractDOList = extContractDOPageResult.getList();
+        List<ExtContractRespVO> extContractRespVOList = new ArrayList<>();
+
+
+        for (ExtContractDO extContractDO : excontractDOList) {
+            Long id = extContractDO.getId();
+            ExtContractRespVO extContractRespVO = getExtContract(id);
+            extContractRespVOList.add(extContractRespVO);
+        }
+        PageResult<ExtContractRespVO> pageResult = new PageResult<>();
+        pageResult.setList(extContractRespVOList);
+        return pageResult;
+    }
+
+    @Override
+    public BigDecimal getContractAmount(Long id) {
+        //前期+设计+地勘+其他+检测
+        ExtContractDO extContract = extContractMapper.selectById(id);
+        BigDecimal preAmount = new BigDecimal(String.valueOf(extContract.getPreAmount()));
+        BigDecimal designFee = new BigDecimal(String.valueOf(extContract.getDesignFee()));
+        BigDecimal surveyFees = new BigDecimal(String.valueOf(extContract.getSurveyFees()));
+        BigDecimal testingFee = new BigDecimal(String.valueOf(extContract.getTestingFee()));
+        BigDecimal other = new BigDecimal(extContract.getOtherFee());
+        return preAmount.add(designFee).add(surveyFees).add(testingFee).add(other);
+    }
+
+}
\ No newline at end of file