From 09d73d3bfc6b0136dd96224b361b79c0e513401b Mon Sep 17 00:00:00 2001
From: fuliqi <fuliqi@qq.com>
Date: 星期五, 22 十一月 2024 11:47:52 +0800
Subject: [PATCH] 项目库初始化

---
 business/src/main/resources/mapper/ProjectInfoMapper.xml                |  133 ++++
 business/src/main/java/com/ycl/domain/vo/ProjectInfoVO.java             |  164 +++++
 business/src/main/java/com/ycl/domain/vue/ProjectInfoView.vue           |  102 +++
 business/src/main/java/com/ycl/domain/vue/ProjectInfoDialog.vue         |  315 ++++++++++
 business/src/main/java/com/ycl/mapper/ProjectInfoMapper.java            |   32 +
 business/src/main/java/com/ycl/domain/form/ProjectInfoForm.java         |  168 +++++
 business/src/main/java/com/ycl/domain/entity/ProjectInfo.java           |  156 +++++
 business/src/main/java/com/ycl/controller/ProjectInfoController.java    |   82 ++
 business/src/main/java/com/ycl/domain/vue/projectInfo.js                |   61 +
 business/src/main/java/com/ycl/domain/vue/index.js                      |   79 ++
 business/src/main/java/com/ycl/service/impl/ProjectInfoServiceImpl.java |  119 +++
 business/src/main/java/com/ycl/domain/vue/ProjectInfoTable.vue          |  320 ++++++++++
 business/src/main/java/com/ycl/domain/query/ProjectInfoQuery.java       |   17 
 business/src/main/java/com/ycl/service/ProjectInfoService.java          |   66 ++
 14 files changed, 1,814 insertions(+), 0 deletions(-)

