Procházet zdrojové kódy

提交培训计划代码

Heyuan před 11 měsíci
rodič
revize
b7881b87c3

+ 2 - 3
cosmic/q1k2-cosmic-debug/build.gradle

@@ -7,12 +7,11 @@
  */
 
 dependencies {
-
 	// 公共基础包
 	implementation project(':q1k2-base-common')
 	implementation project(':q1k2-base-helper')
-
 	// 引入study云模块
 	implementation project(':q1k2-study')
-	
+	// 引入培训云模块
+	implementation project(':q1k2-pxlx')
 } 

+ 14 - 0
cosmic/q1k2-pxlx/build.gradle

@@ -0,0 +1,14 @@
+/*
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: generate_date
+ */
+
+dependencies {
+	implementation project(':q1k2-base-common')
+	implementation project(':q1k2-base-helper')
+} 
+
+

+ 81 - 0
cosmic/q1k2-pxlx/src/main/java/q1k2/pxlx/train/common/Q1k2MonthPlanLwConstant.java

@@ -0,0 +1,81 @@
+package q1k2.pxlx.train.common;
+
+/**
+ * 月度计划_刘维常量类
+ *
+ * @author 刘维
+ * @version 1.0
+ * @date 2024-06-27 11:12:37
+ */
+public class Q1k2MonthPlanLwConstant {
+
+    public static final String FORMBILLID = "q1k2_month_plan_lw";
+    /**缺省id字段**/
+    public static final String ID = "id";
+    /**单据编号**/
+    public static final String BILLNO = "billno";
+    /**单据状态**/
+    public static final String BILLSTATUS = "billstatus";
+    /**创建人**/
+    public static final String CREATOR = "creator";
+    /**修改人**/
+    public static final String MODIFIER = "modifier";
+    /**审核人**/
+    public static final String AUDITOR = "auditor";
+    /**审核日期**/
+    public static final String AUDITDATE = "auditdate";
+    /**修改时间**/
+    public static final String MODIFYTIME = "modifytime";
+    /**创建时间**/
+    public static final String CREATETIME = "createtime";
+    /**组织**/
+    public static final String ORG = "org";
+    /**名称**/
+    public static final String Q1K2_NAME = "q1k2_name";
+    /**行政组织**/
+    public static final String Q1K2_ADMINORG = "q1k2_adminorg";
+    /**年度**/
+    public static final String Q1K2_YEAR = "q1k2_year";
+    /**月度**/
+    public static final String Q1K2_MONTH = "q1k2_month";
+    /**实施部门**/
+    public static final String Q1K2_ORG = "q1k2_org";
+    /**培训级别**/
+    public static final String Q1K2_LEVEL = "q1k2_level";
+    /**培训类型**/
+    public static final String Q1K2_TYPE = "q1k2_type";
+    /**培训对象**/
+    public static final String Q1K2_OBJECT = "q1k2_object";
+    /**联系方式**/
+    public static final String Q1K2_TELEPHONEFIELD = "q1k2_telephonefield";
+    /**联系人**/
+    public static final String Q1K2_CONTACTS = "q1k2_contacts";
+    /**本部门预算**/
+    public static final String Q1K2_BUDGE_SELF = "q1k2_budge_self";
+    /**地点**/
+    public static final String Q1K2_ADDRESS = "q1k2_address";
+    /**天数**/
+    public static final String Q1K2_DAYS = "q1k2_days";
+    /**年度计划**/
+    public static final String Q1K2_YEAR_PLAN = "q1k2_year_plan";
+    /**讲师**/
+    public static final String Q1K2_LECTURER = "q1k2_lecturer";
+    /**课时**/
+    public static final String Q1K2_HOUR = "q1k2_hour";
+    /**计划人数**/
+    public static final String Q1K2_USER = "q1k2_user";
+    /**预算**/
+    public static final String Q1K2_BUDGET = "q1k2_budget";
+    /**师资来源**/
+    public static final String Q1K2_SOURCE = "q1k2_source";
+    /**培训形式**/
+    public static final String Q1K2_TRAINING_TYPE = "q1k2_training_type";
+    /**培训主要内容**/
+    public static final String Q1K2_CONTENT = "q1k2_content";
+    /**计划来源**/
+    public static final String Q1K2_ORIGIN = "q1k2_origin";
+    /**实施状态**/
+    public static final String Q1K2_EXEC_STATUS = "q1k2_exec_status";
+    /**年度计划id**/
+    public static final String Q1K2_YEAR_PLANID = "q1k2_year_planid";
+}

+ 228 - 0
cosmic/q1k2-pxlx/src/main/java/q1k2/pxlx/train/common/Q1k2YearPlanConstant.java

