diff --git a/ProjectManageGttPlugin.java b/ProjectManageGttPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..64a0c5dd2b4a2211b902914e4e4f2d88759a4271 --- /dev/null +++ b/ProjectManageGttPlugin.java @@ -0,0 +1,203 @@ +package kdec; + + + import com.alibaba.fastjson.JSONObject; + import kd.bos.bill.AbstractBillPlugIn; + import kd.bos.ext.form.control.CustomControl; + import kd.bos.form.control.Control; + import kd.bos.form.events.CustomEventArgs; + import kd.bos.util.CollectionUtils; + import kd.sdk.plugin.Plugin; + + import java.math.BigDecimal; + import java.util.ArrayList; + import java.util.EventObject; + import java.util.HashMap; + import java.util.List; + +/** + * 单据界面 + */ +public class ProjectManageGttPlugin extends AbstractBillPlugIn implements Plugin { + @Override + public void afterCreateNewData(EventObject e) { + String planjsonstr="{\"tasks\": [\n" + + " {\"id\": -1, \"name\": \"Gantt editor\", \"progress\": 1, \"progressByWorklog\": false, \"relevance\": 0, \"type\": \"plan\", \"typeId\": \"plan\", \"description\": \"\", \"code\": \"\", \"level\": 0, \"status\": \"STATUS_ACTIVE\", \"depends\": \"\", \"canWrite\": true, \"start\": 1396994400000, \"duration\": 20, \"end\": 0, \"1693474514008\": false, \"endIsMilestone\": false, \"collapsed\": false, \"assigs\": [], \"hasChild\": true},\n" + + " {\"id\": -2, \"name\": \"coding\", \"progress\": 0, \"progressByWorklog\": false, \"relevance\": 0, \"type\": \"\", \"typeId\": \"\", \"description\": \"\", \"code\": \"\", \"level\": 1, \"status\": \"STATUS_ACTIVE\", \"depends\": \"\", \"canWrite\": true, \"start\": 1693474514008, \"duration\": 1000, \"end\": 1713474514008, \"startIsMilestone\": false, \"endIsMilestone\": false, \"collapsed\": false, \"assigs\": [], \"hasChild\": true},\n" + + " {\"id\": -3, \"name\": \"gantt part\", \"progress\": 0, \"progressByWorklog\": false, \"relevance\": 0, \"type\": \"\", \"typeId\": \"\", \"description\": \"\", \"code\": \"\", \"level\": 2, \"status\": \"STATUS_ACTIVE\", \"depends\": \"\", \"canWrite\": true, \"start\": 1693474514008, \"duration\": 500, \"end\": 1693474514008, \"startIsMilestone\": false, \"endIsMilestone\": false, \"collapsed\": false, \"assigs\": [], \"hasChild\": false},\n" + + " {\"id\": -4, \"name\": \"editor part\", \"progress\": 0, \"progressByWorklog\": false, \"relevance\": 0, \"type\": \"\", \"typeId\": \"\", \"description\": \"\", \"code\": \"\", \"level\": 2, \"status\": \"STATUS_SUSPENDED\", \"depends\": \"3\", \"canWrite\": true, \"start\": 1693474514008, \"duration\": 500, \"end\": 1693474514008, \"startIsMilestone\": false, \"endIsMilestone\": false, \"collapsed\": false, \"assigs\": [], \"hasChild\": false},\n" + + " {\"id\": -5, \"name\": \"testing\", \"progress\": 0, \"progressByWorklog\": false, \"relevance\": 0, \"type\": \"\", \"typeId\": \"\", \"description\": \"\", \"code\": \"\", \"level\": 1, \"status\": \"STATUS_SUSPENDED\", \"depends\": \"2:5\", \"canWrite\": true, \"start\": 1693474514008, \"duration\": 5, \"end\": 1693474514008, \"startIsMilestone\": false, \"endIsMilestone\": false, \"collapsed\": false, \"assigs\": [], \"hasChild\": true},\n" + + " {\"id\": -6, \"name\": \"test on safari\", \"progress\": 0, \"progressByWorklog\": false, \"relevance\": 0, \"type\": \"\", \"typeId\": \"\", \"description\": \"\", \"code\": \"\", \"level\": 2, \"status\": \"STATUS_SUSPENDED\", \"depends\": \"\", \"canWrite\": true, \"start\": 1398981600000, \"duration\": 2, \"end\": 1693474514008, \"startIsMilestone\": false, \"endIsMilestone\": false, \"collapsed\": false, \"assigs\": [], \"hasChild\": false},\n" + + " {\"id\": -7, \"name\": \"test on ie\", \"progress\": 0, \"progressByWorklog\": false, \"relevance\": 0, \"type\": \"\", \"typeId\": \"\", \"description\": \"\", \"code\": \"\", \"level\": 2, \"status\": \"STATUS_SUSPENDED\", \"depends\": \"6\", \"canWrite\": true, \"start\": 1399327200000, \"duration\": 3, \"end\": 1693474514008, \"startIsMilestone\": false, \"endIsMilestone\": false, \"collapsed\": false, \"assigs\": [], \"hasChild\": false},\n" + + " {\"id\": -8, \"name\": \"test on chrome\", \"progress\": 0, \"progressByWorklog\": false, \"relevance\": 0, \"type\": \"\", \"typeId\": \"\", \"description\": \"\", \"code\": \"\", \"level\": 2, \"status\": \"STATUS_SUSPENDED\", \"depends\": \"6\", \"canWrite\": true, \"start\": 1399327200000, \"duration\": 2, \"end\": 1693474514008, \"startIsMilestone\": false, \"endIsMilestone\": false, \"collapsed\": false, \"assigs\": [], \"hasChild\": false}\n" + + " ], \"selectedRow\": 2, \"deletedTaskIds\": [],\n" + + " \"resources\": [\n" + + " {\"id\": \"tmp_1\", \"name\": \"Resource 1\"},\n" + + " {\"id\": \"tmp_2\", \"name\": \"Resource 2\"},\n" + + " {\"id\": \"tmp_3\", \"name\": \"Resource 3\"},\n" + + " {\"id\": \"tmp_4\", \"name\": \"Resource 4\"}\n" + + " ],\n" + + " \"roles\": [\n" + + " {\"id\": \"tmp_1\", \"name\": \"Project Manager\"},\n" + + " {\"id\": \"tmp_2\", \"name\": \"Worker\"},\n" + + " {\"id\": \"tmp_3\", \"name\": \"Stakeholder\"},\n" + + " {\"id\": \"tmp_4\", \"name\": \"Customer\"}\n" + + " ], \"canWrite\": true, \"canDelete\":true, \"canWriteOnParent\": true, canAdd:true}"; + JSONObject planjson = (JSONObject) JSONObject.parse(planjsonstr); + JSONObject resources = new JSONObject(); + resources.put("id","123"); + resources.put("name","资源测试"); + planjson.put("resources",resources); + long l = System.currentTimeMillis(); + ArrayList var29 = new ArrayList(); + JSONObject var31 = new JSONObject(); + var31.put("id", 123321); + var31.put("name", "软件开发"); + var29.add(var31); + planjson.put("roles", var29); + HashMap var33 = new HashMap(); + var33.put("result", true); + var33.put("data", planjson); + var33.put("eventArgs", "selectData"); + CustomControl control = this.getView().getControl("kdec_customcontrolap"); + control.setData(var33); + super.afterCreateNewData(e); + } + + @Override + public void afterBindData(EventObject e) { + + super.afterBindData(e); + } + + @Override + public void customEvent(CustomEventArgs e) { + String var2 = e.getEventArgs(); + String var3 = e.getEventName(); + Long var4 = 0L; + Long var5=0L; + byte var7 = -1; + switch(var3.hashCode()) { + case -1656440122: + if (var3.equals("selectData")) {//保存 + var7 = 1; + } + break; + case -850981221: + if (var3.equals("addPlanRequire")) {//新增需求 + var7 = 6; + } + break; + case -335429343: + if (var3.equals("bindWorkItem")) {//关联工作项 + var7 = 2; + } + break; + case 96417: + if (var3.equals("add")) { + var7 = 0; + } + break; + case 894313487: + if (var3.equals("addPlanTask")) {//新增任务 + var7 = 7; + } + break; + case 1339276547: + if (var3.equals("showConfirm")) { + var7 = 4; + } + break; + case 2067279966: + if (var3.equals("showTip")) { + var7 = 3; + } + break; + case 2081159717: + if (var3.equals("taskIsChanged")) { + var7 = 5; + } + } + switch(var7) { + case 0: + this.save(var2, var4);//保存 + break; + case 1: + this.selectData(var4, var5); + break; + case 2: + this.bindWorkItem(var4); + break; + case 3: + this.getView().showTipNotification(var2, 1000); + break; + case 4: + this.showConfirm(); + break; + case 5: + this.taskIsChanged(var2); + break; + case 6: + this.addPlanRequire(var4); + break; + case 7: + this.addPlanTask(var4); + break; + default: + this.getView().showTipNotification("不存在的操作,请联系系统管理员", 1000); + } + super.customEvent(e); + } + + private void addPlanTask(Long var4) { + + } + + private void addPlanRequire(Long var4) { + } + + private void taskIsChanged(String var2) { + } + + private void showConfirm() { + } +//关联工作项,选中行 + private void bindWorkItem(Long projectId) { + ArrayList var4=new ArrayList(); + JSONObject jsonObject=new JSONObject(); + jsonObject.put("id", "123456"); + jsonObject.put("name", "工作名称"); + //任务进度 + jsonObject.put("progress", BigDecimal.valueOf(100L)); + jsonObject.put("code", "123456"); + jsonObject.put("start", System.currentTimeMillis()); + jsonObject.put("end", System.currentTimeMillis()); + jsonObject.put("dmp_type", "需求"); + jsonObject.put("typeId", "dmp_require_manage_org"); + + + jsonObject.put("status", "STATUS_DONE"); + List var15 = new ArrayList(); + JSONObject var17 = new JSONObject(); + var17.put("resourceId", 123456L); + var17.put("roleId", 123321); + var17.put("effort", 0); + var17.put("id", String.format("tmp_%s", System.currentTimeMillis())); + ((List)var15).add(var17); + + jsonObject.put("assigs", var15); + var4.add(jsonObject); + HashMap var19 = new HashMap(); + var19.put("result", true); + var19.put("data", var4); + var19.put("eventArgs", "bindWorkItem"); + CustomControl var20 = (CustomControl)this.getView().getControl("kdec_customcontrolap"); + var20.setData(var19); + } + + private void selectData(Long var4, Long var5) { + } + + private void save(String var2, Long var4) { + } +} \ No newline at end of file diff --git a/README.md b/README.md index db0b39cca7ecef4a34a3711af64709374d3ad4f0..ea7a71681f023e4fa5397b2611259229acbcc0b2 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,112 @@ # jQueryGantt #### 介绍 -金蝶云·苍穹自定义控件之甘特图控件 +金蝶云·苍穹平台自定义控件集成甘特图jquerygantt的开源项目 +JQuery.Gantt是一个开源的基于JQuery库的用于实现甘特图效果的可扩展功能的JS组件库。 #### 软件架构 -软件架构说明 +金蝶云·苍穹平台自定义控件集成甘特图jquerygantt的开源项目 #### 安装教程 -1. xxxx -2. xxxx -3. xxxx +1. 应用中导入元数据gttexample_meta.zip +2. 自定义控件上传的控件方案资源为jQueryGantt +3. 苍穹后台插件文件夹复制到本地 #### 使用说明 +1、打开页面时,初始化甘特图数据 +甘特图控件初始化事件var ge = new GanttMaster(); +ge.init($(“#workSpace”)); +甘特图前端存储项目ge.saveProject() +甘特图前端加载项目ge.loadProject( [yourJsonProject] ) -1. xxxx -2. xxxx -3. xxxx +(1)后台插件发送数据kdec.ProjectManageGttPlugin#afterCreateNewData +(2)前端js接收并初始化数据var updateHtml = function(model,data) +model.dom.ge.loadProject(project); +project的数据结构如下 +{ + "canWriteOnParent": true, + "roles": [ + { + "name": "软件开发", + "id": 123321 + } + ], + "canAdd": true, + "resources": { + "name": "资源测试", + "id": "123" + }, + "canWrite": true, + "canDelete": true, + "selectedRow": 2, + "tasks": [ + { + "code": "", + "assigs": [ + + ], + "level": 0, + "depends": "", + "collapsed": false, + "start": 1396994400000, + "description": "", + "canWrite": true, + "type": "plan", + "progressByWorklog": false, + "relevance": 0, + "duration": 20, + "1693474514008": false, + "endIsMilestone": false, + "hasChild": true, + "name": "Gantt editor", + "progress": 1, + "typeId": "plan", + "end": 0, + "id": -1, + "status": "STATUS_ACTIVE" + }, + { + "code": "", + "assigs": [ + + ], + "level": 1, + "depends": "", + "collapsed": false, + "start": 1693474514008, + "description": "", + "canWrite": true, + "type": "", + "progressByWorklog": false, + "relevance": 0, + "duration": 1000, + "endIsMilestone": false, + "hasChild": true, + "name": "coding", + "progress": 0, + "typeId": "", + "end": 1713474514008, + "id": -2, + "startIsMilestone": false, + "status": "STATUS_ACTIVE" + } + ], + "deletedTaskIds": [ + + ] + } -#### 参与贡献 +2、前后端交互 +(1)前端点击保存、新增需求、新增任务、关联工作项时,分别触发jQueryGantt\js\init.js里面的 +saveGanttOnServer、addPlanRequire、addPlanTask、bindWorkItem等方法,这些js里面会给后端发送invoke指令 +(2)苍穹后端插件接收前端请求并处理相关业务kdec.ProjectManageGttPlugin#customEvent -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +#### 版本支持 +COSMICV5.0.011 -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +#### 参考资料 +开源组件库jQuery Gantt编辑器由Roberto Bicchierai和Silvia Chelazzi编写,源开发文档: +https://roberto.twproject.com/2012/08/24/jquery-gantt-editor/ diff --git a/gttcosmic.zip b/gttcosmic.zip new file mode 100644 index 0000000000000000000000000000000000000000..2b606f0edb9ca7e8b5f385e80ee77cd501ad005b Binary files /dev/null and b/gttcosmic.zip differ diff --git a/gttexample_meta.zip b/gttexample_meta.zip new file mode 100644 index 0000000000000000000000000000000000000000..721dbdb054c23dcd56e45220929c3be6feb5dc12 Binary files /dev/null and b/gttexample_meta.zip differ diff --git a/jQueryGantt/css/index.css b/jQueryGantt/css/index.css new file mode 100644 index 0000000000000000000000000000000000000000..af987d35630407a86e99db1a1e35ad8bb8889e31 --- /dev/null +++ b/jQueryGantt/css/index.css @@ -0,0 +1,22 @@ + + .resEdit { + padding: 15px; + } + + .resLine { + width: 95%; + padding: 3px; + margin: 5px; + border: 1px solid #d0d0d0; + } + + body { + overflow: hidden; + } + + .ganttButtonBar h1{ + color: #000000; + font-weight: bold; + font-size: 28px; + margin-left: 10px; + } \ No newline at end of file diff --git a/jQueryGantt/css/tinyselect.css b/jQueryGantt/css/tinyselect.css new file mode 100644 index 0000000000000000000000000000000000000000..9c3507437fb5c5d6066bbff2a93eed9abc047673 --- /dev/null +++ b/jQueryGantt/css/tinyselect.css @@ -0,0 +1,144 @@ +.tinyselect { + height: 25px; + /* height: 50px; */ + display: inline-block; + min-width: 130px; + position: relative; +} + +.tinyselect .selectbox { + position: absolute; + height: 85%; + width: 100%; + + text-align: left; + + border-top:none; + border-left:none; + border-right:none; + /* line-height: 22px; */ + padding-left: 10px; + box-sizing: border-box; + + cursor: pointer; + border-radius: 3px; + + white-space: nowrap; + overflow-x: hidden; + background-color:white; + margin-top:10px; +} + +.tinyselect .selectbox::after { + content: ' '; + position: absolute; + right: 0px; + /* border-left: 1px solid #ccc; */ + height: 100%; + font-size: 10pt; + line-height: 34px; + padding: 0px 8px; + width: 10px; + /* background-color: #eee; */ + background-repeat: no-repeat; + background-position: center; + + /* background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAJCAYAAADkZNYtAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOWwzfk4AAABXSURBVChTjY0BCYBAFMWugw3MYRAbmMROhjGDFXQTThSfcoNx/P8HV2DEvUG7kxVTUPV+MWCKqt4fLJhC9y96TLH7yIz30PmTDjc09HX+ZUJj3ybC96UczHIuzhJ1BlkAAAAASUVORK5CYII='); */ + +} + +.tinyselect .selectbox.open::after { + content: ' '; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAJCAYAAADkZNYtAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOWwzfk4AAABYSURBVChTY8ABWqE0QZAOxP+hNF4gDMTvgBikGESD+DgByHqQQhjG6RwlIEZWCMMgcQywA4ixKQaJowAbIMamEIZB8nBwB4ixKYJhkDwYRAAxNgVomCECALjaLs5bhaybAAAAAElFTkSuQmCC'); + +} + + + + +.tinyselect .dropdown { + position: absolute; + width: 100%; + top: 33px; + border: 1px solid #ccc; + + background-color: white; + z-index: 100; + + box-sizing: border-box; + max-height: 200px; + + overflow-x: hidden; + overflow-y: scroll; +} + +.tinyselect .dropdown .searchcontainer { + padding: 5px; +} + +.tinyselect .dropdown .searchbox { + /* width: 100%; */ + width: 87%; + border: 1px solid #ccc; + font-size: 10pt; + line-height: 1.5em; + padding: 0 5px; +} + +.tinyselect .dropdown .searchicon { + position: absolute; + top: 12px; + /* right: 8px; */ + right: 3px; + width: 14px; + height: 14px; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOWwzfk4AAADESURBVDhPnZLBDcIwDEW7DIt0CmZgBW5tc2AAFugWDNB7FuDMAB0g+FV25AQLJA5Prb797djJUEoJmabptCzLVVjneb4Lo483yYYadqF0bBQkJzJdSJIOT/7RtPuKLmS0yPgCq+zhyGq+NYGU0tkCXvdQVNh68TgmX697JJahEf/uaAEWE80oMbb9OSPJus1jq5zA6SxmR0erJhFGM30h20kOk85WL5wCWogu3N9q3Y3QFM3Xw8D+adUn9QtvfEQJMWV4A2WMBVG/g0M8AAAAAElFTkSuQmCC'); +} + + + + + +.tinyselect .itemcontainer { + list-style: none; + margin: 0; + padding: 0; +} + +.tinyselect .itemcontainer > li { + padding: 5px 2px; +} + +.tinyselect .itemcontainer > li.item { + padding: 5px 10px; + height:28px; +} + +.tinyselect .itemcontainer > li.selected { + background-color: #eee; + height:28px; +} + +.tinyselect .itemcontainer > li.item:hover { + background-color: #1b6eab; + color: white; +} + +.tinyselect .itemcontainer li.loadindicator { + padding: 15px; + font-weight: bold; +} + +.tinyselect .itemcontainer li.loaderrorindicator { + padding: 15px; + font-weight: bold; + color: red; +} +.select_3 +{ + width:50%; +} +.select_4 +{ + width:100px; +} \ No newline at end of file diff --git a/jQueryGantt/html/gantt.html b/jQueryGantt/html/gantt.html new file mode 100644 index 0000000000000000000000000000000000000000..ffe702a24a2324e42cbda60725471f9a76d5dd6f --- /dev/null +++ b/jQueryGantt/html/gantt.html @@ -0,0 +1,274 @@ +