Browse Source

Merge remote-tracking branch 'origin/master'

wangxx 1 month ago
parent
commit
dcc0e2592c
15 changed files with 2028 additions and 0 deletions
  1. 140 0
      airport-admin/src/main/java/com/sundot/airport/web/controller/ledger/LedgerContractExpirationController.java
  2. 100 0
      airport-admin/src/main/java/com/sundot/airport/web/controller/ledger/LedgerContractExpirationDetailController.java
  3. 249 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/domain/LedgerContractExpiration.java
  4. 128 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/domain/LedgerContractExpirationDetail.java
  5. 41 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/dto/LedgerContractExpirationImportTemplateDTO.java
  6. 62 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/mapper/LedgerContractExpirationDetailMapper.java
  7. 62 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/mapper/LedgerContractExpirationMapper.java
  8. 62 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/service/ILedgerContractExpirationDetailService.java
  9. 71 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/service/ILedgerContractExpirationService.java
  10. 91 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/LedgerContractExpirationDetailServiceImpl.java
  11. 303 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/LedgerContractExpirationServiceImpl.java
  12. 144 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/utils/LedgerContractExcelExportUtil.java
  13. 296 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/utils/LedgerContractExcelImportUtil.java
  14. 121 0
      airport-ledger/src/main/resources/mapper/ledger/LedgerContractExpirationDetailMapper.xml
  15. 158 0
      airport-ledger/src/main/resources/mapper/ledger/LedgerContractExpirationMapper.xml

+ 140 - 0
airport-admin/src/main/java/com/sundot/airport/web/controller/ledger/LedgerContractExpirationController.java

@@ -0,0 +1,140 @@
1
+package com.sundot.airport.web.controller.ledger;
2
+
3
+import java.util.List;
4
+import java.util.Map;
5
+import java.util.stream.Collectors;
6
+import javax.servlet.http.HttpServletResponse;
7
+
8
+import com.sundot.airport.common.core.domain.entity.SysDictData;
9
+import com.sundot.airport.ledger.dto.LedgerContractExpirationImportTemplateDTO;
10
+import com.sundot.airport.ledger.utils.LedgerContractExcelExportUtil;
11
+import com.sundot.airport.ledger.utils.LedgerContractExcelImportUtil;
12
+import com.sundot.airport.system.service.ISysDictDataService;
13
+import org.apache.poi.ss.usermodel.Workbook;
14
+import org.apache.poi.ss.usermodel.WorkbookFactory;
15
+import org.springframework.security.access.prepost.PreAuthorize;
16
+import org.springframework.beans.factory.annotation.Autowired;
17
+import org.springframework.web.bind.annotation.GetMapping;
18
+import org.springframework.web.bind.annotation.PostMapping;
19
+import org.springframework.web.bind.annotation.PutMapping;
20
+import org.springframework.web.bind.annotation.DeleteMapping;
21
+import org.springframework.web.bind.annotation.PathVariable;
22
+import org.springframework.web.bind.annotation.RequestBody;
23
+import org.springframework.web.bind.annotation.RequestMapping;
24
+import org.springframework.web.bind.annotation.RestController;
25
+import com.sundot.airport.common.annotation.Log;
26
+import com.sundot.airport.common.core.controller.BaseController;
27
+import com.sundot.airport.common.core.domain.AjaxResult;
28
+import com.sundot.airport.common.enums.BusinessType;
29
+import com.sundot.airport.ledger.domain.LedgerContractExpiration;
30
+import com.sundot.airport.ledger.service.ILedgerContractExpirationService;
31
+import com.sundot.airport.common.utils.poi.ExcelUtil;
32
+import com.sundot.airport.common.core.page.TableDataInfo;
33
+import org.springframework.web.multipart.MultipartFile;
34
+
35
+/**
36
+ * 合同到期Controller
37
+ *
38
+ * @author ruoyi
39
+ * @date 2026-06-30
40
+ */
41
+@RestController
42
+@RequestMapping("/ledger/contract")
43
+public class LedgerContractExpirationController extends BaseController {
44
+    @Autowired
45
+    private ILedgerContractExpirationService ledgerContractExpirationService;
46
+    @Autowired
47
+    private ISysDictDataService sysDictDataService;
48
+
49
+    /**
50
+     * 查询合同到期列表
51
+     */
52
+    @PreAuthorize("@ss.hasPermi('ledger:contract:list')")
53
+    @GetMapping("/list")
54
+    public TableDataInfo list(LedgerContractExpiration ledgerContractExpiration) {
55
+        startPage();
56
+        List<LedgerContractExpiration> list = ledgerContractExpirationService.selectLedgerContractExpirationList(ledgerContractExpiration);
57
+        return getDataTable(list);
58
+    }
59
+
60
+    /**
61
+     * 导出合同到期列表
62
+     */
63
+    @PreAuthorize("@ss.hasPermi('ledger:contract:export')")
64
+    @Log(title = "合同到期", businessType = BusinessType.EXPORT)
65
+    @PostMapping("/export")
66
+    public void export(HttpServletResponse response, LedgerContractExpiration ledgerContractExpiration) {
67
+        List<LedgerContractExpiration> list = ledgerContractExpirationService.selectLedgerContractExpirationList(ledgerContractExpiration);
68
+        // 用工形式
69
+        SysDictData sexDictData = new SysDictData();
70
+        sexDictData.setDictType("employment_type");
71
+        List<SysDictData> sexDictDataList = sysDictDataService.selectDictDataList(sexDictData);
72
+        Map<String, String> sexDictDataMap = sexDictDataList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
73
+        LedgerContractExcelExportUtil.exportExcel(response, list, "合同到期数据", sexDictDataMap);
74
+    }
75
+
76
+    /**
77
+     * 获取合同到期详细信息
78
+     */
79
+    @PreAuthorize("@ss.hasPermi('ledger:contract:query')")
80
+    @GetMapping(value = "/{id}")
81
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
82
+        return success(ledgerContractExpirationService.selectLedgerContractExpirationById(id));
83
+    }
84
+
85
+    /**
86
+     * 新增合同到期
87
+     */
88
+    @PreAuthorize("@ss.hasPermi('ledger:contract:add')")
89
+    @Log(title = "合同到期", businessType = BusinessType.INSERT)
90
+    @PostMapping
91
+    public AjaxResult add(@RequestBody LedgerContractExpiration ledgerContractExpiration) {
92
+        ledgerContractExpiration.setCreateBy(getUsername());
93
+        return toAjax(ledgerContractExpirationService.insertLedgerContractExpiration(ledgerContractExpiration));
94
+    }
95
+
96
+    /**
97
+     * 修改合同到期
98
+     */
99
+    @PreAuthorize("@ss.hasPermi('ledger:contract:edit')")
100
+    @Log(title = "合同到期", businessType = BusinessType.UPDATE)
101
+    @PutMapping
102
+    public AjaxResult edit(@RequestBody LedgerContractExpiration ledgerContractExpiration) {
103
+        ledgerContractExpiration.setUpdateBy(getUsername());
104
+        return toAjax(ledgerContractExpirationService.updateLedgerContractExpiration(ledgerContractExpiration));
105
+    }
106
+
107
+    /**
108
+     * 删除合同到期
109
+     */
110
+    @PreAuthorize("@ss.hasPermi('ledger:contract:remove')")
111
+    @Log(title = "合同到期", businessType = BusinessType.DELETE)
112
+    @DeleteMapping("/{ids}")
113
+    public AjaxResult remove(@PathVariable Long[] ids) {
114
+        return toAjax(ledgerContractExpirationService.deleteLedgerContractExpirationByIds(ids));
115
+    }
116
+
117
+    /**
118
+     * 导入数据列表
119
+     */
120
+    @PreAuthorize("@ss.hasPermi('ledger:excluded:import')")
121
+    @Log(title = "导入数据列表", businessType = BusinessType.IMPORT)
122
+    @PostMapping("/importData")
123
+    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
124
+        // 使用自定义工具类解析Excel,支持动态合同起止日期列
125
+        Workbook workbook = WorkbookFactory.create(file.getInputStream());
126
+        List<LedgerContractExpiration> list = LedgerContractExcelImportUtil.parseContractExcel(workbook);
127
+        workbook.close();
128
+        String message = ledgerContractExpirationService.importData(list, updateSupport);
129
+        return success(message);
130
+    }
131
+
132
+    /**
133
+     * 获取导入模板
134
+     */
135
+    @PostMapping("/importTemplate")
136
+    public void importTemplate(HttpServletResponse response) {
137
+        ExcelUtil<LedgerContractExpirationImportTemplateDTO> util = new ExcelUtil<>(LedgerContractExpirationImportTemplateDTO.class);
138
+        util.importTemplateExcel(response, "合同到期数据导入模板");
139
+    }
140
+}

+ 100 - 0
airport-admin/src/main/java/com/sundot/airport/web/controller/ledger/LedgerContractExpirationDetailController.java

@@ -0,0 +1,100 @@
1
+package com.sundot.airport.web.controller.ledger;
2
+
3
+import java.util.List;
4
+import javax.servlet.http.HttpServletResponse;
5
+
6
+import org.springframework.security.access.prepost.PreAuthorize;
7
+import org.springframework.beans.factory.annotation.Autowired;
8
+import org.springframework.web.bind.annotation.GetMapping;
9
+import org.springframework.web.bind.annotation.PostMapping;
10
+import org.springframework.web.bind.annotation.PutMapping;
11
+import org.springframework.web.bind.annotation.DeleteMapping;
12
+import org.springframework.web.bind.annotation.PathVariable;
13
+import org.springframework.web.bind.annotation.RequestBody;
14
+import org.springframework.web.bind.annotation.RequestMapping;
15
+import org.springframework.web.bind.annotation.RestController;
16
+import com.sundot.airport.common.annotation.Log;
17
+import com.sundot.airport.common.core.controller.BaseController;
18
+import com.sundot.airport.common.core.domain.AjaxResult;
19
+import com.sundot.airport.common.enums.BusinessType;
20
+import com.sundot.airport.ledger.domain.LedgerContractExpirationDetail;
21
+import com.sundot.airport.ledger.service.ILedgerContractExpirationDetailService;
22
+import com.sundot.airport.common.utils.poi.ExcelUtil;
23
+import com.sundot.airport.common.core.page.TableDataInfo;
24
+
25
+/**
26
+ * 合同到期明细Controller
27
+ *
28
+ * @author ruoyi
29
+ * @date 2026-06-30
30
+ */
31
+@RestController
32
+@RequestMapping("/ledger/contractDetail")
33
+public class LedgerContractExpirationDetailController extends BaseController {
34
+    @Autowired
35
+    private ILedgerContractExpirationDetailService ledgerContractExpirationDetailService;
36
+
37
+    /**
38
+     * 查询合同到期明细列表
39
+     */
40
+    @PreAuthorize("@ss.hasPermi('ledger:contractDetail:list')")
41
+    @GetMapping("/list")
42
+    public TableDataInfo list(LedgerContractExpirationDetail ledgerContractExpirationDetail) {
43
+        startPage();
44
+        List<LedgerContractExpirationDetail> list = ledgerContractExpirationDetailService.selectLedgerContractExpirationDetailList(ledgerContractExpirationDetail);
45
+        return getDataTable(list);
46
+    }
47
+
48
+    /**
49
+     * 导出合同到期明细列表
50
+     */
51
+    @PreAuthorize("@ss.hasPermi('ledger:contractDetail:export')")
52
+    @Log(title = "合同到期明细", businessType = BusinessType.EXPORT)
53
+    @PostMapping("/export")
54
+    public void export(HttpServletResponse response, LedgerContractExpirationDetail ledgerContractExpirationDetail) {
55
+        List<LedgerContractExpirationDetail> list = ledgerContractExpirationDetailService.selectLedgerContractExpirationDetailList(ledgerContractExpirationDetail);
56
+        ExcelUtil<LedgerContractExpirationDetail> util = new ExcelUtil<LedgerContractExpirationDetail>(LedgerContractExpirationDetail.class);
57
+        util.exportExcel(response, list, "合同到期明细数据");
58
+    }
59
+
60
+    /**
61
+     * 获取合同到期明细详细信息
62
+     */
63
+    @PreAuthorize("@ss.hasPermi('ledger:contractDetail:query')")
64
+    @GetMapping(value = "/{id}")
65
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
66
+        return success(ledgerContractExpirationDetailService.selectLedgerContractExpirationDetailById(id));
67
+    }
68
+
69
+    /**
70
+     * 新增合同到期明细
71
+     */
72
+    @PreAuthorize("@ss.hasPermi('ledger:contractDetail:add')")
73
+    @Log(title = "合同到期明细", businessType = BusinessType.INSERT)
74
+    @PostMapping
75
+    public AjaxResult add(@RequestBody LedgerContractExpirationDetail ledgerContractExpirationDetail) {
76
+        ledgerContractExpirationDetail.setCreateBy(getUsername());
77
+        return toAjax(ledgerContractExpirationDetailService.insertLedgerContractExpirationDetail(ledgerContractExpirationDetail));
78
+    }
79
+
80
+    /**
81
+     * 修改合同到期明细
82
+     */
83
+    @PreAuthorize("@ss.hasPermi('ledger:contractDetail:edit')")
84
+    @Log(title = "合同到期明细", businessType = BusinessType.UPDATE)
85
+    @PutMapping
86
+    public AjaxResult edit(@RequestBody LedgerContractExpirationDetail ledgerContractExpirationDetail) {
87
+        ledgerContractExpirationDetail.setUpdateBy(getUsername());
88
+        return toAjax(ledgerContractExpirationDetailService.updateLedgerContractExpirationDetail(ledgerContractExpirationDetail));
89
+    }
90
+
91
+    /**
92
+     * 删除合同到期明细
93
+     */
94
+    @PreAuthorize("@ss.hasPermi('ledger:contractDetail:remove')")
95
+    @Log(title = "合同到期明细", businessType = BusinessType.DELETE)
96
+    @DeleteMapping("/{ids}")
97
+    public AjaxResult remove(@PathVariable Long[] ids) {
98
+        return toAjax(ledgerContractExpirationDetailService.deleteLedgerContractExpirationDetailByIds(ids));
99
+    }
100
+}