@@ -0,0 +1,228 @@
+package q1k2.pxlx.train.common;
+
+/**
+ * 年度计划_刘维常量类
+ *
+ * @author 刘维
+ * @version 1.0
+ * @date 2024-06-26 11:17:35
+ */
+public class Q1k2YearPlanConstant {
+
+    public static final String FORMBILLID = "q1k2_year_plan";
+    /**
+     * 缺省id字段
+     **/
+    public static final String ID = "id";
+    /**
+     * 单据编号
+     **/
+    public static final String BILLNO = "billno";
+    /**
+     * 单据状态
+     **/
+    public static final String BILLSTATUS = "billstatus";
+    /**
+     * 创建人
+     **/
+    public static final String CREATOR = "creator";
+    /**
+     * 修改人
+     **/
+    public static final String MODIFIER = "modifier";
+    /**
+     * 审核人
+     **/
+    public static final String AUDITOR = "auditor";
+    /**
+     * 审核日期
+     **/
+    public static final String AUDITDATE = "auditdate";
+    /**
+     * 修改时间
+     **/
+    public static final String MODIFYTIME = "modifytime";
+    /**
+     * 创建时间
+     **/
+    public static final String CREATETIME = "createtime";
+    /**
+     * 组织
+     **/
+    public static final String ORG = "org";
+
+    /**
+     * 行政组织
+     **/
+    public static final String Q1K2_ADMINORG = "q1k2_adminorg";
+    /**
+     * 单据体
+     **/
+    public static final String Q1K2_YEAR_PLAN_ITEM = "q1k2_year_plan_item";
+    /**
+     * 分录行号
+     **/
+    public static final String SEQ = "seq";
+    /**
+     * 修改人
+     **/
+    public static final String MODIFIERFIELD = "modifierfield";
+    /**
+     * 修改时间
+     **/
+    public static final String MODIFYDATEFIELD = "modifydatefield";
+    /**
+     * 项目名称
+     **/
+    public static final String Q1K2_ITEM_PROJECTNAME = "q1k2_item_projectname";
+    /**
+     * 实施部门
+     **/
+    public static final String Q1K2_ITEM_ORG = "q1k2_item_org";
+    /**
+     * 培训类型
+     **/
+    public static final String Q1K2_ITEM_TYPE = "q1k2_item_type";
+    /**
+     * 培训主要内容
+     **/
+    public static final String Q1K2_ITEM_CONTENT = "q1k2_item_content";
+    /**
+     * 培训级别
+     **/
+    public static final String Q1K2_ITEM_LEVEL = "q1k2_item_level";
+    /**
+     * 培训对象
+     **/
+    public static final String Q1K2_ITEM_OBJ = "q1k2_item_obj";
+    /**
+     * 培训形式
+     **/
+    public static final String Q1K2_ITEM_TRAININGTYPE = "q1k2_item_trainingtype";
+    /**
+     * 师资来源
+     **/
+    public static final String Q1K2_ITEM_SOURCE = "q1k2_item_source";
+    /**
+     * 讲师
+     **/
+    public static final String Q1K2_ITEM_LECTURER = "q1k2_item_lecturer";
+    /**
+     * 预算
+     **/
+    public static final String Q1K2_ITEM_BUDGET = "q1k2_item_budget";
+    /**
+     * 天数
+     **/
+    public static final String Q1K2_ITEM_DAYS = "q1k2_item_days";
+    /**
+     * 人次合计
+     **/
+    public static final String Q1K2_ITEM_COUNT = "q1k2_item_count";
+    /**
+     * 课时
+     **/
+    public static final String Q1K2_ITEM_HOURS = "q1k2_item_hours";
+    /**
+     * 地点
+     **/
+    public static final String Q1K2_ITEM_ADDRESS = "q1k2_item_address";
+    /**
+     * 本部预算金额
+     **/
+    public static final String Q1K2_ITEM_BUDGET_SELF = "q1k2_item_budget_self";
+    /**
+     * 联系人
+     **/
+    public static final String Q1K2_ITEM_CONTACTS = "q1k2_item_contacts";
+    /**
+     * 联系电话
+     **/
+    public static final String Q1K2_ITEM_PHONE = "q1k2_item_phone";
+    /**
+     * 所属计划
+     **/
+    public static final String Q1K2_ITEM_YEAR_PLAN = "q1k2_item_year_plan";
+
+    public static final String Q1K2_ITEM_MONTH = "q1k2_item_month";
+    /**
+     * 一月
+     **/
+    public static final String Q1K2_ITEM_MONTH1 = "q1k2_item_month1";
+    /**
+     * 八月
+     **/
+    public static final String Q1K2_ITEM_MONTH8 = "q1k2_item_month8";
+    /**
+     * 二月
+     **/
+    public static final String Q1K2_ITEM_MONTH2 = "q1k2_item_month2";
+    /**
+     * 三月
+     **/
+    public static final String Q1K2_ITEM_MONTH3 = "q1k2_item_month3";
+    /**
+     * 四月
+     **/
+    public static final String Q1K2_ITEM_MONTH4 = "q1k2_item_month4";
+    /**
+     * 五月
+     **/
+    public static final String Q1K2_ITEM_MONTH5 = "q1k2_item_month5";
+    /**
+     * 六月
+     **/
+    public static final String Q1K2_ITEM_MONTH6 = "q1k2_item_month6";
+    /**
+     * 七月
+     **/
+    public static final String Q1K2_ITEM_MONTH7 = "q1k2_item_month7";
+    /**
+     * 九月
+     **/
+    public static final String Q1K2_ITEM_MONTH9 = "q1k2_item_month9";
+    /**
+     * 十月
+     **/
+    public static final String Q1K2_ITEM_MONTH10 = "q1k2_item_month10";
+    /**
+     * 十一月
+     **/
+    public static final String Q1K2_ITEM_MONTH11 = "q1k2_item_month11";
+    /**
+     * 十二月
+     **/
+    public static final String Q1K2_ITEM_MONTH12 = "q1k2_item_month12";
+    /**
+     * 创建组织
+     **/
+    public static final String Q1K2_CREATEORG = "q1k2_createorg";
+    /**
+     * 名称
+     **/
+    public static final String Q1K2_NAME = "q1k2_name";
+    /**
+     * 年度
+     **/
+    public static final String Q1K2_YEAR = "q1k2_year";
+    /**
+     * 总预算
+     **/
+    public static final String Q1K2_BUDGET = "q1k2_budget";
+    /**
+     * 总人次
+     **/
+    public static final String Q1K2_COUNT = "q1k2_count";
+    /**
+     * 总课时
+     **/
+    public static final String Q1K2_HOURS = "q1k2_hours";
+    /**
+     * 是否拆分月度计划
+     **/
+    public static final String Q1K2_SPLITMONTHPLAN = "q1k2_splitmonthplan";
+    /**
+     * 是否已经生成月度计划
+     **/
+    public static final String Q1K2_GENERATE_MONTH = "q1k2_generate_month";
+}

