摘要:本文介绍了一个基于AngularJS的排产资源占用甘特图系统,包含前端界面展示和后端控制逻辑。系统通过HTML模板实现甘特图展示区域、查询条件表单和数据绑定,使用JavaScript控制器处理数据查询、甘特图初始化和交互逻辑。主要功能包括:1)查询工厂、作业岛类型的排产资源占用情况;2)甘特图展示资源占用时间分布;3)数据字典加载和表单验证。系统采用只读模式展示甘特图,禁用编辑功能,确保数据安全性和稳定性。
1.SchedulingResourceOccupationGanTTScreen-list.html
<link href="Scheduling.SchedulingApp/styles/dhtmlxgantt.css" rel="stylesheet">
<style>
.MainCommandActionButton {
margin-top: 20px !important;
}
/* 启用复制功能 */
.ui-grid-disable-selection {
-webkit-touch-callout: default;
-webkit-user-select: text;
-khtml-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
cursor: auto;
}
</style>
<div id="itemlist" class="content-area content-area-relative" style="height: calc(93% - 30px) !important">
<!--查询条件与功能按钮-->
<div class="col-md-40" style="margin-left: 15px; margin-top: 10px;">
<div class="side-panel-property-area-body">
<sit-property-grid sit-id="add_form" sit-layout="Horizontal" sit-type="Fluid" sit-mode="edit"
sit-columns="5">
<sit-property sit-widget="sit-select" sit-value="vm.Status.value" sit-validation="{ required: true }"
sit-options="vm.Status.options" sit-to-display="'ItemName'" sit-to-keep="'ItemValue'"
style="max-width:200px;">查询类型:</sit-property>
<sit-property sit-widget="sit-select" sit-value="vm.Factory.value" sit-validation="{ required: true }"
sit-options="vm.Factory.options" sit-to-display="'ItemName'" sit-to-keep="'ItemValue'"
style="max-width:200px;">工厂:</sit-property>
<sit-property sit-widget="sit-select" sit-value="vm.OperatingIslandType.value"
sit-validation="{ required: false }" sit-options="vm.OperatingIslandType.options"
sit-to-display="'ItemName'" sit-to-keep="'ItemValue'" style="max-width:200px;">作业岛类型:</sit-property>
<sit-property sit-widget="sit-datepicker" sit-value="vm.StartDate" sit-validation="{required: true}"
sit-options="vm.dateOptions" sit-format="'yyyy-MM-dd'" sit-read-only="false" style="max-width:150px;">开始日期:</sit-property>
<sit-property sit-widget="sit-datepicker" sit-value="vm.EndDate" sit-validation="{required: true}"
sit-options="vm.dateOptions" sit-format="'yyyy-MM-dd'" sit-read-only="false" style="max-width:150px;">结束日期:</sit-property>
<sit-command-bar sit-type="action">
<sit-command sit-icon="fa-search" sit-type="main" sit-name="com.siemens.customcommand.search"
sit-tooltip="" ng-show="false" sit-label="">
</sit-command>
<sit-command sit-icon="fa-search" sit-type="main" sit-name="com.siemens.customcommand.search" ng-show="vm.validInputs"
sit-tooltip="查询" ng-click="vm.searchButtonHandler" sit-label="查询">
</sit-command>
</sit-command-bar>
</sit-property-grid>
</div>
</div>
<div style="width:100%;margin-top: 5px;">
<!-- grid列表 -->
<div id="listClass" style="width:100%; height: 100%; padding:0px 16px 0 16px; margin-top: 3px;">
<div id="divGantt" class="gantt-container" style="height:90vh;"></div>
</div>
</div>
</div>
2.SchedulingResourceOccupationGanTTScreen-list-ctrl.js
(function () {
'use strict';
angular.module('Scheduling.SchedulingApp.SchedulingResourceOccupationGanTT').config(ListScreenRouteConfig);
ListScreenController.$inject = ['Scheduling.SchedulingApp.SchedulingResourceOccupationGanTT.SchedulingResourceOccupationGanTTScreen.service',
'$state', '$stateParams',
'$rootScope', '$scope', 'common.services.authentication', 'common.base', 'common.services.logger.service', 'common.widgets.notificationTile.globalService', 'commonService',
'common.widgets.busyIndicator.service', 'i18nService'];
function ListScreenController(dataService, $state, $stateParams, $rootScope, $scope, auth, base, loggerService, notificationService, commonService, busyIndicatorService, i18nService) {
//国际化
i18nService.setCurrentLang('zh-cn');
var self = this;
var logger, rootstate, messageservice, backendService, signalManager;
activate();
// Initialization function
function activate() {
logger = loggerService.getModuleLogger('Scheduling.SchedulingApp.SchedulingResourceOccupationGanTT.SchedulingResourceOccupationGanTTScreen');
init();
registerEvents();
}
function init() {
logger.logDebug('Initializing controller.......');
rootstate = 'home.Scheduling_SchedulingApp_SchedulingResourceOccupationGanTT_SchedulingResourceOccupationGanTTScreen';
messageservice = base.widgets.messageOverlay.service;
backendService = base.services.runtime.backendService;
signalManager = base.services.signal.service;
//Initialize Model Data
self.selectedItem = null;
self.isButtonVisible = false;
self.validInputs = false;
self.searchButtonHandler = searchButtonHandler;//查询
//查询类型
self.Status = {
value: { 'ItemValue': '作业岛', 'ItemName': '作业岛' },
options: [
{ 'ItemValue': '作业岛', 'ItemName': '作业岛' },
{ 'ItemValue': '班组', 'ItemName': '班组' }
]
};
//工厂
self.Factory = {
value: { 'ItemValue': '', 'ItemName': '--请选择--' },
options: [
{ 'ItemValue': '', 'ItemName': '--请选择--' }
]
};
//作业岛类型
self.OperatingIslandType = {
value: { 'ItemValue': '', 'ItemName': '--请选择--' },
options: [
{ 'ItemValue': '', 'ItemName': '--请选择--' }
]
};
//作业岛编号
self.OperatingIsland = {
value: { 'ItemValue': '', 'ItemName': '--请选择--' },
options: [
{ 'ItemValue': '', 'ItemName': '--请选择--' }
]
};
self.searchParams = {};
//获取数据字典
GetDectionary();
GanttInit();
}
//查询
function searchButtonHandler(clickedCommand) {
initGanttData();
}
//甘特图初始化
function GanttInit() {
//
//汉化
gantt.i18n.setLocale("cn");
// 完全禁用任务拖动
// 1. 初始化配置
gantt.config.date_format = "%Y/%m/%d";
gantt.config.select_task = false;
// 禁用所有交互事件(包括双击编辑)
gantt.config.interaction = {
click: false,//禁用单击
dblclick: false,//禁用双击
drag: false,// 禁用任务拖动
resize: false 禁用调整大小
};
// 仅允许查看但禁止修改
gantt.config.readonly = true;
// 禁用任务点击选中
gantt.config.subscales = [
{ unit: "day", step: 1, date: "%D" }
];
// 初始化时禁用任务创建按钮
gantt.config.show_add_button = false;
gantt.config.toolbar = []; // 清空工具栏
gantt.config.show_quick_info = false; // 隐藏快速操作栏
gantt.config.show_grid_header = false; // 隐藏表头操作栏
gantt.config.columns = [
{ name: "text", label: "任务名称", width: 200, tree: true },
{ name: "start_date", label: "开始时间", width: 110, align: "center" },
{ name: "end_date", label: "结束时间", width: 110, align: "center" },
{ name: "duration", label: "持续时间", width: 80, align: "center" }
];
// 2. 加载数据
gantt.init("divGantt");
gantt.config.work_time = true; // 必须启用工作时间模式
gantt.config.split_tasks = true; // 启用任务分割
gantt.config.show_unscheduled = true; // 可选:允许显示未安排的任务段
// 或通过事件拦截(更灵活)
gantt.attachEvent("onBeforeTaskDrag", function () {
return false; // 取消拖动操作
});
}
//甘特图数据绑定
function GantData(serverData) {
console.log("serverData-------------", JSON.stringify(serverData));
if (serverData.length==0) {
console.log("serverData-----1111111111111111111--------");
//清空数据
gantt.clearAll();
}
else {
console.log("serverData-----22222222222222222--------");
gantt.parse({
data: serverData,
// links: [
// { id: 1, source: 2, target: 3, type: "0" } // 0表示"完成-开始"依赖关系
// ]
});
}
// 刷新视图使配置生效
gantt.render();
}
//甘特图数据查询
function initGanttData() {
self.searchParams.FactoryCode = self.Factory.value.ItemName;
self.searchParams.OperatingIslandTypeCode = self.OperatingIslandType.value.ItemValue;
self.searchParams.TypeCode = self.Status.value.ItemValue;
self.searchParams.StartDate = moment(self.StartDate).format('YYYY-MM-DD HH:mm:ss');
self.searchParams.EndDate = moment(self.EndDate).format('YYYY-MM-DD HH:mm:ss');
dataService.getSchedulingGanttList(self.searchParams).then(function (data) {
if ((data) && (data.succeeded)) {
//数据绑定
GantData(data.data.ReturnValue);
} else {
}
}, backendService.backendError);
// let dd=[
// // { id: 1, text: "PM01", start_date: "2025-05-1", end_date: "2025-05-15", progress: 1 },
// {
// id: 1,
// text: "PM01",
// start_date: "2025-05-01", end_date: "2025-05-10"
// },
// { id: 2, text: "APS000001", start_date: "2025-05-01", end_date: "2025-05-4", parent: 1 },
// { id: 3, text: "APS000002", start_date: "2025-05-6 23:59:59", end_date: "2025-05-10", parent: 1 },
// { id: 4, text: "PM02", start_date: "2025-05-15", duration: 10, parent: 0 },
// { id: 5, text: "PM03", start_date: "2025-05-16", end_date: "2025-05-20", parent: 0 }
// ];
// GantData(dd);
}
//获取数据字典数据
function GetDectionary() {
var dicParamObj = {};
dicParamObj.ItemCodeList = ['FactoryDic', 'OperatingIslandTypeDic', 'OperatingIslandDic', 'StatusDic'];//可以一次查询多个
dataService.getDectionary(dicParamObj).then(function (data) {
if ((data) && (data.succeeded)) {
var resData = data.data.DictionaryDataList;
//工厂
var factoryDicArry = resData.filter(t => t.CategoryCode == 'FactoryDic')
.map(function (item) {
return { 'ItemValue': item.ItemValue, 'ItemName': item.ItemName }
}).sort((a, b) => a.ItemValue.localeCompare(b.ItemValue));
self.Factory.options.push(...factoryDicArry);
//作业岛类型
var operatingIslandTypeDicArry = resData.filter(t => t.CategoryCode == 'OperatingIslandTypeDic')
.map(function (item) {
return { 'ItemValue': item.ItemValue, 'ItemName': item.ItemName }
}).sort((a, b) => a.ItemValue.localeCompare(b.ItemValue));
self.OperatingIslandType.options.push(...operatingIslandTypeDicArry);
// //作业岛编号
// var operatingIslandDicArry = resData.filter(t => t.CategoryCode == 'OperatingIslandDic')
// .map(function (item) {
// return { 'ItemValue': item.ItemValue, 'ItemName': item.ItemName }
// }).sort((a, b) => a.ItemValue.localeCompare(b.ItemValue));
// self.OperatingIsland.options.push(...operatingIslandDicArry);
} else {
self.Factory.options = [];
self.OperatingIslandType.options = [];
self.OperatingIsland.options = [];
}
}, backendService.backendError);
}
function registerEvents() {
$scope.$on('sit-property-grid.validity-changed', onPropertyGridValidityChange);
}
function onPropertyGridValidityChange(event, params) {
self.validInputs = params.validity;
}
}
ListScreenRouteConfig.$inject = ['$stateProvider'];
function ListScreenRouteConfig($stateProvider) {
var moduleStateName = 'home.Scheduling_SchedulingApp_SchedulingResourceOccupationGanTT';
var moduleStateUrl = 'Scheduling_SchedulingApp_SchedulingResourceOccupationGanTT';
var moduleFolder = 'Scheduling.SchedulingApp/modules/SchedulingResourceOccupationGanTT';
var state = {
name: moduleStateName + '_SchedulingResourceOccupationGanTTScreen',
url: '/' + moduleStateUrl + '_SchedulingResourceOccupationGanTTScreen',
views: {
'Canvas@': {
templateUrl: moduleFolder + '/SchedulingResourceOccupationGanTTScreen-list.html',
controller: ListScreenController,
controllerAs: 'vm'
}
},
data: {
title: '排产资源暂用甘特图'
}
};
$stateProvider.state(state);
}
}());