+ 249 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/domain/LedgerContractExpiration.java

@@ -0,0 +1,249 @@
1
+package com.sundot.airport.ledger.domain;
2
+
3
+import java.util.Date;
4
+import java.util.List;
5
+
6
+import com.baomidou.mybatisplus.annotation.IdType;
7
+import com.baomidou.mybatisplus.annotation.TableField;
8
+import com.baomidou.mybatisplus.annotation.TableId;
9
+import com.baomidou.mybatisplus.annotation.TableName;
10
+import com.fasterxml.jackson.annotation.JsonFormat;
11
+import org.apache.commons.lang3.builder.ToStringBuilder;
12
+import org.apache.commons.lang3.builder.ToStringStyle;
13
+import com.sundot.airport.common.annotation.Excel;
14
+import com.sundot.airport.common.core.domain.BaseEntity;
15
+import org.springframework.format.annotation.DateTimeFormat;
16
+
17
+/**
18
+ * 合同到期对象 ledger_contract_expiration
19
+ *
20
+ * @author ruoyi
21
+ * @date 2026-06-30
22
+ */
23
+@TableName("ledger_contract_expiration")
24
+public class LedgerContractExpiration extends BaseEntity {
25
+    private static final long serialVersionUID = 1L;
26
+
27
+    /** 租户号 */
28
+    private String tenantId;
29
+
30
+    /** 乐观锁 */
31
+    private Integer revision;
32
+
33
+    /** 主键 */
34
+    @TableId(type = IdType.AUTO)
35
+    private Long id;
36
+
37
+    /** 用户ID */
38
+    private Long userId;
39
+
40
+    /** 用户名称 */
41
+    @Excel(name = "用户名称")
42
+    private String userName;
43
+
44
+    /** 合同名称 */
45
+    @Excel(name = "合同名称", type = Excel.Type.EXPORT)
46
+    private String contractName;
47
+
48
+    /** 合同开始日期 */
49
+    @JsonFormat(pattern = "yyyy-MM-dd")
50
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
51
+    @Excel(name = "合同开始日期", width = 30, dateFormat = "yyyy-MM-dd", type = Excel.Type.EXPORT)
52
+    private Date contractStartDate;
53
+
54
+    /** 合同结束日期 */
55
+    @JsonFormat(pattern = "yyyy-MM-dd")
56
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
57
+    @Excel(name = "合同结束日期", width = 30, dateFormat = "yyyy-MM-dd", type = Excel.Type.EXPORT)
58
+    private Date contractEndDate;
59
+
60
+    /** 大队ID */
61
+    private Long brigadeId;
62
+
63
+    /** 大队名称 */
64
+    @Excel(name = "大队名称", type = Excel.Type.EXPORT)
65
+    private String brigadeName;
66
+
67
+    /** 用工形式 */
68
+    @Excel(name = "用工形式", readConverterExp = "DISPATCHED_WORKER=派遣工,REGULAR_EMPLOYEE=正式工,INTERN=实习生", combo = "派遣工,正式工,实习生", type = Excel.Type.EXPORT)
69
+    private String employmentType;
70
+
71
+    /** 合同开始日期-查询开始日期 */
72
+    @TableField(exist = false)
73
+    @JsonFormat(pattern = "yyyy-MM-dd")
74
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
75
+    private Date contractStartDateQueryStartDate;
76
+
77
+    /** 合同开始日期-查询结束日期 */
78
+    @TableField(exist = false)
79
+    @JsonFormat(pattern = "yyyy-MM-dd")
80
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
81
+    private Date contractStartDateQueryEndDate;
82
+
83
+    /** 合同结束日期-查询开始日期 */
84
+    @TableField(exist = false)
85
+    @JsonFormat(pattern = "yyyy-MM-dd")
86
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
87
+    private Date contractEndDateQueryStartDate;
88
+
89
+    /** 合同结束日期-查询结束日期 */
90
+    @TableField(exist = false)
91
+    @JsonFormat(pattern = "yyyy-MM-dd")
92
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
93
+    private Date contractEndDateQueryEndDate;
94
+
95
+    /** 合同到期明细列表 */
96
+    @TableField(exist = false)
97
+    private List<LedgerContractExpirationDetail> ledgerContractExpirationDetailList;
98
+
99
+    public void setTenantId(String tenantId) {
100
+        this.tenantId = tenantId;
101
+    }
102
+
103
+    public String getTenantId() {
104
+        return tenantId;
105
+    }
106
+
107
+    public void setRevision(Integer revision) {
108
+        this.revision = revision;
109
+    }
110
+
111
+    public Integer getRevision() {
112
+        return revision;
113
+    }
114
+
115
+    public void setId(Long id) {
116
+        this.id = id;
117
+    }
118
+
119
+    public Long getId() {
120
+        return id;
121
+    }
122
+
123
+    public void setUserId(Long userId) {
124
+        this.userId = userId;
125
+    }
126
+
127
+    public Long getUserId() {
128
+        return userId;
129
+    }
130
+
131
+    public void setUserName(String userName) {
132
+        this.userName = userName;
133
+    }
134
+
135
+    public String getUserName() {
136
+        return userName;
137
+    }
138
+
139
+    public void setContractName(String contractName) {
140
+        this.contractName = contractName;
141
+    }
142
+
143
+    public String getContractName() {
144
+        return contractName;
145
+    }
146
+
147
+    public void setContractStartDate(Date contractStartDate) {
148
+        this.contractStartDate = contractStartDate;
149
+    }
150
+
151
+    public Date getContractStartDate() {
152
+        return contractStartDate;
153
+    }
154
+
155
+    public void setContractEndDate(Date contractEndDate) {
156
+        this.contractEndDate = contractEndDate;
157
+    }
158
+
159
+    public Date getContractEndDate() {
160
+        return contractEndDate;
161
+    }
162
+
163
+    public void setBrigadeId(Long brigadeId) {
164
+        this.brigadeId = brigadeId;
165
+    }
166
+
167
+    public Long getBrigadeId() {
168
+        return brigadeId;
169
+    }
170
+
171
+    public void setBrigadeName(String brigadeName) {
172
+        this.brigadeName = brigadeName;
173
+    }
174
+
175
+    public String getBrigadeName() {
176
+        return brigadeName;
177
+    }
178
+
179
+    public void setEmploymentType(String employmentType) {
180
+        this.employmentType = employmentType;
181
+    }
182
+
183
+    public String getEmploymentType() {
184
+        return employmentType;
185
+    }
186
+
187
+    public Date getContractStartDateQueryStartDate() {
188
+        return contractStartDateQueryStartDate;
189
+    }
190
+
191
+    public void setContractStartDateQueryStartDate(Date contractStartDateQueryStartDate) {
192
+        this.contractStartDateQueryStartDate = contractStartDateQueryStartDate;
193
+    }
194
+
195
+    public Date getContractStartDateQueryEndDate() {
196
+        return contractStartDateQueryEndDate;
197
+    }
198
+
199
+    public void setContractStartDateQueryEndDate(Date contractStartDateQueryEndDate) {
200
+        this.contractStartDateQueryEndDate = contractStartDateQueryEndDate;
201
+    }
202
+
203
+    public Date getContractEndDateQueryStartDate() {
204
+        return contractEndDateQueryStartDate;
205
+    }
206
+
207
+    public void setContractEndDateQueryStartDate(Date contractEndDateQueryStartDate) {
208
+        this.contractEndDateQueryStartDate = contractEndDateQueryStartDate;
209
+    }
210
+
211
+    public Date getContractEndDateQueryEndDate() {
212
+        return contractEndDateQueryEndDate;
213
+    }
214
+
215
+    public void setContractEndDateQueryEndDate(Date contractEndDateQueryEndDate) {
216
+        this.contractEndDateQueryEndDate = contractEndDateQueryEndDate;
217
+    }
218
+
219
+    public List<LedgerContractExpirationDetail> getLedgerContractExpirationDetailList() {
220
+        return ledgerContractExpirationDetailList;
221
+    }
222
+
223
+    public void setLedgerContractExpirationDetailList(List<LedgerContractExpirationDetail> ledgerContractExpirationDetailList) {
224
+        this.ledgerContractExpirationDetailList = ledgerContractExpirationDetailList;
225
+    }
226
+
227
+    @Override
228
+    public String toString() {
229
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
230
+                .append("tenantId", getTenantId())
231
+                .append("revision", getRevision())
232
+                .append("createBy", getCreateBy())
233
+                .append("createTime", getCreateTime())
234
+                .append("updateBy", getUpdateBy())
235
+                .append("updateTime", getUpdateTime())
236
+                .append("remark", getRemark())
237
+                .append("id", getId())
238
+                .append("userId", getUserId())
239
+                .append("userName", getUserName())
240
+                .append("contractName", getContractName())
241
+                .append("contractStartDate", getContractStartDate())
242
+                .append("contractEndDate", getContractEndDate())
243
+                .append("brigadeId", getBrigadeId())
244
+                .append("brigadeName", getBrigadeName())
245
+                .append("employmentType", getEmploymentType())
246
+                .append("ledgerContractExpirationDetailList", getLedgerContractExpirationDetailList())
247
+                .toString();
248
+    }
249
+}