+ 59 - 0
cosmic/q1k2-pxlx/src/main/java/q1k2/pxlx/train/plugin/form/MonthPlanBillPlugin.java

@@ -0,0 +1,59 @@
+package q1k2.pxlx.train.plugin.form;
+
+import kd.bos.bill.AbstractBillPlugIn;
+import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.form.field.ComboEdit;
+import kd.bos.form.field.ComboItem;
+import kd.sdk.plugin.Plugin;
+import q1k2.pxlx.train.common.Q1k2MonthPlanLwConstant;
+import q1k2.pxlx.train.common.Q1k2YearPlanConstant;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.EventObject;
+import java.util.List;
+
+/**
+ * @Description 月度计划表单插件
+ * @Created 刘维
+ */
+public class MonthPlanBillPlugin extends AbstractBillPlugIn implements Plugin {
+    @Override
+    public void afterLoadData(EventObject e) {
+        super.afterLoadData(e);
+        setComboItems();
+    }
+
+
+    @Override
+    public void afterCreateNewData(EventObject e) {
+        super.afterCreateNewData(e);
+        setComboItems();
+    }
+
+    /**
+     * 设置年度下拉值
+     */
+    private void setComboItems() {
+        Calendar calendar = Calendar.getInstance();
+        int year = calendar.get(Calendar.YEAR);//当前年度
+        //获取年度下拉控件
+        ComboEdit yearComboEdit = this.getControl(Q1k2MonthPlanLwConstant.Q1K2_YEAR);
+        //设置下拉值
+        List<ComboItem> data = new ArrayList<>();
+        for (int i = year - 3; i <= year + 3; i++) {
+            data.add(new ComboItem(new LocaleString(String.valueOf(i)), String.valueOf(i)));
+        }
+        //绑定下拉值
+        yearComboEdit.setComboItems(data);
+        //获取月度下拉控件
+        ComboEdit monthComboEdit = this.getControl(Q1k2MonthPlanLwConstant.Q1K2_MONTH);
+        //设置下拉值
+        List<ComboItem> monthData = new ArrayList<>();
+        for (int i = 1; i <= 12; i++) {
+            monthData.add(new ComboItem(new LocaleString(String.valueOf(i)), String.valueOf(i)));
+        }
+        //绑定下拉值
+        monthComboEdit.setComboItems(monthData);
+    }
+}

+ 92 - 0
cosmic/q1k2-pxlx/src/main/java/q1k2/pxlx/train/plugin/form/MonthPlanListPlugin.java

@@ -0,0 +1,92 @@
+package q1k2.pxlx.train.plugin.form;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.entity.datamodel.events.PackageDataEvent;
+import kd.bos.filter.CommonFilterColumn;
+import kd.bos.form.events.FilterContainerInitArgs;
+import kd.bos.form.field.ComboItem;
+import kd.bos.form.operatecol.OperationColItem;
+import kd.bos.list.column.ListOperationColumnDesc;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.sdk.plugin.Plugin;
+import q1k2.pxlx.train.common.Q1k2MonthPlanLwConstant;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * @Description 月度计划列表插件
+ * @Created 刘维
+ */
+public class MonthPlanListPlugin extends AbstractListPlugin implements Plugin {
+    /**
+     * 过滤控件初始化
+     *
+     * @param args
+     */
+    @Override
+    public void filterContainerInit(FilterContainerInitArgs args) {
+        super.filterContainerInit(args);
+        /****** 常用过滤视图下的筛选条件处理 ******/
+        CommonFilterColumn yearFilter = new CommonFilterColumn(Q1k2MonthPlanLwConstant.Q1K2_YEAR);
+        //多选
+        yearFilter.setMulti(true);
+        // 设置标题
+        yearFilter.setCaption(new LocaleString("年度"));
+        Calendar calendar = Calendar.getInstance();
+        int year = calendar.get(Calendar.YEAR);//当前年度
+        // 设置下拉值
+        List<ComboItem> data = new ArrayList<>();
+        for (int i = year - 3; i <= year + 3; i++) {
+            data.add(new ComboItem(new LocaleString(String.valueOf(i)), String.valueOf(i)));
+        }
+        yearFilter.setComboItems(data);
+        args.addFilterColumn(yearFilter);
+    }
+
+    /**
+     * 数据包装事件,用于修改发送给前端之前的数据,用于单元格填值
+     *
+     * @param evt 数据包装事件参数 PackageDataEvent
+     */
+    @Override
+    public void packageData(PackageDataEvent evt) {
+        super.packageData(evt);
+        this.setOperationColItemStyle(evt);
+    }
+
+    /**
+     * 操作列控制(某个操作项上显示名称)
+     *
+     * @param evt
+     */
+    private void setOperationColItemStyle(PackageDataEvent evt) {
+        Object obj = evt.getSource();
+        // 获取当前行数据
+        DynamicObject rowData = evt.getRowData();
+        // 判断是否是操作列
+        if (obj instanceof ListOperationColumnDesc) {
+            String billstatus = rowData.getString("billstatus");// 状态
+            List<OperationColItem> operationColItems = (List<OperationColItem>) evt.getFormatValue();
+            for (OperationColItem item : operationColItems) {
+                //操作键
+                String operationKey = item.getOperationKey();
+                if (("modify".equalsIgnoreCase(operationKey)
+                        || "submit".equalsIgnoreCase(operationKey))
+                        && "A".equals(billstatus)) {
+                    //暂存状态 显示 修改和提交
+                    item.setVisible(true);
+                    //item.setLocked(true);
+                } else if (("unsubmit".equalsIgnoreCase(operationKey)
+                        || "changeplan".equalsIgnoreCase(operationKey)
+                        || "execstatus".equalsIgnoreCase(operationKey))
+                        && "B".equals(billstatus)) {
+                    //已提交状态 显示 撤销、变更计划、实施情况
+                    item.setVisible(true);
+                }
+            }
+        }
+    }
+}