diff --git a/business/src/main/java/com/ycl/controller/ProjectInfoController.java b/business/src/main/java/com/ycl/controller/ProjectInfoController.java
new file mode 100644
index 0000000..d0144ee
--- /dev/null
+++ b/business/src/main/java/com/ycl/controller/ProjectInfoController.java
@@ -0,0 +1,82 @@
+package com.ycl.controller;
+
+import com.ycl.common.base.Result;
+import com.ycl.common.group.Add;
+import com.ycl.common.group.Update;
+import com.ycl.domain.form.ProjectInfoForm;
+import com.ycl.domain.query.ProjectInfoQuery;
+import com.ycl.service.ProjectInfoService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 椤圭洰绠$悊鍩虹淇℃伅琛� 鍓嶇鎺у埗鍣�
+ *
+ * @author flq
+ * @since 2024-11-22
+ */
+@Validated
+@RequiredArgsConstructor
+@Api(value = "椤圭洰绠$悊鍩虹淇℃伅琛�", tags = "椤圭洰绠$悊鍩虹淇℃伅琛ㄧ鐞�")
+@RestController
+@RequestMapping("/api/project-info")
+public class ProjectInfoController {
+
+    private final ProjectInfoService projectInfoService;
+
+    @PostMapping
+    @ApiOperation(value = "娣诲姞", notes = "娣诲姞")
+    @PreAuthorize("hasAuthority('projectInfo:add')")
+    public Result add(@RequestBody @Validated(Add.class) ProjectInfoForm form) {
+        return projectInfoService.add(form);
+    }
+
+    @PutMapping
+    @ApiOperation(value = "淇敼", notes = "淇敼")
+    @PreAuthorize("hasAuthority('projectInfo:edit')")
+    public Result update(@RequestBody @Validated(Update.class) ProjectInfoForm form) {
+        return projectInfoService.update(form);
+    }
+
+    @DeleteMapping("/{id}")
+    @ApiOperation(value = "ID鍒犻櫎", notes = "ID鍒犻櫎")
+    @PreAuthorize("hasAuthority('projectInfo:del')")
+    public Result removeById(@PathVariable("id") String id) {
+        return projectInfoService.removeById(id);
+    }
+
+    @DeleteMapping("/batch")
+    @ApiOperation(value = "鎵归噺鍒犻櫎", notes = "鎵归噺鍒犻櫎")
+    @PreAuthorize("hasAuthority('projectInfo:del:batch')")
+    public Result remove(@RequestBody @NotEmpty(message = "璇烽�夋嫨鏁版嵁") List<String> ids) {
+        return projectInfoService.remove(ids);
+    }
+
+    @GetMapping("/page")
+    @ApiOperation(value = "鍒嗛〉", notes = "鍒嗛〉")
+    @PreAuthorize("hasAuthority('projectInfo:page')")
+    public Result page(ProjectInfoQuery query) {
+        return projectInfoService.page(query);
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation(value = "璇︽儏", notes = "璇︽儏")
+    @PreAuthorize("hasAuthority('projectInfo:detail')")
+    public Result detail(@PathVariable("id") Integer id) {
+        return projectInfoService.detail(id);
+    }
+
+    @GetMapping("/list")
+    @PreAuthorize("hasAuthority('projectInfo:list')")
+    @ApiOperation(value = "鍒楄〃", notes = "鍒楄〃")
+    public Result list() {
+        return projectInfoService.all();
+    }
+}
diff --git a/business/src/main/java/com/ycl/domain/entity/ProjectInfo.java b/business/src/main/java/com/ycl/domain/entity/ProjectInfo.java
new file mode 100644
index 0000000..59e77c5
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/entity/ProjectInfo.java
@@ -0,0 +1,156 @@
+package com.ycl.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ycl.system.domain.base.AbsEntity;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 椤圭洰绠$悊鍩虹淇℃伅琛�
+ *
+ * @author flq
+ * @since 2024-11-22
+ */
+@Data
+@TableName("t_project_info")
+public class ProjectInfo extends AbsEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableField("project_name")
+    /** 椤圭洰鍚嶇О */
+    private String projectName;
+
+    @TableField("project_code")
+    /** 椤圭洰浠g爜 */
+    private String projectCode;
+
+    @TableField("content")
+    /** 寤鸿鍐呭 */
+    private String content;
+
+    @TableField("project_type")
+    /** 椤圭洰绫诲瀷锛�0鎴垮眿寤虹瓚锛�1鍩庡競鍩虹璁炬柦锛�2浜ら�氳繍杈擄紝3姘村埄锛�4鑳芥簮锛�5闈炵叅鐭垮北锛�6鍏朵粬锛� */
+    private String projectType;
+
+    @TableField("project_status")
+    /** 椤圭洰鐘舵��  (0鏈紑宸ワ紝1宸插紑宸ワ紝2宸茬宸ワ紝3鏆傚仠) */
+    private String projectStatus;
+
+    @TableField("fund_type")
+    /** 璧勯噾绫诲瀷锛�0涓璧勯噾锛�1鍥藉�鸿祫閲戯紝2瓒呴暱鏈熷浗鍊猴紝3鍦版柟鏀垮簻涓撻」鍊猴級 */
+    private String fundType;
+
+    @TableField("invest_type")
+    /** 鎶曡祫绫诲埆锛�0浼佷笟鎶曡祫锛�1鏀垮簻鎶曡祫锛�2澶栧晢鎶曡祫锛�3澧冨鎶曡祫锛� */
+    private String investType;
+
+    @TableField("project_phase")
+    /** 椤圭洰闃舵(0鍌ㄥ瑙勫垝闃舵,  1椤圭洰鍓嶆湡闃舵,  2瀹炴柦闃舵,  3绔e伐鎶曠敤闃舵) */
+    private String projectPhase;
+
+    @TableField("tag")
+    /** 鏍囩 */
+    private String tag;
+
+    @TableField("competent_department")
+    /** 涓荤閮ㄩ棬(瀵瑰簲瀹℃壒閮ㄩ棬id) */
+    private Integer competentDepartment;
+
+    @TableField("area_code")
+    /** 琛屾斂鍖哄煙 */
+    private String areaCode;
+
+    @TableField("management_centralization")
+    /** 绠$悊褰掑彛  (0鍩烘湰寤鸿(鍙戞敼),  1鏇存柊鏀归��(缁忎俊),  2鍗曠函璐疆(鍙戞敼),  3淇℃伅鍖�(鍙戞敼),  4鍏朵粬鎶曡祫) */
+    private String managementCentralization;
+
+    @TableField("project_approval_type")
+    /** 椤圭洰瀹℃壒绫诲瀷 */
+    private String projectApprovalType;
+
+    @TableField("investment_catalogue")
+    /** 鎶曡祫鐩綍(锛�) */
+    private String investmentCatalogue;
+
+    @TableField("importance_type")
+    /** 閲嶇偣鍒嗙被  (0鐪侀噸鐐归」鐩�,  1閬傚畞甯傞噸鐐归」鐩�,  2.灏勬椽甯傞噸鐐归」鐩�,  3.涓�鑸」鐩�) */
+    private String importanceType;
+
+    @TableField("year")
+    /** 骞村害鎶曡祫璁″垝 */
+    private String year;
+
+    @TableField("year_invest_amount")
+    /** 骞村害鎶曡祫閲戦 */
+    private BigDecimal yearInvestAmount;
+
+    @TableField("create_project_time")
+    /** 绔嬮」鏃堕棿 */
+    private LocalDateTime createProjectTime;
+
+    @TableField("plan_start_time")
+    /** 璁″垝寮�宸ユ椂闂� */
+    private LocalDateTime planStartTime;
+
+    @TableField("plan_complete_time")
+    /** 璁″垝绔e伐鏃堕棿 */
+    private LocalDateTime planCompleteTime;
+
+    @TableField("win_unit")
+    /** 涓爣鍗曚綅 */
+    private String winUnit;
+
+    @TableField("win_amount")
+    /** 涓爣閲戦 */
+    private String winAmount;
+
+    @TableField("win_time")
+    /** 涓爣鏃堕棿 */
+    private LocalDateTime winTime;
+
+    @TableField("project_address")
+    /** 璇︾粏鍦板潃 */
+    private String projectAddress;
+
+    @TableField("longitude")
+    /** 缁忓害 */
+    private String longitude;
+
+    @TableField("latitude")
+    /** 绾害 */
+    private String latitude;
+
+    @TableField("project_owner_unit")
+    /** 椤圭洰涓氫富鍗曚綅 */
+    private String projectOwnerUnit;
+
+    @TableField("project_contact_person")
+    /** 椤圭洰鑱旂郴浜� */
+    private String projectContactPerson;
+
+    @TableField("contact")
+    /** 鑱旂郴鏂瑰紡 */
+    private String contact;
+
+    @TableField("gmt_create_time")
+    /** 鍒涘缓鏃堕棿 */
+    private LocalDateTime gmtCreateTime;
+
+    @TableField("gmt_update_time")
+    /** 鏇存柊鏃堕棿 */
+    private LocalDateTime gmtUpdateTime;
+
+    @TableField("update_by")
+    /** 鏇存柊浜� */
+    private Long updateBy;
+
+    @TableField("create_by")
+    /** 鍒涘缓浜� */
+    private Long createBy;
+
+
+}
diff --git a/business/src/main/java/com/ycl/domain/form/ProjectInfoForm.java b/business/src/main/java/com/ycl/domain/form/ProjectInfoForm.java
new file mode 100644
index 0000000..7d4b1f3
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/form/ProjectInfoForm.java
@@ -0,0 +1,168 @@
+package com.ycl.domain.form;
+
+import com.ycl.common.group.Add;
+import com.ycl.common.group.Update;
+import com.ycl.domain.entity.ProjectInfo;
+import com.ycl.system.domain.base.AbsForm;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.beans.BeanUtils;
+import org.springframework.lang.NonNull;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 椤圭洰绠$悊鍩虹淇℃伅琛ㄨ〃鍗�
+ *
+ * @author flq
+ * @since 2024-11-22
+ */
+@Data
+@ApiModel(value = "ProjectInfo琛ㄥ崟", description = "椤圭洰绠$悊鍩虹淇℃伅琛ㄨ〃鍗�")
+public class ProjectInfoForm extends AbsForm {
+
+    @NotBlank(message = "椤圭洰鍚嶇О涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("椤圭洰鍚嶇О")
+    private String projectName;
+
+    @NotBlank(message = "椤圭洰浠g爜涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("椤圭洰浠g爜")
+    private String projectCode;
+
+    @NotBlank(message = "寤鸿鍐呭涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("寤鸿鍐呭")
+    private String content;
+
+    @NotBlank(message = "椤圭洰绫诲瀷锛�0鎴垮眿寤虹瓚锛�1鍩庡競鍩虹璁炬柦锛�2浜ら�氳繍杈擄紝3姘村埄锛�4鑳芥簮锛�5闈炵叅鐭垮北锛�6鍏朵粬锛変笉鑳戒负绌�", groups = {Add.class, Update.class})
+    @ApiModelProperty("椤圭洰绫诲瀷锛�0鎴垮眿寤虹瓚锛�1鍩庡競鍩虹璁炬柦锛�2浜ら�氳繍杈擄紝3姘村埄锛�4鑳芥簮锛�5闈炵叅鐭垮北锛�6鍏朵粬锛�")
+    private String projectType;
+
+    @NotBlank(message = "椤圭洰鐘舵��  (0鏈紑宸ワ紝1宸插紑宸ワ紝2宸茬宸ワ紝3鏆傚仠)涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("椤圭洰鐘舵��  (0鏈紑宸ワ紝1宸插紑宸ワ紝2宸茬宸ワ紝3鏆傚仠)")
+    private String projectStatus;
+
+    @NotBlank(message = "璧勯噾绫诲瀷锛�0涓璧勯噾锛�1鍥藉�鸿祫閲戯紝2瓒呴暱鏈熷浗鍊猴紝3鍦版柟鏀垮簻涓撻」鍊猴級涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("璧勯噾绫诲瀷锛�0涓璧勯噾锛�1鍥藉�鸿祫閲戯紝2瓒呴暱鏈熷浗鍊猴紝3鍦版柟鏀垮簻涓撻」鍊猴級")
+    private String fundType;
+
+    @NotBlank(message = "鎶曡祫绫诲埆锛�0浼佷笟鎶曡祫锛�1鏀垮簻鎶曡祫锛�2澶栧晢鎶曡祫锛�3澧冨鎶曡祫锛変笉鑳戒负绌�", groups = {Add.class, Update.class})
+    @ApiModelProperty("鎶曡祫绫诲埆锛�0浼佷笟鎶曡祫锛�1鏀垮簻鎶曡祫锛�2澶栧晢鎶曡祫锛�3澧冨鎶曡祫锛�")
+    private String investType;
+
+    @NotBlank(message = "椤圭洰闃舵(0鍌ㄥ瑙勫垝闃舵,  1椤圭洰鍓嶆湡闃舵,  2瀹炴柦闃舵,  3绔e伐鎶曠敤闃舵)涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("椤圭洰闃舵(0鍌ㄥ瑙勫垝闃舵,  1椤圭洰鍓嶆湡闃舵,  2瀹炴柦闃舵,  3绔e伐鎶曠敤闃舵)")
+    private String projectPhase;
+
+    @NotBlank(message = "鏍囩涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("鏍囩")
+    private String tag;
+
+    @NotNull(message = "涓荤閮ㄩ棬(瀵瑰簲瀹℃壒閮ㄩ棬id)涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("涓荤閮ㄩ棬(瀵瑰簲瀹℃壒閮ㄩ棬id)")
+    private Integer competentDepartment;
+
+    @NotBlank(message = "琛屾斂鍖哄煙涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("琛屾斂鍖哄煙")
+    private String areaCode;
+
+    @NotBlank(message = "绠$悊褰掑彛  (0鍩烘湰寤鸿(鍙戞敼),  1鏇存柊鏀归��(缁忎俊),  2鍗曠函璐疆(鍙戞敼),  3淇℃伅鍖�(鍙戞敼),  4鍏朵粬鎶曡祫)涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("绠$悊褰掑彛  (0鍩烘湰寤鸿(鍙戞敼),  1鏇存柊鏀归��(缁忎俊),  2鍗曠函璐疆(鍙戞敼),  3淇℃伅鍖�(鍙戞敼),  4鍏朵粬鎶曡祫)")
+    private String managementCentralization;
+
+    @NotBlank(message = "椤圭洰瀹℃壒绫诲瀷涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("椤圭洰瀹℃壒绫诲瀷")
+    private String projectApprovalType;
+
+    @NotBlank(message = "鎶曡祫鐩綍(锛�)涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("鎶曡祫鐩綍(锛�)")
+    private String investmentCatalogue;
+
+    @NotBlank(message = "閲嶇偣鍒嗙被  (0鐪侀噸鐐归」鐩�,  1閬傚畞甯傞噸鐐归」鐩�,  2.灏勬椽甯傞噸鐐归」鐩�,  3.涓�鑸」鐩�)涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("閲嶇偣鍒嗙被  (0鐪侀噸鐐归」鐩�,  1閬傚畞甯傞噸鐐归」鐩�,  2.灏勬椽甯傞噸鐐归」鐩�,  3.涓�鑸」鐩�)")
+    private String importanceType;
+
+    @NotBlank(message = "骞村害鎶曡祫璁″垝涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("骞村害鎶曡祫璁″垝")
+    private String year;
+
+    @NotNull(message = "骞村害鎶曡祫閲戦涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("骞村害鎶曡祫閲戦")
+    private BigDecimal yearInvestAmount;
+
+    @NotNull(message = "绔嬮」鏃堕棿涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("绔嬮」鏃堕棿")
+    private Date createProjectTime;
+
+    @NotNull(message = "璁″垝寮�宸ユ椂闂翠笉鑳戒负绌�", groups = {Add.class, Update.class})
+    @ApiModelProperty("璁″垝寮�宸ユ椂闂�")
+    private Date planStartTime;
+
+    @NotNull(message = "璁″垝绔e伐鏃堕棿涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("璁″垝绔e伐鏃堕棿")
+    private Date planCompleteTime;
+
+    @NotBlank(message = "涓爣鍗曚綅涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("涓爣鍗曚綅")
+    private String winUnit;
+
+    @NotBlank(message = "涓爣閲戦涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("涓爣閲戦")
+    private String winAmount;
+
+    @NotNull(message = "涓爣鏃堕棿涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("涓爣鏃堕棿")
+    private Date winTime;
+
+    @NotBlank(message = "璇︾粏鍦板潃涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("璇︾粏鍦板潃")
+    private String projectAddress;
+
+    @NotBlank(message = "缁忓害涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("缁忓害")
+    private String longitude;
+
+    @NotBlank(message = "绾害涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("绾害")
+    private String latitude;
+
+    @NotBlank(message = "椤圭洰涓氫富鍗曚綅涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("椤圭洰涓氫富鍗曚綅")
+    private String projectOwnerUnit;
+
+    @NotBlank(message = "椤圭洰鑱旂郴浜轰笉鑳戒负绌�", groups = {Add.class, Update.class})
+    @ApiModelProperty("椤圭洰鑱旂郴浜�")
+    private String projectContactPerson;
+
+    @NotBlank(message = "鑱旂郴鏂瑰紡涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("鑱旂郴鏂瑰紡")
+    private String contact;
+
+    @NotNull(message = "鍒涘缓鏃堕棿涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    private Date gmtCreateTime;
+
+    @NotNull(message = "鏇存柊鏃堕棿涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    private Date gmtUpdateTime;
+
+    @NotNull(message = "鏇存柊浜轰笉鑳戒负绌�", groups = {Add.class, Update.class})
+    @ApiModelProperty("鏇存柊浜�")
+    private Long updateBy;
+
+    @NotNull(message = "鍒涘缓浜轰笉鑳戒负绌�", groups = {Add.class, Update.class})
+    @ApiModelProperty("鍒涘缓浜�")
+    private Long createBy;
+
+    public static ProjectInfo getEntityByForm(@NonNull ProjectInfoForm form, ProjectInfo entity) {
+        if(entity == null) {
+          entity = new ProjectInfo();
+        }
+        BeanUtils.copyProperties(form, entity);
+        return entity;
+    }
+
+}
diff --git a/business/src/main/java/com/ycl/domain/query/ProjectInfoQuery.java b/business/src/main/java/com/ycl/domain/query/ProjectInfoQuery.java
new file mode 100644
index 0000000..071663f
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/query/ProjectInfoQuery.java
@@ -0,0 +1,17 @@
+package com.ycl.domain.query;
+
+import com.ycl.system.domain.base.AbsQuery;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+/**
+ * 椤圭洰绠$悊鍩虹淇℃伅琛ㄦ煡璇�
+ *
+ * @author flq
+ * @since 2024-11-22
+ */
+@Data
+@ApiModel(value = "ProjectInfo鏌ヨ鍙傛暟", description = "椤圭洰绠$悊鍩虹淇℃伅琛ㄦ煡璇㈠弬鏁�")
+public class ProjectInfoQuery extends AbsQuery {
+}
+
diff --git a/business/src/main/java/com/ycl/domain/vo/ProjectInfoVO.java b/business/src/main/java/com/ycl/domain/vo/ProjectInfoVO.java
new file mode 100644
index 0000000..dafbba3
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/vo/ProjectInfoVO.java
@@ -0,0 +1,164 @@
+package com.ycl.domain.vo;
+
+import com.ycl.domain.entity.ProjectInfo;
+import com.ycl.system.domain.base.AbsVo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.beans.BeanUtils;
+import org.springframework.lang.NonNull;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 椤圭洰绠$悊鍩虹淇℃伅琛ㄥ睍绀�
+ *
+ * @author flq
+ * @since 2024-11-22
+ */
+@Data
+@ApiModel(value = "椤圭洰绠$悊鍩虹淇℃伅琛ㄥ搷搴旀暟鎹�", description = "椤圭洰绠$悊鍩虹淇℃伅琛ㄥ搷搴旀暟鎹�")
+public class ProjectInfoVO extends AbsVo {
+
+    /** 椤圭洰鍚嶇О */
+    @ApiModelProperty("椤圭洰鍚嶇О")
+    private String projectName;
+
+    /** 椤圭洰浠g爜 */
+    @ApiModelProperty("椤圭洰浠g爜")
+    private String projectCode;
+
+    /** 寤鸿鍐呭 */
+    @ApiModelProperty("寤鸿鍐呭")
+    private String content;
+
+    /** 椤圭洰绫诲瀷锛�0鎴垮眿寤虹瓚锛�1鍩庡競鍩虹璁炬柦锛�2浜ら�氳繍杈擄紝3姘村埄锛�4鑳芥簮锛�5闈炵叅鐭垮北锛�6鍏朵粬锛� */
+    @ApiModelProperty("椤圭洰绫诲瀷锛�0鎴垮眿寤虹瓚锛�1鍩庡競鍩虹璁炬柦锛�2浜ら�氳繍杈擄紝3姘村埄锛�4鑳芥簮锛�5闈炵叅鐭垮北锛�6鍏朵粬锛�")
+    private String projectType;
+
+    /** 椤圭洰鐘舵��  (0鏈紑宸ワ紝1宸插紑宸ワ紝2宸茬宸ワ紝3鏆傚仠) */
+    @ApiModelProperty("椤圭洰鐘舵��  (0鏈紑宸ワ紝1宸插紑宸ワ紝2宸茬宸ワ紝3鏆傚仠)")
+    private String projectStatus;
+
+    /** 璧勯噾绫诲瀷锛�0涓璧勯噾锛�1鍥藉�鸿祫閲戯紝2瓒呴暱鏈熷浗鍊猴紝3鍦版柟鏀垮簻涓撻」鍊猴級 */
+    @ApiModelProperty("璧勯噾绫诲瀷锛�0涓璧勯噾锛�1鍥藉�鸿祫閲戯紝2瓒呴暱鏈熷浗鍊猴紝3鍦版柟鏀垮簻涓撻」鍊猴級")
+    private String fundType;
+
+    /** 鎶曡祫绫诲埆锛�0浼佷笟鎶曡祫锛�1鏀垮簻鎶曡祫锛�2澶栧晢鎶曡祫锛�3澧冨鎶曡祫锛� */
+    @ApiModelProperty("鎶曡祫绫诲埆锛�0浼佷笟鎶曡祫锛�1鏀垮簻鎶曡祫锛�2澶栧晢鎶曡祫锛�3澧冨鎶曡祫锛�")
+    private String investType;
+
+    /** 椤圭洰闃舵(0鍌ㄥ瑙勫垝闃舵,  1椤圭洰鍓嶆湡闃舵,  2瀹炴柦闃舵,  3绔e伐鎶曠敤闃舵) */
+    @ApiModelProperty("椤圭洰闃舵(0鍌ㄥ瑙勫垝闃舵,  1椤圭洰鍓嶆湡闃舵,  2瀹炴柦闃舵,  3绔e伐鎶曠敤闃舵)")
+    private String projectPhase;
+
+    /** 鏍囩 */
+    @ApiModelProperty("鏍囩")
+    private String tag;
+
+    /** 涓荤閮ㄩ棬(瀵瑰簲瀹℃壒閮ㄩ棬id) */
+    @ApiModelProperty("涓荤閮ㄩ棬(瀵瑰簲瀹℃壒閮ㄩ棬id)")
+    private Integer competentDepartment;
+
+    /** 琛屾斂鍖哄煙 */
+    @ApiModelProperty("琛屾斂鍖哄煙")
+    private String areaCode;
+
+    /** 绠$悊褰掑彛  (0鍩烘湰寤鸿(鍙戞敼),  1鏇存柊鏀归��(缁忎俊),  2鍗曠函璐疆(鍙戞敼),  3淇℃伅鍖�(鍙戞敼),  4鍏朵粬鎶曡祫) */
+    @ApiModelProperty("绠$悊褰掑彛  (0鍩烘湰寤鸿(鍙戞敼),  1鏇存柊鏀归��(缁忎俊),  2鍗曠函璐疆(鍙戞敼),  3淇℃伅鍖�(鍙戞敼),  4鍏朵粬鎶曡祫)")
+    private String managementCentralization;
+
+    /** 椤圭洰瀹℃壒绫诲瀷 */
+    @ApiModelProperty("椤圭洰瀹℃壒绫诲瀷")
+    private String projectApprovalType;
+
+    /** 鎶曡祫鐩綍(锛�) */
+    @ApiModelProperty("鎶曡祫鐩綍(锛�)")
+    private String investmentCatalogue;
+
+    /** 閲嶇偣鍒嗙被  (0鐪侀噸鐐归」鐩�,  1閬傚畞甯傞噸鐐归」鐩�,  2.灏勬椽甯傞噸鐐归」鐩�,  3.涓�鑸」鐩�) */
+    @ApiModelProperty("閲嶇偣鍒嗙被  (0鐪侀噸鐐归」鐩�,  1閬傚畞甯傞噸鐐归」鐩�,  2.灏勬椽甯傞噸鐐归」鐩�,  3.涓�鑸」鐩�)")
+    private String importanceType;
+
+    /** 骞村害鎶曡祫璁″垝 */
+    @ApiModelProperty("骞村害鎶曡祫璁″垝")
+    private String year;
+
+    /** 骞村害鎶曡祫閲戦 */
+    @ApiModelProperty("骞村害鎶曡祫閲戦")
+    private BigDecimal yearInvestAmount;
+
+    /** 绔嬮」鏃堕棿 */
+    @ApiModelProperty("绔嬮」鏃堕棿")
+    private Date createProjectTime;
+
+    /** 璁″垝寮�宸ユ椂闂� */
+    @ApiModelProperty("璁″垝寮�宸ユ椂闂�")
+    private Date planStartTime;
+
+    /** 璁″垝绔e伐鏃堕棿 */
+    @ApiModelProperty("璁″垝绔e伐鏃堕棿")
+    private Date planCompleteTime;
+
+    /** 涓爣鍗曚綅 */
+    @ApiModelProperty("涓爣鍗曚綅")
+    private String winUnit;
+
+    /** 涓爣閲戦 */
+    @ApiModelProperty("涓爣閲戦")
+    private String winAmount;
+
+    /** 涓爣鏃堕棿 */
+    @ApiModelProperty("涓爣鏃堕棿")
+    private Date winTime;
+
+    /** 璇︾粏鍦板潃 */
+    @ApiModelProperty("璇︾粏鍦板潃")
+    private String projectAddress;
+
+    /** 缁忓害 */
+    @ApiModelProperty("缁忓害")
+    private String longitude;
+
+    /** 绾害 */
+    @ApiModelProperty("绾害")
+    private String latitude;
+
+    /** 椤圭洰涓氫富鍗曚綅 */
+    @ApiModelProperty("椤圭洰涓氫富鍗曚綅")
+    private String projectOwnerUnit;
+
+    /** 椤圭洰鑱旂郴浜� */
+    @ApiModelProperty("椤圭洰鑱旂郴浜�")
+    private String projectContactPerson;
+
+    /** 鑱旂郴鏂瑰紡 */
+    @ApiModelProperty("鑱旂郴鏂瑰紡")
+    private String contact;
+
+    /** 鍒涘缓鏃堕棿 */
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    private Date gmtCreateTime;
+
+    /** 鏇存柊鏃堕棿 */
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    private Date gmtUpdateTime;
+
+    /** 鏇存柊浜� */
+    @ApiModelProperty("鏇存柊浜�")
+    private Long updateBy;
+
+    /** 鍒涘缓浜� */
+    @ApiModelProperty("鍒涘缓浜�")
+    private Long createBy;
+
+    public static ProjectInfoVO getVoByEntity(@NonNull ProjectInfo entity, ProjectInfoVO vo) {
+        if(vo == null) {
+            vo = new ProjectInfoVO();
+        }
+        BeanUtils.copyProperties(entity, vo);
+        return vo;
+    }
+
+}
diff --git a/business/src/main/java/com/ycl/domain/vue/ProjectInfoDialog.vue b/business/src/main/java/com/ycl/domain/vue/ProjectInfoDialog.vue
new file mode 100644
index 0000000..099b884
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/vue/ProjectInfoDialog.vue
@@ -0,0 +1,315 @@
+<template>
+  <div>
+    <el-dialog width="35%" :title="dialogTitle" @close="closeDialog" :visible.sync="dialogFormVisible" :destroy-on-close="true" :append-to-body="true" :close-on-click-modal="false">
+      <el-form :model="projectInfoForm" :rules="projectInfoRules" ref="projectInfoForm">
+        <el-form-item label="椤圭洰鍚嶇О" :label-width="formLabelWidth" prop="projectName">
+          <el-input v-model="projectInfoForm.projectName" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="椤圭洰浠g爜" :label-width="formLabelWidth" prop="projectCode">
+          <el-input v-model="projectInfoForm.projectCode" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="寤鸿鍐呭" :label-width="formLabelWidth" prop="content">
+          <el-input v-model="projectInfoForm.content" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="椤圭洰绫诲瀷锛�0鎴垮眿寤虹瓚锛�1鍩庡競鍩虹璁炬柦锛�2浜ら�氳繍杈擄紝3姘村埄锛�4鑳芥簮锛�5闈炵叅鐭垮北锛�6鍏朵粬锛�" :label-width="formLabelWidth" prop="projectType">
+          <el-input v-model="projectInfoForm.projectType" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="椤圭洰鐘舵��  (0鏈紑宸ワ紝1宸插紑宸ワ紝2宸茬宸ワ紝3鏆傚仠)" :label-width="formLabelWidth" prop="projectStatus">
+          <el-input v-model="projectInfoForm.projectStatus" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="璧勯噾绫诲瀷锛�0涓璧勯噾锛�1鍥藉�鸿祫閲戯紝2瓒呴暱鏈熷浗鍊猴紝3鍦版柟鏀垮簻涓撻」鍊猴級" :label-width="formLabelWidth" prop="fundType">
+          <el-input v-model="projectInfoForm.fundType" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="鎶曡祫绫诲埆锛�0浼佷笟鎶曡祫锛�1鏀垮簻鎶曡祫锛�2澶栧晢鎶曡祫锛�3澧冨鎶曡祫锛�" :label-width="formLabelWidth" prop="investType">
+          <el-input v-model="projectInfoForm.investType" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="椤圭洰闃舵(0鍌ㄥ瑙勫垝闃舵,  1椤圭洰鍓嶆湡闃舵,  2瀹炴柦闃舵,  3绔e伐鎶曠敤闃舵)" :label-width="formLabelWidth" prop="projectPhase">
+          <el-input v-model="projectInfoForm.projectPhase" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="鏍囩" :label-width="formLabelWidth" prop="tag">
+          <el-input v-model="projectInfoForm.tag" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="涓荤閮ㄩ棬(瀵瑰簲瀹℃壒閮ㄩ棬id)" :label-width="formLabelWidth" prop="competentDepartment">
+          <el-input v-model="projectInfoForm.competentDepartment" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="琛屾斂鍖哄煙" :label-width="formLabelWidth" prop="areaCode">
+          <el-input v-model="projectInfoForm.areaCode" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="绠$悊褰掑彛  (0鍩烘湰寤鸿(鍙戞敼),  1鏇存柊鏀归��(缁忎俊),  2鍗曠函璐疆(鍙戞敼),  3淇℃伅鍖�(鍙戞敼),  4鍏朵粬鎶曡祫)" :label-width="formLabelWidth" prop="managementCentralization">
+          <el-input v-model="projectInfoForm.managementCentralization" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="椤圭洰瀹℃壒绫诲瀷" :label-width="formLabelWidth" prop="projectApprovalType">
+          <el-input v-model="projectInfoForm.projectApprovalType" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="鎶曡祫鐩綍(锛�)" :label-width="formLabelWidth" prop="investmentCatalogue">
+          <el-input v-model="projectInfoForm.investmentCatalogue" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="閲嶇偣鍒嗙被  (0鐪侀噸鐐归」鐩�,  1閬傚畞甯傞噸鐐归」鐩�,  2.灏勬椽甯傞噸鐐归」鐩�,  3.涓�鑸」鐩�)" :label-width="formLabelWidth" prop="importanceType">
+          <el-input v-model="projectInfoForm.importanceType" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="骞村害鎶曡祫璁″垝" :label-width="formLabelWidth" prop="year">
+          <el-input v-model="projectInfoForm.year" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="骞村害鎶曡祫閲戦" :label-width="formLabelWidth" prop="yearInvestAmount">
+          <el-input v-model="projectInfoForm.yearInvestAmount" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="绔嬮」鏃堕棿" :label-width="formLabelWidth" prop="createProjectTime">
+          <el-input v-model="projectInfoForm.createProjectTime" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="璁″垝寮�宸ユ椂闂�" :label-width="formLabelWidth" prop="planStartTime">
+          <el-input v-model="projectInfoForm.planStartTime" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="璁″垝绔e伐鏃堕棿" :label-width="formLabelWidth" prop="planCompleteTime">
+          <el-input v-model="projectInfoForm.planCompleteTime" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="涓爣鍗曚綅" :label-width="formLabelWidth" prop="winUnit">
+          <el-input v-model="projectInfoForm.winUnit" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="涓爣閲戦" :label-width="formLabelWidth" prop="winAmount">
+          <el-input v-model="projectInfoForm.winAmount" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="涓爣鏃堕棿" :label-width="formLabelWidth" prop="winTime">
+          <el-input v-model="projectInfoForm.winTime" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="璇︾粏鍦板潃" :label-width="formLabelWidth" prop="projectAddress">
+          <el-input v-model="projectInfoForm.projectAddress" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="缁忓害" :label-width="formLabelWidth" prop="longitude">
+          <el-input v-model="projectInfoForm.longitude" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="绾害" :label-width="formLabelWidth" prop="latitude">
+          <el-input v-model="projectInfoForm.latitude" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="椤圭洰涓氫富鍗曚綅" :label-width="formLabelWidth" prop="projectOwnerUnit">
+          <el-input v-model="projectInfoForm.projectOwnerUnit" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="椤圭洰鑱旂郴浜�" :label-width="formLabelWidth" prop="projectContactPerson">
+          <el-input v-model="projectInfoForm.projectContactPerson" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="鑱旂郴鏂瑰紡" :label-width="formLabelWidth" prop="contact">
+          <el-input v-model="projectInfoForm.contact" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="鍒涘缓鏃堕棿" :label-width="formLabelWidth" prop="gmtCreateTime">
+          <el-input v-model="projectInfoForm.gmtCreateTime" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="鏇存柊鏃堕棿" :label-width="formLabelWidth" prop="gmtUpdateTime">
+          <el-input v-model="projectInfoForm.gmtUpdateTime" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="鏇存柊浜�" :label-width="formLabelWidth" prop="updateBy">
+          <el-input v-model="projectInfoForm.updateBy" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="鍒涘缓浜�" :label-width="formLabelWidth" prop="createBy">
+          <el-input v-model="projectInfoForm.createBy" autocomplete="off"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="closeDialog">鍙� 娑�</el-button>
+        <el-button type="primary" @click="addOrEditProjectInfo">纭� 瀹�</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import {Message} from "element-ui";
+  import {getDictDataByType} from "@/api/dict-data";
+  import {addProjectInfo, editProjectInfo, getProjectInfos} from "@/api/projectInfo";
+  export default {
+    name: "ProjectInfoDialog",
+    data() {
+      return {
+        formLabelWidth: '120px',
+        projectInfoRules: {
+            projectName: [
+              { required: true, message: '璇疯緭鍏ラ」鐩悕绉�', trigger: 'blur' }
+            ],
+            projectCode: [
+              { required: true, message: '璇疯緭鍏ラ」鐩唬鐮�', trigger: 'blur' }
+            ],
+            content: [
+              { required: true, message: '璇疯緭鍏ュ缓璁惧唴瀹�', trigger: 'blur' }
+            ],
+            projectType: [
+              { required: true, message: '璇疯緭鍏ラ」鐩被鍨嬶紙0鎴垮眿寤虹瓚锛�1鍩庡競鍩虹璁炬柦锛�2浜ら�氳繍杈擄紝3姘村埄锛�4鑳芥簮锛�5闈炵叅鐭垮北锛�6鍏朵粬锛�', trigger: 'blur' }
+            ],
+            projectStatus: [
+              { required: true, message: '璇疯緭鍏ラ」鐩姸鎬�  (0鏈紑宸ワ紝1宸插紑宸ワ紝2宸茬宸ワ紝3鏆傚仠)', trigger: 'blur' }
+            ],
+            fundType: [
+              { required: true, message: '璇疯緭鍏ヨ祫閲戠被鍨嬶紙0涓璧勯噾锛�1鍥藉�鸿祫閲戯紝2瓒呴暱鏈熷浗鍊猴紝3鍦版柟鏀垮簻涓撻」鍊猴級', trigger: 'blur' }
+            ],
+            investType: [
+              { required: true, message: '璇疯緭鍏ユ姇璧勭被鍒紙0浼佷笟鎶曡祫锛�1鏀垮簻鎶曡祫锛�2澶栧晢鎶曡祫锛�3澧冨鎶曡祫锛�', trigger: 'blur' }
+            ],
+            projectPhase: [
+              { required: true, message: '璇疯緭鍏ラ」鐩樁娈�(0鍌ㄥ瑙勫垝闃舵,  1椤圭洰鍓嶆湡闃舵,  2瀹炴柦闃舵,  3绔e伐鎶曠敤闃舵)', trigger: 'blur' }
+            ],
+            tag: [
+              { required: true, message: '璇疯緭鍏ユ爣绛�', trigger: 'blur' }
+            ],
+            competentDepartment: [
+              { required: true, message: '璇疯緭鍏ヤ富绠¢儴闂�(瀵瑰簲瀹℃壒閮ㄩ棬id)', trigger: 'blur' }
+            ],
+            areaCode: [
+              { required: true, message: '璇疯緭鍏ヨ鏀垮尯鍩�', trigger: 'blur' }
+            ],
+            managementCentralization: [
+              { required: true, message: '璇疯緭鍏ョ鐞嗗綊鍙�  (0鍩烘湰寤鸿(鍙戞敼),  1鏇存柊鏀归��(缁忎俊),  2鍗曠函璐疆(鍙戞敼),  3淇℃伅鍖�(鍙戞敼),  4鍏朵粬鎶曡祫)', trigger: 'blur' }
+            ],
+            projectApprovalType: [
+              { required: true, message: '璇疯緭鍏ラ」鐩鎵圭被鍨�', trigger: 'blur' }
+            ],
+            investmentCatalogue: [
+              { required: true, message: '璇疯緭鍏ユ姇璧勭洰褰�(锛�)', trigger: 'blur' }
+            ],
+            importanceType: [
+              { required: true, message: '璇疯緭鍏ラ噸鐐瑰垎绫�  (0鐪侀噸鐐归」鐩�,  1閬傚畞甯傞噸鐐归」鐩�,  2.灏勬椽甯傞噸鐐归」鐩�,  3.涓�鑸」鐩�)', trigger: 'blur' }
+            ],
+            year: [
+              { required: true, message: '璇疯緭鍏ュ勾搴︽姇璧勮鍒�', trigger: 'blur' }
+            ],
+            yearInvestAmount: [
+              { required: true, message: '璇疯緭鍏ュ勾搴︽姇璧勯噾棰�', trigger: 'blur' }
+            ],
+            createProjectTime: [
+              { required: true, message: '璇疯緭鍏ョ珛椤规椂闂�', trigger: 'blur' }
+            ],
+            planStartTime: [
+              { required: true, message: '璇疯緭鍏ヨ鍒掑紑宸ユ椂闂�', trigger: 'blur' }
+            ],
+            planCompleteTime: [
+              { required: true, message: '璇疯緭鍏ヨ鍒掔宸ユ椂闂�', trigger: 'blur' }
+            ],
+            winUnit: [
+              { required: true, message: '璇疯緭鍏ヤ腑鏍囧崟浣�', trigger: 'blur' }
+            ],
+            winAmount: [
+              { required: true, message: '璇疯緭鍏ヤ腑鏍囬噾棰�', trigger: 'blur' }
+            ],
+            winTime: [
+              { required: true, message: '璇疯緭鍏ヤ腑鏍囨椂闂�', trigger: 'blur' }
+            ],
+            projectAddress: [
+              { required: true, message: '璇疯緭鍏ヨ缁嗗湴鍧�', trigger: 'blur' }
+            ],
+            longitude: [
+              { required: true, message: '璇疯緭鍏ョ粡搴�', trigger: 'blur' }
+            ],
+            latitude: [
+              { required: true, message: '璇疯緭鍏ョ含搴�', trigger: 'blur' }
+            ],
+            projectOwnerUnit: [
+              { required: true, message: '璇疯緭鍏ラ」鐩笟涓诲崟浣�', trigger: 'blur' }
+            ],
+            projectContactPerson: [
+              { required: true, message: '璇疯緭鍏ラ」鐩仈绯讳汉', trigger: 'blur' }
+            ],
+            contact: [
+              { required: true, message: '璇疯緭鍏ヨ仈绯绘柟寮�', trigger: 'blur' }
+            ],
+            gmtCreateTime: [
+              { required: true, message: '璇疯緭鍏ュ垱寤烘椂闂�', trigger: 'blur' }
+            ],
+            gmtUpdateTime: [
+              { required: true, message: '璇疯緭鍏ユ洿鏂版椂闂�', trigger: 'blur' }
+            ],
+            updateBy: [
+              { required: true, message: '璇疯緭鍏ユ洿鏂颁汉', trigger: 'blur' }
+            ],
+            createBy: [
+              { required: true, message: '璇疯緭鍏ュ垱寤轰汉', trigger: 'blur' }
+            ],
+      }
+      }
+    },
+    computed: {
+      dialogFormVisible: {
+        get() {
+          return this.$store.state.projectInfo.dialogFormVisible;
+        },
+        set(value) {
+          this.$store.state.projectInfo.dialogFormVisible = value;
+        }
+      },
+      dialogTitle: {
+        get() {
+          return this.$store.state.projectInfo.dialogTitle;
+        },
+        set(value) {
+          this.$store.state.projectInfo.dialogTitle = value;
+        }
+
+      },
+      projectInfoForm: {
+        get() {
+          return this.$store.state.projectInfo.projectInfoForm;
+        },
+        set(value) {
+          this.$store.state.projectInfo.projectInfoForm = value;
+        }
+      }
+    },
+    mounted() {
+    },
+    methods: {
+      getDictData(value) {
+        let params = {
+          keyword: value,
+          dictTypeId: value,
+          current: 1,
+          size: 200
+        }
+        getDictDataByType(params).then(res => {
+          this.dictTypeList = res.data.data
+        })
+      },
+      refreshData() {
+        var params = {
+          "current": this.$store.state.projectInfo.currentPage,
+          "size": this.$store.state.projectInfo.pageSize
+        };
+        // 鍒锋柊
+        getProjectInfos(params).then((res) => {
+          this.$store.state.projectInfo.tableData = res.data.data;
+          this.$store.state.projectInfo.total = res.data.total;
+          this.clearForm();
+        })
+      },
+      clearForm() {
+        Object.keys(this.projectInfoForm).forEach((key) => {
+          this.projectInfoForm[key] = null;
+        })
+      },
+      closeDialog() {
+        this.$store.state.projectInfo.dialogFormVisible = false;
+        this.clearForm();
+      },
+      addOrEditProjectInfo() {
+        this.$refs["projectInfoForm"].validate((valid) => {
+          if (valid) {
+            if (this.dialogTitle === "娣诲姞椤圭洰绠$悊鍩虹淇℃伅琛�") {
+              addProjectInfo(this.projectInfoForm).then((res) => {
+                Message.success(res.data.msg);
+                this.dialogFormVisible = false;
+                this.refreshData();
+              })
+            } else {
+              editProjectInfo(this.projectInfoForm).then((res) => {
+                Message.success(res.data.msg);
+                this.dialogFormVisible = false;
+                this.refreshData();
+              })
+            }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+        });
+      }
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>
diff --git a/business/src/main/java/com/ycl/domain/vue/ProjectInfoTable.vue b/business/src/main/java/com/ycl/domain/vue/ProjectInfoTable.vue
new file mode 100644
index 0000000..77d0c07
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/vue/ProjectInfoTable.vue
@@ -0,0 +1,320 @@
+<template>
+  <div>
+    <el-table
+        :data="tableData"
+        :class="{tableTopLevel1: topLevel === 1, tableTopLevel2: topLevel === 2, tableTopLevel3: topLevel === 3, tableTopLevelDefault: topLevel === -1}"
+        row-key="id"
+        border
+        @selection-change="handleSelectionChange">
+      <el-table-column
+          type="selection"
+          width="55">
+      </el-table-column>
+      <el-table-column
+          prop="projectName"
+          label="椤圭洰鍚嶇О"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="projectCode"
+          label="椤圭洰浠g爜"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="content"
+          label="寤鸿鍐呭"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="projectType"
+          label="椤圭洰绫诲瀷锛�0鎴垮眿寤虹瓚锛�1鍩庡競鍩虹璁炬柦锛�2浜ら�氳繍杈擄紝3姘村埄锛�4鑳芥簮锛�5闈炵叅鐭垮北锛�6鍏朵粬锛�"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="projectStatus"
+          label="椤圭洰鐘舵��  (0鏈紑宸ワ紝1宸插紑宸ワ紝2宸茬宸ワ紝3鏆傚仠)"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="fundType"
+          label="璧勯噾绫诲瀷锛�0涓璧勯噾锛�1鍥藉�鸿祫閲戯紝2瓒呴暱鏈熷浗鍊猴紝3鍦版柟鏀垮簻涓撻」鍊猴級"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="investType"
+          label="鎶曡祫绫诲埆锛�0浼佷笟鎶曡祫锛�1鏀垮簻鎶曡祫锛�2澶栧晢鎶曡祫锛�3澧冨鎶曡祫锛�"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="projectPhase"
+          label="椤圭洰闃舵(0鍌ㄥ瑙勫垝闃舵,  1椤圭洰鍓嶆湡闃舵,  2瀹炴柦闃舵,  3绔e伐鎶曠敤闃舵)"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="tag"
+          label="鏍囩"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="competentDepartment"
+          label="涓荤閮ㄩ棬(瀵瑰簲瀹℃壒閮ㄩ棬id)"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="areaCode"
+          label="琛屾斂鍖哄煙"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="managementCentralization"
+          label="绠$悊褰掑彛  (0鍩烘湰寤鸿(鍙戞敼),  1鏇存柊鏀归��(缁忎俊),  2鍗曠函璐疆(鍙戞敼),  3淇℃伅鍖�(鍙戞敼),  4鍏朵粬鎶曡祫)"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="projectApprovalType"
+          label="椤圭洰瀹℃壒绫诲瀷"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="investmentCatalogue"
+          label="鎶曡祫鐩綍(锛�)"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="importanceType"
+          label="閲嶇偣鍒嗙被  (0鐪侀噸鐐归」鐩�,  1閬傚畞甯傞噸鐐归」鐩�,  2.灏勬椽甯傞噸鐐归」鐩�,  3.涓�鑸」鐩�)"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="year"
+          label="骞村害鎶曡祫璁″垝"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="yearInvestAmount"
+          label="骞村害鎶曡祫閲戦"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="createProjectTime"
+          label="绔嬮」鏃堕棿"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="planStartTime"
+          label="璁″垝寮�宸ユ椂闂�"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="planCompleteTime"
+          label="璁″垝绔e伐鏃堕棿"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="winUnit"
+          label="涓爣鍗曚綅"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="winAmount"
+          label="涓爣閲戦"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="winTime"
+          label="涓爣鏃堕棿"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="projectAddress"
+          label="璇︾粏鍦板潃"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="longitude"
+          label="缁忓害"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="latitude"
+          label="绾害"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="projectOwnerUnit"
+          label="椤圭洰涓氫富鍗曚綅"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="projectContactPerson"
+          label="椤圭洰鑱旂郴浜�"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="contact"
+          label="鑱旂郴鏂瑰紡"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="gmtCreateTime"
+          label="鍒涘缓鏃堕棿"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="gmtUpdateTime"
+          label="鏇存柊鏃堕棿"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="updateBy"
+          label="鏇存柊浜�"
+          >
+      </el-table-column>
+      <el-table-column
+          prop="createBy"
+          label="鍒涘缓浜�"
+          >
+      </el-table-column>
+      <el-table-column
+          label="鎿嶄綔">
+        <template slot-scope="scope">
+          <el-button v-if="editShow" type="primary" @click="editProjectInfo(scope.row.id)" size="mini">淇敼</el-button>
+          <el-button v-if="delShow" type="primary" @click="deleteProjectInfo(scope.row.id)" size="mini">鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <PageC
+            :top-level="topLevel"
+            :handleSizeChange="handleSizeChange"
+            :handleCurrentChange="handleCurrentChange"
+            :pageSize="pageSize"
+            :total="total"
+            :currentPage="currentPage"></PageC>
+  </div>
+</template>
+
+<script>
+  import PageC from "@/components/PageC";
+  import {deleteProjectInfoById, getProjectInfos} from "@/api/projectInfo";
+  import {Message} from "element-ui";
+  export default {
+    name: "ProjectInfoTable",
+    components: {PageC},
+    computed: {
+      tableData: {
+        get() {
+          return this.$store.state.projectInfo.tableData;
+        },
+        set(value) {
+          this.$store.state.projectInfo.tableData = value;
+        }
+      },
+      // 閫変腑琛宨d
+      multipleSelection: {
+        get() {
+          return this.$store.state.projectInfo.multipleSelection;
+        },
+        set(value) {
+          this.$store.state.projectInfo.multipleSelection = value;
+        }
+      },
+      total: {
+        get() {
+          return this.$store.state.projectInfo.total;
+        },
+        set(value) {
+          this.$store.state.projectInfo.total = value;
+        }
+      },
+      pageSize: {
+        get() {
+          return this.$store.state.projectInfo.pageSize;
+        },
+        set(value) {
+          this.$store.state.projectInfo.pageSize = value;
+        }
+      },
+      currentPage: {
+        get() {
+          return this.$store.state.projectInfo.currentPage;
+        },
+        set(value) {
+          this.$store.state.projectInfo.currentPage = value;
+        }
+      }
+    },
+    props: {
+      topLevel: {
+        required: false,
+        default: -1,
+        type: Number
+      },
+      editShow: {
+        required: true,
+        default: false,
+        type: Boolean
+      },
+      delShow: {
+        required: true,
+        default: false,
+        type: Boolean
+      },
+    },
+    methods: {
+      handleSelectionChange(val) {
+        this.multipleSelection = val.map((item) => {return item.id;})
+      },
+      getProjectInfos(params) {
+        if (! params) {
+          params = {
+            "current": this.currentPage,
+            "size": this.pageSize
+          };
+        } else {
+          params.current = this.currentPage;
+          params.size = this.pageSize;
+        }
+        // 鍒锋柊
+        getProjectInfos(params).then((res) => {
+          this.tableData = res.data.data;
+          this.total = res.data.total;
+        })
+      },
+      editProjectInfo(id) {
+        this.$store.dispatch("projectInfo/editProjectInfo", id);
+      },
+      deleteProjectInfo(id) {
+        this.$confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ヨ褰�, 鏄惁缁х画?', '鎻愮ず', {
+          confirmButtonText: '纭畾',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          deleteProjectInfoById(id).then((res) => {
+            Message.success(res.data.msg);
+            this.getProjectInfos();
+          })
+        }).catch(() => {
+          this.$message({
+            type: 'info',
+            message: '宸插彇娑堝垹闄�'
+          });
+        });
+      },
+      handleSizeChange(val) {
+        this.pageSize = val;
+        this.getProjectInfos();
+      },
+      handleCurrentChange(val) {
+        this.currentPage = val;
+        this.getProjectInfos();
+      }
+    },
+    created() {
+      this.getProjectInfos();
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>
diff --git a/business/src/main/java/com/ycl/domain/vue/ProjectInfoView.vue b/business/src/main/java/com/ycl/domain/vue/ProjectInfoView.vue
new file mode 100644
index 0000000..ef6223b
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/vue/ProjectInfoView.vue
@@ -0,0 +1,102 @@
+<template>
+  <div class="view">
+    <div class="search-warp">
+      <el-form :inline="true" :model="searchForm" class="demo-form-inline">
+        <el-form-item>
+          <el-button size="small" type="primary" @click="search">鏌ユ壘</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <OperateC
+            :top-level="topLevel"
+            :add="addProjectInfo"
+            :edit="editProjectInfo"
+            :remove="removeProjectInfo"
+            :add-show="this.$getButtonAuth('projectInfo:add')"
+            :remove-show="this.$getButtonAuth('projectInfo:del:batch')"
+    ></OperateC>
+    <ProjectInfoTable
+            :top-level="topLevel"
+            ref="ProjectInfoTableRef"
+            :edit-show="this.$getButtonAuth('projectInfo:edit')"
+            :del-show="this.$getButtonAuth('projectInfo:del')"
+    ></ProjectInfoTable>
+    <ProjectInfoDialog></ProjectInfoDialog>
+  </div>
+</template>
+
+<script>
+  import ProjectInfoDialog from "@/components/dialog/ProjectInfoDialog";
+  import OperateC from "@/components/OperateC";
+  import ProjectInfoTable from "@/components/table/ProjectInfoTable";
+  import {deleteProjectInfoByIds, getProjectInfos} from "@/api/projectInfo";
+  export default {
+    name: "ProjectInfoView",
+    components: {ProjectInfoDialog, OperateC, ProjectInfoTable},
+    data() {
+      return {
+        searchForm: {
+        },
+        topLevel: -1
+      }
+    },
+    methods: {
+      search() {
+        this.$refs.ProjectInfoTableRef.getProjectInfos(this.searchForm)
+      },
+      addProjectInfo() {
+        let params = {
+          dialogFormVisible: true,
+          dialogTitle: "娣诲姞椤圭洰绠$悊鍩虹淇℃伅琛�"
+        }
+        this.$store.commit("projectInfo/openDialogForm", params);
+      },
+      editProjectInfo() {
+        let selected = this.$store.state.projectInfo.multipleSelection;
+        if (selected.length < 1) {
+          this.$message.warning("浣犺繕娌℃湁閫変腑鏁版嵁鍝︼紒");
+          return;
+        }
+        if (selected.length > 1) {
+          this.$message.warning("涓�娆″彧鑳戒慨鏀逛竴鏉℃暟鎹摝锛�")
+          return;
+        }
+        this.$store.dispatch("projectInfo/editProjectInfo", selected[0]);
+      },
+      removeProjectInfo() {
+        let selected = this.$store.state.projectInfo.multipleSelection;
+        if (selected.length < 1) {
+          this.$message.warning("璇峰厛閫夋嫨瑕佸垹闄ょ殑鏁版嵁鍝︼紒");
+          return;
+        }
+        this.$confirm('纭畾鍒犻櫎鍚�?', '鎻愮ず', {
+          confirmButtonText: '纭畾',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          deleteProjectInfoByIds(selected).then((res) => {
+            this.$message.success(res.data.msg);
+            // 鍒锋柊
+            let params = {
+              "current": this.$store.state.projectInfo.currentPage,
+              "size": this.$store.state.projectInfo.pageSize
+            };
+            getProjectInfos(params).then((res) => {
+              this.$store.state.projectInfo.tableData = res.data.data;
+              this.$store.state.projectInfo.total = res.data.total;
+            })
+          })
+        }).catch(() => {
+          this.$message({
+            type: 'info',
+            message: '宸插彇娑堝垹闄�'
+          });
+        });
+      },
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>
diff --git a/business/src/main/java/com/ycl/domain/vue/index.js b/business/src/main/java/com/ycl/domain/vue/index.js
new file mode 100644
index 0000000..c1218ea
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/vue/index.js
@@ -0,0 +1,79 @@
+import {getProjectInfoById} from "@/api/projectInfo";
+
+export default {
+    namespaced: true,
+    state: {
+        dialogFormVisible: false,
+        dialogTitle: '',
+        pageSize: 10,
+        currentPage: 1,
+        total: 0,
+        // 淇敼娣诲姞鐨勮〃鍗曟暟鎹�
+        projectInfoForm: {
+            id: null,
+            projectName: "" ,
+            projectCode: "" ,
+            content: "" ,
+            projectType: "" ,
+            projectStatus: "" ,
+            fundType: "" ,
+            investType: "" ,
+            projectPhase: "" ,
+            tag: "" ,
+            competentDepartment: null ,
+            areaCode: "" ,
+            managementCentralization: "" ,
+            projectApprovalType: "" ,
+            investmentCatalogue: "" ,
+            importanceType: "" ,
+            year: "" ,
+            yearInvestAmount: null ,
+            createProjectTime: null ,
+            planStartTime: null ,
+            planCompleteTime: null ,
+            winUnit: "" ,
+            winAmount: "" ,
+            winTime: null ,
+            projectAddress: "" ,
+            longitude: "" ,
+            latitude: "" ,
+            projectOwnerUnit: "" ,
+            projectContactPerson: "" ,
+            contact: "" ,
+            gmtCreateTime: null ,
+            gmtUpdateTime: null ,
+            updateBy: null ,
+            createBy: null ,
+        },
+        // 琛ㄦ牸鏁版嵁
+        tableData: [],
+        // 琛ㄦ牸閫変腑鏁版嵁
+        multipleSelection: [],
+    },
+    getters: {},
+    mutations: {
+        openDialogForm(state, value) {
+            state.dialogFormVisible = value.dialogFormVisible;
+            state.dialogTitle = value.dialogTitle;
+        },
+        EditProjectInfo(state, value) {
+            state.dialogFormVisible = value.dialogFormVisible;
+            state.dialogTitle = value.dialogTitle;
+            Object.keys(state.projectInfoForm).forEach((key) => {
+                state.projectInfoForm[key] = value.projectInfoForm[key]
+            })
+        }
+    },
+    actions: {
+        editProjectInfo(state, id) {
+            getProjectInfoById(id).then((res) => {
+                var params = {
+                    dialogFormVisible: true,
+                    dialogTitle: "淇敼椤圭洰绠$悊鍩虹淇℃伅琛�",
+                    projectInfoForm: res.data.data
+                }
+                state.commit("EditProjectInfo", params);
+            })
+        }
+    },
+}
diff --git a/business/src/main/java/com/ycl/domain/vue/projectInfo.js b/business/src/main/java/com/ycl/domain/vue/projectInfo.js
new file mode 100644
index 0000000..d31ccab
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/vue/projectInfo.js
@@ -0,0 +1,61 @@
+import axios from "./request";
+
+// 鑾峰彇椤圭洰绠$悊鍩虹淇℃伅琛ㄥ垎椤�
+export const getProjectInfos = (params) => {
+    return axios({
+        url: "/api/project-info/page",
+        method: "GET",
+        params: params
+    })
+}
+
+// 鑾峰彇椤圭洰绠$悊鍩虹淇℃伅琛ㄥ垪琛�
+export const getProjectInfoList = () => {
+    return axios({
+        url: "/api/project-info/list",
+        method: "GET"
+    })
+}
+
+// 閫氳繃id鑾峰彇椤圭洰绠$悊鍩虹淇℃伅琛�
+export const getProjectInfoById = (params) => {
+    return axios({
+        url: "/api/project-info/" + params,
+        method: "GET"
+    })
+}
+
+// 閫氳繃id鍒犻櫎椤圭洰绠$悊鍩虹淇℃伅琛�
+export const deleteProjectInfoById = (params) => {
+    return axios({
+        url: "/api/project-info/" + params,
+        method: "DELETE"
+    })
+}
+
+// 鎵归噺鍒犻櫎椤圭洰绠$悊鍩虹淇℃伅琛�
+export const deleteProjectInfoByIds = (params) => {
+    return axios({
+        url: "/api/project-info/batch",
+        method: "DELETE",
+        data: params
+    })
+}
+
+// 淇敼椤圭洰绠$悊鍩虹淇℃伅琛�
+export const editProjectInfo = (params) => {
+    return axios({
+        url: "/api/project-info/",
+        method: "PUT",
+        data: params
+    })
+}
+
+// 娣诲姞椤圭洰绠$悊鍩虹淇℃伅琛�
+export const addProjectInfo = (params) => {
+    return axios({
+        url: "/api/project-info/",
+        method: "POST",
+        data: params
+    })
+}
diff --git a/business/src/main/java/com/ycl/mapper/ProjectInfoMapper.java b/business/src/main/java/com/ycl/mapper/ProjectInfoMapper.java
new file mode 100644
index 0000000..d1a54f3
--- /dev/null
+++ b/business/src/main/java/com/ycl/mapper/ProjectInfoMapper.java
@@ -0,0 +1,32 @@
+package com.ycl.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.ycl.domain.entity.ProjectInfo;
+import com.ycl.domain.query.ProjectInfoQuery;
+import com.ycl.domain.vo.ProjectInfoVO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 椤圭洰绠$悊鍩虹淇℃伅琛� Mapper 鎺ュ彛
+ *
+ * @author flq
+ * @since 2024-11-22
+ */
+@Mapper
+public interface ProjectInfoMapper extends BaseMapper<ProjectInfo> {
+
+    /**
+     * id鏌ユ壘椤圭洰绠$悊鍩虹淇℃伅琛�
+     * @param id
+     * @return
+     */
+    ProjectInfoVO getById(Integer id);
+
+    /**
+    *  鍒嗛〉
+    */
+    IPage getPage(IPage page, @Param("query") ProjectInfoQuery query);
+
+}
diff --git a/business/src/main/java/com/ycl/service/ProjectInfoService.java b/business/src/main/java/com/ycl/service/ProjectInfoService.java
new file mode 100644
index 0000000..fea0421
--- /dev/null
+++ b/business/src/main/java/com/ycl/service/ProjectInfoService.java
@@ -0,0 +1,66 @@
+package com.ycl.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ycl.common.base.Result;
+import com.ycl.domain.entity.ProjectInfo;
+import com.ycl.domain.form.ProjectInfoForm;
+import com.ycl.domain.query.ProjectInfoQuery;
+
+import java.util.List;
+
+/**
+ * 椤圭洰绠$悊鍩虹淇℃伅琛� 鏈嶅姟绫�
+ *
+ * @author flq
+ * @since 2024-11-22
+ */
+public interface ProjectInfoService extends IService<ProjectInfo> {
+
+    /**
+     * 娣诲姞
+     * @param form
+     * @return
+     */
+    Result add(ProjectInfoForm form);
+
+    /**
+     * 淇敼
+     * @param form
+     * @return
+     */
+    Result update(ProjectInfoForm form);
+
+    /**
+     * 鎵归噺鍒犻櫎
+     * @param ids
+     * @return
+     */
+    Result remove(List<String> ids);
+
+    /**
+     * id鍒犻櫎
+     * @param id
+     * @return
+     */
+    Result removeById(String id);
+
+    /**
+     * 鍒嗛〉鏌ヨ
+     * @param query
+     * @return
+     */
+    Result page(ProjectInfoQuery query);
+
+    /**
+     * 鏍规嵁id鏌ユ壘
+     * @param id
+     * @return
+     */
+    Result detail(Integer id);
+
+    /**
+     * 鍒楄〃
+     * @return
+     */
+    Result all();
+}
diff --git a/business/src/main/java/com/ycl/service/impl/ProjectInfoServiceImpl.java b/business/src/main/java/com/ycl/service/impl/ProjectInfoServiceImpl.java
new file mode 100644
index 0000000..eeca686
--- /dev/null
+++ b/business/src/main/java/com/ycl/service/impl/ProjectInfoServiceImpl.java
@@ -0,0 +1,119 @@
+package com.ycl.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ycl.common.base.Result;
+import com.ycl.domain.entity.ProjectInfo;
+import com.ycl.domain.form.ProjectInfoForm;
+import com.ycl.domain.query.ProjectInfoQuery;
+import com.ycl.domain.vo.ProjectInfoVO;
+import com.ycl.framework.utils.PageUtil;
+import com.ycl.mapper.ProjectInfoMapper;
+import com.ycl.service.ProjectInfoService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 椤圭洰绠$悊鍩虹淇℃伅琛� 鏈嶅姟瀹炵幇绫�
+ *
+ * @author flq
+ * @since 2024-11-22
+ */
+@Service
+@RequiredArgsConstructor
+public class ProjectInfoServiceImpl extends ServiceImpl<ProjectInfoMapper, ProjectInfo> implements ProjectInfoService {
+
+    private final ProjectInfoMapper projectInfoMapper;
+
+    /**
+     * 娣诲姞
+     * @param form
+     * @return
+     */
+    @Override
+    public Result add(ProjectInfoForm form) {
+        ProjectInfo entity = ProjectInfoForm.getEntityByForm(form, null);
+        baseMapper.insert(entity);
+        return Result.ok("娣诲姞鎴愬姛");
+    }
+
+    /**
+     * 淇敼
+     * @param form
+     * @return
+     */
+    @Override
+    public Result update(ProjectInfoForm form) {
+        ProjectInfo entity = baseMapper.selectById(form.getId());
+
+        // 涓虹┖鎶汭llegalArgumentException锛屽仛鍏ㄥ眬寮傚父澶勭悊
+        Assert.notNull(entity, "璁板綍涓嶅瓨鍦�");
+        BeanUtils.copyProperties(form, entity);
+        baseMapper.updateById(entity);
+        return Result.ok("淇敼鎴愬姛");
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎
+     * @param ids
+     * @return
+     */
+    @Override
+    public Result remove(List<String> ids) {
+        baseMapper.deleteBatchIds(ids);
+        return Result.ok("鍒犻櫎鎴愬姛");
+    }
+
+    /**
+     * id鍒犻櫎
+     * @param id
+     * @return
+     */
+    @Override
+    public Result removeById(String id) {
+        baseMapper.deleteById(id);
+        return Result.ok("鍒犻櫎鎴愬姛");
+    }
+
+    /**
+     * 鍒嗛〉鏌ヨ
+     * @param query
+     * @return
+     */
+    @Override
+    public Result page(ProjectInfoQuery query) {
+        IPage<ProjectInfoVO> page = PageUtil.getPage(query, ProjectInfoVO.class);
+        baseMapper.getPage(page, query);
+        return Result.ok().data(page.getRecords()).total(page.getTotal());
+    }
+
+    /**
+     * 鏍规嵁id鏌ユ壘
+     * @param id
+     * @return
+     */
+    @Override
+    public Result detail(Integer id) {
+        ProjectInfoVO vo = baseMapper.getById(id);
+        Assert.notNull(vo, "璁板綍涓嶅瓨鍦�");
+        return Result.ok().data(vo);
+    }
+
+    /**
+     * 鍒楄〃
+     * @return
+     */
+    @Override
+    public Result all() {
+        List<ProjectInfo> entities = baseMapper.selectList(null);
+        List<ProjectInfoVO> vos = entities.stream()
+                .map(entity -> ProjectInfoVO.getVoByEntity(entity, null))
+                .collect(Collectors.toList());
+        return Result.ok().data(vos);
+    }
+}
diff --git a/business/src/main/resources/mapper/ProjectInfoMapper.xml b/business/src/main/resources/mapper/ProjectInfoMapper.xml
new file mode 100644
index 0000000..a656bb3
--- /dev/null
+++ b/business/src/main/resources/mapper/ProjectInfoMapper.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ycl.mapper.ProjectInfoMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ycl.domain.vo.ProjectInfoVO">
+        <result column="project_name" property="projectName" />
+        <result column="project_code" property="projectCode" />
+        <result column="content" property="content" />
+        <result column="project_type" property="projectType" />
+        <result column="project_status" property="projectStatus" />
+        <result column="fund_type" property="fundType" />
+        <result column="invest_type" property="investType" />
+        <result column="project_phase" property="projectPhase" />
+        <result column="tag" property="tag" />
+        <result column="competent_department" property="competentDepartment" />
+        <result column="area_code" property="areaCode" />
+        <result column="management_centralization" property="managementCentralization" />
+        <result column="project_approval_type" property="projectApprovalType" />
+        <result column="investment_catalogue" property="investmentCatalogue" />
+        <result column="importance_type" property="importanceType" />
+        <result column="year" property="year" />
+        <result column="year_invest_amount" property="yearInvestAmount" />
+        <result column="create_project_time" property="createProjectTime" />
+        <result column="plan_start_time" property="planStartTime" />
+        <result column="plan_complete_time" property="planCompleteTime" />
+        <result column="win_unit" property="winUnit" />
+        <result column="win_amount" property="winAmount" />
+        <result column="win_time" property="winTime" />
+        <result column="project_address" property="projectAddress" />
+        <result column="longitude" property="longitude" />
+        <result column="latitude" property="latitude" />
+        <result column="project_owner_unit" property="projectOwnerUnit" />
+        <result column="project_contact_person" property="projectContactPerson" />
+        <result column="contact" property="contact" />
+        <result column="gmt_create_time" property="gmtCreateTime" />
+        <result column="gmt_update_time" property="gmtUpdateTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="create_by" property="createBy" />
+    </resultMap>
+
+
+
+
+
+
+
+    <select id="getById" resultMap="BaseResultMap">
+        SELECT
+            TPI.project_name,
+            TPI.project_code,
+            TPI.content,
+            TPI.project_type,
+            TPI.project_status,
+            TPI.fund_type,
+            TPI.invest_type,
+            TPI.project_phase,
+            TPI.tag,
+            TPI.competent_department,
+            TPI.area_code,
+            TPI.management_centralization,
+            TPI.project_approval_type,
+            TPI.investment_catalogue,
+            TPI.importance_type,
+            TPI.year,
+            TPI.year_invest_amount,
+            TPI.create_project_time,
+            TPI.plan_start_time,
+            TPI.plan_complete_time,
+            TPI.win_unit,
+            TPI.win_amount,
+            TPI.win_time,
+            TPI.project_address,
+            TPI.longitude,
+            TPI.latitude,
+            TPI.project_owner_unit,
+            TPI.project_contact_person,
+            TPI.contact,
+            TPI.gmt_create_time,
+            TPI.gmt_update_time,
+            TPI.update_by,
+            TPI.create_by,
+            TPI.id
+        FROM
+            t_project_info TPI
+        WHERE
+            TPI.id = #{id} AND TPI.deleted = 0
+    </select>
+
+
+    <select id="getPage" resultMap="BaseResultMap">
+        SELECT
+            TPI.project_name,
+            TPI.project_code,
+            TPI.content,
+            TPI.project_type,
+            TPI.project_status,
+            TPI.fund_type,
+            TPI.invest_type,
+            TPI.project_phase,
+            TPI.tag,
+            TPI.competent_department,
+            TPI.area_code,
+            TPI.management_centralization,
+            TPI.project_approval_type,
+            TPI.investment_catalogue,
+            TPI.importance_type,
+            TPI.year,
+            TPI.year_invest_amount,
+            TPI.create_project_time,
+            TPI.plan_start_time,
+            TPI.plan_complete_time,
+            TPI.win_unit,
+            TPI.win_amount,
+            TPI.win_time,
+            TPI.project_address,
+            TPI.longitude,
+            TPI.latitude,
+            TPI.project_owner_unit,
+            TPI.project_contact_person,
+            TPI.contact,
+            TPI.gmt_create_time,
+            TPI.gmt_update_time,
+            TPI.update_by,
+            TPI.create_by,
+            TPI.id
+        FROM
+            t_project_info TPI
+        WHERE
+            TPI.deleted = 0
+    </select>
+
+</mapper>

--
Gitblit v1.8.0