+ 128 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/domain/LedgerContractExpirationDetail.java

@@ -0,0 +1,128 @@
1
+package com.sundot.airport.ledger.domain;
2
+
3
+import java.util.Date;
4
+
5
+import com.baomidou.mybatisplus.annotation.IdType;
6
+import com.baomidou.mybatisplus.annotation.TableId;
7
+import com.baomidou.mybatisplus.annotation.TableName;
8
+import com.fasterxml.jackson.annotation.JsonFormat;
9
+import org.apache.commons.lang3.builder.ToStringBuilder;
10
+import org.apache.commons.lang3.builder.ToStringStyle;
11
+import com.sundot.airport.common.annotation.Excel;
12
+import com.sundot.airport.common.core.domain.BaseEntity;
13
+import org.springframework.format.annotation.DateTimeFormat;
14
+
15
+/**
16
+ * 合同到期明细对象 ledger_contract_expiration_detail
17
+ *
18
+ * @author ruoyi
19
+ * @date 2026-06-30
20
+ */
21
+@TableName("ledger_contract_expiration_detail")
22
+public class LedgerContractExpirationDetail extends BaseEntity {
23
+    private static final long serialVersionUID = 1L;
24
+
25
+    /** 租户号 */
26
+    private String tenantId;
27
+
28
+    /** 乐观锁 */
29
+    private Integer revision;
30
+
31
+    /** 主键 */
32
+    @TableId(type = IdType.AUTO)
33
+    private Long id;
34
+
35
+    /** 来源ID */
36
+    @Excel(name = "来源ID")
37
+    private Long sourceId;
38
+
39
+    /** 合同名称 */
40
+    @Excel(name = "合同名称")
41
+    private String contractName;
42
+
43
+    /** 合同开始日期 */
44
+    @JsonFormat(pattern = "yyyy-MM-dd")
45
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
46
+    @Excel(name = "合同开始日期", width = 30, dateFormat = "yyyy-MM-dd")
47
+    private Date contractStartDate;
48
+
49
+    /** 合同结束日期 */
50
+    @JsonFormat(pattern = "yyyy-MM-dd")
51
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
52
+    @Excel(name = "合同结束日期", width = 30, dateFormat = "yyyy-MM-dd")
53
+    private Date contractEndDate;
54
+
55
+    public void setTenantId(String tenantId) {
56
+        this.tenantId = tenantId;
57
+    }
58
+
59
+    public String getTenantId() {
60
+        return tenantId;
61
+    }
62
+
63
+    public void setRevision(Integer revision) {
64
+        this.revision = revision;
65
+    }
66
+
67
+    public Integer getRevision() {
68
+        return revision;
69
+    }
70
+
71
+    public void setId(Long id) {
72
+        this.id = id;
73
+    }
74
+
75
+    public Long getId() {
76
+        return id;
77
+    }
78
+
79
+    public void setSourceId(Long sourceId) {
80
+        this.sourceId = sourceId;
81
+    }
82
+
83
+    public Long getSourceId() {
84
+        return sourceId;
85
+    }
86
+
87
+    public void setContractName(String contractName) {
88
+        this.contractName = contractName;
89
+    }
90
+
91
+    public String getContractName() {
92
+        return contractName;
93
+    }
94
+
95
+    public void setContractStartDate(Date contractStartDate) {
96
+        this.contractStartDate = contractStartDate;
97
+    }
98
+
99
+    public Date getContractStartDate() {
100
+        return contractStartDate;
101
+    }
102
+
103
+    public void setContractEndDate(Date contractEndDate) {
104
+        this.contractEndDate = contractEndDate;
105
+    }
106
+
107
+    public Date getContractEndDate() {
108
+        return contractEndDate;
109
+    }
110
+
111
+    @Override
112
+    public String toString() {
113
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
114
+                .append("tenantId", getTenantId())
115
+                .append("revision", getRevision())
116
+                .append("createBy", getCreateBy())
117
+                .append("createTime", getCreateTime())
118
+                .append("updateBy", getUpdateBy())
119
+                .append("updateTime", getUpdateTime())
120
+                .append("remark", getRemark())
121
+                .append("id", getId())
122
+                .append("sourceId", getSourceId())
123
+                .append("contractName", getContractName())
124
+                .append("contractStartDate", getContractStartDate())
125
+                .append("contractEndDate", getContractEndDate())
126
+                .toString();
127
+    }
128
+}

+ 41 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/dto/LedgerContractExpirationImportTemplateDTO.java

@@ -0,0 +1,41 @@
1
+package com.sundot.airport.ledger.dto;
2
+
3
+import com.sundot.airport.common.annotation.Excel;
4
+import lombok.Data;
5
+
6
+import java.io.Serializable;
7
+
8
+/**
9
+ * 合同到期导入模板对象
10
+ *
11
+ * @author ruoyi
12
+ * @date 2026-06-30
13
+ */
14
+@Data
15
+public class LedgerContractExpirationImportTemplateDTO implements Serializable {
16
+    private static final long serialVersionUID = 1L;
17
+
18
+    /** 用户名称 */
19
+    @Excel(name = "用户名称")
20
+    private String userName;
21
+
22
+    /** 合同1起止日期 */
23
+    @Excel(name = "合同1起止日期")
24
+    private String contract1StartEndDate;
25
+
26
+    /** 合同2起止日期 */
27
+    @Excel(name = "合同2起止日期")
28
+    private String contract2StartEndDate;
29
+
30
+    /** 合同3起止日期 */
31
+    @Excel(name = "合同3起止日期")
32
+    private String contract3StartEndDate;
33
+
34
+    /** 合同4起止日期 */
35
+    @Excel(name = "合同4起止日期")
36
+    private String contract4StartEndDate;
37
+
38
+    /** 合同5起止日期 */
39
+    @Excel(name = "合同5起止日期")
40
+    private String contract5StartEndDate;
41
+}

+ 62 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/mapper/LedgerContractExpirationDetailMapper.java

@@ -0,0 +1,62 @@
1
+package com.sundot.airport.ledger.mapper;
2
+
3
+import java.util.List;
4
+
5
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
6
+import com.sundot.airport.ledger.domain.LedgerContractExpirationDetail;
7
+
8
+/**
9
+ * 合同到期明细Mapper接口
10
+ *
11
+ * @author ruoyi
12
+ * @date 2026-06-30
13
+ */
14
+public interface LedgerContractExpirationDetailMapper extends BaseMapper<LedgerContractExpirationDetail> {
15
+    /**
16
+     * 查询合同到期明细
17
+     *
18
+     * @param id 合同到期明细主键
19
+     * @return 合同到期明细
20
+     */
21
+    public LedgerContractExpirationDetail selectLedgerContractExpirationDetailById(Long id);
22
+
23
+    /**
24
+     * 查询合同到期明细列表
25
+     *
26
+     * @param ledgerContractExpirationDetail 合同到期明细
27
+     * @return 合同到期明细集合
28
+     */
29
+    public List<LedgerContractExpirationDetail> selectLedgerContractExpirationDetailList(LedgerContractExpirationDetail ledgerContractExpirationDetail);
30
+
31
+    /**
32
+     * 新增合同到期明细
33
+     *
34
+     * @param ledgerContractExpirationDetail 合同到期明细
35
+     * @return 结果
36
+     */
37
+    public int insertLedgerContractExpirationDetail(LedgerContractExpirationDetail ledgerContractExpirationDetail);
38
+
39
+    /**
40
+     * 修改合同到期明细
41
+     *
42
+     * @param ledgerContractExpirationDetail 合同到期明细
43
+     * @return 结果
44
+     */
45
+    public int updateLedgerContractExpirationDetail(LedgerContractExpirationDetail ledgerContractExpirationDetail);
46
+
47
+    /**
48
+     * 删除合同到期明细
49
+     *
50
+     * @param id 合同到期明细主键
51
+     * @return 结果
52
+     */
53
+    public int deleteLedgerContractExpirationDetailById(Long id);
54
+
55
+    /**
56
+     * 批量删除合同到期明细
57
+     *
58
+     * @param ids 需要删除的数据主键集合
59
+     * @return 结果
60
+     */
61
+    public int deleteLedgerContractExpirationDetailByIds(Long[] ids);
62
+}

+ 62 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/mapper/LedgerContractExpirationMapper.java

@@ -0,0 +1,62 @@
1
+package com.sundot.airport.ledger.mapper;
2
+
3
+import java.util.List;
4
+
5
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
6
+import com.sundot.airport.ledger.domain.LedgerContractExpiration;
7
+
8
+/**
9
+ * 合同到期Mapper接口
10
+ *
11
+ * @author ruoyi
12
+ * @date 2026-06-30
13
+ */
14
+public interface LedgerContractExpirationMapper extends BaseMapper<LedgerContractExpiration> {
15
+    /**
16
+     * 查询合同到期
17
+     *
18
+     * @param id 合同到期主键
19
+     * @return 合同到期
20
+     */
21
+    public LedgerContractExpiration selectLedgerContractExpirationById(Long id);
22
+
23
+    /**
24
+     * 查询合同到期列表
25
+     *
26
+     * @param ledgerContractExpiration 合同到期
27
+     * @return 合同到期集合
28
+     */
29
+    public List<LedgerContractExpiration> selectLedgerContractExpirationList(LedgerContractExpiration ledgerContractExpiration);
30
+
31
+    /**
32
+     * 新增合同到期
33
+     *
34
+     * @param ledgerContractExpiration 合同到期
35
+     * @return 结果
36
+     */
37
+    public int insertLedgerContractExpiration(LedgerContractExpiration ledgerContractExpiration);
38
+
39
+    /**
40
+     * 修改合同到期
41
+     *
42
+     * @param ledgerContractExpiration 合同到期
43
+     * @return 结果
44
+     */
45
+    public int updateLedgerContractExpiration(LedgerContractExpiration ledgerContractExpiration);
46
+
47
+    /**
48
+     * 删除合同到期
49
+     *
50
+     * @param id 合同到期主键
51
+     * @return 结果
52
+     */
53
+    public int deleteLedgerContractExpirationById(Long id);
54
+
55
+    /**
56
+     * 批量删除合同到期
57
+     *
58
+     * @param ids 需要删除的数据主键集合
59
+     * @return 结果
60
+     */
61
+    public int deleteLedgerContractExpirationByIds(Long[] ids);
62
+}

+ 62 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/service/ILedgerContractExpirationDetailService.java

@@ -0,0 +1,62 @@
1
+package com.sundot.airport.ledger.service;
2
+
3
+import java.util.List;
4
+
5
+import com.baomidou.mybatisplus.extension.service.IService;
6
+import com.sundot.airport.ledger.domain.LedgerContractExpirationDetail;
7
+
8
+/**
9
+ * 合同到期明细Service接口
10
+ *
11
+ * @author ruoyi
12
+ * @date 2026-06-30
13
+ */
14
+public interface ILedgerContractExpirationDetailService extends IService<LedgerContractExpirationDetail> {
15
+    /**
16
+     * 查询合同到期明细
17
+     *
18
+     * @param id 合同到期明细主键
19
+     * @return 合同到期明细
20
+     */
21
+    public LedgerContractExpirationDetail selectLedgerContractExpirationDetailById(Long id);
22
+
23
+    /**
24
+     * 查询合同到期明细列表
25
+     *
26
+     * @param ledgerContractExpirationDetail 合同到期明细
27
+     * @return 合同到期明细集合
28
+     */
29
+    public List<LedgerContractExpirationDetail> selectLedgerContractExpirationDetailList(LedgerContractExpirationDetail ledgerContractExpirationDetail);
30
+
31
+    /**
32
+     * 新增合同到期明细
33
+     *
34
+     * @param ledgerContractExpirationDetail 合同到期明细
35
+     * @return 结果
36
+     */
37
+    public int insertLedgerContractExpirationDetail(LedgerContractExpirationDetail ledgerContractExpirationDetail);
38
+
39
+    /**
40
+     * 修改合同到期明细
41
+     *
42
+     * @param ledgerContractExpirationDetail 合同到期明细
43
+     * @return 结果
44
+     */
45
+    public int updateLedgerContractExpirationDetail(LedgerContractExpirationDetail ledgerContractExpirationDetail);
46
+
47
+    /**
48
+     * 批量删除合同到期明细
49
+     *
50
+     * @param ids 需要删除的合同到期明细主键集合
51
+     * @return 结果
52
+     */
53
+    public int deleteLedgerContractExpirationDetailByIds(Long[] ids);
54
+
55
+    /**
56
+     * 删除合同到期明细信息
57
+     *
58
+     * @param id 合同到期明细主键
59
+     * @return 结果
60
+     */
61
+    public int deleteLedgerContractExpirationDetailById(Long id);
62
+}