+ 49 - 0
cosmic/q1k2-pxlx/src/main/java/q1k2/pxlx/train/plugin/form/YearPlanBillPlugin.java

@@ -0,0 +1,49 @@
+package q1k2.pxlx.train.plugin.form;
+
+import kd.bos.bill.AbstractBillPlugIn;
+import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.form.field.ComboEdit;
+import kd.bos.form.field.ComboItem;
+import kd.sdk.plugin.Plugin;
+import q1k2.pxlx.train.common.Q1k2YearPlanConstant;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.EventObject;
+import java.util.List;
+
+/**
+ * @Description 年度计划表单插件
+ * @Created 刘维
+ */
+public class YearPlanBillPlugin extends AbstractBillPlugIn implements Plugin {
+    @Override
+    public void afterLoadData(EventObject e) {
+        super.afterLoadData(e);
+        setYearComboItems();
+    }
+
+
+    @Override
+    public void afterCreateNewData(EventObject e) {
+        super.afterCreateNewData(e);
+        setYearComboItems();
+    }
+
+    /**
+     * 设置年度下拉值
+     */
+    private void setYearComboItems() {
+        Calendar calendar = Calendar.getInstance();
+        int year = calendar.get(Calendar.YEAR);//当前年度
+        //获取年度下拉控件
+        ComboEdit ComboEdit = this.getControl(Q1k2YearPlanConstant.Q1K2_YEAR);
+        //设置下拉值
+        List<ComboItem> data = new ArrayList<>();
+        for (int i = year - 3; i <= year + 3; i++) {
+            data.add(new ComboItem(new LocaleString(String.valueOf(i)), String.valueOf(i)));
+        }
+        //绑定下拉值
+        ComboEdit.setComboItems(data);
+    }
+}

+ 29 - 0
cosmic/q1k2-pxlx/src/main/java/q1k2/pxlx/train/plugin/form/YearPlanListDetailPlugin.java

@@ -0,0 +1,29 @@
+package q1k2.pxlx.train.plugin.form;
+
+import com.alibaba.fastjson.JSONArray;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.list.BillList;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.sdk.plugin.Plugin;
+
+import java.util.*;
+
+/**
+ * 年度计划详情动态表单插件
+ */
+public class YearPlanListDetailPlugin extends AbstractFormPlugin implements Plugin {
+    @Override
+    public void afterCreateNewData(EventObject e) {
+        super.afterCreateNewData(e);
+        //获取父页面的传参
+        JSONArray ids = this.getView().getFormShowParameter().getCustomParam("ids");
+        QFilter filter = new QFilter("id", QCP.in, ids.toArray());
+        //获取单据列表控件
+        BillList billList = this.getView().getControl("q1k2_billlistap");
+        //设置过滤条件
+        billList.setFilter(filter);
+        //刷新
+        billList.refresh();
+    }
+}

+ 129 - 0
cosmic/q1k2-pxlx/src/main/java/q1k2/pxlx/train/plugin/form/YearPlanListPlugin.java

