diff --git a/ruoyi-modules/ruoyi-oa/pom.xml b/ruoyi-modules/ruoyi-oa/pom.xml
new file mode 100644
index 00000000..ab199088
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/pom.xml
@@ -0,0 +1,128 @@
+
+
+
+ org.dromara
+ ruoyi-modules
+ ${revision}
+
+ 4.0.0
+
+ ruoyi-oa
+
+
+ ruoyi-oa办公模块
+
+
+
+
+
+ org.dromara
+ ruoyi-common-nacos
+
+
+
+
+ org.dromara
+ ruoyi-common-log
+
+
+
+ org.dromara
+ ruoyi-common-service-impl
+
+
+
+ org.dromara
+ ruoyi-common-doc
+
+
+
+ org.dromara
+ ruoyi-common-web
+
+
+
+ org.dromara
+ ruoyi-common-mybatis
+
+
+
+ org.dromara
+ ruoyi-common-dubbo
+
+
+
+ org.dromara
+ ruoyi-common-seata
+
+
+
+ org.dromara
+ ruoyi-common-idempotent
+
+
+
+ org.dromara
+ ruoyi-common-tenant
+
+
+
+ org.dromara
+ ruoyi-common-security
+
+
+
+ org.dromara
+ ruoyi-common-translation
+
+
+
+ org.dromara
+ ruoyi-common-sensitive
+
+
+
+ org.dromara
+ ruoyi-common-encrypt
+
+
+
+
+ org.dromara
+ ruoyi-api-system
+
+
+
+ org.dromara
+ ruoyi-api-resource
+
+
+
+
+ org.dromara
+ ruoyi-api-workflow
+
+
+
+
+
+ ${project.artifactId}
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
+
diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/RuoYiOaApplication.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/RuoYiOaApplication.java
new file mode 100644
index 00000000..9832b394
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/RuoYiOaApplication.java
@@ -0,0 +1,22 @@
+package org.dromara.oa;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
+
+/**
+ * OA模块
+ *
+ * @author Yinq
+ */
+@EnableDubbo
+@SpringBootApplication
+public class RuoYiOaApplication {
+ public static void main(String[] args) {
+ SpringApplication application = new SpringApplication(RuoYiOaApplication.class);
+ application.setApplicationStartup(new BufferingApplicationStartup(2048));
+ application.run(args);
+ System.out.println("(♥◠‿◠)ノ゙ OA模块启动成功 ლ(´ڡ`ლ)゙ ");
+ }
+}
diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/controller/BaseCustomerController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/controller/BaseCustomerController.java
new file mode 100644
index 00000000..6ba48ab7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/controller/BaseCustomerController.java
@@ -0,0 +1,116 @@
+package org.dromara.oa.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.oa.domain.vo.BaseCustomerVo;
+import org.dromara.oa.domain.bo.BaseCustomerBo;
+import org.dromara.oa.service.IBaseCustomerService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 客户信息
+ * 前端访问路由地址为:/oa/baseCustomer
+ *
+ * @author Yinq
+ * @date 2025-09-15
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/baseCustomer")
+public class BaseCustomerController extends BaseController {
+
+ private final IBaseCustomerService baseCustomerService;
+
+ /**
+ * 查询客户信息列表
+ */
+ @SaCheckPermission("oa:baseCustomer:list")
+ @GetMapping("/list")
+ public TableDataInfo list(BaseCustomerBo bo, PageQuery pageQuery) {
+ return baseCustomerService.queryPageList(bo, pageQuery);
+ }
+
+ /**
+ * 导出客户信息列表
+ */
+ @SaCheckPermission("oa:baseCustomer:export")
+ @Log(title = "客户信息", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ public void export(BaseCustomerBo bo, HttpServletResponse response) {
+ List list = baseCustomerService.queryList(bo);
+ ExcelUtil.exportExcel(list, "客户信息", BaseCustomerVo.class, response);
+ }
+
+ /**
+ * 获取客户信息详细信息
+ *
+ * @param customerId 主键
+ */
+ @SaCheckPermission("oa:baseCustomer:query")
+ @GetMapping("/{customerId}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable("customerId") Long customerId) {
+ return R.ok(baseCustomerService.queryById(customerId));
+ }
+
+ /**
+ * 新增客户信息
+ */
+ @SaCheckPermission("oa:baseCustomer:add")
+ @Log(title = "客户信息", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated(AddGroup.class) @RequestBody BaseCustomerBo bo) {
+ return toAjax(baseCustomerService.insertByBo(bo));
+ }
+
+ /**
+ * 修改客户信息
+ */
+ @SaCheckPermission("oa:baseCustomer:edit")
+ @Log(title = "客户信息", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated(EditGroup.class) @RequestBody BaseCustomerBo bo) {
+ return toAjax(baseCustomerService.updateByBo(bo));
+ }
+
+ /**
+ * 删除客户信息
+ *
+ * @param customerIds 主键串
+ */
+ @SaCheckPermission("oa:baseCustomer:remove")
+ @Log(title = "客户信息", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{customerIds}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable("customerIds") Long[] customerIds) {
+ return toAjax(baseCustomerService.deleteWithValidByIds(List.of(customerIds), true));
+ }
+
+ /**
+ * 下拉框查询客户信息列表
+ */
+ @GetMapping("/getBaseCustomerList")
+ public R> getBaseCustomerList(BaseCustomerBo bo) {
+ List list = baseCustomerService.queryList(bo);
+ return R.ok(list);
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/domain/BaseCustomer.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/domain/BaseCustomer.java
new file mode 100644
index 00000000..9ddf41b8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/domain/BaseCustomer.java
@@ -0,0 +1,122 @@
+package org.dromara.oa.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 客户信息对象 base_customer
+ *
+ * @author Yinq
+ * @date 2025-09-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("base_customer")
+public class BaseCustomer extends TenantEntity {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 客户ID
+ */
+ @TableId(value = "customer_id", type = IdType.AUTO)
+ private Long customerId;
+
+ /**
+ * 客户名称
+ */
+ private String customerName;
+
+ /**
+ * 助记名称
+ */
+ private String mnemonicName;
+
+ /**
+ * 所属行业(1制造业 2仓储业 ……)
+ */
+ private Long industryId;
+
+ /**
+ * 客户类型(1企业客户 2个人客户)
+ */
+ private Long customerType;
+
+ /**
+ * 客户状态(1了解产品 2正在跟进 3正在试用 4准备购买 5准备付款 6已经购买 7暂时搁置)
+ */
+ private Long customerStatus;
+
+ /**
+ * 客户级别(1普通客户 2意向客户 3重要客户)
+ */
+ private Long customerLevel;
+
+ /**
+ * 客户来源(1电话营销 2主动来电 3客户介绍 4朋友介绍 5独立开发 6网络搜索 7广告杂志 8展会促销 9其它途径)
+ */
+ private Long customerSource;
+
+ /**
+ * 归属人员ID
+ */
+ private Long ownerId;
+
+ /**
+ * 详细地址
+ */
+ private String detailedAddress;
+
+ /**
+ * 企业规模(10人以内 10-20人 21人-50人 51人-200人 201人-500人 500人以上)
+ */
+ private Long customerScale;
+
+ /**
+ * 下级客户
+ */
+ private Long parentCustomerId;
+
+ /**
+ * 法定代表人
+ */
+ private String legalRepresentative;
+
+ /**
+ * 营业执照号码
+ */
+ private String businessLicenseNumber;
+
+ /**
+ * 开户银行
+ */
+ private String bankAccountOpening;
+
+ /**
+ * 税号
+ */
+ private String taxNumber;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 激活标识(1是 0否)
+ */
+ private String activeFlag;
+
+ /**
+ * 删除标志(0代表存在 1代表删除)
+ */
+ @TableLogic
+ private String delFlag;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/domain/bo/BaseCustomerBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/domain/bo/BaseCustomerBo.java
new file mode 100644
index 00000000..48f41e13
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/domain/bo/BaseCustomerBo.java
@@ -0,0 +1,111 @@
+package org.dromara.oa.domain.bo;
+
+import org.dromara.oa.domain.BaseCustomer;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 客户信息业务对象 base_customer
+ *
+ * @author Yinq
+ * @date 2025-09-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = BaseCustomer.class, reverseConvertGenerate = false)
+public class BaseCustomerBo extends BaseEntity {
+
+ /**
+ * 客户ID
+ */
+ private Long customerId;
+
+ /**
+ * 客户名称
+ */
+ private String customerName;
+
+ /**
+ * 助记名称
+ */
+ private String mnemonicName;
+
+ /**
+ * 所属行业(1制造业 2仓储业 ……)
+ */
+ private Long industryId;
+
+ /**
+ * 客户类型(1企业客户 2个人客户)
+ */
+ private Long customerType;
+
+ /**
+ * 客户状态(1了解产品 2正在跟进 3正在试用 4准备购买 5准备付款 6已经购买 7暂时搁置)
+ */
+ private Long customerStatus;
+
+ /**
+ * 客户级别(1普通客户 2意向客户 3重要客户)
+ */
+ private Long customerLevel;
+
+ /**
+ * 客户来源(1电话营销 2主动来电 3客户介绍 4朋友介绍 5独立开发 6网络搜索 7广告杂志 8展会促销 9其它途径)
+ */
+ private Long customerSource;
+
+ /**
+ * 归属人员ID
+ */
+ private Long ownerId;
+
+ /**
+ * 详细地址
+ */
+ private String detailedAddress;
+
+ /**
+ * 企业规模(10人以内 10-20人 21人-50人 51人-200人 201人-500人 500人以上)
+ */
+ private Long customerScale;
+
+ /**
+ * 下级客户
+ */
+ private Long parentCustomerId;
+
+ /**
+ * 法定代表人
+ */
+ private String legalRepresentative;
+
+ /**
+ * 营业执照号码
+ */
+ private String businessLicenseNumber;
+
+ /**
+ * 开户银行
+ */
+ private String bankAccountOpening;
+
+ /**
+ * 税号
+ */
+ private String taxNumber;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 激活标识(1是 0否)
+ */
+ private String activeFlag;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/domain/vo/BaseCustomerVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/domain/vo/BaseCustomerVo.java
new file mode 100644
index 00000000..8507e887
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/domain/vo/BaseCustomerVo.java
@@ -0,0 +1,177 @@
+package org.dromara.oa.domain.vo;
+
+import org.dromara.oa.domain.BaseCustomer;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 客户信息视图对象 base_customer
+ *
+ * @author Yinq
+ * @date 2025-09-12
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = BaseCustomer.class)
+public class BaseCustomerVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 客户ID
+ */
+ @ExcelProperty(value = "客户ID")
+ private Long customerId;
+
+ /**
+ * 客户名称
+ */
+ @ExcelProperty(value = "客户名称")
+ private String customerName;
+
+ /**
+ * 助记名称
+ */
+ @ExcelProperty(value = "助记名称")
+ private String mnemonicName;
+
+ /**
+ * 所属行业(1制造业 2仓储业 ……)
+ */
+ @ExcelProperty(value = "所属行业", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "industry_id")
+ private Long industryId;
+
+ /**
+ * 客户类型(1企业客户 2个人客户)
+ */
+ @ExcelProperty(value = "客户类型", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "customer_type")
+ private Long customerType;
+
+ /**
+ * 客户状态(1了解产品 2正在跟进 3正在试用 4准备购买 5准备付款 6已经购买 7暂时搁置)
+ */
+ @ExcelProperty(value = "客户状态", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "customer_status")
+ private Long customerStatus;
+
+ /**
+ * 客户级别(1普通客户 2意向客户 3重要客户)
+ */
+ @ExcelProperty(value = "客户级别", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "customer_level")
+ private Long customerLevel;
+
+ /**
+ * 客户来源(1电话营销 2主动来电 3客户介绍 4朋友介绍 5独立开发 6网络搜索 7广告杂志 8展会促销 9其它途径)
+ */
+ @ExcelProperty(value = "客户来源", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "customer_source")
+ private Long customerSource;
+
+ /**
+ * 归属人员ID
+ */
+ @ExcelProperty(value = "归属人员ID")
+ private Long ownerId;
+
+ /**
+ * 详细地址
+ */
+ @ExcelProperty(value = "详细地址")
+ private String detailedAddress;
+
+ /**
+ * 企业规模(10人以内 10-20人 21人-50人 51人-200人 201人-500人 500人以上)
+ */
+ @ExcelProperty(value = "企业规模", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "customer_scale")
+ private Long customerScale;
+
+ /**
+ * 下级客户
+ */
+ @ExcelProperty(value = "下级客户")
+ private Long parentCustomerId;
+
+ /**
+ * 法定代表人
+ */
+ @ExcelProperty(value = "法定代表人")
+ private String legalRepresentative;
+
+ /**
+ * 营业执照号码
+ */
+ @ExcelProperty(value = "营业执照号码")
+ private String businessLicenseNumber;
+
+ /**
+ * 开户银行
+ */
+ @ExcelProperty(value = "开户银行")
+ private String bankAccountOpening;
+
+ /**
+ * 税号
+ */
+ @ExcelProperty(value = "税号")
+ private String taxNumber;
+
+ /**
+ * 备注
+ */
+ @ExcelProperty(value = "备注")
+ private String remark;
+
+ /**
+ * 激活标识(1是 0否)
+ */
+ @ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "active_flag")
+ private String activeFlag;
+
+ /**
+ * 创建部门
+ */
+ @ExcelProperty(value = "创建部门")
+ private Long createDept;
+
+ /**
+ * 创建人
+ */
+ @ExcelProperty(value = "创建人")
+ private Long createBy;
+
+ /**
+ * 创建时间
+ */
+ @ExcelProperty(value = "创建时间")
+ private Date createTime;
+
+ /**
+ * 更新人
+ */
+ @ExcelProperty(value = "更新人")
+ private Long updateBy;
+
+ /**
+ * 更新时间
+ */
+ @ExcelProperty(value = "更新时间")
+ private Date updateTime;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/mapper/BaseCustomerMapper.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/mapper/BaseCustomerMapper.java
new file mode 100644
index 00000000..b5306ea7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/mapper/BaseCustomerMapper.java
@@ -0,0 +1,37 @@
+package org.dromara.oa.mapper;
+
+import java.util.List;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import org.dromara.oa.domain.BaseCustomer;
+import org.dromara.oa.domain.vo.BaseCustomerVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 客户信息Mapper接口
+ *
+ * @author Yinq
+ * @date 2025-09-15
+ */
+public interface BaseCustomerMapper extends BaseMapperPlus {
+
+ /**
+ * 查询客户信息列表
+ *
+ * @param page 分页
+ * @param queryWrapper 条件
+ * @return 客户信息集合
+ */
+ public Page selectCustomBaseCustomerVoList(@Param("page") Page page, @Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper);
+
+ /**
+ * 查询客户信息列表
+ *
+ * @param queryWrapper 条件
+ * @return 客户信息集合
+ */
+ public List selectCustomBaseCustomerVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper);
+
+}
diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/service/IBaseCustomerService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/service/IBaseCustomerService.java
new file mode 100644
index 00000000..c3299d29
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/service/IBaseCustomerService.java
@@ -0,0 +1,69 @@
+package org.dromara.oa.service;
+
+import org.dromara.oa.domain.BaseCustomer;
+import org.dromara.oa.domain.vo.BaseCustomerVo;
+import org.dromara.oa.domain.bo.BaseCustomerBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 客户信息Service接口
+ *
+ * @author Yinq
+ * @date 2025-09-12
+ */
+public interface IBaseCustomerService {
+
+ /**
+ * 查询客户信息
+ *
+ * @param customerId 主键
+ * @return 客户信息
+ */
+ BaseCustomerVo queryById(Long customerId);
+
+ /**
+ * 分页查询客户信息列表
+ *
+ * @param bo 查询条件
+ * @param pageQuery 分页参数
+ * @return 客户信息分页列表
+ */
+ TableDataInfo queryPageList(BaseCustomerBo bo, PageQuery pageQuery);
+
+ /**
+ * 查询符合条件的客户信息列表
+ *
+ * @param bo 查询条件
+ * @return 客户信息列表
+ */
+ List queryList(BaseCustomerBo bo);
+
+ /**
+ * 新增客户信息
+ *
+ * @param bo 客户信息
+ * @return 是否新增成功
+ */
+ Boolean insertByBo(BaseCustomerBo bo);
+
+ /**
+ * 修改客户信息
+ *
+ * @param bo 客户信息
+ * @return 是否修改成功
+ */
+ Boolean updateByBo(BaseCustomerBo bo);
+
+ /**
+ * 校验并批量删除客户信息信息
+ *
+ * @param ids 待删除的主键集合
+ * @param isValid 是否进行有效性校验
+ * @return 是否删除成功
+ */
+ Boolean deleteWithValidByIds(Collection ids, Boolean isValid);
+}
diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/service/impl/BaseCustomerServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/service/impl/BaseCustomerServiceImpl.java
new file mode 100644
index 00000000..58c4e437
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/service/impl/BaseCustomerServiceImpl.java
@@ -0,0 +1,147 @@
+package org.dromara.oa.service.impl;
+
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.yulichang.toolkit.JoinWrappers;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.dromara.oa.domain.bo.BaseCustomerBo;
+import org.dromara.oa.domain.vo.BaseCustomerVo;
+import org.dromara.oa.domain.BaseCustomer;
+import org.dromara.oa.mapper.BaseCustomerMapper;
+import org.dromara.oa.service.IBaseCustomerService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 客户信息Service业务层处理
+ *
+ * @author Yinq
+ * @date 2025-09-15
+ */
+@RequiredArgsConstructor
+@Service
+public class BaseCustomerServiceImpl implements IBaseCustomerService {
+
+ private final BaseCustomerMapper baseMapper;
+
+ /**
+ * 查询客户信息
+ *
+ * @param customerId 主键
+ * @return 客户信息
+ */
+ @Override
+ public BaseCustomerVo queryById(Long customerId) {
+ return baseMapper.selectVoById(customerId);
+ }
+
+ /**
+ * 分页查询客户信息列表
+ *
+ * @param bo 查询条件
+ * @param pageQuery 分页参数
+ * @return 客户信息分页列表
+ */
+ @Override
+ public TableDataInfo queryPageList(BaseCustomerBo bo, PageQuery pageQuery) {
+ MPJLambdaWrapper lqw = buildQueryWrapper(bo);
+ Page result = baseMapper.selectCustomBaseCustomerVoList(pageQuery.build(), lqw);
+ return TableDataInfo.build(result);
+ }
+
+ /**
+ * 查询符合条件的客户信息列表
+ *
+ * @param bo 查询条件
+ * @return 客户信息列表
+ */
+ @Override
+ public List queryList(BaseCustomerBo bo) {
+ MPJLambdaWrapper lqw = buildQueryWrapper(bo);
+ return baseMapper.selectCustomBaseCustomerVoList(lqw);
+ }
+
+ private MPJLambdaWrapper buildQueryWrapper(BaseCustomerBo bo) {
+ Map params = bo.getParams();
+ MPJLambdaWrapper lqw = JoinWrappers.lambda(BaseCustomer.class)
+ .selectAll(BaseCustomer.class)
+ .like(StringUtils.isNotBlank(bo.getCustomerName()), BaseCustomer::getCustomerName, bo.getCustomerName())
+ .like(StringUtils.isNotBlank(bo.getMnemonicName()), BaseCustomer::getMnemonicName, bo.getMnemonicName())
+ .eq(bo.getIndustryId() != null, BaseCustomer::getIndustryId, bo.getIndustryId())
+ .eq(bo.getCustomerType() != null, BaseCustomer::getCustomerType, bo.getCustomerType())
+ .eq(bo.getCustomerStatus() != null, BaseCustomer::getCustomerStatus, bo.getCustomerStatus())
+ .eq(bo.getCustomerLevel() != null, BaseCustomer::getCustomerLevel, bo.getCustomerLevel())
+ .eq(bo.getCustomerSource() != null, BaseCustomer::getCustomerSource, bo.getCustomerSource())
+ .eq(bo.getOwnerId() != null, BaseCustomer::getOwnerId, bo.getOwnerId())
+ .eq(StringUtils.isNotBlank(bo.getDetailedAddress()), BaseCustomer::getDetailedAddress, bo.getDetailedAddress())
+ .eq(bo.getCustomerScale() != null, BaseCustomer::getCustomerScale, bo.getCustomerScale())
+ .eq(bo.getParentCustomerId() != null, BaseCustomer::getParentCustomerId, bo.getParentCustomerId())
+ .eq(StringUtils.isNotBlank(bo.getLegalRepresentative()), BaseCustomer::getLegalRepresentative, bo.getLegalRepresentative())
+ .eq(StringUtils.isNotBlank(bo.getBusinessLicenseNumber()), BaseCustomer::getBusinessLicenseNumber, bo.getBusinessLicenseNumber())
+ .eq(StringUtils.isNotBlank(bo.getBankAccountOpening()), BaseCustomer::getBankAccountOpening, bo.getBankAccountOpening())
+ .eq(StringUtils.isNotBlank(bo.getTaxNumber()), BaseCustomer::getTaxNumber, bo.getTaxNumber())
+ .eq(StringUtils.isNotBlank(bo.getActiveFlag()), BaseCustomer::getActiveFlag, bo.getActiveFlag())
+ .orderByAsc(BaseCustomer::getCustomerId);
+ return lqw;
+ }
+
+ /**
+ * 新增客户信息
+ *
+ * @param bo 客户信息
+ * @return 是否新增成功
+ */
+ @Override
+ public Boolean insertByBo(BaseCustomerBo bo) {
+ BaseCustomer add = MapstructUtils.convert(bo, BaseCustomer.class);
+ validEntityBeforeSave(add);
+ boolean flag = baseMapper.insert(add) > 0;
+ if (flag) {
+ bo.setCustomerId(add.getCustomerId());
+ }
+ return flag;
+ }
+
+ /**
+ * 修改客户信息
+ *
+ * @param bo 客户信息
+ * @return 是否修改成功
+ */
+ @Override
+ public Boolean updateByBo(BaseCustomerBo bo) {
+ BaseCustomer update = MapstructUtils.convert(bo, BaseCustomer.class);
+ validEntityBeforeSave(update);
+ return baseMapper.updateById(update) > 0;
+ }
+
+ /**
+ * 保存前的数据校验
+ */
+ private void validEntityBeforeSave(BaseCustomer entity) {
+ //TODO 做一些数据校验,如唯一约束
+ }
+
+ /**
+ * 校验并批量删除客户信息信息
+ *
+ * @param ids 待删除的主键集合
+ * @param isValid 是否进行有效性校验
+ * @return 是否删除成功
+ */
+ @Override
+ public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) {
+ if (isValid) {
+ //TODO 做一些业务上的校验,判断是否需要校验
+ }
+ return baseMapper.deleteByIds(ids) > 0;
+ }
+}
diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/application.yml b/ruoyi-modules/ruoyi-oa/src/main/resources/application.yml
new file mode 100644
index 00000000..bf2e59ea
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/resources/application.yml
@@ -0,0 +1,34 @@
+# Tomcat
+server:
+ port: 9301
+
+# Spring
+spring:
+ application:
+ # 应用名称
+ name: ruoyi-oa
+ profiles:
+ # 环境配置
+ active: @profiles.active@
+
+--- # nacos 配置
+spring:
+ cloud:
+ nacos:
+ # nacos 服务地址
+ server-addr: @nacos.server@
+ username: @nacos.username@
+ password: @nacos.password@
+ discovery:
+ # 注册组
+ group: @nacos.discovery.group@
+ namespace: ${spring.profiles.active}
+ config:
+ # 配置组
+ group: @nacos.config.group@
+ namespace: ${spring.profiles.active}
+ config:
+ import:
+ - optional:nacos:application-common.yml
+ - optional:nacos:datasource.yml
+ - optional:nacos:${spring.application.name}.yml
diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/banner.txt b/ruoyi-modules/ruoyi-oa/src/main/resources/banner.txt
new file mode 100644
index 00000000..3e3b6d37
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/resources/banner.txt
@@ -0,0 +1,9 @@
+Spring Boot Version: ${spring-boot.version}
+Spring Application Name: ${spring.application.name}
+ _ _ __ __ ___ _
+ | | | | \ \ / / / _ \ / \
+ | |_| | \ \ /\ / / _____ | | | | / _ \
+ | _ | \ V V / |_____| | |_| | / ___ \
+ |_| |_| \_/\_/ \___/ /_/ \_\
+
+
diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/logback-plus.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/logback-plus.xml
new file mode 100644
index 00000000..00d30896
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/resources/logback-plus.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+ ${console.log.pattern}
+ utf-8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/BaseCustomerMapper.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/BaseCustomerMapper.xml
new file mode 100644
index 00000000..0771d5b8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/BaseCustomerMapper.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+