+ 71 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/service/ILedgerContractExpirationService.java

@@ -0,0 +1,71 @@
1
+package com.sundot.airport.ledger.service;
2
+
3
+import java.util.List;
4
+
5
+import com.baomidou.mybatisplus.extension.service.IService;
6
+import com.sundot.airport.ledger.domain.LedgerContractExpiration;
7
+
8
+/**
9
+ * 合同到期Service接口
10
+ *
11
+ * @author ruoyi
12
+ * @date 2026-06-30
13
+ */
14
+public interface ILedgerContractExpirationService extends IService<LedgerContractExpiration> {
15
+    /**
16
+     * 查询合同到期
17
+     *
18
+     * @param id 合同到期主键
19
+     * @return 合同到期
20
+     */
21
+    public LedgerContractExpiration selectLedgerContractExpirationById(Long id);
22
+
23
+    /**
24
+     * 查询合同到期列表
25
+     *
26
+     * @param ledgerContractExpiration 合同到期
27
+     * @return 合同到期集合
28
+     */
29
+    public List<LedgerContractExpiration> selectLedgerContractExpirationList(LedgerContractExpiration ledgerContractExpiration);
30
+
31
+    /**
32
+     * 新增合同到期
33
+     *
34
+     * @param ledgerContractExpiration 合同到期
35
+     * @return 结果
36
+     */
37
+    public int insertLedgerContractExpiration(LedgerContractExpiration ledgerContractExpiration);
38
+
39
+    /**
40
+     * 修改合同到期
41
+     *
42
+     * @param ledgerContractExpiration 合同到期
43
+     * @return 结果
44
+     */
45
+    public int updateLedgerContractExpiration(LedgerContractExpiration ledgerContractExpiration);
46
+
47
+    /**
48
+     * 批量删除合同到期
49
+     *
50
+     * @param ids 需要删除的合同到期主键集合
51
+     * @return 结果
52
+     */
53
+    public int deleteLedgerContractExpirationByIds(Long[] ids);
54
+
55
+    /**
56
+     * 删除合同到期信息
57
+     *
58
+     * @param id 合同到期主键
59
+     * @return 结果
60
+     */
61
+    public int deleteLedgerContractExpirationById(Long id);
62
+
63
+    /**
64
+     * 导入数据列表
65
+     *
66
+     * @param list          数据列表
67
+     * @param updateSupport 是否更新支持
68
+     * @return 导入结果信息
69
+     */
70
+    public String importData(List<LedgerContractExpiration> list, boolean updateSupport);
71
+}

+ 91 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/LedgerContractExpirationDetailServiceImpl.java

@@ -0,0 +1,91 @@
1
+package com.sundot.airport.ledger.service.impl;
2
+
3
+import java.util.List;
4
+
5
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
6
+import com.sundot.airport.common.utils.DateUtils;
7
+import org.springframework.beans.factory.annotation.Autowired;
8
+import org.springframework.stereotype.Service;
9
+import com.sundot.airport.ledger.mapper.LedgerContractExpirationDetailMapper;
10
+import com.sundot.airport.ledger.domain.LedgerContractExpirationDetail;
11
+import com.sundot.airport.ledger.service.ILedgerContractExpirationDetailService;
12
+
13
+/**
14
+ * 合同到期明细Service业务层处理
15
+ *
16
+ * @author ruoyi
17
+ * @date 2026-06-30
18
+ */
19
+@Service
20
+public class LedgerContractExpirationDetailServiceImpl extends ServiceImpl<LedgerContractExpirationDetailMapper, LedgerContractExpirationDetail> implements ILedgerContractExpirationDetailService {
21
+    @Autowired
22
+    private LedgerContractExpirationDetailMapper ledgerContractExpirationDetailMapper;
23
+
24
+    /**
25
+     * 查询合同到期明细
26
+     *
27
+     * @param id 合同到期明细主键
28
+     * @return 合同到期明细
29
+     */
30
+    @Override
31
+    public LedgerContractExpirationDetail selectLedgerContractExpirationDetailById(Long id) {
32
+        return ledgerContractExpirationDetailMapper.selectLedgerContractExpirationDetailById(id);
33
+    }
34
+
35
+    /**
36
+     * 查询合同到期明细列表
37
+     *
38
+     * @param ledgerContractExpirationDetail 合同到期明细
39
+     * @return 合同到期明细
40
+     */
41
+    @Override
42
+    public List<LedgerContractExpirationDetail> selectLedgerContractExpirationDetailList(LedgerContractExpirationDetail ledgerContractExpirationDetail) {
43
+        return ledgerContractExpirationDetailMapper.selectLedgerContractExpirationDetailList(ledgerContractExpirationDetail);
44
+    }
45
+
46
+    /**
47
+     * 新增合同到期明细
48
+     *
49
+     * @param ledgerContractExpirationDetail 合同到期明细
50
+     * @return 结果
51
+     */
52
+    @Override
53
+    public int insertLedgerContractExpirationDetail(LedgerContractExpirationDetail ledgerContractExpirationDetail) {
54
+        ledgerContractExpirationDetail.setCreateTime(DateUtils.getNowDate());
55
+        return ledgerContractExpirationDetailMapper.insertLedgerContractExpirationDetail(ledgerContractExpirationDetail);
56
+    }
57
+
58
+    /**
59
+     * 修改合同到期明细
60
+     *
61
+     * @param ledgerContractExpirationDetail 合同到期明细
62
+     * @return 结果
63
+     */
64
+    @Override
65
+    public int updateLedgerContractExpirationDetail(LedgerContractExpirationDetail ledgerContractExpirationDetail) {
66
+        ledgerContractExpirationDetail.setUpdateTime(DateUtils.getNowDate());
67
+        return ledgerContractExpirationDetailMapper.updateLedgerContractExpirationDetail(ledgerContractExpirationDetail);
68
+    }
69
+
70
+    /**
71
+     * 批量删除合同到期明细
72
+     *
73
+     * @param ids 需要删除的合同到期明细主键
74
+     * @return 结果
75
+     */
76
+    @Override
77
+    public int deleteLedgerContractExpirationDetailByIds(Long[] ids) {
78
+        return ledgerContractExpirationDetailMapper.deleteLedgerContractExpirationDetailByIds(ids);
79
+    }
80
+
81
+    /**
82
+     * 删除合同到期明细信息
83
+     *
84
+     * @param id 合同到期明细主键
85
+     * @return 结果
86
+     */
87
+    @Override
88
+    public int deleteLedgerContractExpirationDetailById(Long id) {
89
+        return ledgerContractExpirationDetailMapper.deleteLedgerContractExpirationDetailById(id);
90
+    }
91
+}

+ 303 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/LedgerContractExpirationServiceImpl.java