@@ -0,0 +1,129 @@
+package q1k2.pxlx.train.plugin.form;
+
+import com.kingdee.util.StringUtils;
+import kd.bos.bill.OperationStatus;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
+import kd.bos.entity.datamodel.events.PackageDataEvent;
+import kd.bos.filter.CommonFilterColumn;
+import kd.bos.form.FormShowParameter;
+import kd.bos.form.OpenStyle;
+import kd.bos.form.ShowType;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.FilterContainerInitArgs;
+import kd.bos.form.field.ComboItem;
+import kd.bos.form.operatecol.OperationColItem;
+import kd.bos.list.IListView;
+import kd.bos.list.column.ListOperationColumnDesc;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.sdk.plugin.Plugin;
+import q1k2.pxlx.train.common.Q1k2YearPlanConstant;
+
+import java.util.*;
+
+/**
+ * @Description 年度计划列表插件
+ * @Created 刘维
+ */
+public class YearPlanListPlugin extends AbstractListPlugin implements Plugin {
+    //查看明细
+    private String VIEWDETAIL = "viewdetail";
+
+    /**
+     * 过滤控件初始化
+     *
+     * @param args
+     */
+    @Override
+    public void filterContainerInit(FilterContainerInitArgs args) {
+        super.filterContainerInit(args);
+        /****** 常用过滤视图下的筛选条件处理 ******/
+        CommonFilterColumn yearFilter = new CommonFilterColumn(Q1k2YearPlanConstant.Q1K2_YEAR);
+        //多选
+        yearFilter.setMulti(true);
+        // 设置标题
+        yearFilter.setCaption(new LocaleString("年度"));
+        Calendar calendar = Calendar.getInstance();
+        int year = calendar.get(Calendar.YEAR);//当前年度
+        // 设置下拉值
+        List<ComboItem> data = new ArrayList<>();
+        for (int i = year - 3; i <= year + 3; i++) {
+            data.add(new ComboItem(new LocaleString(String.valueOf(i)), String.valueOf(i)));
+        }
+        yearFilter.setComboItems(data);
+        args.addFilterColumn(yearFilter);
+    }
+
+    /**
+     * 数据包装事件,用于修改发送给前端之前的数据,用于单元格填值
+     *
+     * @param evt 数据包装事件参数 PackageDataEvent
+     */
+    @Override
+    public void packageData(PackageDataEvent evt) {
+        super.packageData(evt);
+        this.setOperationColItemStyle(evt);
+    }
+
+    /**
+     * 操作列控制(某个操作项上显示名称)
+     *
+     * @param evt
+     */
+    private void setOperationColItemStyle(PackageDataEvent evt) {
+        Object obj = evt.getSource();
+        // 获取当前行数据
+        DynamicObject rowData = evt.getRowData();
+        // 判断是否是操作列
+        if (obj instanceof ListOperationColumnDesc) {
+            String billstatus = rowData.getString("billstatus");// 状态
+            List<OperationColItem> operationColItems = (List<OperationColItem>) evt.getFormatValue();
+            for (OperationColItem item : operationColItems) {
+                //操作键
+                String operationKey = item.getOperationKey();
+                if (("modify".equalsIgnoreCase(operationKey)
+                        || "submit".equalsIgnoreCase(operationKey))
+                        && "A".equals(billstatus)) {
+                    //暂存状态 显示 修改和提交
+                    item.setVisible(true);
+                    //item.setLocked(true);
+                } else if (("unsubmit".equalsIgnoreCase(operationKey)
+                        || "viewdetail".equalsIgnoreCase(operationKey)
+                        || "process".equalsIgnoreCase(operationKey)
+                        || "split_month_plan".equalsIgnoreCase(operationKey))
+                        && "B".equals(billstatus)) {
+                    //已提交状态 显示 撤销、查看明细、执行情况、拆分月度计划
+                    item.setVisible(true);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs args) {
+        super.afterDoOperation(args);
+        // 查看明细
+        if (StringUtils.equals(VIEWDETAIL, args.getOperateKey())) {
+            // 获取列表
+            IListView listView = (IListView) this.getView();
+            //获取当前选中所有行
+            ListSelectedRowCollection selectedRows = listView.getSelectedRows();
+            //单据主键ids
+            Object[] primaryKeyValues = selectedRows.getPrimaryKeyValues();
+            //构造ListShowParameter,打开子页面弹窗
+            //父页面传递参数
+            FormShowParameter showParameter = new FormShowParameter();
+            showParameter.setFormId("q1k2_year_plan_detail_lw");
+            //传递单个参数
+            showParameter.setCustomParam("ids", primaryKeyValues);
+            //设置单据主键
+            //showParameter.setPkId(selectedRow.getPrimaryKeyValue());
+            OpenStyle openStyle = showParameter.getOpenStyle();
+            openStyle.setShowType(ShowType.Modal);//设置打开方式
+            //打开状态:新增
+            showParameter.setStatus(OperationStatus.VIEW);
+            this.getView().showForm(showParameter);//通过showForm打开新页面
+        }
+    }
+}

+ 181 - 0
cosmic/q1k2-pxlx/src/main/java/q1k2/pxlx/train/plugin/operate/YearPlanOperationServicePlugIn.java

@@ -0,0 +1,181 @@
+package q1k2.pxlx.train.plugin.operate;
+
+import kd.bos.bill.BillShowParameter;
+import kd.bos.bill.OperationStatus;
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.entity.MulBasedataDynamicObjectCollection;
+import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
+import kd.bos.entity.plugin.args.AfterOperationArgs;
+import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
+import kd.bos.form.OpenStyle;
+import kd.bos.form.ShowType;
+import kd.bos.form.StyleCss;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.DeleteServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.sdk.plugin.Plugin;
+import q1k2.pxlx.train.common.Q1k2MonthPlanLwConstant;
+import q1k2.pxlx.train.common.Q1k2YearPlanConstant;
+
+import java.math.BigDecimal;
+
+/**
+ * @Description 年度计划操作插件
+ * @Created 刘维
+ */
+public class YearPlanOperationServicePlugIn extends AbstractOperationServicePlugIn implements Plugin {
+
+    @Override
+    public void afterExecuteOperationTransaction(AfterOperationArgs e) {
+        super.afterExecuteOperationTransaction(e);
+    }
+
+    /**
+     * 单据数据已经提交到数据库之后,事务未提交之前,触发此事件;
+     *
+     * @remark 可以在此事件,进行数据同步处理;
+     */
+    @Override
+    public void endOperationTransaction(EndOperationTransactionArgs e) {
+        super.endOperationTransaction(e);
+        String operationKey = e.getOperationKey();
+        if ("submit".equals(operationKey)) {//提交
+            //判断 是否拆分月度计划
+            DynamicObject[] dataEntities = e.getDataEntities();
+            for (int i = 0; i < dataEntities.length; i++) {
+                //年度计划
+                DynamicObject yearPlan = dataEntities[i];
+                long yearPlanId = (long) yearPlan.getPkValue();
+                //查询数据
+                yearPlan = BusinessDataServiceHelper.loadSingle(yearPlanId, Q1k2YearPlanConstant.FORMBILLID);
+                //是否拆分月度计划
+                boolean isSplitmonthplan = yearPlan.getBoolean(Q1k2YearPlanConstant.Q1K2_SPLITMONTHPLAN);
+                //是否已经生成月度计划
+                boolean isGenerateMonth = yearPlan.getBoolean(Q1k2YearPlanConstant.Q1K2_GENERATE_MONTH);
+                if (isSplitmonthplan && !isGenerateMonth) {
+                    //单据体
+                    DynamicObjectCollection yearPlanItems = yearPlan.getDynamicObjectCollection(Q1k2YearPlanConstant.Q1K2_YEAR_PLAN_ITEM);
+                    for (int j = 0; j < yearPlanItems.size(); j++) {
+                        DynamicObject yearPlanItem = yearPlanItems.get(j);
+                        for (int month = 1; month <= 12; month++) {
+                            boolean isSelectMonth = yearPlanItem.getBoolean(Q1k2YearPlanConstant.Q1K2_ITEM_MONTH + month);
+                            if (isSelectMonth) {
+                                //生成月度计划
+                                generateMonthPlan(j, month, yearPlan);
+                            }
+                        }
+                    }
+                    yearPlan.set(Q1k2YearPlanConstant.Q1K2_GENERATE_MONTH, true);
+                    SaveServiceHelper.save(new DynamicObject[]{yearPlan});
+                }
+            }
+        } else if ("unsubmit".equals(operationKey)) {
+            //撤销
+            DynamicObject[] dataEntities = e.getDataEntities();
+            for (int i = 0; i < dataEntities.length; i++) {
+                //年度计划
+                DynamicObject yearPlan = dataEntities[i];
+                //查询数据
+                yearPlan = BusinessDataServiceHelper.loadSingle(yearPlan.getPkValue(), Q1k2YearPlanConstant.FORMBILLID);
+                //是否拆分月度计划
+                boolean isSplitmonthplan = yearPlan.getBoolean(Q1k2YearPlanConstant.Q1K2_SPLITMONTHPLAN);
+                //是否已经生成月度计划
+                boolean isGenerateMonth = yearPlan.getBoolean(Q1k2YearPlanConstant.Q1K2_GENERATE_MONTH);
+                if (isSplitmonthplan && isGenerateMonth) {
+                    QFilter qFilter = new QFilter(Q1k2MonthPlanLwConstant.Q1K2_YEAR_PLANID, "=", yearPlan.getPkValue());
+                    DeleteServiceHelper.delete(Q1k2MonthPlanLwConstant.FORMBILLID, qFilter.toArray());
+                    //更新 是否已经生成月度计划 为 否
+                    yearPlan.set(Q1k2YearPlanConstant.Q1K2_GENERATE_MONTH, false);
+                    SaveServiceHelper.save(new DynamicObject[]{yearPlan});
+                }
+            }
+        }
+    }
+
+    /**
+     * 生成月度计划
+     */
+    private void generateMonthPlan(int index, int month, DynamicObject yearPlan) {
+        long yearPlanId = (long) yearPlan.getPkValue();
+        //年度
+        String year = yearPlan.getString(Q1k2YearPlanConstant.Q1K2_YEAR);
+        DynamicObject yearPlanItem = yearPlan.getDynamicObjectCollection(Q1k2YearPlanConstant.Q1K2_YEAR_PLAN_ITEM).get(index);
+        DynamicObject monthPlan = BusinessDataServiceHelper.newDynamicObject(Q1k2MonthPlanLwConstant.FORMBILLID);
+
+        DynamicObject org = yearPlan.getDynamicObject(Q1k2YearPlanConstant.ORG);
+        //实施部门
+        DynamicObject itemorg = yearPlanItem.getDynamicObject(Q1k2YearPlanConstant.Q1K2_ITEM_ORG);
+        monthPlan.set(Q1k2MonthPlanLwConstant.ORG, org);
+        //年度计划
+        //String level = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_LEVEL);
+        //部门预算
+        //String budget = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_BUDGET);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_MONTH, month);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_YEAR, year);
+        //项目名称
+        String projectname = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_PROJECTNAME);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_NAME, projectname);//名称
+        //培训级别
+        String level = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_LEVEL);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_LEVEL, level);
+        //培训类型
+        String type = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_TYPE);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_TYPE, type);
+        //培训对象
+        String obj = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_OBJ);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_OBJECT, obj);
+        //培训主要内容
+        String content = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_CONTENT);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_CONTENT, content);
+        //培训形式
+        String trainingType = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_TRAININGTYPE);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_TRAINING_TYPE, trainingType);
+        //教师来源
+        String source = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_SOURCE);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_SOURCE, source);
+        //预算
+        BigDecimal budget = yearPlanItem.getBigDecimal(Q1k2YearPlanConstant.Q1K2_ITEM_BUDGET);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_BUDGE_SELF, budget);
+        //计划人数
+        BigDecimal count = yearPlanItem.getBigDecimal(Q1k2YearPlanConstant.Q1K2_ITEM_COUNT);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_USER, count);
+        //课时
+        BigDecimal hours = yearPlanItem.getBigDecimal(Q1k2YearPlanConstant.Q1K2_ITEM_HOURS);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_HOUR, hours);
+        //讲师
+        MulBasedataDynamicObjectCollection lecturers = (MulBasedataDynamicObjectCollection) yearPlanItem.getDynamicObjectCollection(Q1k2YearPlanConstant.Q1K2_ITEM_LECTURER);
+        MulBasedataDynamicObjectCollection monthlecturers = (MulBasedataDynamicObjectCollection) monthPlan.getDynamicObjectCollection(Q1k2MonthPlanLwConstant.Q1K2_LECTURER);
+        for (int i = 0; i < lecturers.size(); i++) {
+            DynamicObject user = (DynamicObject) lecturers.get(i).get("fbasedataid");
+            DynamicObject monthlecturer = monthlecturers.addNew();
+            monthlecturer.set("fbasedataid",user);
+        }
+        // monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_LECTURER, lecturers);
+        //天数
+        BigDecimal days = yearPlanItem.getBigDecimal(Q1k2YearPlanConstant.Q1K2_ITEM_DAYS);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_DAYS, days);
+        //地点
+        String address = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_ADDRESS);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_ADDRESS, address);
+        //联系人
+        String contacts = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_CONTACTS);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_CONTACTS, contacts);
+        //联系电话
+        String phone = yearPlanItem.getString(Q1k2YearPlanConstant.Q1K2_ITEM_PHONE);
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_TELEPHONEFIELD, phone);
+        //实施状态
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_EXEC_STATUS, "NOT_START");
+        //计划来源
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_ORIGIN, "YEAR");
+        //年度计划id
+        monthPlan.set(Q1k2MonthPlanLwConstant.Q1K2_YEAR_PLANID, yearPlanId);
+        //状态更新为已提交
+        monthPlan.set(Q1k2MonthPlanLwConstant.BILLSTATUS, "B");
+        //保存
+        SaveServiceHelper.saveOperate(Q1k2MonthPlanLwConstant.FORMBILLID, new DynamicObject[]{monthPlan}, OperateOption.create());
+    }
+}

