diff --git a/gear-admin/src/main/resources/application-prod.yml b/gear-admin/src/main/resources/application-prod.yml
index 758469c..86275f9 100644
--- a/gear-admin/src/main/resources/application-prod.yml
+++ b/gear-admin/src/main/resources/application-prod.yml
@@ -60,9 +60,9 @@ spring:
lazy: true
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://47.117.71.33:11293/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
- username:
- password:
+ url: jdbc:mysql://47.117.71.33:11293/gear?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
+ username: root
+ password: Fuande@666
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
diff --git a/gear-oa/pom.xml b/gear-oa/pom.xml
index a05a137..da5c3ab 100644
--- a/gear-oa/pom.xml
+++ b/gear-oa/pom.xml
@@ -21,7 +21,22 @@
com.gear
gear-common
-
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.35
+
+
+ com.zto.zop
+ zopsdk
+ 0.11
+
+
+ com.yundasys
+ kfpt-sdk
+ 1.0.0
+
diff --git a/gear-oa/src/main/java/com/gear/oa/controller/OaExpressController.java b/gear-oa/src/main/java/com/gear/oa/controller/OaExpressController.java
new file mode 100644
index 0000000..eb2663a
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/controller/OaExpressController.java
@@ -0,0 +1,108 @@
+package com.gear.oa.controller;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import lombok.RequiredArgsConstructor;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.*;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import com.gear.common.annotation.RepeatSubmit;
+import com.gear.common.annotation.Log;
+import com.gear.common.core.controller.BaseController;
+import com.gear.common.core.domain.PageQuery;
+import com.gear.common.core.domain.R;
+import com.gear.common.core.validate.AddGroup;
+import com.gear.common.core.validate.EditGroup;
+import com.gear.common.core.validate.QueryGroup;
+import com.gear.common.enums.BusinessType;
+import com.gear.common.utils.poi.ExcelUtil;
+import com.gear.oa.domain.vo.OaExpressVo;
+import com.gear.oa.domain.bo.OaExpressBo;
+import com.gear.oa.service.IOaExpressService;
+import com.gear.common.core.page.TableDataInfo;
+
+/**
+ * 物流预览
+ *
+ * @author hdka
+ * @date 2025-07-20
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/oa/express")
+public class OaExpressController extends BaseController {
+
+ private final IOaExpressService iOaExpressService;
+
+ /**
+ * 查询物流预览列表
+ */
+ @GetMapping("/list")
+ public TableDataInfo list(OaExpressBo bo, PageQuery pageQuery) {
+ return iOaExpressService.queryPageList(bo, pageQuery);
+ }
+
+ /**
+ * 导出物流预览列表
+ */
+ @Log(title = "物流预览", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ public void export(OaExpressBo bo, HttpServletResponse response) {
+ List list = iOaExpressService.queryList(bo);
+ ExcelUtil.exportExcel(list, "物流预览", OaExpressVo.class, response);
+ }
+
+ /**
+ * 获取物流预览详细信息
+ *
+ * @param expressId 主键
+ */
+ @GetMapping("/{expressId}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable Long expressId) {
+ return R.ok(iOaExpressService.queryById(expressId));
+ }
+
+ /**
+ * 新增物流预览
+ */
+ @Log(title = "物流预览", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated(AddGroup.class) @RequestBody OaExpressBo bo) {
+ return toAjax(iOaExpressService.insertByBo(bo));
+ }
+
+ /**
+ * 修改物流预览
+ */
+ @Log(title = "物流预览", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated(EditGroup.class) @RequestBody OaExpressBo bo) {
+ return toAjax(iOaExpressService.updateByBo(bo));
+ }
+
+ /**
+ * 删除物流预览
+ *
+ * @param expressIds 主键串
+ */
+ @Log(title = "物流预览", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{expressIds}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] expressIds) {
+ return toAjax(iOaExpressService.deleteWithValidByIds(Arrays.asList(expressIds), true));
+ }
+
+
+ @GetMapping("/refresh/{expressIds}")
+ public R getRefreshExpress(@PathVariable Long[] expressIds) throws IOException {
+ return toAjax(iOaExpressService.getRefreshExpress(Arrays.asList(expressIds)));
+ }
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/controller/OaExpressQuestionController.java b/gear-oa/src/main/java/com/gear/oa/controller/OaExpressQuestionController.java
new file mode 100644
index 0000000..b8ca562
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/controller/OaExpressQuestionController.java
@@ -0,0 +1,101 @@
+package com.gear.oa.controller;
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import lombok.RequiredArgsConstructor;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.*;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import com.gear.common.annotation.RepeatSubmit;
+import com.gear.common.annotation.Log;
+import com.gear.common.core.controller.BaseController;
+import com.gear.common.core.domain.PageQuery;
+import com.gear.common.core.domain.R;
+import com.gear.common.core.validate.AddGroup;
+import com.gear.common.core.validate.EditGroup;
+import com.gear.common.core.validate.QueryGroup;
+import com.gear.common.enums.BusinessType;
+import com.gear.common.utils.poi.ExcelUtil;
+import com.gear.oa.domain.vo.OaExpressQuestionVo;
+import com.gear.oa.domain.bo.OaExpressQuestionBo;
+import com.gear.oa.service.IOaExpressQuestionService;
+import com.gear.common.core.page.TableDataInfo;
+
+/**
+ * 快递问题
+ *
+ * @author hdka
+ * @date 2025-07-21
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/oa/expressQuestion")
+public class OaExpressQuestionController extends BaseController {
+
+ private final IOaExpressQuestionService iOaExpressQuestionService;
+
+ /**
+ * 查询快递问题列表
+ */
+ @GetMapping("/list")
+ public TableDataInfo list(OaExpressQuestionBo bo, PageQuery pageQuery) {
+ return iOaExpressQuestionService.queryPageList(bo, pageQuery);
+ }
+
+ /**
+ * 导出快递问题列表
+ */
+ @Log(title = "快递问题", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ public void export(OaExpressQuestionBo bo, HttpServletResponse response) {
+ List list = iOaExpressQuestionService.queryList(bo);
+ ExcelUtil.exportExcel(list, "快递问题", OaExpressQuestionVo.class, response);
+ }
+
+ /**
+ * 获取快递问题详细信息
+ *
+ * @param questionId 主键
+ */
+ @GetMapping("/{questionId}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable Long questionId) {
+ return R.ok(iOaExpressQuestionService.queryById(questionId));
+ }
+
+ /**
+ * 新增快递问题
+ */
+ @Log(title = "快递问题", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated(AddGroup.class) @RequestBody OaExpressQuestionBo bo) {
+ return toAjax(iOaExpressQuestionService.insertByBo(bo));
+ }
+
+ /**
+ * 修改快递问题
+ */
+ @Log(title = "快递问题", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated(EditGroup.class) @RequestBody OaExpressQuestionBo bo) {
+ return toAjax(iOaExpressQuestionService.updateByBo(bo));
+ }
+
+ /**
+ * 删除快递问题
+ *
+ * @param questionIds 主键串
+ */
+ @Log(title = "快递问题", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{questionIds}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] questionIds) {
+ return toAjax(iOaExpressQuestionService.deleteWithValidByIds(Arrays.asList(questionIds), true));
+ }
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/controller/OaFeedbackController.java b/gear-oa/src/main/java/com/gear/oa/controller/OaFeedbackController.java
new file mode 100644
index 0000000..2c5c63e
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/controller/OaFeedbackController.java
@@ -0,0 +1,122 @@
+package com.gear.oa.controller;
+
+import com.gear.common.annotation.RepeatSubmit;
+import com.gear.common.core.controller.BaseController;
+import com.gear.common.core.domain.PageQuery;
+import com.gear.common.core.domain.R;
+import com.gear.common.core.page.TableDataInfo;
+import com.gear.common.core.validate.AddGroup;
+import com.gear.common.core.validate.EditGroup;
+import com.gear.common.utils.poi.ExcelUtil;
+import com.gear.oa.domain.bo.OaFeedbackBo;
+import com.gear.oa.domain.vo.OaFeedbackVo;
+import com.gear.oa.service.IOaFeedbackService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 问题反馈
+ *
+ * @author ruoyi
+ * @date 2025-03-28
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/oa/feedback")
+public class OaFeedbackController extends BaseController {
+
+ private final IOaFeedbackService iOaFeedbackService;
+
+ /**
+ * 查询问题反馈列表
+ */
+ @GetMapping("/list")
+ public TableDataInfo list(OaFeedbackBo bo, PageQuery pageQuery) {
+ return iOaFeedbackService.queryPageList(bo, pageQuery);
+ }
+
+ /**
+ * 查询问题反馈列表
+ */
+ @GetMapping("/index-list")
+ public TableDataInfo indexList(OaFeedbackBo bo, PageQuery pageQuery) {
+ return iOaFeedbackService.indexQueryList(bo, pageQuery);
+ }
+
+ /**
+ * 导出问题反馈列表
+ */
+ @PostMapping("/export")
+ public void export(OaFeedbackBo bo, HttpServletResponse response) {
+ List list = iOaFeedbackService.queryList(bo);
+ ExcelUtil.exportExcel(list, "问题反馈", OaFeedbackVo.class, response);
+ }
+
+ /**
+ * 获取问题反馈详细信息
+ *
+ * @param feedbackId 主键
+ */
+ @GetMapping("/{feedbackId}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable Long feedbackId) {
+ return R.ok(iOaFeedbackService.queryById(feedbackId));
+ }
+
+ /**
+ * 新增问题反馈
+ */
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated(AddGroup.class) @RequestBody OaFeedbackBo bo) {
+ return toAjax(iOaFeedbackService.insertByBo(bo));
+ }
+
+ /**
+ * 修改问题反馈
+ */
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated(EditGroup.class) @RequestBody OaFeedbackBo bo) {
+ return toAjax(iOaFeedbackService.updateByBo(bo));
+ }
+
+ /**
+ * 删除问题反馈
+ *
+ * @param feedbackIds 主键串
+ */
+ @DeleteMapping("/{feedbackIds}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] feedbackIds) {
+ return toAjax(iOaFeedbackService.deleteWithValidByIds(Arrays.asList(feedbackIds), true));
+ }
+ /**
+ * 删除问题反馈
+ *
+ * @param feedbackId 主键
+ */
+ @DeleteMapping("/remove/{feedbackId}")
+ public R removeItem(@PathVariable("feedbackId") Long feedbackId) {
+ return toAjax(iOaFeedbackService.delItem(feedbackId));
+ }
+
+
+ /**
+ * 修改问题反馈
+ */
+ @RepeatSubmit()
+ @PutMapping("/toRead")
+ public R toRead(@Validated(EditGroup.class) @RequestBody OaFeedbackBo bo) {
+ return toAjax(iOaFeedbackService.updateToRead(bo));
+ }
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/controller/OaReportController.java b/gear-oa/src/main/java/com/gear/oa/controller/OaReportController.java
new file mode 100644
index 0000000..27996fa
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/controller/OaReportController.java
@@ -0,0 +1,193 @@
+package com.gear.oa.controller;
+
+import com.gear.common.annotation.Log;
+import com.gear.common.annotation.RepeatSubmit;
+import com.gear.common.core.controller.BaseController;
+import com.gear.common.core.domain.PageQuery;
+import com.gear.common.core.domain.R;
+import com.gear.common.core.page.TableDataInfo;
+import com.gear.common.core.validate.AddGroup;
+import com.gear.common.core.validate.EditGroup;
+import com.gear.common.enums.BusinessType;
+import com.gear.common.utils.poi.ExcelUtil;
+import com.gear.oa.domain.bo.OaReportBo;
+import com.gear.oa.domain.vo.OaReportVo;
+import com.gear.oa.domain.vo.ReportCardVo;
+import com.gear.oa.domain.vo.ReportPieVo;
+import com.gear.oa.domain.vo.ReportTrendVo;
+import com.gear.oa.service.IOaReportService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDate;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 项目报工
+ *
+ * @author hdka
+ * @date 2025-06-16
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/oa/projectReport")
+public class OaReportController extends BaseController {
+
+ private final IOaReportService iOaReportService;
+
+ /**
+ * 查询项目报工列表
+ */
+// @SaCheckPermission("oa:projectReport:list")
+ @GetMapping("/list")
+ public TableDataInfo list(OaReportBo bo, PageQuery pageQuery) {
+ return iOaReportService.queryPageList(bo, pageQuery);
+ }
+
+ /**
+ * 查询项目报工列表
+ */
+// @SaCheckPermission("oa:projectReport:list")
+ @GetMapping("/report")
+ public R> clearList(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate start,
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate end) {
+ return R.ok(iOaReportService.clearList(start,end));
+ }
+
+ /**
+ * 导出项目报工列表
+ */
+// @SaCheckPermission("oa:projectReport:export")
+ @Log(title = "项目报工", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ public void export(@RequestBody OaReportBo bo, HttpServletResponse response) {
+ List list = iOaReportService.queryList(bo);
+ // 处理content去标签
+ for (OaReportVo reportVo : list) {
+ reportVo.setContent(stripHtml(reportVo.getContent()));
+ reportVo.setTrip(reportVo.getIsTrip() == 1 ? "是" : "否");
+ reportVo.setWorkTypeName(reportVo.getWorkType() == 1 ? "国外" : "国内");
+ if (reportVo.getIsTrip() == null) {
+ reportVo.setIsTrip(0L); // 防止ExcelDictConvert NPE
+ }
+ }
+ ExcelUtil.exportExcel(list, "项目报工", OaReportVo.class, response);
+ }
+
+ // 工具方法
+ private static String stripHtml(String html) {
+ return html == null ? null : html.replaceAll("<[^>]+>", "");
+ }
+
+ /**
+ * 获取项目报工详细信息
+ *
+ * @param reportId 主键
+ */
+// @SaCheckPermission("oa:projectReport:query")
+ @GetMapping("/{reportId}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable Long reportId) {
+ return R.ok(iOaReportService.queryById(reportId));
+ }
+
+ /**
+ * 新增项目报工
+ */
+// @SaCheckPermission("oa:projectReport:add")
+ @Log(title = "项目报工", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated(AddGroup.class) @RequestBody OaReportBo bo) {
+ return toAjax(iOaReportService.insertByBo(bo));
+ }
+
+ /**
+ * 修改项目报工
+ */
+// @SaCheckPermission("oa:projectReport:edit")
+ @Log(title = "项目报工", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated(EditGroup.class) @RequestBody OaReportBo bo) {
+ return toAjax(iOaReportService.updateByBo(bo));
+ }
+
+ /**
+ * 删除项目报工
+ *
+ * @param reportIds 主键串
+ */
+// @SaCheckPermission("oa:projectReport:remove")
+ @Log(title = "项目报工", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{reportIds}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] reportIds) {
+ return toAjax(iOaReportService.deleteWithValidByIds(Arrays.asList(reportIds), true));
+ }
+
+
+
+ /**
+ * 数据统计接口
+ */
+ @GetMapping("/rank")
+ public R> getRankData(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate start,
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate end
+ ){
+
+ return R.ok(iOaReportService.getRankData(start,end));
+ }
+
+
+ /**
+ * 数据统计接口
+ */
+ @GetMapping("/card")
+ public R getCardData(){
+
+ return R.ok(iOaReportService.getCardData());
+ }
+
+ /**
+ * GET /api/reports/trend?start=2025-06-01&end=2025-06-07
+ */
+ @GetMapping("/trend")
+ public R> trend(
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate start,
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate end
+ ) {
+ return R.ok(iOaReportService.getTrend(start, end));
+ }
+
+// /**
+// * GET /api/reports/distribution
+// */
+// @GetMapping("/distribution")
+// public R> distribution(
+// @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate start,
+// @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate end
+// ) {
+// return R.ok(iOaReportService.getDistribution(start,end));
+// }
+
+ @GetMapping("/projects")
+ public R> getProjects(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate start,
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate end) {
+ return R.ok(iOaReportService.getProjects(start,end));
+ }
+
+
+ @GetMapping("/summary")
+ public R> summary(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate start,
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate end) {
+ return R.ok(iOaReportService.getSummaryData(start,end));
+ }
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/OaExpress.java b/gear-oa/src/main/java/com/gear/oa/domain/OaExpress.java
new file mode 100644
index 0000000..05a6f14
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/OaExpress.java
@@ -0,0 +1,86 @@
+package com.gear.oa.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.gear.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 物流预览对象 oa_express
+ *
+ * @author hdka
+ * @date 2025-07-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("oa_express")
+public class OaExpress extends BaseEntity {
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 主键id
+ */
+ @TableId(value = "express_id")
+ private Long expressId;
+
+ /**
+ * 物流编号
+ */
+ private String expressCode;
+ /**
+ * 数据状态0未确认1进行中2已完成
+ */
+ private Long status;
+ /**
+ * 供应商姓名
+ */
+ private String supplyName;
+ /**
+ * 供应商联系方式
+ */
+ private String supplyPhone;
+ /**
+ * 负责人id
+ */
+ private Long ownerId;
+ /**
+ * 负责人手机号(快递手机号)
+ */
+ private String ownerPhone;
+ /**
+ * 计划到货时间
+ */
+ private Date planDate;
+ /**
+ * 物流公司标识
+ */
+ private String expressType;
+ /**
+ * 删除标志
+ */
+ @TableLogic
+ private Long delFlag;
+ /**
+ * 备注
+ */
+ private String remark;
+
+
+ /**
+ * 节点变化时间
+ */
+ private Date lastUpdateTime;
+
+ /**
+ * 当前节点
+ */
+ private String lastStatus;
+
+
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/OaExpressQuestion.java b/gear-oa/src/main/java/com/gear/oa/domain/OaExpressQuestion.java
new file mode 100644
index 0000000..7b54f5d
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/OaExpressQuestion.java
@@ -0,0 +1,60 @@
+package com.gear.oa.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.gear.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 快递问题对象 oa_express_question
+ *
+ * @author hdka
+ * @date 2025-07-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("oa_express_question")
+public class OaExpressQuestion extends BaseEntity {
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 主键id
+ */
+ @TableId(value = "question_id")
+ private Long questionId;
+ /**
+ * 关联快递
+ */
+ private Long expressId;
+ /**
+ * 问题描述
+ */
+ private String description;
+ /**
+ * 汇报时间
+ */
+ private Date reportTime;
+ /**
+ * 汇报人
+ */
+ private String reportBy;
+ /**
+ * 0未解决1已解决
+ */
+ private Long status;
+ /**
+ * 删除标志
+ */
+ @TableLogic
+ private Long delFlag;
+ /**
+ * 备注
+ */
+ private String remark;
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/OaFeedback.java b/gear-oa/src/main/java/com/gear/oa/domain/OaFeedback.java
new file mode 100644
index 0000000..5761bf8
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/OaFeedback.java
@@ -0,0 +1,48 @@
+package com.gear.oa.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.gear.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 问题反馈对象 oa_feedback
+ *
+ * @author ruoyi
+ * @date 2025-03-28
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("oa_feedback")
+public class OaFeedback extends BaseEntity {
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 主键id
+ */
+ @TableId(value = "feedback_id")
+ private Long feedbackId;
+ /**
+ * 反馈内容
+ */
+ private String content;
+ /**
+ * 反馈状态
+ */
+ private Long status;
+ /**
+ *
+ */
+ private String remark;
+ /**
+ *
+ */
+ @TableLogic
+ private Long delFlag;
+
+ private String title;
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/OaReport.java b/gear-oa/src/main/java/com/gear/oa/domain/OaReport.java
new file mode 100644
index 0000000..4dbca34
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/OaReport.java
@@ -0,0 +1,65 @@
+package com.gear.oa.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.gear.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 项目报工对象 oa_project_report
+ *
+ * @author hdka
+ * @date 2025-06-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("oa_project_report")
+public class OaReport extends BaseEntity {
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 主键 ID
+ */
+ @TableId(value = "report_id")
+ private Long reportId;
+ /**
+ * 经办人
+ */
+ private Long userId;
+ /**
+ * 工作地点
+ */
+ private String workPlace;
+ /**
+ * 项目 ID
+ */
+ private Long projectId;
+ /**
+ * 报工内容
+ */
+ private String content;
+ /**
+ * 删除标志 (0 正常, 1 删除)
+ */
+ @TableLogic
+ private Integer delFlag;
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 是否出差
+ */
+ private Long isTrip;
+
+ /**
+ * 报工时间
+ */
+ private Long workType;
+
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/OaExpressBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/OaExpressBo.java
new file mode 100644
index 0000000..05bdfde
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/OaExpressBo.java
@@ -0,0 +1,81 @@
+package com.gear.oa.domain.bo;
+
+import com.gear.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 物流预览业务对象 oa_express
+ *
+ * @author hdka
+ * @date 2025-07-20
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class OaExpressBo extends BaseEntity {
+
+ /**
+ * 主键id
+ */
+ private Long expressId;
+
+ /**
+ * 物流编号
+ */
+ private String expressCode;
+
+ /**
+ * 数据状态0未确认1进行中2已完成
+ */
+ private Long status;
+
+ /**
+ * 供应商姓名
+ */
+ private String supplyName;
+
+ /**
+ * 供应商联系方式
+ */
+ private String supplyPhone;
+
+ /**
+ * 负责人id
+ */
+ private Long ownerId;
+
+ /**
+ * 负责人手机号(快递手机号)
+ */
+ private String ownerPhone;
+
+ /**
+ * 计划到货时间
+ */
+ private Date planDate;
+
+ /**
+ * 物流公司标识
+ */
+ private String expressType;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+
+ /**
+ * 节点变化时间
+ */
+ private Date lastUpdateTime;
+
+ /**
+ * 当前节点
+ */
+ private String lastStatus;
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/OaExpressQuestionBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/OaExpressQuestionBo.java
new file mode 100644
index 0000000..2631520
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/OaExpressQuestionBo.java
@@ -0,0 +1,58 @@
+package com.gear.oa.domain.bo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.gear.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 快递问题业务对象 oa_express_question
+ *
+ * @author hdka
+ * @date 2025-07-21
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class OaExpressQuestionBo extends BaseEntity {
+
+ /**
+ * 主键id
+ */
+ private Long questionId;
+
+ /**
+ * 关联快递
+ */
+ private Long expressId;
+
+ /**
+ * 问题描述
+ */
+ private String description;
+
+ /**
+ * 汇报时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date reportTime;
+
+ /**
+ * 汇报人
+ */
+ private String reportBy;
+
+ /**
+ * 0未解决1已解决
+ */
+ private Long status;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/OaFeedbackBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/OaFeedbackBo.java
new file mode 100644
index 0000000..a8e6dbe
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/OaFeedbackBo.java
@@ -0,0 +1,41 @@
+package com.gear.oa.domain.bo;
+
+import com.gear.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 问题反馈业务对象 oa_feedback
+ *
+ * @author ruoyi
+ * @date 2025-03-28
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class OaFeedbackBo extends BaseEntity {
+
+ /**
+ * 主键id
+ */
+ private Long feedbackId;
+
+ /**
+ * 反馈内容
+ */
+ private String content;
+
+ /**
+ * 反馈状态
+ */
+ private Long status;
+
+ /**
+ *
+ */
+ private String remark;
+
+ private Long state;
+
+ private String title;
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/OaReportBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/OaReportBo.java
new file mode 100644
index 0000000..b075b64
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/OaReportBo.java
@@ -0,0 +1,91 @@
+package com.gear.oa.domain.bo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.gear.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 项目报工业务对象 oa_project_report
+ *
+ * @author hdka
+ * @date 2025-06-16
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class OaReportBo extends BaseEntity {
+
+ /**
+ * 主键 ID
+ */
+ private Long reportId;
+
+ /**
+ * 经办人
+ */
+ private Long userId;
+
+ /**
+ * 工作地点
+ */
+ private String workPlace;
+
+
+ /**
+ * 报工内容
+ */
+ private String content;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 是否出差
+ */
+ private Long isTrip;
+
+ /**
+ * 部门id
+ */
+ private Long deptId;
+
+ /**
+ * 项目编号
+ */
+ private String projectNum;
+
+ /**
+ * 项目代号
+ */
+ private String projectCode;
+
+ /**
+ * 名字
+ */
+ private String nickName;
+
+ /**
+ * 报工时间
+ */
+ private Long workType;
+
+ /**
+ * 修改创建时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date time;
+
+ // 新增:多用户ID和时间范围
+ private List userIds;
+ @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+ private Date startDate;
+ @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+ private Date endDate;
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/OaExpressQuestionVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/OaExpressQuestionVo.java
new file mode 100644
index 0000000..7eb7a53
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/OaExpressQuestionVo.java
@@ -0,0 +1,70 @@
+package com.gear.oa.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+
+/**
+ * 快递问题视图对象 oa_express_question
+ *
+ * @author hdka
+ * @date 2025-07-21
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class OaExpressQuestionVo {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键id
+ */
+ @ExcelProperty(value = "主键id")
+ private Long questionId;
+
+ /**
+ * 关联快递
+ */
+ @ExcelProperty(value = "关联快递")
+ private Long expressId;
+
+ /**
+ * 问题描述
+ */
+ @ExcelProperty(value = "问题描述")
+ private String description;
+
+ /**
+ * 汇报时间
+ */
+ @ExcelProperty(value = "汇报时间")
+ private Date reportTime;
+
+ /**
+ * 汇报人
+ */
+ @ExcelProperty(value = "汇报人")
+ private String reportBy;
+
+ /**
+ * 0未解决1已解决
+ */
+ @ExcelProperty(value = "状态")
+ private Long status;
+
+ /**
+ * 备注
+ */
+ @ExcelProperty(value = "备注")
+ private String remark;
+
+ /**
+ * 快递单号
+ */
+ private String expressCode;
+
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/OaExpressVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/OaExpressVo.java
new file mode 100644
index 0000000..090dd75
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/OaExpressVo.java
@@ -0,0 +1,116 @@
+package com.gear.oa.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.gear.common.annotation.ExcelDictFormat;
+import com.gear.common.convert.ExcelDictConvert;
+import lombok.Data;
+
+import java.util.Date;
+
+
+/**
+ * 物流预览视图对象 oa_express
+ *
+ * @author hdka
+ * @date 2025-07-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class OaExpressVo {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键id
+ */
+ @ExcelProperty(value = "主键id")
+ private Long expressId;
+
+ /**
+ * 物流编号
+ */
+ @ExcelProperty(value = "物流编号")
+ private String expressCode;
+
+ /**
+ * 数据状态0未确认1进行中2已完成
+ */
+ @ExcelProperty(value = "数据状态0未确认1进行中2已完成")
+ private Long status;
+
+ /**
+ * 供应商姓名
+ */
+ @ExcelProperty(value = "供应商姓名")
+ private String supplyName;
+
+ /**
+ * 供应商联系方式
+ */
+ @ExcelProperty(value = "供应商联系方式")
+ private String supplyPhone;
+
+ /**
+ * 负责人id
+ */
+ private Long ownerId;
+
+
+ /**
+ * 负责人id
+ */
+ @ExcelProperty(value = "负责人")
+ private String ownerName;
+
+ /**
+ * 负责人手机号(快递手机号)
+ */
+ @ExcelProperty(value = "负责人手机号", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "快=递手机号")
+ private String ownerPhone;
+
+ /**
+ * 计划到货时间
+ */
+ @ExcelProperty(value = "计划到货时间")
+ private Date planDate;
+
+ /**
+ * 物流公司标识
+ */
+ @ExcelProperty(value = "物流公司标识", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "oa_express_type")
+ private String expressType;
+
+ /**
+ * 备注
+ */
+ @ExcelProperty(value = "备注")
+ private String remark;
+
+ /**
+ * 接收时间
+ */
+ private Date acceptTime;
+
+ /**
+ * 物流状态
+ */
+ private String firstStatusName;
+
+ /**
+ * 节点变化时间
+ */
+ private Date lastUpdateTime;
+
+ /**
+ * 当前节点
+ */
+ private String lastStatus;
+
+ /**
+ * 更新时间
+ */
+ private Date updateTime;
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/OaFeedbackVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/OaFeedbackVo.java
new file mode 100644
index 0000000..4f81a5d
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/OaFeedbackVo.java
@@ -0,0 +1,52 @@
+package com.gear.oa.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+
+/**
+ * 问题反馈视图对象 oa_feedback
+ *
+ * @author ruoyi
+ * @date 2025-03-28
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class OaFeedbackVo {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键id
+ */
+ @ExcelProperty(value = "主键id")
+ private Long feedbackId;
+
+ /**
+ * 反馈内容
+ */
+ @ExcelProperty(value = "反馈内容")
+ private String content;
+
+ /**
+ * 反馈状态
+ */
+ @ExcelProperty(value = "反馈状态")
+ private Long status;
+
+ /**
+ *
+ */
+ @ExcelProperty(value = "")
+ private String remark;
+ /**
+ *
+ */
+ @ExcelProperty(value = "")
+ private Long state;
+
+ private String title;
+
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/OaReportVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/OaReportVo.java
new file mode 100644
index 0000000..79274b9
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/OaReportVo.java
@@ -0,0 +1,125 @@
+package com.gear.oa.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.format.DateTimeFormat;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+
+/**
+ * 项目报工视图对象 oa_project_report
+ *
+ * @author hdka
+ * @date 2025-06-16
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class OaReportVo {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键 ID
+ */
+ @ExcelProperty(value = "主键 ID")
+ private Long reportId;
+
+ /**
+ * 经办人
+ */
+ private Long userId;
+
+ /**
+ * 经办人姓名
+ */
+ @ExcelProperty(value = "姓名")
+ private String nickName;
+
+ /**
+ * 部门名称
+ */
+ private String deptName;
+
+ /**
+ * 工作地点
+ */
+ @ExcelProperty(value = "工作地点")
+ private String workPlace;
+
+
+ /**
+ * 报工内容
+ */
+ @ExcelProperty(value = "报工内容")
+ private String content;
+
+ /**
+ * 备注
+ */
+ @ExcelProperty(value = "备注")
+ private String remark;
+
+ /**
+ * 是否出差
+ */
+
+ private Long isTrip;
+ /**
+ * 是否出差
+ */
+ @ExcelProperty(value = "是否出差")
+ private String trip;
+ /**
+ * 报工次数
+ */
+ private Long count;
+ /**
+ * 报工次数
+ */
+ private Long reportCount;
+
+ /**
+ * 项目剩余时间
+ */
+ private Long remainTime;
+
+ /**
+ * 项目状态
+ */
+ private Long projectStatus;
+
+ /**
+ * 报工时间
+ */
+ @ExcelProperty(value = "报工时间")
+ @DateTimeFormat("yyyy-MM-dd HH:mm:ss") // EasyExcel注解
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") // Jackson注解,便于前后端一致
+ private Date createTime;
+
+ /**
+ * 国内外标志
+ */
+ private Long workType;
+ /**
+ * 国内外
+ */
+ @ExcelProperty(value = "国内/国外")
+ private String workTypeName;
+
+ /**
+ * inWorkNum
+ * 国内工作时间
+ */
+ private Long inWorkNum;
+
+ /**
+ * inWorkNum
+ * 国外工作时间
+ */
+ private Long outWorkNum;
+
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/ReportCardVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/ReportCardVo.java
new file mode 100644
index 0000000..eeea653
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/ReportCardVo.java
@@ -0,0 +1,44 @@
+package com.gear.oa.domain.vo;
+
+
+import lombok.Data;
+
+@Data
+public class ReportCardVo {
+
+ /**
+ * 今日报工
+ */
+ private Long todayCount;
+
+ /**
+ * 昨日报工
+ */
+ private Long todayCountChange;
+
+ /**
+ * 今日涉及项目数
+ */
+ private Long inProgressProjects;
+
+ /**
+ * 昨日涉及项目数量
+ */
+ private Long projectChange;
+
+ /**
+ * 涉及完成
+ */
+ private Long completionRate;
+
+ /**
+ * 昨日涉及完成
+ */
+ private Long completionChange;
+
+ /**
+ * 未完成(等待,未完成,待)
+ */
+ private Long exceptions;
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/ReportPieVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/ReportPieVo.java
new file mode 100644
index 0000000..b3e7e22
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/ReportPieVo.java
@@ -0,0 +1,11 @@
+package com.gear.oa.domain.vo;
+
+
+import lombok.Data;
+
+@Data
+public class ReportPieVo {
+
+ private String projectName;
+ private Integer value;
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/ReportTrendVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/ReportTrendVo.java
new file mode 100644
index 0000000..d6b9a55
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/ReportTrendVo.java
@@ -0,0 +1,14 @@
+package com.gear.oa.domain.vo;
+
+import lombok.Data;
+
+import java.time.LocalDate;
+
+@Data
+public class ReportTrendVo {
+
+ private LocalDate date;
+
+ private Integer count;
+
+}
diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/OaExpressMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/OaExpressMapper.java
new file mode 100644
index 0000000..5527ffa
--- /dev/null
+++ b/gear-oa/src/main/java/com/gear/oa/mapper/OaExpressMapper.java
@@ -0,0 +1,23 @@
+package com.gear.oa.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.gear.common.core.mapper.BaseMapperPlus;
+import com.gear.oa.domain.OaExpress;
+import com.gear.oa.domain.vo.OaExpressVo;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 物流预览Mapper接口
+ *
+ * @author hdka
+ * @date 2025-07-20
+ */
+public interface OaExpressMapper extends BaseMapperPlus {
+
+ Page selectVoPagePlus(@Param("build") Page