@@ -0,0 +1,303 @@
1
+package com.sundot.airport.ledger.service.impl;
2
+
3
+import java.util.Comparator;
4
+import java.util.HashMap;
5
+import java.util.List;
6
+import java.util.Map;
7
+import java.util.stream.Collectors;
8
+
9
+import cn.hutool.core.collection.CollUtil;
10
+import cn.hutool.core.util.ObjUtil;
11
+import cn.hutool.core.util.StrUtil;
12
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
13
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
14
+import com.sundot.airport.common.core.domain.entity.SysDept;
15
+import com.sundot.airport.common.core.domain.entity.SysUser;
16
+import com.sundot.airport.common.enums.DeptTypeEnum;
17
+import com.sundot.airport.common.exception.ServiceException;
18
+import com.sundot.airport.common.utils.DateUtils;
19
+import com.sundot.airport.ledger.domain.LedgerContractExpirationDetail;
20
+import com.sundot.airport.ledger.service.ILedgerContractExpirationDetailService;
21
+import com.sundot.airport.system.service.ISysDeptService;
22
+import com.sundot.airport.system.service.ISysUserService;
23
+import org.springframework.beans.factory.annotation.Autowired;
24
+import org.springframework.stereotype.Service;
25
+import com.sundot.airport.ledger.mapper.LedgerContractExpirationMapper;
26
+import com.sundot.airport.ledger.domain.LedgerContractExpiration;
27
+import com.sundot.airport.ledger.service.ILedgerContractExpirationService;
28
+import org.springframework.transaction.annotation.Transactional;
29
+
30
+/**
31
+ * 合同到期Service业务层处理
32
+ *
33
+ * @author ruoyi
34
+ * @date 2026-06-30
35
+ */
36
+@Service
37
+public class LedgerContractExpirationServiceImpl extends ServiceImpl<LedgerContractExpirationMapper, LedgerContractExpiration> implements ILedgerContractExpirationService {
38
+    @Autowired
39
+    private LedgerContractExpirationMapper ledgerContractExpirationMapper;
40
+    @Autowired
41
+    private ILedgerContractExpirationDetailService ledgerContractExpirationDetailService;
42
+    @Autowired
43
+    private ISysDeptService sysDeptService;
44
+    @Autowired
45
+    private ISysUserService sysUserService;
46
+
47
+    /**
48
+     * 查询合同到期
49
+     *
50
+     * @param id 合同到期主键
51
+     * @return 合同到期
52
+     */
53
+    @Override
54
+    public LedgerContractExpiration selectLedgerContractExpirationById(Long id) {
55
+        LedgerContractExpiration result = ledgerContractExpirationMapper.selectLedgerContractExpirationById(id);
56
+        LambdaQueryWrapper<LedgerContractExpirationDetail> wrapper = new LambdaQueryWrapper<>();
57
+        wrapper.eq(LedgerContractExpirationDetail::getSourceId, id);
58
+        List<LedgerContractExpirationDetail> ledgerContractExpirationDetailList = ledgerContractExpirationDetailService.getBaseMapper().selectList(wrapper);
59
+        result.setLedgerContractExpirationDetailList(ledgerContractExpirationDetailList);
60
+        return result;
61
+    }
62
+
63
+    /**
64
+     * 查询合同到期列表
65
+     *
66
+     * @param ledgerContractExpiration 合同到期
67
+     * @return 合同到期
68
+     */
69
+    @Override
70
+    public List<LedgerContractExpiration> selectLedgerContractExpirationList(LedgerContractExpiration ledgerContractExpiration) {
71
+        List<LedgerContractExpiration> result = ledgerContractExpirationMapper.selectLedgerContractExpirationList(ledgerContractExpiration);
72
+        if (CollUtil.isNotEmpty(result)) {
73
+            List<Long> idList = result.stream().map(LedgerContractExpiration::getId).collect(Collectors.toList());
74
+            LambdaQueryWrapper<LedgerContractExpirationDetail> wrapper = new LambdaQueryWrapper<>();
75
+            wrapper.in(LedgerContractExpirationDetail::getSourceId, idList);
76
+            List<LedgerContractExpirationDetail> ledgerContractExpirationDetailList = ledgerContractExpirationDetailService.getBaseMapper().selectList(wrapper);
77
+            if (CollUtil.isNotEmpty(ledgerContractExpirationDetailList)) {
78
+                Map<Long, List<LedgerContractExpirationDetail>> groupingByMap = ledgerContractExpirationDetailList.stream().collect(Collectors.groupingBy(LedgerContractExpirationDetail::getSourceId));
79
+                result.forEach(item -> {
80
+                    item.setLedgerContractExpirationDetailList(groupingByMap.get(item.getId()));
81
+                });
82
+            }
83
+        }
84
+        return result;
85
+    }
86
+
87
+    /**
88
+     * 新增合同到期
89
+     *
90
+     * @param ledgerContractExpiration 合同到期
91
+     * @return 结果
92
+     */
93
+    @Override
94
+    public int insertLedgerContractExpiration(LedgerContractExpiration ledgerContractExpiration) {
95
+        ledgerContractExpiration.setCreateTime(DateUtils.getNowDate());
96
+        int result = ledgerContractExpirationMapper.insertLedgerContractExpiration(ledgerContractExpiration);
97
+        if (CollUtil.isNotEmpty(ledgerContractExpiration.getLedgerContractExpirationDetailList())) {
98
+            List<LedgerContractExpirationDetail> ledgerContractExpirationDetailList = ledgerContractExpiration.getLedgerContractExpirationDetailList();
99
+            ledgerContractExpirationDetailList.sort(Comparator.comparing(LedgerContractExpirationDetail::getContractEndDate));
100
+            String contractName = "合同" + (ledgerContractExpirationDetailList.size() - 1);
101
+            LedgerContractExpirationDetail ledgerContractExpirationDetail = ledgerContractExpirationDetailList.get(ledgerContractExpirationDetailList.size() - 1);
102
+            ledgerContractExpiration.setContractName(contractName);
103
+            ledgerContractExpiration.setContractStartDate(ledgerContractExpirationDetail.getContractStartDate());
104
+            ledgerContractExpiration.setContractEndDate(ledgerContractExpirationDetail.getContractEndDate());
105
+            result = ledgerContractExpirationMapper.updateLedgerContractExpiration(ledgerContractExpiration);
106
+            ledgerContractExpirationDetailList.forEach(item -> {
107
+                item.setCreateBy(ledgerContractExpiration.getCreateBy());
108
+                item.setCreateTime(DateUtils.getNowDate());
109
+                item.setSourceId(ledgerContractExpiration.getId());
110
+            });
111
+            ledgerContractExpirationDetailService.saveBatch(ledgerContractExpirationDetailList);
112
+        }
113
+        return result;
114
+    }
115
+
116
+    /**
117
+     * 修改合同到期
118
+     *
119
+     * @param ledgerContractExpiration 合同到期
120
+     * @return 结果
121
+     */
122
+    @Override
123
+    public int updateLedgerContractExpiration(LedgerContractExpiration ledgerContractExpiration) {
124
+        ledgerContractExpiration.setUpdateTime(DateUtils.getNowDate());
125
+        int result = ledgerContractExpirationMapper.updateLedgerContractExpiration(ledgerContractExpiration);
126
+        LambdaQueryWrapper<LedgerContractExpirationDetail> wrapper = new LambdaQueryWrapper<>();
127
+        wrapper.eq(LedgerContractExpirationDetail::getSourceId, ledgerContractExpiration.getId());
128
+        List<LedgerContractExpirationDetail> ledgerContractExpirationDetailListOld = ledgerContractExpirationDetailService.getBaseMapper().selectList(wrapper);
129
+        ledgerContractExpirationDetailService.removeBatchByIds(ledgerContractExpirationDetailListOld);
130
+        if (CollUtil.isNotEmpty(ledgerContractExpiration.getLedgerContractExpirationDetailList())) {
131
+            List<LedgerContractExpirationDetail> ledgerContractExpirationDetailList = ledgerContractExpiration.getLedgerContractExpirationDetailList();
132
+            ledgerContractExpirationDetailList.sort(Comparator.comparing(LedgerContractExpirationDetail::getContractEndDate));
133
+            String contractName = "合同" + (ledgerContractExpirationDetailList.size() - 1);
134
+            LedgerContractExpirationDetail ledgerContractExpirationDetail = ledgerContractExpirationDetailList.get(ledgerContractExpirationDetailList.size() - 1);
135
+            ledgerContractExpiration.setContractName(contractName);
136
+            ledgerContractExpiration.setContractStartDate(ledgerContractExpirationDetail.getContractStartDate());
137
+            ledgerContractExpiration.setContractEndDate(ledgerContractExpirationDetail.getContractEndDate());
138
+            result = ledgerContractExpirationMapper.updateLedgerContractExpiration(ledgerContractExpiration);
139
+            ledgerContractExpirationDetailList.forEach(item -> {
140
+                item.setCreateBy(ledgerContractExpiration.getCreateBy());
141
+                item.setCreateTime(DateUtils.getNowDate());
142
+                item.setSourceId(ledgerContractExpiration.getId());
143
+            });
144
+            ledgerContractExpirationDetailService.saveBatch(ledgerContractExpirationDetailList);
145
+        }
146
+        return result;
147
+    }
148
+
149
+    /**
150
+     * 批量删除合同到期
151
+     *
152
+     * @param ids 需要删除的合同到期主键
153
+     * @return 结果
154
+     */
155
+    @Override
156
+    public int deleteLedgerContractExpirationByIds(Long[] ids) {
157
+        int result = ledgerContractExpirationMapper.deleteLedgerContractExpirationByIds(ids);
158
+        for (Long id : ids) {
159
+            LambdaQueryWrapper<LedgerContractExpirationDetail> wrapper = new LambdaQueryWrapper<>();
160
+            wrapper.eq(LedgerContractExpirationDetail::getSourceId, id);
161
+            List<LedgerContractExpirationDetail> ledgerContractExpirationDetailList = ledgerContractExpirationDetailService.getBaseMapper().selectList(wrapper);
162
+            ledgerContractExpirationDetailService.removeBatchByIds(ledgerContractExpirationDetailList);
163
+        }
164
+        return result;
165
+    }
166
+
167
+    /**
168
+     * 删除合同到期信息
169
+     *
170
+     * @param id 合同到期主键
171
+     * @return 结果
172
+     */
173
+    @Override
174
+    public int deleteLedgerContractExpirationById(Long id) {
175
+        int result = ledgerContractExpirationMapper.deleteLedgerContractExpirationById(id);
176
+        LambdaQueryWrapper<LedgerContractExpirationDetail> wrapper = new LambdaQueryWrapper<>();
177
+        wrapper.eq(LedgerContractExpirationDetail::getSourceId, id);
178
+        List<LedgerContractExpirationDetail> ledgerContractExpirationDetailList = ledgerContractExpirationDetailService.getBaseMapper().selectList(wrapper);
179
+        ledgerContractExpirationDetailService.removeBatchByIds(ledgerContractExpirationDetailList);
180
+        return result;
181
+    }
182
+
183
+    /**
184
+     * 导入数据
185
+     *
186
+     * @param list            数据列表
187
+     * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
188
+     * @return 结果
189
+     */
190
+    @Transactional(rollbackFor = Exception.class)
191
+    @Override
192
+    public String importData(List<LedgerContractExpiration> list, boolean isUpdateSupport) {
193
+        if (CollUtil.isEmpty(list)) {
194
+            throw new ServiceException("导入数据不能为空!");
195
+        }
196
+
197
+        // 用户
198
+        List<SysUser> sysUserListAll = sysUserService.selectUserAll();
199
+        Map<String, Long> sysUserMap = sysUserListAll.stream().collect(Collectors.toMap(SysUser::getNickName, SysUser::getUserId, (oldValue, newValue) -> newValue));
200
+
201
+        // 用工形式
202
+        Map<Long, String> userIdEmploymentTypeMap = sysUserListAll.stream().filter(sysUser -> StrUtil.isNotEmpty(sysUser.getEmploymentType())).collect(Collectors.toMap(SysUser::getUserId, SysUser::getEmploymentType));
203
+
204
+        // 大队
205
+        Map<Long, Long> userIdBrigadeIdMap = new HashMap<>();
206
+        Map<Long, String> brigadeIdNameMap = new HashMap<>();
207
+        SysDept sysDeptQuery = new SysDept();
208
+        sysDeptQuery.setStatus("0");
209
+        sysDeptQuery.setDelFlag("0");
210
+        sysDeptQuery.setDeptType(DeptTypeEnum.BRIGADE.getCode());
211
+        List<SysDept> sysDeptList = sysDeptService.selectDeptInfoAll(sysDeptQuery);
212
+        sysDeptList.forEach(dept -> {
213
+            brigadeIdNameMap.put(dept.getDeptId(), dept.getDeptName());
214
+            List<SysUser> sysUserList = sysUserService.selectUserByDeptId(dept.getDeptId());
215
+            sysUserList.forEach(sysUser -> {
216
+                userIdBrigadeIdMap.put(sysUser.getUserId(), dept.getDeptId());
217
+            });
218
+        });
219
+
220
+        int successNum = 0;
221
+        int failureNum = 0;
222
+        StringBuilder successMsg = new StringBuilder();
223
+        StringBuilder failureMsg = new StringBuilder();
224
+
225
+        for (LedgerContractExpiration data : list) {
226
+            // 根据名称填充ID字段
227
+            fillIdsByName(data, sysUserMap, userIdEmploymentTypeMap, userIdBrigadeIdMap, brigadeIdNameMap);
228
+            try {
229
+                // 必填字段校验
230
+                if (ObjUtil.isNull(data.getUserName())) {
231
+                    failureNum++;
232
+                    failureMsg.append("<br/>" + failureNum + "、用户名称【" + data.getUserName() + "】用户名称不能为空");
233
+                    continue;
234
+                }
235
+
236
+                // 数据准确性校验
237
+                if (ObjUtil.isNull(data.getUserId())) {
238
+                    failureNum++;
239
+                    failureMsg.append("<br/>" + failureNum + "、用户名称【" + data.getUserName() + "】用户数据错误");
240
+                    continue;
241
+                }
242
+
243
+                // 查询是否已存在(根据【用户ID】唯一)
244
+                LedgerContractExpiration queryParam = new LedgerContractExpiration();
245
+                queryParam.setUserId(data.getUserId());
246
+                List<LedgerContractExpiration> existingList = ledgerContractExpirationMapper.selectLedgerContractExpirationList(queryParam);
247
+
248
+                if (CollUtil.isEmpty(existingList)) {
249
+                    data.setCreateTime(DateUtils.getNowDate());
250
+                    insertLedgerContractExpiration(data);
251
+                    successNum++;
252
+                    successMsg.append("<br/>" + successNum + "、用户名称【" + data.getUserName() + "】导入成功");
253
+                } else if (isUpdateSupport) {
254
+                    LedgerContractExpiration old = existingList.get(0);
255
+                    data.setId(old.getId());
256
+                    data.setUpdateTime(DateUtils.getNowDate());
257
+                    updateLedgerContractExpiration(data);
258
+                    successNum++;
259
+                    successMsg.append("<br/>" + successNum + "、用户名称【" + data.getUserName() + "】更新成功");
260
+                } else {
261
+                    failureNum++;
262
+                    failureMsg.append("<br/>" + failureNum + "、用户名称【" + data.getUserName() + "】已存在");
263
+                }
264
+            } catch (Exception e) {
265
+                failureNum++;
266
+                String msg = "<br/>" + failureNum + "、用户名称【" + data.getUserName() + "】导入失败:";
267
+                failureMsg.append(msg + e.getMessage());
268
+            }
269
+        }
270
+
271
+        if (failureNum > 0) {
272
+            failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
273
+            throw new ServiceException(failureMsg.toString());
274
+        } else {
275
+            successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
276
+        }
277
+        return successMsg.toString();
278
+    }
279
+
280
+    /**
281
+     * 根据名称填充ID字段
282
+     *
283
+     * @param data 速率数据
284
+     */
285
+    private void fillIdsByName(LedgerContractExpiration data, Map<String, Long> sysUserMap, Map<Long, String> userIdEmploymentTypeMap, Map<Long, Long> userIdBrigadeIdMap, Map<Long, String> brigadeIdNameMap) {
286
+        // 用户ID
287
+        if (ObjUtil.isNotNull(data.getUserName())) {
288
+            data.setUserId(sysUserMap.get(data.getUserName()));
289
+        }
290
+        // 用工形式
291
+        if (ObjUtil.isNotNull(data.getUserId())) {
292
+            data.setEmploymentType(userIdEmploymentTypeMap.get(data.getUserId()));
293
+        }
294
+        // 大队ID
295
+        if (ObjUtil.isNotNull(data.getUserId())) {
296
+            data.setBrigadeId(userIdBrigadeIdMap.get(data.getUserId()));
297
+        }
298
+        // 大队名称
299
+        if (ObjUtil.isNotNull(data.getBrigadeId())) {
300
+            data.setBrigadeName(brigadeIdNameMap.get(data.getBrigadeId()));
301
+        }
302
+    }
303
+}

