diff --git a/common/common-association/src/main/java/apelet/association/controller/ContractController.java b/common/common-association/src/main/java/apelet/association/controller/ContractController.java new file mode 100644 index 0000000..cdb8cce --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/controller/ContractController.java @@ -0,0 +1,33 @@ +package apelet.association.controller; + +import apelet.association.service.ContractService; +import apelet.association.vo.ContractListVo; +import apelet.common.core.object.ResponseResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 合同管理 + */ +@RestController +@RequestMapping("/tenantadmin/contract") +public class ContractController { + + @Autowired + private ContractService contractService; + + /** + * 查询所有合同(合同签订日期、报价负责人、名称、总报价、产品服务交付日期) + * + * @return 合同列表 + */ + @GetMapping("/contractList") + public ResponseResult> contractList() { + List result = contractService.contractList(); + return ResponseResult.success(result); + } +} diff --git a/common/common-association/src/main/java/apelet/association/controller/QuotationController.java b/common/common-association/src/main/java/apelet/association/controller/QuotationController.java new file mode 100644 index 0000000..a123dff --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/controller/QuotationController.java @@ -0,0 +1,28 @@ +package apelet.association.controller; + +import apelet.association.service.QuotationService; +import apelet.association.vo.QuotationListVo; +import apelet.common.core.object.ResponseResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 报价单管理 + */ +@RestController +@RequestMapping("/tenantadmin") +public class QuotationController { + + @Autowired + private QuotationService quotationService; + + @GetMapping("/quotationSheetList") + public ResponseResult> quotationSheetList() { + List result = quotationService.quotationSheetList(); + return ResponseResult.success(result); + } +} diff --git a/common/common-association/src/main/java/apelet/association/dao/ContractMapper.java b/common/common-association/src/main/java/apelet/association/dao/ContractMapper.java new file mode 100644 index 0000000..fb97ea0 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/dao/ContractMapper.java @@ -0,0 +1,18 @@ +package apelet.association.dao; + +import apelet.association.model.Contract; +import apelet.association.vo.ContractListVo; +import apelet.common.core.base.dao.BaseDaoMapper; + +import java.util.List; + +public interface ContractMapper extends BaseDaoMapper { + + /** + * 查询所有合同,关联 sys_user_info 解析报价负责人姓名。 + * 仅返回:合同签订日期、报价负责人(ID+姓名)、名称、总报价、产品服务交付日期。 + * + * @return 合同列表 + */ + List contractList(); +} diff --git a/common/common-association/src/main/java/apelet/association/dao/QuotationMapper.java b/common/common-association/src/main/java/apelet/association/dao/QuotationMapper.java new file mode 100644 index 0000000..6324aea --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/dao/QuotationMapper.java @@ -0,0 +1,18 @@ +package apelet.association.dao; + +import apelet.association.model.Quotation; +import apelet.association.vo.QuotationListVo; +import apelet.common.core.base.dao.BaseDaoMapper; + +import java.util.List; + +public interface QuotationMapper extends BaseDaoMapper { + + /** + * 查询所有报价单,关联 sys_user_info 解析报价负责人姓名,并映射状态字典。 + * 仅返回:创建时间、报价负责人(ID+姓名)、项目名称、总报价、状态(key+名称)。 + * + * @return 报价单列表 + */ + List listAllWithManagerName(); +} diff --git a/common/common-association/src/main/java/apelet/association/model/Contract.java b/common/common-association/src/main/java/apelet/association/model/Contract.java new file mode 100644 index 0000000..461802a --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/model/Contract.java @@ -0,0 +1,183 @@ +package apelet.association.model; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 合同 + */ +@Data +@TableName("contract") +public class Contract implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 创建人登录名称 + */ + @TableField("create_user_id") + private String createUserId; + + /** + * 创建日期 + */ + @TableField("create_time") + private Date createTime; + + /** + * 更新人登录名称 + */ + @TableField("update_user_id") + private String updateUserId; + + /** + * 更新日期 + */ + @TableField("update_time") + private Date updateTime; + + /** + * 逻辑删除标记(1: 正常 -1: 已删除) + */ + @TableField("deleted_flag") + private Integer deletedFlag; + + /** + * 编码 + */ + @TableField("number") + private String number; + + /** + * 名称 + */ + @TableField("name") + private String name; + + /** + * 流程状态 + */ + @TableField("flow_status") + private Integer flowStatus; + + /** + * 流程最新状态 + */ + @TableField("flow_approval_status") + private Integer flowApprovalStatus; + + /** + * 流程实例id + */ + @TableField("pro_ins_id") + private String proInsId; + + /** + * 状态 + */ + @TableField("billstatus") + private String billstatus; + + /** + * 公司 + */ + @TableField("org") + private Integer org; + + /** + * 来源单据ID + */ + @TableField("srcbillid") + private Integer srcbillid; + + /** + * 来源单据编码 + */ + @TableField("srcbillnumber") + private Integer srcbillnumber; + + /** + * 来源分录Id + */ + @TableField("srcentryid") + private Integer srcentryid; + + /** + * 总报价 + */ + @TableField("qty") + private BigDecimal qty; + + /** + * 报价负责人ID + */ + @TableField("managerperson") + private Long managerperson; + + /** + * 项目类型 + */ + @TableField("type") + private String type; + + /** + * 合同签订日期 + */ + @TableField("signing_date") + private Date signingDate; + + /** + * 产品服务交付日期 + */ + @TableField("delivery_date") + private Date deliveryDate; + + /** + * 分包价格 + */ + @TableField("price") + private BigDecimal price; + + /** + * 收款计划 + */ + @TableField("get_date") + private Date getDate; + + /** + * 产品服务交付负责人 + */ + @TableField("delivery_person") + private Long deliveryPerson; + + /** + * 附件 + */ + @TableField("file_text") + private String fileText; + + /** + * 分包商 + */ + @TableField("subcontractor") + private String subcontractor; + + /** + * 客户 + */ + @TableField("bd_customer") + private Long bdCustomer; +} diff --git a/common/common-association/src/main/java/apelet/association/model/Quotation.java b/common/common-association/src/main/java/apelet/association/model/Quotation.java new file mode 100644 index 0000000..0a33823 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/model/Quotation.java @@ -0,0 +1,195 @@ +package apelet.association.model; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 报价单 + */ +@Data +@TableName("quotation") +public class Quotation implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 创建人登录名称 + */ + @TableField("create_user_id") + private String createUserId; + + /** + * 创建日期 + */ + @TableField("create_time") + private Date createTime; + + /** + * 更新人登录名称 + */ + @TableField("update_user_id") + private String updateUserId; + + /** + * 更新日期 + */ + @TableField("update_time") + private Date updateTime; + + /** + * 逻辑删除标记(1: 正常 -1: 已删除) + */ + @TableField("deleted_flag") + private Integer deletedFlag; + + /** + * 编码 + */ + @TableField("number") + private String number; + + /** + * 名称 + */ + @TableField("name") + private String name; + + /** + * 流程状态 + */ + @TableField("flow_status") + private Integer flowStatus; + + /** + * 流程最新状态 + */ + @TableField("flow_approval_status") + private Integer flowApprovalStatus; + + /** + * 流程实例id + */ + @TableField("pro_ins_id") + private String proInsId; + + /** + * 状态 + */ + @TableField("billstatus") + private String billstatus; + + /** + * 公司 + */ + @TableField("org") + private Integer org; + + /** + * 来源单据ID + */ + @TableField("srcbillid") + private Long srcbillid; + + /** + * 来源单据编码 + */ + @TableField("srcbillnumber") + private Integer srcbillnumber; + + /** + * 来源分录Id + */ + @TableField("srcentryid") + private Long srcentryid; + + /** + * 项目类型ID + */ + @TableField("type") + private String type; + + /** + * 总报价 + */ + @TableField("qty") + private BigDecimal qty; + + /** + * 报价负责人ID + */ + @TableField("managerperson") + private Long managerperson; + + /** + * 报价单状态 + */ + @TableField("status") + private String status; + + /** + * 取消原因 + */ + @TableField("canaelreason") + private String canaelreason; + + /** + * 合同签订日期 + */ + @TableField("signing_date") + private Date signingDate; + + /** + * 产品服务交付日期 + */ + @TableField("delivery_date") + private Date deliveryDate; + + /** + * 分包价格 + */ + @TableField("price") + private BigDecimal price; + + /** + * 收款计划 + */ + @TableField("get_date") + private Date getDate; + + /** + * 产品服务交付负责人 + */ + @TableField("delivery_person") + private Long deliveryPerson; + + /** + * 附件 + */ + @TableField("file_text") + private String fileText; + + /** + * 分包商 + */ + @TableField("subcontractor") + private String subcontractor; + + /** + * 客户 + */ + @TableField("bd_customer") + private Long bdCustomer; +} diff --git a/common/common-association/src/main/java/apelet/association/plugin/active/ActivityLiveArchivePlugin.java b/common/common-association/src/main/java/apelet/association/plugin/active/ActivityLiveArchivePlugin.java new file mode 100644 index 0000000..599f699 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/plugin/active/ActivityLiveArchivePlugin.java @@ -0,0 +1,168 @@ +package apelet.association.plugin.active; + +import apelet.association.plugin.fileLibraryMange.FileLibrayFormPlugin; +import apelet.common.core.exception.MyRuntimeException; +import apelet.common.core.object.ObjectValue; +import apelet.common.core.object.TokenData; +import apelet.common.core.util.ApplicationContextHolder; +import apelet.common.generator.utils.OrmGenDataSourceUtil; +import apelet.common.online.abstractplugin.ExecutePluginParent; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Date; + +/** + * 活动直播文件归档插件 + * 监听 association_activity 表单的"保存"按钮, + * 将活动直播视频文件(video 字段)归档到文件库表 file_library: + * - video 附件 JSON 数组整体存入 file_library.file_name + * - 自动解析第一个文件的大小与类型,写入 file_size / file_type + * - 归档默认值:分类(classification)4、阅读权限(read_auth)1、 + * 阅读次数(read_count)0、发布状态(publish_status)1 + * - 补齐创建人/创建时间等公共字段,其余字段保持 null + * 注意:每次点击"保存"都会新增一条文件库记录 + */ +public class ActivityLiveArchivePlugin extends ExecutePluginParent { + + /** 文件库目标表 */ + private static final String FILE_LIBRARY_TABLE = "file_library"; + + private final OrmGenDataSourceUtil ormGenDataSourceUtil; + + public ActivityLiveArchivePlugin() { + ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class); + } + + /** + * 按钮触发事件:检测到"保存"按钮时,将活动直播视频归档到文件库 + * + * @param widgetVariableName 按钮标识 + * @param objectValue 当前表单数据对象 + */ + @Override + public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) { + super.buttonTriggered(widgetVariableName, objectValue); + // 仅响应"保存"按钮 + if (!"保存".equals(widgetVariableName)) { + return; + } + saveLiveVideoToFileLibrary(objectValue); + } + + /** + * 保存活动直播视频到文件库表 file_library + * 视频字段为空时直接跳过,不写入任何记录 + * + * @param objectValue 活动表单数据对象 + */ + private void saveLiveVideoToFileLibrary(ObjectValue objectValue) { + // 读取活动直播视频字段(association_activity.video),为空则跳过 + Object videoObj = objectValue.get("video"); + if (videoObj == null) { + return; + } + String videoText = videoObj.toString(); + if (videoText.isEmpty()) { + return; + } + // 解析附件 JSON 数组 + JSONArray fileArray; + try { + fileArray = JSON.parseArray(videoText); + } catch (Exception e) { + fileArray = null; + } + if (fileArray == null || fileArray.isEmpty()) { + return; + } + // file_size / file_type 为单值字段,取第一个文件的大小与类型 + String fileType = null; + String fileSize = null; + JSONObject firstFile = fileArray.getJSONObject(0); + if (firstFile != null) { + fileType = resolveFileType(firstFile.getString("filename")); + fileSize = resolveFileSize(firstFile); + } + // 当前登录用户与当前时间(公共字段) + TokenData tokenData = TokenData.takeFromRequest(); + Long userId = tokenData == null ? null : tokenData.getUserId(); + Date now = new Date(); + // 组装 file_library 记录 + ObjectValue record = new ObjectValue(FILE_LIBRARY_TABLE); + record.put("file_name", videoText); + record.put("file_type", fileType); + record.put("file_size", fileSize); + // 活动直播归档默认值:分类 4、阅读权限 1、阅读次数 0、发布状态 1 + record.put("classification", "4"); + record.put("read_auth", "1"); + record.put("read_count", 0); + record.put("publish_status", "1"); + // 公共字段 + record.put("create_user_id", userId); + record.put("create_time", now); + record.put("update_user_id", userId); + record.put("update_time", now); + record.put("deleted_flag", 1); + // 插入文件库表,主键 id 由框架自动生成 + try { + ormGenDataSourceUtil.addNew(FILE_LIBRARY_TABLE, record); + } catch (Exception e) { + throw new MyRuntimeException("保存活动直播文件到文件库失败:" + e.getMessage()); + } + } + + /** + * 通过 HEAD 请求获取 OSS 文件大小,并格式化为 KB/MB 展示字符串 + * 获取失败返回 null,不阻塞保存流程 + * + * @param file 附件 JSON 中的单个文件对象 + * @return 格式化后的文件大小(如 "1.6 MB"),失败返回 null + */ + private String resolveFileSize(JSONObject file) { + String baseUrl = file.getString("baseUrl"); + String uploadPath = file.getString("uploadPath"); + String filename = file.getString("filename"); + if (baseUrl == null || uploadPath == null || filename == null) { + return null; + } + String fullUrl = baseUrl + "/" + uploadPath + "/" + filename; + HttpURLConnection connection = null; + try { + URL url = new URL(fullUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("HEAD"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + long fileSize = connection.getContentLengthLong(); + if (fileSize > 0) { + return FileLibrayFormPlugin.formatFileSize(fileSize); + } + } catch (Exception e) { + // 获取大小失败时返回 null,不影响保存 + System.out.println("获取附件文件大小失败:" + fullUrl + "," + e.getMessage()); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + return null; + } + + /** + * 从文件名提取扩展名作为文件类型,如 "直播回放.mp4" -> "mp4" + * + * @param fileName 文件名 + * @return 文件扩展名,无法识别返回 null + */ + private String resolveFileType(String fileName) { + if (fileName == null || fileName.isEmpty() || !fileName.contains(".")) { + return null; + } + return fileName.substring(fileName.lastIndexOf(".") + 1); + } +} diff --git a/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueAuditNewOpPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueAuditNewOpPlugin.java new file mode 100644 index 0000000..e6026f8 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueAuditNewOpPlugin.java @@ -0,0 +1,53 @@ +package apelet.association.plugin.clueManage; + +import apelet.common.core.exception.MyRuntimeException; +import apelet.common.core.object.ObjectCollection; +import apelet.common.core.object.ObjectValue; +import apelet.common.core.util.ApplicationContextHolder; +import apelet.common.generator.utils.OrmGenDataSourceUtil; +import apelet.common.online.plugin.BeginOperationTransactionArgs; +import apelet.common.online.plugin.OperationServicePlugIn; +import apelet.common.online.plugin.OperationServicePlugInArgs; +import apelet.common.orm.impl.Selector; +import apelet.common.orm.impl.SelectorItem; + +public class ClueAuditNewOpPlugin extends OperationServicePlugIn { + + private final OrmGenDataSourceUtil ormGenDataSourceUtil; + + public ClueAuditNewOpPlugin() { + ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class); + } + + @Override + public void onPreparePropertys(OperationServicePlugInArgs e) { + e.addFiledKey("id"); + e.addFiledKey("status"); + } + + @Override + public void beginOperationTransaction(BeginOperationTransactionArgs e) { + super.beginOperationTransaction(e); + ObjectCollection modelCollcetion = e.getModelCollcetion(); + + if (modelCollcetion != null && !modelCollcetion.isEmpty()) { + for (int i = 0; i < modelCollcetion.size(); i++) { + try { + // 获取单据对象 + ObjectValue bill = modelCollcetion.getObject(i); + if (bill.get("status").equals("B")) { + bill.put("status", "C"); + Selector selector = new Selector(); + selector.getList().add(new SelectorItem("status")); + ormGenDataSourceUtil.update(bill.getTableName(), bill, selector); + } else { + throw new MyRuntimeException("单据不为提交状态"); + } + + } catch (Exception ex) { + throw new MyRuntimeException(ex.getMessage()); + } + } + } + } +} diff --git a/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueManageFormPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueManageFormPlugin.java index 7603645..4ed2104 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueManageFormPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueManageFormPlugin.java @@ -62,6 +62,9 @@ public class ClueManageFormPlugin extends ExecutePluginParent { if (objectValue.get("clue_type") == null) { this.setWidgetAttribute("billstatus", AttributeEnum.VALUE_CHANGE, "A"); } + if (objectValue.get("clue_type") == null) { + this.setWidgetAttribute("status", AttributeEnum.VALUE_CHANGE, "A"); + } } diff --git a/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueSubmitNewOpPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueSubmitNewOpPlugin.java new file mode 100644 index 0000000..3dd8c30 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueSubmitNewOpPlugin.java @@ -0,0 +1,54 @@ +package apelet.association.plugin.clueManage; + +import apelet.common.core.exception.MyRuntimeException; +import apelet.common.core.object.ObjectCollection; +import apelet.common.core.object.ObjectValue; +import apelet.common.core.util.ApplicationContextHolder; +import apelet.common.generator.utils.OrmGenDataSourceUtil; +import apelet.common.online.plugin.BeginOperationTransactionArgs; +import apelet.common.online.plugin.OperationResult; +import apelet.common.online.plugin.OperationServicePlugIn; +import apelet.common.online.plugin.OperationServicePlugInArgs; +import apelet.common.orm.impl.Selector; +import apelet.common.orm.impl.SelectorItem; + +public class ClueSubmitNewOpPlugin extends OperationServicePlugIn { + + private final OrmGenDataSourceUtil ormGenDataSourceUtil; + + public ClueSubmitNewOpPlugin() { + ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class); + } + + @Override + public void onPreparePropertys(OperationServicePlugInArgs e) { + e.addFiledKey("id"); + e.addFiledKey("status"); + } + + @Override + public void beginOperationTransaction(BeginOperationTransactionArgs e) { + super.beginOperationTransaction(e); + ObjectCollection modelCollcetion = e.getModelCollcetion(); + + if (modelCollcetion != null && !modelCollcetion.isEmpty()) { + for (int i = 0; i < modelCollcetion.size(); i++) { + try { + // 获取单据对象 + ObjectValue bill = modelCollcetion.getObject(i); + if (bill.get("status").equals("A")) { + bill.put("status", "B"); + Selector selector = new Selector(); + selector.getList().add(new SelectorItem("status")); + ormGenDataSourceUtil.update(bill.getTableName(), bill, selector); + } else { + throw new MyRuntimeException("单据不为编辑状态"); + } + + } catch (Exception ex) { + throw new MyRuntimeException(ex.getMessage()); + } + } + } + } + } diff --git a/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueUnAuditNewOpPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueUnAuditNewOpPlugin.java new file mode 100644 index 0000000..47d61e1 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueUnAuditNewOpPlugin.java @@ -0,0 +1,53 @@ +package apelet.association.plugin.clueManage; + +import apelet.common.core.exception.MyRuntimeException; +import apelet.common.core.object.ObjectCollection; +import apelet.common.core.object.ObjectValue; +import apelet.common.core.util.ApplicationContextHolder; +import apelet.common.generator.utils.OrmGenDataSourceUtil; +import apelet.common.online.plugin.BeginOperationTransactionArgs; +import apelet.common.online.plugin.OperationServicePlugIn; +import apelet.common.online.plugin.OperationServicePlugInArgs; +import apelet.common.orm.impl.Selector; +import apelet.common.orm.impl.SelectorItem; + +public class ClueUnAuditNewOpPlugin extends OperationServicePlugIn { + + private final OrmGenDataSourceUtil ormGenDataSourceUtil; + + public ClueUnAuditNewOpPlugin() { + ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class); + } + + @Override + public void onPreparePropertys(OperationServicePlugInArgs e) { + e.addFiledKey("id"); + e.addFiledKey("status"); + } + + @Override + public void beginOperationTransaction(BeginOperationTransactionArgs e) { + super.beginOperationTransaction(e); + ObjectCollection modelCollcetion = e.getModelCollcetion(); + + if (modelCollcetion != null && !modelCollcetion.isEmpty()) { + for (int i = 0; i < modelCollcetion.size(); i++) { + try { + // 获取单据对象 + ObjectValue bill = modelCollcetion.getObject(i); + if (bill.get("status").equals("C")) { + bill.put("status", "A"); + Selector selector = new Selector(); + selector.getList().add(new SelectorItem("status")); + ormGenDataSourceUtil.update(bill.getTableName(), bill, selector); + } else { + throw new MyRuntimeException("单据不为审核状态"); + } + + } catch (Exception ex) { + throw new MyRuntimeException(ex.getMessage()); + } + } + } + } +} diff --git a/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueUnSubmitNewOpPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueUnSubmitNewOpPlugin.java new file mode 100644 index 0000000..776eac3 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueUnSubmitNewOpPlugin.java @@ -0,0 +1,53 @@ +package apelet.association.plugin.clueManage; + +import apelet.common.core.exception.MyRuntimeException; +import apelet.common.core.object.ObjectCollection; +import apelet.common.core.object.ObjectValue; +import apelet.common.core.util.ApplicationContextHolder; +import apelet.common.generator.utils.OrmGenDataSourceUtil; +import apelet.common.online.plugin.BeginOperationTransactionArgs; +import apelet.common.online.plugin.OperationServicePlugIn; +import apelet.common.online.plugin.OperationServicePlugInArgs; +import apelet.common.orm.impl.Selector; +import apelet.common.orm.impl.SelectorItem; + +public class ClueUnSubmitNewOpPlugin extends OperationServicePlugIn { + + private final OrmGenDataSourceUtil ormGenDataSourceUtil; + + public ClueUnSubmitNewOpPlugin() { + ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class); + } + + @Override + public void onPreparePropertys(OperationServicePlugInArgs e) { + e.addFiledKey("id"); + e.addFiledKey("status"); + } + + @Override + public void beginOperationTransaction(BeginOperationTransactionArgs e) { + super.beginOperationTransaction(e); + ObjectCollection modelCollcetion = e.getModelCollcetion(); + + if (modelCollcetion != null && !modelCollcetion.isEmpty()) { + for (int i = 0; i < modelCollcetion.size(); i++) { + try { + // 获取单据对象 + ObjectValue bill = modelCollcetion.getObject(i); + if (bill.get("status").equals("B")) { + bill.put("status", "A"); + Selector selector = new Selector(); + selector.getList().add(new SelectorItem("status")); + ormGenDataSourceUtil.update(bill.getTableName(), bill, selector); + } else { + throw new MyRuntimeException("单据不为提交状态不能撤销"); + } + + } catch (Exception ex) { + throw new MyRuntimeException(ex.getMessage()); + } + } + } + } +} diff --git a/common/common-association/src/main/java/apelet/association/plugin/electronicJournal/ElectronicJournalFormPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/electronicJournal/ElectronicJournalFormPlugin.java index e7f04f4..4c9e479 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/electronicJournal/ElectronicJournalFormPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/electronicJournal/ElectronicJournalFormPlugin.java @@ -1,13 +1,22 @@ package apelet.association.plugin.electronicJournal; +import apelet.association.plugin.fileLibraryMange.FileLibrayFormPlugin; import apelet.common.core.exception.MyRuntimeException; import apelet.common.core.object.ObjectValue; +import apelet.common.core.object.TokenData; import apelet.common.core.util.ApplicationContextHolder; import apelet.common.generator.utils.OrmGenDataSourceUtil; import apelet.common.online.abstractplugin.ExecutePluginParent; import apelet.common.online.model.constant.AttributeEnum; import apelet.common.orm.impl.Selector; import apelet.common.orm.impl.SelectorItem; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Date; public class ElectronicJournalFormPlugin extends ExecutePluginParent { @@ -17,21 +26,155 @@ public class ElectronicJournalFormPlugin extends ExecutePluginParent { ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class); } +// @Override +// public void formCreated(String widgetVariableName, ObjectValue objectValue) { +// super.formCreated(widgetVariableName, objectValue); +// Object viewCount = objectValue.get("view_count"); +// if (viewCount == null) { +// this.setWidgetAttribute("viewCount", AttributeEnum.VALUE_CHANGE, "0"); +// } else { +// objectValue.put("view_count", (Integer) viewCount + 1); +// Selector selector = new Selector(); +// selector.getList().add(new SelectorItem("view_count")); +// try { +// ormGenDataSourceUtil.update(objectValue.getTableName(), objectValue, selector); +// } catch (Exception e) { +// throw new MyRuntimeException(e.getMessage()); +// } +// } +// } + + /** + * 按钮触发事件:检测到"保存"按钮时,将电子期刊附件(file)同步写入文件库表 file_library + * - file 附件 JSON 数组整体存入 file_library.file_name + * - 自动解析第一个文件的大小与类型,写入 file_size / file_type + * - 阅读权限(read_auth)、阅读次数(read_count)、状态(publish_status)、分类(classification)默认 0 + * - 补齐创建人/创建时间等公共字段,其余字段保持 null + * 注意:每次点击"保存"都会新增一条文件库记录 + * + * @param widgetVariableName 按钮标识 + * @param objectValue 当前表单数据对象 + */ @Override - public void formCreated(String widgetVariableName, ObjectValue objectValue) { - super.formCreated(widgetVariableName, objectValue); - Object viewCount = objectValue.get("view_count"); - if (viewCount == null) { - this.setWidgetAttribute("viewCount", AttributeEnum.VALUE_CHANGE, "0"); - } else { - objectValue.put("view_count", (Integer) viewCount + 1); - Selector selector = new Selector(); - selector.getList().add(new SelectorItem("view_count")); - try { - ormGenDataSourceUtil.update(objectValue.getTableName(), objectValue, selector); - } catch (Exception e) { - throw new MyRuntimeException(e.getMessage()); + public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) { + super.buttonTriggered(widgetVariableName, objectValue); + // 仅响应"保存"按钮 + if (!"保存".equals(widgetVariableName)) { + return; + } + saveAttachmentToFileLibrary(objectValue); + } + + /** + * 保存电子期刊附件到文件库表 file_library + * 附件为空时直接跳过,不写入任何记录 + * + * @param objectValue 电子期刊表单数据对象 + */ + private void saveAttachmentToFileLibrary(ObjectValue objectValue) { + // 读取附件字段(电子期刊表单的附件控件为 file),附件为空则跳过 + Object fileObj = objectValue.get("file"); + if (fileObj == null) { + return; + } + String fileText = fileObj.toString(); + if (fileText.isEmpty()) { + return; + } + // 解析附件 JSON 数组 + JSONArray fileArray; + try { + fileArray = JSON.parseArray(fileText); + } catch (Exception e) { + fileArray = null; + } + if (fileArray == null || fileArray.isEmpty()) { + return; + } + // file_size / file_type 为单值字段,取第一个文件的大小与类型 + String fileType = null; + String fileSize = null; + JSONObject firstFile = fileArray.getJSONObject(0); + if (firstFile != null) { + fileType = resolveFileType(firstFile.getString("filename")); + fileSize = resolveFileSize(firstFile); + } + // 当前登录用户与当前时间(公共字段) + TokenData tokenData = TokenData.takeFromRequest(); + Long userId = tokenData == null ? null : tokenData.getUserId(); + Date now = new Date(); + // 组装 file_library 记录 + ObjectValue record = new ObjectValue("file_library"); + record.put("file_name", fileText); + record.put("file_type", fileType); + record.put("file_size", fileSize); + // 阅读权限、阅读次数、状态、分类默认 0 + record.put("read_auth", "1"); + record.put("read_count", 0); + record.put("publish_status", "1"); + record.put("classification", "2"); + // 公共字段 + record.put("create_user_id", userId); + record.put("create_time", now); + record.put("update_user_id", userId); + record.put("update_time", now); + record.put("deleted_flag", 1); + // 插入文件库表,主键 id 由框架自动生成 + try { + ormGenDataSourceUtil.addNew("file_library", record); + } catch (Exception e) { + throw new MyRuntimeException("保存附件到文件库失败:" + e.getMessage()); + } + } + + /** + * 通过 HEAD 请求获取 OSS 文件大小,并格式化为 KB/MB 展示字符串 + * 获取失败返回 null,不阻塞保存流程 + * + * @param file 附件 JSON 中的单个文件对象 + * @return 格式化后的文件大小(如 "1.6 MB"),失败返回 null + */ + private String resolveFileSize(JSONObject file) { + String baseUrl = file.getString("baseUrl"); + String uploadPath = file.getString("uploadPath"); + String filename = file.getString("filename"); + if (baseUrl == null || uploadPath == null || filename == null) { + return null; + } + String fullUrl = baseUrl + "/" + uploadPath + "/" + filename; + HttpURLConnection connection = null; + try { + URL url = new URL(fullUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("HEAD"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + long fileSize = connection.getContentLengthLong(); + if (fileSize > 0) { + return FileLibrayFormPlugin.formatFileSize(fileSize); } + } catch (Exception e) { + // 获取大小失败时返回 null,不影响保存 + System.out.println("获取附件文件大小失败:" + fullUrl + "," + e.getMessage()); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + return null; + } + + /** + * 从文件名提取扩展名作为文件类型,如 "期刊.pdf" -> "pdf" + * + * @param fileName 文件名 + * @return 文件扩展名,无法识别返回 null + */ + private String resolveFileType(String fileName) { + if (fileName == null || fileName.isEmpty() || !fileName.contains(".")) { + return null; } + return fileName.substring(fileName.lastIndexOf(".") + 1); } } diff --git a/common/common-association/src/main/java/apelet/association/plugin/fileLibraryMange/FileLibrayListPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/fileLibraryMange/FileLibrayListPlugin.java index ec460a7..eee49b8 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/fileLibraryMange/FileLibrayListPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/fileLibraryMange/FileLibrayListPlugin.java @@ -1,5 +1,10 @@ package apelet.association.plugin.fileLibraryMange; +import apelet.common.core.object.ObjectValue; +import apelet.common.core.object.ObjectValue; +import apelet.common.core.object.TokenData; +import apelet.common.core.util.ApplicationContextHolder; +import apelet.common.generator.utils.OrmGenDataSourceUtil; import apelet.common.online.abstractplugin.ListPlugin; import apelet.common.online.dto.OnlineEventPluginExecuteDto; import apelet.common.online.dto.OnlineFilterDto; @@ -7,21 +12,84 @@ import apelet.common.orm.impl.Filter; import apelet.common.orm.impl.FilterItem; import java.util.ArrayList; +import java.util.List; +import java.util.Map; public class FileLibrayListPlugin extends ListPlugin { @Override - protected Filter getFilter() { + public String getSql(ObjectValue objectValue) { OnlineEventPluginExecuteDto filter1 = this.getDto(); ArrayList filterDtoList = (ArrayList) filter1.getListParams().get("filterDtoList"); - Filter filter = new Filter(); + +// return super.getSql(objectValue); + String sql = "select * from file_library "; + //阅读权限 + sql += "where (read_auth = 1"; if (!filterDtoList.isEmpty()) { OnlineFilterDto onlineFilterDto = filterDtoList.get(0); Object filterFile = onlineFilterDto.getColumnValue(); - filter.add(new FilterItem("classification", "=", filterFile)); + //上线 + sql += " and classification = "+filterFile.toString(); + } + System.out.println(sql); + Long userId = TokenData.takeFromRequest().getUserId(); + //获取当前用户 + ObjectValue user = ormGenDataSourceUtil().queryOne("xy_sys_user", userId); + String userName = user.getString("show_name"); + String userType = user.getString("user_type"); - } else { - filter = new Filter(); + System.out.println("userName:" + userName+user.getString("user_type")); + if (userType.equals("0")) { + sql += " or read_auth = 2"; + } + sql += " and publish_status = 1"; + sql += " or (create_user_id = "+userId.toString()+" and read_auth = 3))"; + //下线 + sql += " or (publish_status = 2"; + if (!filterDtoList.isEmpty()) { + OnlineFilterDto onlineFilterDto = filterDtoList.get(0); + Object filterFile = onlineFilterDto.getColumnValue(); + sql += " and classification = "+filterFile.toString(); } - return filter; + if (userType.equals("0")) { + sql += " or read_auth = 2"; + } + sql += " or (create_user_id = "+userId.toString()+" and read_auth = 3))"; + + return sql; } + + /** + * 编辑按钮检测:仅允许选中文件的 classification=5(上传文件)时才可编辑 + * 否则提示并取消编辑操作 + * + * @param widgetVariableName 按钮标识 + * @param objectValue 当前事件数据对象 + */ + @Override + public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) { + super.buttonTriggered(widgetVariableName, objectValue); + // 仅对"编辑"按钮做检测 + if (!"编辑".equals(widgetVariableName)) { + return; + } + // 获取列表当前选中的行数据 + List rowDatas = getDto().getModel().getRowDatas(); + if (rowDatas == null || rowDatas.isEmpty()) { + showWarningMessage("请先在列表中选中要编辑的文件"); + this.cancelOperate(); + return; + } + // 遍历选中行,任一文件 classification != 5 则禁止编辑 + for (Map rowData : rowDatas) { + Object classificationObj = rowData.get("classification"); + String classification = classificationObj == null ? "" : String.valueOf(classificationObj); + if (!"5".equals(classification)) { + showWarningMessage("仅\"上传文件\"分类的文件允许编辑"); + this.cancelOperate(); + return; + } + } + } + } diff --git a/common/common-association/src/main/java/apelet/association/plugin/quotation/QuotationPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/quotation/QuotationPlugin.java index 061404d..3cb1628 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/quotation/QuotationPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/quotation/QuotationPlugin.java @@ -1,5 +1,7 @@ package apelet.association.plugin.quotation; +import apelet.association.plugin.fileLibraryMange.FileLibrayFormPlugin; +import apelet.common.core.exception.MyRuntimeException; import apelet.common.core.object.ObjectCollection; import apelet.common.core.object.ObjectValue; import apelet.common.core.object.TokenData; @@ -7,9 +9,15 @@ import apelet.common.core.util.ApplicationContextHolder; import apelet.common.generator.utils.OrmGenDataSourceUtil; import apelet.common.online.abstractplugin.ExecutePluginParent; import apelet.common.online.model.constant.AttributeEnum; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import liquibase.repackaged.org.apache.commons.lang3.StringUtils; import java.math.BigDecimal; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -92,4 +100,127 @@ public class QuotationPlugin extends ExecutePluginParent { type = StringUtils.removeEnd(type, ","); this.setWidgetAttribute("type", AttributeEnum.VALUE_CHANGE, type); } + + @Override + public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) { + super.buttonTriggered(widgetVariableName, objectValue); + // 仅响应"保存"按钮 + if (!"保存".equals(widgetVariableName)) { + return; + } + saveAttachmentToFileLibrary(objectValue); + } + + /** + * 保存报价单附件到文件库表 file_library + * 附件为空时直接跳过,不写入任何记录 + * + * @param objectValue 报价单表单数据对象 + */ + private void saveAttachmentToFileLibrary(ObjectValue objectValue) { + // 读取附件字段,附件为空则跳过 + Object fileTextObj = objectValue.get("file_text"); + if (fileTextObj == null) { + return; + } + String fileText = fileTextObj.toString(); + if (fileText.isEmpty()) { + return; + } + // 解析附件 JSON 数组 + JSONArray fileArray; + try { + fileArray = JSON.parseArray(fileText); + } catch (Exception e) { + fileArray = null; + } + if (fileArray == null || fileArray.isEmpty()) { + return; + } + // file_size / file_type 为单值字段,取第一个文件的大小与类型 + String fileType = null; + String fileSize = null; + JSONObject firstFile = fileArray.getJSONObject(0); + if (firstFile != null) { + fileType = resolveFileType(firstFile.getString("filename")); + fileSize = resolveFileSize(firstFile); + } + // 当前登录用户与当前时间(公共字段) + TokenData tokenData = TokenData.takeFromRequest(); + Long userId = tokenData == null ? null : tokenData.getUserId(); + Date now = new Date(); + // 组装 file_library 记录 + ObjectValue record = new ObjectValue("file_library"); + record.put("file_name", fileText); + record.put("file_type", fileType); + record.put("file_size", fileSize); + // 阅读权限、阅读次数、状态、分类默认 0 + record.put("read_auth", "1"); + record.put("read_count", 0); + record.put("publish_status", "1"); + record.put("classification", "3"); + // 公共字段 + record.put("create_user_id", userId); + record.put("create_time", now); + record.put("update_user_id", userId); + record.put("update_time", now); + record.put("deleted_flag", 1); + // 插入文件库表,主键 id 由框架自动生成 + try { + ormGenDataSourceUtil.addNew("file_library", record); + } catch (Exception e) { + throw new MyRuntimeException("保存附件到文件库失败:" + e.getMessage()); + } + } + + /** + * 通过 HEAD 请求获取 OSS 文件大小,并格式化为 KB/MB 展示字符串 + * 获取失败返回 null,不阻塞保存流程 + * + * @param file 附件 JSON 中的单个文件对象 + * @return 格式化后的文件大小(如 "1.6 MB"),失败返回 null + */ + private String resolveFileSize(JSONObject file) { + String baseUrl = file.getString("baseUrl"); + String uploadPath = file.getString("uploadPath"); + String filename = file.getString("filename"); + if (baseUrl == null || uploadPath == null || filename == null) { + return null; + } + String fullUrl = baseUrl + "/" + uploadPath + "/" + filename; + HttpURLConnection connection = null; + try { + URL url = new URL(fullUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("HEAD"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + long fileSize = connection.getContentLengthLong(); + if (fileSize > 0) { + return FileLibrayFormPlugin.formatFileSize(fileSize); + } + } catch (Exception e) { + // 获取大小失败时返回 null,不影响保存 + System.out.println("获取附件文件大小失败:" + fullUrl + "," + e.getMessage()); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + return null; + } + + /** + * 从文件名提取扩展名作为文件类型,如 "合同.pdf" -> "pdf" + * + * @param fileName 文件名 + * @return 文件扩展名,无法识别返回 null + */ + private String resolveFileType(String fileName) { + if (StringUtils.isEmpty(fileName) || !fileName.contains(".")) { + return null; + } + return fileName.substring(fileName.lastIndexOf(".") + 1); + } } diff --git a/common/common-association/src/main/java/apelet/association/service/ContractService.java b/common/common-association/src/main/java/apelet/association/service/ContractService.java new file mode 100644 index 0000000..7c7eb68 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/service/ContractService.java @@ -0,0 +1,17 @@ +package apelet.association.service; + +import apelet.association.model.Contract; +import apelet.association.vo.ContractListVo; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +public interface ContractService extends IService { + + /** + * 查询所有合同(合同签订日期、报价负责人、名称、总报价、产品服务交付日期) + * + * @return 合同列表 + */ + List contractList(); +} diff --git a/common/common-association/src/main/java/apelet/association/service/QuotationService.java b/common/common-association/src/main/java/apelet/association/service/QuotationService.java new file mode 100644 index 0000000..9010e52 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/service/QuotationService.java @@ -0,0 +1,17 @@ +package apelet.association.service; + +import apelet.association.model.Quotation; +import apelet.association.vo.QuotationListVo; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +public interface QuotationService extends IService { + + /** + * 查询所有报价单(仅返回创建时间、报价负责人、项目名称、总报价、状态) + * + * @return 报价单列表 + */ + List quotationSheetList(); +} diff --git a/common/common-association/src/main/java/apelet/association/service/impl/ContractServiceImpl.java b/common/common-association/src/main/java/apelet/association/service/impl/ContractServiceImpl.java new file mode 100644 index 0000000..7868604 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/service/impl/ContractServiceImpl.java @@ -0,0 +1,19 @@ +package apelet.association.service.impl; + +import apelet.association.dao.ContractMapper; +import apelet.association.model.Contract; +import apelet.association.service.ContractService; +import apelet.association.vo.ContractListVo; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class ContractServiceImpl extends ServiceImpl implements ContractService { + + @Override + public List contractList() { + return baseMapper.contractList(); + } +} diff --git a/common/common-association/src/main/java/apelet/association/service/impl/QuotationServiceImpl.java b/common/common-association/src/main/java/apelet/association/service/impl/QuotationServiceImpl.java new file mode 100644 index 0000000..5b36c01 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/service/impl/QuotationServiceImpl.java @@ -0,0 +1,19 @@ +package apelet.association.service.impl; + +import apelet.association.dao.QuotationMapper; +import apelet.association.model.Quotation; +import apelet.association.service.QuotationService; +import apelet.association.vo.QuotationListVo; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class QuotationServiceImpl extends ServiceImpl implements QuotationService { + + @Override + public List quotationSheetList() { + return baseMapper.listAllWithManagerName(); + } +} diff --git a/common/common-association/src/main/java/apelet/association/vo/ContractListVo.java b/common/common-association/src/main/java/apelet/association/vo/ContractListVo.java new file mode 100644 index 0000000..f497521 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/vo/ContractListVo.java @@ -0,0 +1,48 @@ +package apelet.association.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 合同列表展示对象 + */ +@Data +public class ContractListVo { + + /** + * 主键ID + */ + private Long id; + + /** + * 合同签订日期 + */ + private Date signingDate; + + /** + * 报价负责人ID + */ + private Long managerperson; + + /** + * 报价负责人姓名(关联 sys_user_info.USER_NAME) + */ + private String managerName; + + /** + * 名称 + */ + private String name; + + /** + * 总报价 + */ + private BigDecimal qty; + + /** + * 产品服务交付日期 + */ + private Date deliveryDate; +} diff --git a/common/common-association/src/main/java/apelet/association/vo/QuotationListVo.java b/common/common-association/src/main/java/apelet/association/vo/QuotationListVo.java new file mode 100644 index 0000000..24d4b32 --- /dev/null +++ b/common/common-association/src/main/java/apelet/association/vo/QuotationListVo.java @@ -0,0 +1,48 @@ +package apelet.association.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 报价单列表展示对象 + */ +@Data +public class QuotationListVo { + + /** + * 主键ID + */ + private Long id; + + /** + * 创建日期 + */ + private Date createTime; + + /** + * 报价负责人ID + */ + private Long managerperson; + + /** + * 报价负责人姓名(关联 xy_sys_user.show_name) + */ + private String managerName; + + /** + * 项目名称 + */ + private String name; + + /** + * 总报价 + */ + private BigDecimal qty; + + /** + * 报价单状态(字典翻译后的中文值: 报价草案/报价审批/报价生效/作废) + */ + private String status; +} diff --git a/common/common-association/src/main/resources/mapper/ContractMapper.xml b/common/common-association/src/main/resources/mapper/ContractMapper.xml new file mode 100644 index 0000000..e60a1e0 --- /dev/null +++ b/common/common-association/src/main/resources/mapper/ContractMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/common/common-association/src/main/resources/mapper/QuotationMapper.xml b/common/common-association/src/main/resources/mapper/QuotationMapper.xml new file mode 100644 index 0000000..442a7ad --- /dev/null +++ b/common/common-association/src/main/resources/mapper/QuotationMapper.xml @@ -0,0 +1,29 @@ + + + + + + + +