+ 210 - 0
cosmic/q1k2-pxlx/src/main/java/q1k2/pxlx/train/plugin/other/GenMetaConstantPlugin.java

@@ -0,0 +1,210 @@
+package q1k2.pxlx.train.plugin.other;
+
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
+import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.property.EntryProp;
+import kd.bos.entity.property.SubEntryProp;
+import kd.bos.form.control.CodeEdit;
+import kd.bos.form.control.Control;
+import kd.bos.form.plugin.AbstractFormPlugin;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author:liul
+ * @date:2022/11/7
+ * @time: 9:53
+ * Description:(常量类生成工具)
+ */
+public class GenMetaConstantPlugin extends AbstractFormPlugin {
+    /**
+     * 生成按钮标识
+     */
+    protected final String CREATEJAVA = "createjava";
+    /**
+     * 元数据对象字段标识
+     */
+    protected final String ENTITYOBJECT = "entityobject";
+    /**
+     * 换行标识符
+     */
+    protected final String LINEFEED = "\r\n";
+    /**
+     * 包路径字段标识
+     */
+    protected final String PACKAGENAME = "packagename";
+
+    private static final String CODE = "code";
+    protected Map<String, String> codeLineMap = new HashMap();
+    protected SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+
+    public void registerListener(EventObject evt) {
+        this.addClickListeners(new String[]{CREATEJAVA});
+    }
+
+    public void click(EventObject evt) {
+        Control control = (Control) evt.getSource();
+        String key = control.getKey();
+        if (CREATEJAVA.equals(key)) {
+            this.afterDoCreateJava();
+        }
+    }
+
+    protected void afterDoCreateJava() {
+        // 获取数据实体对象
+        DynamicObject dataEntity = this.getModel().getDataEntity();
+
+        // 检查是否选择了主实体对象
+        DynamicObject entityObject = dataEntity.getDynamicObject(ENTITYOBJECT);
+        if (entityObject == null) {
+            this.getView().showTipNotification("请选择【主实体对象】");
+            return;
+        }
+
+        // 获取实体编号和名称
+        String entityNumber = entityObject.getString("number");
+        String entityName = entityObject.getString("name");
+
+        // 创建字符串构建器
+        StringBuilder content = new StringBuilder();
+
+        // 获取主实体类型及其属性集合
+        MainEntityType mainEntityType = EntityMetadataCache.getDataEntityType(entityNumber);
+        DataEntityPropertyCollection mainEntityProperties = mainEntityType.getProperties();
+
+        // 创建前缀代码
+        this.createPrefixCode(content, entityNumber, entityName);
+
+        // 遍历主实体属性,处理所有类型的属性
+        for (IDataEntityProperty property : mainEntityProperties) {
+            this.createProperteyCode(content, property);
+
+            // 如果当前属性是 EntryProp 类型,进一步处理其子属性
+            if (property instanceof EntryProp) {
+                handleEntryProp((EntryProp) property, content);
+            }
+        }
+
+        // 创建后缀代码并输出生成的 Java 代码
+        this.createSuffixCode(content);
+        this.outPutJava(content);
+        this.getView().showSuccessNotification("生成成功。");
+    }
+
+    // 提取处理 EntryProp 子属性的逻辑
+    private void handleEntryProp(EntryProp entryProp, StringBuilder content) {
+        DynamicObjectType entryPropType = entryProp.getDynamicCollectionItemPropertyType();
+
+        // 遍历 EntryProp 的属性
+        for (IDataEntityProperty entryPropProperty : entryPropType.getProperties()) {
+            this.createProperteyCode(content, entryPropProperty);
+
+            // 如果当前属性是 SubEntryProp 类型,进一步处理其子属性
+            if (entryPropProperty instanceof SubEntryProp) {
+                handleSubEntryProp((SubEntryProp) entryPropProperty, content);
+            }
+        }
+    }
+
+    // 提取处理 SubEntryProp 子属性的逻辑
+    private void handleSubEntryProp(SubEntryProp subEntryProp, StringBuilder content) {
+        DynamicObjectType subEntryPropType = subEntryProp.getDynamicCollectionItemPropertyType();
+
+        // 遍历 SubEntryProp 的属性,并生成对应的代码
+        for (IDataEntityProperty subEntryPropProperty : subEntryPropType.getProperties()) {
+            this.createProperteyCode(content, subEntryPropProperty);
+        }
+    }
+
+
+    protected String rename(String javaName) {
+        String splitStr = "_";
+        String result = "";
+        if (javaName.contains(splitStr)) {
+            String[] splitArray = javaName.split(splitStr);
+
+            for (int i = 0; i < splitArray.length; ++i) {
+                result = result + this.toUpperFirstChar(splitArray[i]);
+            }
+        } else {
+            result = this.toUpperFirstChar(javaName);
+        }
+
+        return result;
+    }
+
+    protected String toUpperFirstChar(String string) {
+        char[] chars = string.toCharArray();
+        if (chars[0] >= 'a' && chars[0] <= 'z') {
+            chars[0] = (char) (chars[0] - 32);
+            return String.valueOf(chars);
+        } else {
+            return string;
+        }
+    }
+
+    protected void createSuffixCode(StringBuilder content) {
+        content.append("}" + LINEFEED);
+    }
+
+    protected void createPrefixCode(StringBuilder content, String entityNumber, String entityName) {
+        // 生成常量类名
+        String javaName = entityNumber + "Constant";
+        javaName = this.rename(javaName);
+
+        String packageName = "kd.constant";
+        Object packageNameValue = this.getModel().getValue(PACKAGENAME);
+        if (packageNameValue != null && !packageNameValue.toString().isEmpty()) {
+            packageName = packageNameValue.toString();
+        }
+
+        String rdNumber = RequestContext.get().getUserName();
+
+        String dateStr = this.formatter.format(new Date());
+        String prefixCode = "package " + packageName + ";" + LINEFEED + LINEFEED + "/**" + LINEFEED + " * "
+                + entityName + "常量类" + LINEFEED + " *" + LINEFEED + " * @author " + rdNumber + LINEFEED + " * @version 1.0"
+                + LINEFEED + " * @date " + dateStr + LINEFEED + " */" + LINEFEED + "public class " + javaName + " {" + LINEFEED + LINEFEED
+                + "    public static final String FORMBILLID = \"" + entityNumber + "\";" + LINEFEED;
+        content.append(prefixCode);
+    }
+
+    protected void createProperteyCode(StringBuilder content, IDataEntityProperty iDataEntityProperty) {
+        String propertyName = iDataEntityProperty.getName();
+        if (this.codeLineMap.get(propertyName) == null) {
+            LocaleString displayNameObj = iDataEntityProperty.getDisplayName();
+
+            if (displayNameObj == null && !"id".equals(propertyName)) {
+                return;
+            }
+
+            String disPlayName = "缺省id字段";
+
+            if (displayNameObj != null) {
+                disPlayName = displayNameObj.getLocaleValue_zh_CN();
+            }
+
+
+            this.codeLineMap.put(propertyName, disPlayName);
+            String uppercasePropertyName = propertyName.toUpperCase();
+            String annotation = "    /**" + disPlayName + "**/" + LINEFEED;
+            String code = "    public static final String " + uppercasePropertyName + " = \"" + propertyName + "\";" + LINEFEED;
+            content.append(annotation + code);
+        }
+    }
+
+    protected void outPutJava(StringBuilder content) {
+        CodeEdit codeshow = this.getView().getControl(CODE);
+        codeshow.setText(content.toString());
+    }
+}

+ 4 - 0
cosmic/settings.gradle

@@ -13,6 +13,7 @@ include(
 		':q1k2-base-helper',
 		
 		':q1k2-study',
+		':q1k2-pxlx',
 )
 
 // -------------- 引入苍穹调试工程模块 --------------
@@ -24,3 +25,6 @@ project(':q1k2-base-helper').projectDir = new File('base/q1k2-base-helper')
 
 // -------------- 引入study云模块 --------------
 project(':q1k2-study').projectDir = new File('q1k2-study')
+
+// -------------- 引入培训云模块 --------------
+project(':q1k2-pxlx').projectDir = new File('q1k2-pxlx')