+ 144 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/utils/LedgerContractExcelExportUtil.java

@@ -0,0 +1,144 @@
1
+package com.sundot.airport.ledger.utils;
2
+
3
+import com.sundot.airport.common.utils.DateUtils;
4
+import com.sundot.airport.ledger.domain.LedgerContractExpiration;
5
+import com.sundot.airport.ledger.domain.LedgerContractExpirationDetail;
6
+import lombok.SneakyThrows;
7
+import org.apache.poi.ss.usermodel.BorderStyle;
8
+import org.apache.poi.ss.usermodel.Cell;
9
+import org.apache.poi.ss.usermodel.CellStyle;
10
+import org.apache.poi.ss.usermodel.FillPatternType;
11
+import org.apache.poi.ss.usermodel.Font;
12
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
13
+import org.apache.poi.ss.usermodel.IndexedColors;
14
+import org.apache.poi.ss.usermodel.Row;
15
+import org.apache.poi.ss.usermodel.Sheet;
16
+import org.apache.poi.ss.usermodel.VerticalAlignment;
17
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
18
+
19
+import javax.servlet.http.HttpServletResponse;
20
+import java.net.URLEncoder;
21
+import java.util.ArrayList;
22
+import java.util.HashMap;
23
+import java.util.LinkedHashSet;
24
+import java.util.List;
25
+import java.util.Map;
26
+import java.util.Set;
27
+
28
+/**
29
+ * 合同到期Excel导出工具类
30
+ *
31
+ * @author ruoyi
32
+ * @date 2026-06-29
33
+ */
34
+public class LedgerContractExcelExportUtil {
35
+
36
+    /**
37
+     * 导出数据列表
38
+     *
39
+     * @param response 响应对象
40
+     * @param list     数据列表
41
+     * @param sheetName 工作表名称
42
+     */
43
+    @SneakyThrows
44
+    public static void exportExcel(HttpServletResponse response, List<LedgerContractExpiration> list, String sheetName, Map<String, String> sexDictDataMap) {
45
+        // 1. 获取所有合同名
46
+        Set<String> contractNameSet = new LinkedHashSet<>();
47
+        for (LedgerContractExpiration e : list) {
48
+            if (e.getLedgerContractExpirationDetailList() != null) {
49
+                e.getLedgerContractExpirationDetailList().forEach(c ->
50
+                        contractNameSet.add(c.getContractName())
51
+                );
52
+            }
53
+        }
54
+
55
+        List<String> contractNameList = new ArrayList<>(contractNameSet);
56
+
57
+        // 2. 创建 Workbook
58
+        SXSSFWorkbook workbook = new SXSSFWorkbook();
59
+        Sheet sheet = workbook.createSheet(sheetName);
60
+        // 3. 表头
61
+        CellStyle headStyle = createHeadStyle(workbook);
62
+        Row header = sheet.createRow(0);
63
+        int colIndex = 0;
64
+        String[] baseHeaders = {"用户名称", "大队名称", "用工形式"};
65
+        for (String h : baseHeaders) {
66
+            Cell cell = header.createCell(colIndex++);
67
+            cell.setCellValue(h);
68
+            cell.setCellStyle(headStyle);                  // ← 套样式
69
+        }
70
+
71
+        for (String name : contractNameList) {
72
+            Cell cell = header.createCell(colIndex++);
73
+            cell.setCellValue(name);
74
+            cell.setCellStyle(headStyle);
75
+        }
76
+
77
+        // 4. 数据行
78
+        int rowNum = 1;
79
+        for (LedgerContractExpiration entity : list) {
80
+
81
+            Row row = sheet.createRow(rowNum++);
82
+            colIndex = 0;
83
+
84
+            row.createCell(colIndex++).setCellValue(entity.getUserName());
85
+            row.createCell(colIndex++).setCellValue(entity.getBrigadeName());
86
+            row.createCell(colIndex++).setCellValue(sexDictDataMap.get(entity.getEmploymentType()));
87
+
88
+            // 合同 Map
89
+            Map<String, LedgerContractExpirationDetail> map = new HashMap<>();
90
+            if (entity.getLedgerContractExpirationDetailList() != null) {
91
+                entity.getLedgerContractExpirationDetailList().forEach(c ->
92
+                        map.put(c.getContractName(), c)
93
+                );
94
+            }
95
+
96
+            for (String name : contractNameList) {
97
+                LedgerContractExpirationDetail contract = map.get(name);
98
+                if (contract != null && contract.getContractStartDate() != null && contract.getContractEndDate() != null) {
99
+                    row.createCell(colIndex++).setCellValue(DateUtils.dateTime(contract.getContractStartDate()) + "至" + DateUtils.dateTime(contract.getContractEndDate()));
100
+                } else {
101
+                    row.createCell(colIndex++).setCellValue("");
102
+                }
103
+            }
104
+        }
105
+
106
+        // 5. 输出
107
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
108
+        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("合同到期数据.xlsx", "UTF-8"));
109
+
110
+        workbook.write(response.getOutputStream());
111
+        workbook.close();
112
+    }
113
+
114
+    /**
115
+     * 创建表头样式
116
+     */
117
+    private static CellStyle createHeadStyle(SXSSFWorkbook workbook) {
118
+        CellStyle style = workbook.createCellStyle();
119
+
120
+        // 对齐
121
+        style.setAlignment(HorizontalAlignment.CENTER);
122
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
123
+
124
+        // 背景 —— 若依单体版默认 GREY_50_PERCENT
125
+        style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
126
+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
127
+
128
+        // 四边细线(若依 header 也有边框)
129
+        style.setBorderLeft(BorderStyle.THIN);
130
+        style.setBorderRight(BorderStyle.THIN);
131
+        style.setBorderTop(BorderStyle.THIN);
132
+        style.setBorderBottom(BorderStyle.THIN);
133
+
134
+        // 字体:白色 + 加粗 + Arial 10pt(和若依 initStyles 里 fontName 对齐)
135
+        Font font = workbook.createFont();
136
+        font.setColor(IndexedColors.WHITE.getIndex());
137
+        font.setBold(true);
138
+        font.setFontName("Arial");
139
+        font.setFontHeightInPoints((short) 10);
140
+        style.setFont(font);
141
+
142
+        return style;
143
+    }
144
+}

+ 296 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/utils/LedgerContractExcelImportUtil.java

@@ -0,0 +1,296 @@
1
+package com.sundot.airport.ledger.utils;
2
+
3
+import cn.hutool.core.collection.CollUtil;
4
+import cn.hutool.core.util.ObjUtil;
5
+import com.sundot.airport.common.utils.poi.ExcelUtil;
6
+import com.sundot.airport.ledger.domain.LedgerContractExpiration;
7
+import com.sundot.airport.ledger.domain.LedgerContractExpirationDetail;
8
+import org.apache.poi.ss.usermodel.Cell;
9
+import org.apache.poi.ss.usermodel.DateUtil;
10
+import org.apache.poi.ss.usermodel.Row;
11
+import org.apache.poi.ss.usermodel.Sheet;
12
+import org.apache.poi.ss.usermodel.Workbook;
13
+
14
+import java.util.ArrayList;
15
+import java.util.Date;
16
+import java.util.HashMap;
17
+import java.util.List;
18
+import java.util.Map;
19
+import java.util.regex.Matcher;
20
+import java.util.regex.Pattern;
21
+
22
+/**
23
+ * 合同到期Excel导入工具类
24
+ * 利用现有的ExcelUtil和@Excel注解实现动态列识别
25
+ *
26
+ * @author ruoyi
27
+ * @date 2026-06-29
28
+ */
29
+public class LedgerContractExcelImportUtil {
30
+
31
+    // 匹配格式: "合同N起止日期" 或 "合同一起止日期"
32
+    // 支持阿拉伯数字(1,2,3...999)和中文数字(一,二,三...九百九十九)
33
+    private static final Pattern CONTRACT_DATE_PATTERN = Pattern.compile("合同([\\d]+|[一二三四五六七八九十百千]+)起止日期");
34
+
35
+    /**
36
+     * 解析Excel文件,提取合同到期信息和合同到期明细列表
37
+     * 使用现有的ExcelUtil进行基本字段解析,额外处理动态的合同起止日期列
38
+     *
39
+     * @param workbook Excel工作簿
40
+     * @return 合同到期信息(包含合同到期明细列表)
41
+     */
42
+    public static List<LedgerContractExpiration> parseContractExcel(Workbook workbook) {
43
+        try {
44
+            // 将Workbook转换为InputStream以便重用ExcelUtil
45
+            // 注意:这里我们需要重新从workbook获取输入流,所以采用另一种方式
46
+            // 直接使用ExcelUtil,但它不支持动态列,所以我们需要扩展
47
+
48
+            Sheet sheet = workbook.getSheetAt(0);
49
+            if (sheet == null) {
50
+                return new ArrayList<>();
51
+            }
52
+
53
+            // 第一步:使用ExcelUtil解析基本字段(利用@Excel注解)
54
+            // 由于ExcelUtil需要InputStream,我们创建一个临时的
55
+            java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
56
+            workbook.write(baos);
57
+            java.io.ByteArrayInputStream bais = new java.io.ByteArrayInputStream(baos.toByteArray());
58
+
59
+            ExcelUtil<LedgerContractExpiration> excelUtil = new ExcelUtil<>(LedgerContractExpiration.class);
60
+            List<LedgerContractExpiration> ledgerContractExpirationList = excelUtil.importExcel(bais, 0);
61
+            bais.close();
62
+
63
+            // 第二步:解析合同起止日期列(动态列,不在@Excel注解中)
64
+            parseContractDateColumns(sheet, ledgerContractExpirationList);
65
+
66
+            return ledgerContractExpirationList;
67
+
68
+        } catch (Exception e) {
69
+            System.err.println("解析Excel失败: " + e.getMessage());
70
+            e.printStackTrace();
71
+            return new ArrayList<>();
72
+        }
73
+    }
74
+
75
+    /**
76
+     * 解析合同起止日期列(动态列)
77
+     *
78
+     * @param sheet Excel工作表
79
+     * @param ledgerContractExpirationList 已解析的合同到期列表
80
+     */
81
+    private static void parseContractDateColumns(Sheet sheet, List<LedgerContractExpiration> ledgerContractExpirationList) {
82
+        if (CollUtil.isEmpty(ledgerContractExpirationList)) {
83
+            return;
84
+        }
85
+
86
+        // 读取表头,找到所有"合同N起止日期"列的位置
87
+        Row headerRow = sheet.getRow(0);
88
+        if (headerRow == null) {
89
+            return;
90
+        }
91
+
92
+        // 建立合同起止日期列映射: key=次序, value=列索引
93
+        Map<Integer, Integer> contractDateColumnMap = new HashMap<>();
94
+        for (int i = 0; i < headerRow.getLastCellNum(); i++) {
95
+            Cell cell = headerRow.getCell(i);
96
+            if (cell != null) {
97
+                String columnName = getCellValue(cell);
98
+                if (columnName != null) {
99
+                    // 去除所有空白字符(包括换行符\n、制表符\t、空格等)
100
+                    String cleanColumnName = columnName.replaceAll("\\s+", "");
101
+                    Matcher matcher = CONTRACT_DATE_PATTERN.matcher(cleanColumnName);
102
+                    if (matcher.find()) {
103
+                        int seq = chineseToNumber(matcher.group(1));
104
+                        contractDateColumnMap.put(seq, i);
105
+                    }
106
+                }
107
+            }
108
+        }
109
+
110
+        // 如果没有复审时间列,直接返回
111
+        if (contractDateColumnMap.isEmpty()) {
112
+            return;
113
+        }
114
+
115
+        // 为每个合同到期信息提取合同起止日期
116
+        for (int i = 0; i < ledgerContractExpirationList.size(); i++) {
117
+            LedgerContractExpiration ledgerContractExpiration = ledgerContractExpirationList.get(i);
118
+            // ExcelUtil已经从第1行开始读取数据,所以这里是 i+1
119
+            Row dataRow = sheet.getRow(i + 1);
120
+            if (dataRow == null) {
121
+                continue;
122
+            }
123
+
124
+            List<LedgerContractExpirationDetail> ledgerContractExpirationDetailList = new ArrayList<>();
125
+            for (Map.Entry<Integer, Integer> entry : contractDateColumnMap.entrySet()) {
126
+                int seq = entry.getKey();
127
+                int colIndex = entry.getValue();
128
+
129
+                Cell cell = dataRow.getCell(colIndex);
130
+                String contractDate = getCellValue(cell);
131
+                if (ObjUtil.isNotEmpty(contractDate) && contractDate.contains("至")) {
132
+                    LedgerContractExpirationDetail ledgerContractExpirationDetail = new LedgerContractExpirationDetail();
133
+                    ledgerContractExpirationDetail.setContractName("合同" + seq);
134
+                    Date startDate = parseDate(contractDate.split("至")[0]);
135
+                    Date endDate = parseDate(contractDate.split("至")[1]);
136
+                    ledgerContractExpirationDetail.setContractStartDate(startDate);
137
+                    ledgerContractExpirationDetail.setContractEndDate(endDate);
138
+                    ledgerContractExpirationDetailList.add(ledgerContractExpirationDetail);
139
+                }
140
+            }
141
+            ledgerContractExpiration.setLedgerContractExpirationDetailList(ledgerContractExpirationDetailList);
142
+        }
143
+    }
144
+
145
+    /**
146
+     * 获取单元格值(复用ExcelUtil的逻辑)
147
+     */
148
+    private static String getCellValue(Cell cell) {
149
+        if (cell == null) {
150
+            return null;
151
+        }
152
+
153
+        try {
154
+            switch (cell.getCellType()) {
155
+                case STRING:
156
+                    return cell.getStringCellValue().trim();
157
+                case NUMERIC:
158
+                    if (DateUtil.isCellDateFormatted(cell)) {
159
+                        // 日期类型格式化为 yyyy-MM-dd
160
+                        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
161
+                        return sdf.format(cell.getDateCellValue());
162
+                    } else {
163
+                        double value = cell.getNumericCellValue();
164
+                        if (value == Math.floor(value)) {
165
+                            return String.valueOf((long) value);
166
+                        } else {
167
+                            return String.valueOf(value);
168
+                        }
169
+                    }
170
+                case BOOLEAN:
171
+                    return String.valueOf(cell.getBooleanCellValue());
172
+                case FORMULA:
173
+                    try {
174
+                        // 尝试获取数值结果
175
+                        return String.valueOf(cell.getNumericCellValue());
176
+                    } catch (Exception e) {
177
+                        // 如果失败,尝试获取字符串结果
178
+                        try {
179
+                            return cell.getStringCellValue().trim();
180
+                        } catch (Exception ex) {
181
+                            return cell.getCellFormula();
182
+                        }
183
+                    }
184
+                case BLANK:
185
+                    return "";
186
+                default:
187
+                    return null;
188
+            }
189
+        } catch (IllegalStateException e) {
190
+            // 处理类型不匹配的情况:尝试以字符串方式读取
191
+            try {
192
+                return cell.getStringCellValue().trim();
193
+            } catch (Exception ex) {
194
+                // 如果还是失败,返回null
195
+                return null;
196
+            }
197
+        } catch (Exception e) {
198
+            // 其他异常也返回null
199
+            return null;
200
+        }
201
+    }
202
+
203
+    /**
204
+     * 解析日期
205
+     */
206
+    private static Date parseDate(String value) {
207
+        if (ObjUtil.isEmpty(value)) {
208
+            return null;
209
+        }
210
+
211
+        // 尝试解析常见日期格式
212
+        String[] patterns = {
213
+                "yyyy-MM-dd",
214
+                "yyyy/MM/dd",
215
+                "yyyy年MM月dd日",
216
+                "MM/dd/yyyy",
217
+                "MM-dd-yyyy",
218
+                "dd-MMM-yyyy",  // 01-十二月-2012
219
+                "dd/MMM/yyyy",  // 01/Dec/2012
220
+                "yyyy-MM-dd HH:mm:ss",
221
+                "yyyy/MM/dd HH:mm:ss"
222
+        };
223
+
224
+        for (String pattern : patterns) {
225
+            try {
226
+                java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern, java.util.Locale.CHINA);
227
+                sdf.setLenient(false); // 严格模式
228
+                return sdf.parse(value);
229
+            } catch (Exception e) {
230
+                // 继续尝试下一个格式
231
+            }
232
+        }
233
+
234
+        return null;
235
+    }
236
+
237
+    /**
238
+     * 中文数字转阿拉伯数字
239
+     * 支持: 一~九, 十, 十一~九十九, 一百~九百九十九等
240
+     */
241
+    private static int chineseToNumber(String chinese) {
242
+        // 如果是阿拉伯数字,直接返回
243
+        try {
244
+            return Integer.parseInt(chinese);
245
+        } catch (NumberFormatException e) {
246
+            // 不是阿拉伯数字,继续处理中文数字
247
+        }
248
+
249
+        // 简单映射(个位数)
250
+        Map<String, Integer> basicMap = new HashMap<>();
251
+        basicMap.put("一", 1);
252
+        basicMap.put("二", 2);
253
+        basicMap.put("三", 3);
254
+        basicMap.put("四", 4);
255
+        basicMap.put("五", 5);
256
+        basicMap.put("六", 6);
257
+        basicMap.put("七", 7);
258
+        basicMap.put("八", 8);
259
+        basicMap.put("九", 9);
260
+        basicMap.put("十", 10);
261
+
262
+        // 如果是个位数或十,直接返回
263
+        if (basicMap.containsKey(chinese)) {
264
+            return basicMap.get(chinese);
265
+        }
266
+
267
+        // 处理复合数字: 十一~十九
268
+        if (chinese.startsWith("十") && chinese.length() == 2) {
269
+            String secondChar = chinese.substring(1);
270
+            if (basicMap.containsKey(secondChar)) {
271
+                return 10 + basicMap.get(secondChar);
272
+            }
273
+        }
274
+
275
+        // 处理: 二十~九十九
276
+        if (chinese.length() == 2 && chinese.endsWith("十")) {
277
+            String firstChar = chinese.substring(0, 1);
278
+            if (basicMap.containsKey(firstChar)) {
279
+                return basicMap.get(firstChar) * 10;
280
+            }
281
+        }
282
+
283
+        // 处理: 二十一~九十九
284
+        if (chinese.length() == 3 && chinese.charAt(1) == '十') {
285
+            String firstChar = chinese.substring(0, 1);
286
+            String thirdChar = chinese.substring(2, 3);
287
+            if (basicMap.containsKey(firstChar) && basicMap.containsKey(thirdChar)) {
288
+                return basicMap.get(firstChar) * 10 + basicMap.get(thirdChar);
289
+            }
290
+        }
291
+
292
+        // 如果不支持中文数字格式,返回0
293
+        System.err.println("不支持的中文数字格式: " + chinese + ", 请使用阿拉伯数字");
294
+        return 0;
295
+    }
296
+}

+ 121 - 0
airport-ledger/src/main/resources/mapper/ledger/LedgerContractExpirationDetailMapper.xml

@@ -0,0 +1,121 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper
3
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
+<mapper namespace="com.sundot.airport.ledger.mapper.LedgerContractExpirationDetailMapper">
6
+
7
+    <resultMap type="LedgerContractExpirationDetail" id="LedgerContractExpirationDetailResult">
8
+        <result property="tenantId" column="tenant_id"/>
9
+        <result property="revision" column="revision"/>
10
+        <result property="createBy" column="create_by"/>
11
+        <result property="createTime" column="create_time"/>
12
+        <result property="updateBy" column="update_by"/>
13
+        <result property="updateTime" column="update_time"/>
14
+        <result property="remark" column="remark"/>
15
+        <result property="id" column="id"/>
16
+        <result property="sourceId" column="source_id"/>
17
+        <result property="contractName" column="contract_name"/>
18
+        <result property="contractStartDate" column="contract_start_date"/>
19
+        <result property="contractEndDate" column="contract_end_date"/>
20
+    </resultMap>
21
+
22
+    <sql id="selectLedgerContractExpirationDetailVo">
23
+        select tenant_id,
24
+               revision,
25
+               create_by,
26
+               create_time,
27
+               update_by,
28
+               update_time,
29
+               remark,
30
+               id,
31
+               source_id,
32
+               contract_name,
33
+               contract_start_date,
34
+               contract_end_date
35
+        from ledger_contract_expiration_detail
36
+    </sql>
37
+
38
+    <select id="selectLedgerContractExpirationDetailList" parameterType="LedgerContractExpirationDetail"
39
+            resultMap="LedgerContractExpirationDetailResult">
40
+        <include refid="selectLedgerContractExpirationDetailVo"/>
41
+        <where>
42
+            <if test="tenantId != null  and tenantId != ''">and tenant_id = #{tenantId}</if>
43
+            <if test="revision != null ">and revision = #{revision}</if>
44
+            <if test="sourceId != null ">and source_id = #{sourceId}</if>
45
+            <if test="contractName != null  and contractName != ''">and contract_name like concat('%', #{contractName},
46
+                '%')
47
+            </if>
48
+            <if test="contractStartDate != null ">and contract_start_date = #{contractStartDate}</if>
49
+            <if test="contractEndDate != null ">and contract_end_date = #{contractEndDate}</if>
50
+        </where>
51
+        order by create_time desc
52
+    </select>
53
+
54
+    <select id="selectLedgerContractExpirationDetailById" parameterType="Long"
55
+            resultMap="LedgerContractExpirationDetailResult">
56
+        <include refid="selectLedgerContractExpirationDetailVo"/>
57
+        where id = #{id}
58
+    </select>
59
+
60
+    <insert id="insertLedgerContractExpirationDetail" parameterType="LedgerContractExpirationDetail"
61
+            useGeneratedKeys="true" keyProperty="id">
62
+        insert into ledger_contract_expiration_detail
63
+        <trim prefix="(" suffix=")" suffixOverrides=",">
64
+            <if test="tenantId != null">tenant_id,</if>
65
+            <if test="revision != null">revision,</if>
66
+            <if test="createBy != null">create_by,</if>
67
+            <if test="createTime != null">create_time,</if>
68
+            <if test="updateBy != null">update_by,</if>
69
+            <if test="updateTime != null">update_time,</if>
70
+            <if test="remark != null">remark,</if>
71
+            <if test="sourceId != null">source_id,</if>
72
+            <if test="contractName != null and contractName != ''">contract_name,</if>
73
+            <if test="contractStartDate != null">contract_start_date,</if>
74
+            <if test="contractEndDate != null">contract_end_date,</if>
75
+        </trim>
76
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
77
+            <if test="tenantId != null">#{tenantId},</if>
78
+            <if test="revision != null">#{revision},</if>
79
+            <if test="createBy != null">#{createBy},</if>
80
+            <if test="createTime != null">#{createTime},</if>
81
+            <if test="updateBy != null">#{updateBy},</if>
82
+            <if test="updateTime != null">#{updateTime},</if>
83
+            <if test="remark != null">#{remark},</if>
84
+            <if test="sourceId != null">#{sourceId},</if>
85
+            <if test="contractName != null and contractName != ''">#{contractName},</if>
86
+            <if test="contractStartDate != null">#{contractStartDate},</if>
87
+            <if test="contractEndDate != null">#{contractEndDate},</if>
88
+        </trim>
89
+    </insert>
90
+
91
+    <update id="updateLedgerContractExpirationDetail" parameterType="LedgerContractExpirationDetail">
92
+        update ledger_contract_expiration_detail
93
+        <trim prefix="SET" suffixOverrides=",">
94
+            <if test="tenantId != null">tenant_id = #{tenantId},</if>
95
+            <if test="revision != null">revision = #{revision},</if>
96
+            <if test="createBy != null">create_by = #{createBy},</if>
97
+            <if test="createTime != null">create_time = #{createTime},</if>
98
+            <if test="updateBy != null">update_by = #{updateBy},</if>
99
+            <if test="updateTime != null">update_time = #{updateTime},</if>
100
+            <if test="remark != null">remark = #{remark},</if>
101
+            <if test="sourceId != null">source_id = #{sourceId},</if>
102
+            <if test="contractName != null and contractName != ''">contract_name = #{contractName},</if>
103
+            <if test="contractStartDate != null">contract_start_date = #{contractStartDate},</if>
104
+            <if test="contractEndDate != null">contract_end_date = #{contractEndDate},</if>
105
+        </trim>
106
+        where id = #{id}
107
+    </update>
108
+
109
+    <delete id="deleteLedgerContractExpirationDetailById" parameterType="Long">
110
+        delete
111
+        from ledger_contract_expiration_detail
112
+        where id = #{id}
113
+    </delete>
114
+
115
+    <delete id="deleteLedgerContractExpirationDetailByIds" parameterType="String">
116
+        delete from ledger_contract_expiration_detail where id in
117
+        <foreach item="id" collection="array" open="(" separator="," close=")">
118
+            #{id}
119
+        </foreach>
120
+    </delete>
121
+</mapper>

+ 158 - 0
airport-ledger/src/main/resources/mapper/ledger/LedgerContractExpirationMapper.xml

@@ -0,0 +1,158 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper
3
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
+<mapper namespace="com.sundot.airport.ledger.mapper.LedgerContractExpirationMapper">
6
+
7
+    <resultMap type="LedgerContractExpiration" id="LedgerContractExpirationResult">
8
+        <result property="tenantId" column="tenant_id"/>
9
+        <result property="revision" column="revision"/>
10
+        <result property="createBy" column="create_by"/>
11
+        <result property="createTime" column="create_time"/>
12
+        <result property="updateBy" column="update_by"/>
13
+        <result property="updateTime" column="update_time"/>
14
+        <result property="remark" column="remark"/>
15
+        <result property="id" column="id"/>
16
+        <result property="userId" column="user_id"/>
17
+        <result property="userName" column="user_name"/>
18
+        <result property="contractName" column="contract_name"/>
19
+        <result property="contractStartDate" column="contract_start_date"/>
20
+        <result property="contractEndDate" column="contract_end_date"/>
21
+        <result property="brigadeId" column="brigade_id"/>
22
+        <result property="brigadeName" column="brigade_name"/>
23
+        <result property="employmentType" column="employment_type"/>
24
+    </resultMap>
25
+
26
+    <sql id="selectLedgerContractExpirationVo">
27
+        select tenant_id,
28
+               revision,
29
+               create_by,
30
+               create_time,
31
+               update_by,
32
+               update_time,
33
+               remark,
34
+               id,
35
+               user_id,
36
+               user_name,
37
+               contract_name,
38
+               contract_start_date,
39
+               contract_end_date,
40
+               brigade_id,
41
+               brigade_name,
42
+               employment_type
43
+        from ledger_contract_expiration
44
+    </sql>
45
+
46
+    <select id="selectLedgerContractExpirationList" parameterType="LedgerContractExpiration"
47
+            resultMap="LedgerContractExpirationResult">
48
+        <include refid="selectLedgerContractExpirationVo"/>
49
+        <where>
50
+            <if test="tenantId != null  and tenantId != ''">and tenant_id = #{tenantId}</if>
51
+            <if test="revision != null ">and revision = #{revision}</if>
52
+            <if test="userId != null ">and user_id = #{userId}</if>
53
+            <if test="userName != null  and userName != ''">and user_name like concat('%', #{userName}, '%')</if>
54
+            <if test="contractName != null  and contractName != ''">and contract_name like concat('%', #{contractName},
55
+                '%')
56
+            </if>
57
+            <if test="contractStartDate != null ">and contract_start_date = #{contractStartDate}</if>
58
+            <if test="contractEndDate != null ">and contract_end_date = #{contractEndDate}</if>
59
+            <if test="brigadeId != null ">and brigade_id = #{brigadeId}</if>
60
+            <if test="brigadeName != null  and brigadeName != ''">and brigade_name like concat('%', #{brigadeName},
61
+                '%')
62
+            </if>
63
+            <if test="employmentType != null  and employmentType != ''">and employment_type = #{employmentType}</if>
64
+            <if test="contractStartDateQueryStartDate != null ">
65
+                and contract_start_date <![CDATA[ >= ]]> #{contractStartDateQueryStartDate}
66
+            </if>
67
+            <if test="contractStartDateQueryEndDate != null ">
68
+                and contract_start_date <![CDATA[ <= ]]> #{contractStartDateQueryEndDate}
69
+            </if>
70
+            <if test="contractEndDateQueryStartDate != null ">
71
+                and contract_end_date <![CDATA[ >= ]]> #{contractEndDateQueryStartDate}
72
+            </if>
73
+            <if test="contractEndDateQueryEndDate != null ">
74
+                and contract_end_date <![CDATA[ <= ]]> #{contractEndDateQueryEndDate}
75
+            </if>
76
+        </where>
77
+        order by create_time desc
78
+    </select>
79
+
80
+    <select id="selectLedgerContractExpirationById" parameterType="Long" resultMap="LedgerContractExpirationResult">
81
+        <include refid="selectLedgerContractExpirationVo"/>
82
+        where id = #{id}
83
+    </select>
84
+
85
+    <insert id="insertLedgerContractExpiration" parameterType="LedgerContractExpiration" useGeneratedKeys="true"
86
+            keyProperty="id">
87
+        insert into ledger_contract_expiration
88
+        <trim prefix="(" suffix=")" suffixOverrides=",">
89
+            <if test="tenantId != null">tenant_id,</if>
90
+            <if test="revision != null">revision,</if>
91
+            <if test="createBy != null">create_by,</if>
92
+            <if test="createTime != null">create_time,</if>
93
+            <if test="updateBy != null">update_by,</if>
94
+            <if test="updateTime != null">update_time,</if>
95
+            <if test="remark != null">remark,</if>
96
+            <if test="userId != null">user_id,</if>
97
+            <if test="userName != null and userName != ''">user_name,</if>
98
+            <if test="contractName != null and contractName != ''">contract_name,</if>
99
+            <if test="contractStartDate != null">contract_start_date,</if>
100
+            <if test="contractEndDate != null">contract_end_date,</if>
101
+            <if test="brigadeId != null">brigade_id,</if>
102
+            <if test="brigadeName != null">brigade_name,</if>
103
+            <if test="employmentType != null">employment_type,</if>
104
+        </trim>
105
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
106
+            <if test="tenantId != null">#{tenantId},</if>
107
+            <if test="revision != null">#{revision},</if>
108
+            <if test="createBy != null">#{createBy},</if>
109
+            <if test="createTime != null">#{createTime},</if>
110
+            <if test="updateBy != null">#{updateBy},</if>
111
+            <if test="updateTime != null">#{updateTime},</if>
112
+            <if test="remark != null">#{remark},</if>
113
+            <if test="userId != null">#{userId},</if>
114
+            <if test="userName != null and userName != ''">#{userName},</if>
115
+            <if test="contractName != null and contractName != ''">#{contractName},</if>
116
+            <if test="contractStartDate != null">#{contractStartDate},</if>
117
+            <if test="contractEndDate != null">#{contractEndDate},</if>
118
+            <if test="brigadeId != null">#{brigadeId},</if>
119
+            <if test="brigadeName != null">#{brigadeName},</if>
120
+            <if test="employmentType != null">#{employmentType},</if>
121
+        </trim>
122
+    </insert>
123
+
124
+    <update id="updateLedgerContractExpiration" parameterType="LedgerContractExpiration">
125
+        update ledger_contract_expiration
126
+        <trim prefix="SET" suffixOverrides=",">
127
+            <if test="tenantId != null">tenant_id = #{tenantId},</if>
128
+            <if test="revision != null">revision = #{revision},</if>
129
+            <if test="createBy != null">create_by = #{createBy},</if>
130
+            <if test="createTime != null">create_time = #{createTime},</if>
131
+            <if test="updateBy != null">update_by = #{updateBy},</if>
132
+            <if test="updateTime != null">update_time = #{updateTime},</if>
133
+            <if test="remark != null">remark = #{remark},</if>
134
+            <if test="userId != null">user_id = #{userId},</if>
135
+            <if test="userName != null and userName != ''">user_name = #{userName},</if>
136
+            <if test="contractName != null and contractName != ''">contract_name = #{contractName},</if>
137
+            <if test="contractStartDate != null">contract_start_date = #{contractStartDate},</if>
138
+            <if test="contractEndDate != null">contract_end_date = #{contractEndDate},</if>
139
+            <if test="brigadeId != null">brigade_id = #{brigadeId},</if>
140
+            <if test="brigadeName != null">brigade_name = #{brigadeName},</if>
141
+            <if test="employmentType != null">employment_type = #{employmentType},</if>
142
+        </trim>
143
+        where id = #{id}
144
+    </update>
145
+
146
+    <delete id="deleteLedgerContractExpirationById" parameterType="Long">
147
+        delete
148
+        from ledger_contract_expiration
149
+        where id = #{id}
150
+    </delete>
151
+
152
+    <delete id="deleteLedgerContractExpirationByIds" parameterType="String">
153
+        delete from ledger_contract_expiration where id in
154
+        <foreach item="id" collection="array" open="(" separator="," close=")">
155
+            #{id}
156
+        </foreach>
157
+    </delete>
158
+</mapper>