惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
S
Schneier on Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
The Exploit Database - CXSecurity.com
B
Blog RSS Feed
G
GRAHAM CLULEY
Microsoft Azure Blog
Microsoft Azure Blog
Know Your Adversary
Know Your Adversary
N
Netflix TechBlog - Medium
A
Arctic Wolf
W
WeLiveSecurity
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
The Blog of Author Tim Ferriss
AWS News Blog
AWS News Blog
Engineering at Meta
Engineering at Meta
T
Threatpost
博客园 - 叶小钗
G
Google Developers Blog
U
Unit 42
Latest news
Latest news
Cyberwarzone
Cyberwarzone
N
News and Events Feed by Topic
Simon Willison's Weblog
Simon Willison's Weblog
Hacker News: Ask HN
Hacker News: Ask HN
MongoDB | Blog
MongoDB | Blog
H
Hacker News: Front Page
F
Fortinet All Blogs
T
Tailwind CSS Blog
The Register - Security
The Register - Security
Apple Machine Learning Research
Apple Machine Learning Research
C
CXSECURITY Database RSS Feed - CXSecurity.com
H
Heimdal Security Blog
A
About on SuperTechFans
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
CERT Recently Published Vulnerability Notes
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News and Events Feed by Topic
Application and Cybersecurity Blog
Application and Cybersecurity Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Schneier on Security
Schneier on Security
Y
Y Combinator Blog
V
Visual Studio Blog
GbyAI
GbyAI
Forbes - Security
Forbes - Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
N
News | PayPal Newsroom
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs

博客园 - 遗忘海岸

简协运动模拟 电磁场中的运动轨迹模拟 圆周运动模拟 带阻力的平抛运动 C# 队列的一些并发模拟 devexpress gridview master,detail视图 focuseRowHandle 同步选中 C# Tcp Server端实现,使用TcpListener 深信服务超融合管理Api调用 GDI+画工作流图的一些总结 绘制贝塞而曲线 GDI+画直线带箭头 逻辑回归损失函数求导 matplotlim柱状图 匀加速运动模拟python,(matplotlib) C# 实现排列 python 类鸟群Boids C#动态编译 正太分布数据排序后分段数据的方差与标准差 Android 的一个通用列表单选AlertDialog封装
devexpress schedulerControl Gantt View 使用
遗忘海岸 · 2024-03-27 · via 博客园 - 遗忘海岸
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using F.Studio.DevExpressUI;
using DevExpress.XtraScheduler;
using com.geelyhd.MFG.IService;
using com.geelyhd.MFG.EFModel;
using F.Studio.Prime.Util;
using F.Studio.Prime.IService;
using F.Studio.Infrastructure;
using DevExpress.Utils.Menu;

namespace com.geelyhd.MFG.WR.UI.GA
{
    /// <summary>
    /// 有3分数据(考虑CustomAppointmentForm)
    /// A是BindingSource中的,用户自己的对象
    /// B是ScheduleStorage.Appointments 中的数据,类型是Appointment
    /// C是CustomerAppointmentForm 中的LoadFormData,SaveFormData
    ///       这两个函数中传入appointment的hashcode 跟B中是不一样的,所以这里的appointment.id是null
    /// B中的更改在AppointmentInserting中还位写入到A中,需要等到AppointmentsInserted时写入
    /// 在SC中添加新的Appointment后除了要设置Appointment.Id外还需要设置GA_Task.RecId
    /// 否则GA_Task.RecId会一致是0
    /// 是否给Appointment.Id设置映射并保证其有值,会决定针对该apppointment是否可创建依赖
    /// 
    /// 所以针对发布功能以下代码会触发2次changing
    ///    apt.LabelId = 1; //设置2个属性,触发了两次Changing
    ///    apt.CustomFields["IsPub"] = true;
    ///所以CustomAppointmentForm会复制一appointment防止多次触发
    /// </summary>
    public partial class frmGA_PlanAdmin : AdminFormBase
    {
        private long _RecId4New = 0;
        public frmGA_PlanAdmin()
        {
            InitializeComponent();
            MainBindingSource = this.gAPositionBindingSource;
            ConfigGrid(gridControl1);
            #region gridview
            gridView1.OptionsSelection.EnableAppearanceFocusedCell = false; //整行选中,不显示单独单元格
            gridView1.OptionsBehavior.ReadOnly = true;
            gridView1.OptionsBehavior.Editable = false;
            #endregion
            CfgSchedulerControl(schedulerControl1);

            #region 班组选择变动
            MainBindingSource.CurrentChanged += (s, e) =>
            {
                var cur = MainBindingSource.Current as GA_Position;
                if (cur == null) return;
                var iv = new TimeInterval(schedulerControl1.GanttView.SelectedInterval.Start, TimeSpan.FromDays(0.0d));// schedulerControl1.GanttView.SelectedInterval;
                var res= schedulerControl1.Storage.Resources.Items.FirstOrDefault(ent => ent.Id == cur.Position);
                if (res == null) return;
                schedulerControl1.GanttView.SetSelection(iv,res);
            };
            #endregion
        }
        protected override void LoadData()
        {
            Action act = () =>
            {
                var sc = schedulerControl1;
                var positionList = Fetch<IGA_PositionService>().GetList();
                var appointmentList = LoadRangeAppointmentList();
                var positionVsHarnessList = Fetch<IGA_PositionVsHarnessService>().GetList();
                foreach (var p in positionList)
                {
                    p.HarnessList=positionVsHarnessList.Where(ent => ent.Position == p.Position).ToList();
                }
                SyncContext.Post(o => {
                    //MainBindingSource.Clear();
                    //gATaskBindingSource.Clear();
                    MainBindingSource.DataSource = positionList;
                    gATaskBindingSource.DataSource = appointmentList;
                
                },null);
            };
            InvokeService(act, "数据加载...");
            
        }
        public static string CFT(string name,Appointment apt)
        {
            return CUtil.TryParserV2<String>( apt.CustomFields[name],"");
        }
        public static string CFT4Dec(string name, Appointment apt, string format)
        {
            var v= CUtil.TryParserV2<decimal>(apt.CustomFields[name], 0.0m);
            return v.ToString(format);
        }
        public static void UpdateScheduleAmount(long planRecId)
        {
            var sql = string.Format(" select SUM(ISNULL(Amount,0)) from GA_Task where PlanRecId={0}", planRecId);
            var scSum =CUtil.V( ExeScalar<IGA_TaskService, decimal?>(sql));
          
            //更新分配量
            var sql_update = string.Format("update GA_Plan Set ScheduledAmount={0} where PlanRecId={1}", scSum, planRecId);
            ServiceLocator.Fetch<IGA_PlanService>().ExeSql(sql_update);
        }
        private void CfgSchedulerControl(SchedulerControl sc)
        {
            sc.OptionsCustomization.AllowAppointmentDrag = DevExpress.XtraScheduler.UsedAppointmentType.None;
            sc.OptionsBehavior.ShowRemindersForm = false;
            sc.OptionsCustomization.AllowInplaceEditor = UsedAppointmentType.None;
            sc.OptionsCustomization.AllowAppointmentConflicts = AppointmentConflictsMode.Forbidden;
            sc.GroupType = SchedulerGroupType.Resource;
            sc.Storage.Appointments.AutoReload = true; //没有这句databindings中的数据部会自动加载到schedulerStorage
       
            #region 设置时间区间
            var monthFirstDay = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
            sc.LimitInterval.Start = monthFirstDay.AddDays(-5);
            sc.LimitInterval.End = monthFirstDay.AddDays(36);
            #endregion
            #region 日尺度单元格长度

            var scales4Day = sc.GanttView.Scales.OfType<DevExpress.XtraScheduler.TimeScaleDay>().FirstOrDefault();
            scales4Day.Width = 200;
            #endregion
            #region 显示内容
            sc.InitAppointmentDisplayText += (s, e) =>
            {
                var sb = new StringBuilder();
                var apt=e.Appointment;
                sb.AppendFormat("{0},{1}\r\n",CFT("Batno",apt),CFT("CarType",apt));
                sb.AppendFormat("{0},{1}件\r\n", CFT("MNo", apt), CFT4Dec("Amount", apt,"F0"));
                sb.AppendFormat("{0} ",CFT("MName",apt));
                e.Text = sb.ToString();
            };
            #endregion
         


            sc.GanttView.ResourcesPerPage = 4;//资源(泳道)显示数
            sc.GanttView.AppointmentDisplayOptions.AppointmentAutoHeight = true;
         
            #region 右键菜单
            sc.PopupMenuShowing += (s, e) =>
            {
                if (e.Menu.Id == DevExpress.XtraScheduler.SchedulerMenuItemId.DefaultMenu)
                {
                    e.Menu.RemoveMenuItem(SchedulerMenuItemId.NewRecurringAppointment);
                    e.Menu.RemoveMenuItem(SchedulerMenuItemId.NewRecurringEvent);
                    e.Menu.RemoveMenuItem(SchedulerMenuItemId.NewAllDayEvent);
                    e.Menu.RemoveMenuItem(SchedulerMenuItemId.SwitchViewMenu);

                    SchedulerMenuItem item = e.Menu.GetMenuItemById(SchedulerMenuItemId.NewAppointment);
                    if (item != null) item.Caption = "新建作业";
                }
                else if (e.Menu.Id == SchedulerMenuItemId.AppointmentMenu)
                {
                    e.Menu.RemoveMenuItem(SchedulerMenuItemId.AppointmentDependencyCreation);
                    e.Menu.RemoveMenuItem(SchedulerMenuItemId.LabelSubMenu);
                    e.Menu.RemoveMenuItem(SchedulerMenuItemId.StatusSubMenu);

                    #region 放行
                    //创建一个新的自定义事件菜单
                    DXMenuItem menuPub= new SchedulerMenuItem("放行");
                    menuPub.Click += new EventHandler(menuPub_Click);
                    menuPub.BeginGroup = true;
                    e.Menu.Items.Insert(1,menuPub);
                    #endregion
                }
            };
            #endregion
            #region Storage CURD

            #region 新记录初始化属性
            sc.InitNewAppointment += (s, e) =>
            {
                var dbTime = Fetch<IInitService>().Now();
                sc.Storage.SetAppointmentId(e.Appointment, _RecId4New);
                e.Appointment.AllDay = false;
                e.Appointment.CustomFields["AddTime"] = dbTime;
                e.Appointment.CustomFields["AddEmpNo"] = UserSetting.UserName;
                e.Appointment.CustomFields["Status"] = "Init";
                e.Appointment.CustomFields["IsPub"] = false;
                e.Appointment.CustomFields["IsClose"] = false;
                e.Appointment.CustomFields["ExeStatus"] = 0;
                e.Appointment.CustomFields["Priority"] = 100;
                e.Appointment.CustomFields["MUnit"] = "PC";
                e.Appointment.CustomFields["OriginalPosition"] = CUtil.TryParserV2<String>(e.Appointment.ResourceId, "OriginalPosition");
                e.Appointment.CustomFields["TaskNo"] = Fetch<IInitService>().GetOrderId("0000004838_TaskNo", 10);
                //这里获取到taskEnt==null
                //var taskEnt= e.Appointment.GetSourceObject(sc.Storage);

                _RecId4New--;
            };
            #endregion

            sc.Storage.AppointmentInserting += (s, e) =>
            {
                try
                {
                    Console.WriteLine("Inserting...");
                    var apt = e.Object as Appointment;
                    var taskEnt = new GA_Task();
                    AppointEntMap(sc, apt, taskEnt);

                    #region 数据校验
                    var plan = Fetch<IGA_PlanService>().Get("PlanRecId", taskEnt.PlanRecId);
                    if (plan == null) throw new Exception("PlanRecId对应的GA_Plan记录不存在");
                    var sql=string.Format(" select SUM(ISNULL(Amount,0)) from GA_Task where PlanRecId={0}",taskEnt.PlanRecId);
                    var scSum =CUtil.V( ExeScalar<IGA_TaskService, decimal?>(sql));
                    if ((plan.Amount - scSum) < taskEnt.Amount) throw new Exception("未分配量不足");
                    
                    #endregion

                    var dbIt = Fetch<IGA_TaskService>().Add(taskEnt);
                    UpdateScheduleAmount(dbIt.PlanRecId.Value);

                    sc.Storage.SetAppointmentId(apt, dbIt.RecId); 

                    Console.WriteLine("End Inserting");
                    e.Cancel = false;
                }
                catch (Exception ex)
                {
                    ErrMsg(ex.Message);
                    e.Cancel = true;
                }
            };
            sc.Storage.AppointmentsInserted += (s, e) =>
            {
                
                
                var apt = e.Objects[0] as Appointment;
                var row = apt.GetRow(sc.Storage);
                var taskEnt = apt.GetSourceObject(sc.Storage) as GA_Task;
                if (taskEnt != null)
                {
                    taskEnt.RecId = CUtil.TryParserV2<long>(apt.Id, 0);
                }

               
            };
            sc.Storage.AppointmentDeleting += (s, e) =>
            {
                try
                {
                    var apt = e.Object as Appointment;
                    if (MessageBox.Show("确定删除选中记录,该操作不可恢复!", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != System.Windows.Forms.DialogResult.Yes)
                    {
                        e.Cancel = true;
                        return;
                    }
                    var recId = CUtil.TryParserV2<long>(apt.Id, 0);
                    var dbIt = Fetch<IGA_TaskService>().Get("RecId", recId);
                    if (dbIt == null) throw new Exception("记录已经被删除了,请刷新");
                    if (dbIt.IsPub == true) throw new Exception("已放行记录不允许删除!");
                    Fetch<IGA_TaskService>().Delete(dbIt);
                    UpdateScheduleAmount(dbIt.PlanRecId.Value);
                }
                catch (Exception ex)
                {
                    ErrMsg(ex.Message);
                    e.Cancel = true;
                }
               

            };
            sc.Storage.AppointmentChanging += (s, e) =>
            {
                try
                {
                  
                    var taskEnt = new GA_Task();
                    var apt = e.Object as Appointment;
                    AppointEntMap(sc, apt, taskEnt);

                    #region 数据校验
                    var plan = Fetch<IGA_PlanService>().Get("PlanRecId", taskEnt.PlanRecId);
                    if (plan == null) throw new Exception("PlanRecId对应的GA_Plan记录不存在");
                    var sql = string.Format(" select SUM(ISNULL(Amount,0)) from GA_Task where PlanRecId={0} And RecId!={1}", taskEnt.PlanRecId,taskEnt.RecId);
                    var scSum =CUtil.V( ExeScalar<IGA_TaskService, decimal?>(sql));
                    if ((plan.Amount - scSum) < taskEnt.Amount) throw new Exception("未分配量不足");

                    #endregion

                    Fetch<IGA_TaskService>().Update(taskEnt);
                    UpdateScheduleAmount(taskEnt.PlanRecId.Value);

                    e.Cancel = false;
                }
                catch (Exception ex)
                {
                    ErrMsg(ex.Message);
                    e.Cancel = true;
                }
              
    
            };
            sc.Storage.AppointmentsChanged += (s, e) =>
            {

                Console.WriteLine("Changed:" + (e.Objects[0] as Appointment).LabelId);
            };
            #endregion

            #region 标签
            sc.Storage.Appointments.Labels.Clear();
            sc.Storage.Appointments.Labels.Add(new AppointmentLabel(Color.FromArgb(0xee,0xee,0xee), "未放行"));
            sc.Storage.Appointments.Labels.Add(new AppointmentLabel(Color.FromArgb(200, 200, 140), "待生产"));
            sc.Storage.Appointments.Labels.Add(new AppointmentLabel(Color.Orange, "生产中"));
            sc.Storage.Appointments.Labels.Add(new AppointmentLabel(Color.LawnGreen, "生产完成"));
            sc.Storage.Appointments.Labels.Add(new AppointmentLabel(Color.Red, "逾期"));


            #endregion
            #region 数据映射
            {

                AppointmentMappingInfo appoint = sc.Storage.Appointments.Mappings;
                appoint.AllDay = "S_AllDay";
                appoint.Description = "S_Description";
                appoint.End = "S_End";
                appoint.Label = "S_Label";
                appoint.Location = "S_Location";
                appoint.ResourceId = "Position";
                appoint.Start = "S_Start";
                appoint.Status = "S_Status";
                appoint.Subject = "S_Subject";
                appoint.Type = "S_Type";
                appoint.AppointmentId = "RecId";
                appoint.PercentComplete = "CompletedPercent";
                AppointmentCustomFieldMappingCollection appointCust = sc.Storage.Appointments.CustomFieldMappings;
                var ptyList = typeof(GA_Task).GetProperties().Where(ent => !CUtil.StartsWith(ent.Name, "S_,RecId,CompletedPercent,Position,EntityState,EntityKey")).ToList();
                foreach (var pty in ptyList)
                {
                    appointCust.Add(new AppointmentCustomFieldMapping(pty.Name, pty.Name));
                }

                ResourceMappingInfo res = sc.Storage.Resources.Mappings;
                res.Caption = "Name";
                res.Id = "Position";
             
            }
            #endregion
        }

        void menuPub_Click(object sender, EventArgs e)
        {
            var sc = schedulerControl1;
            if (sc.SelectedAppointments == null || sc.SelectedAppointments.Count <= 0) return;
            var apt = sc.SelectedAppointments[0];
            try
            {
                if (MessageBox.Show("确定放行选中记录,该操作不可恢复!", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != System.Windows.Forms.DialogResult.Yes) return;
                var recId = CUtil.TryParserV2<long>(apt.Id, 0);
                var dbIt = Fetch<IGA_TaskService>().Get("RecId", recId);
                if (dbIt == null) throw new Exception("记录已经被删除了,请刷新");
                if (dbIt.IsPub == true) throw new Exception("已放行记录无需再次执行!");
                dbIt.IsPub = true;
                dbIt.S_Label = 1;
                Fetch<IGA_TaskService>().Update(dbIt);

                var taskEnt = apt.GetSourceObject(sc.Storage) as GA_Task;
                taskEnt.S_Label = 1;
                taskEnt.IsPub = true;
                sc.RefreshData();//指的是从bindingSource数据源读取到Appointment
            }
            catch (Exception ex)
            {
                ErrMsg(ex.Message);
            }
           
        }
        public static void AppointEntMap(SchedulerControl sc, Appointment apt,GA_Task ent)
        {
            AppointmentMappingInfo aptMaps = sc.Storage.Appointments.Mappings;
            AppointmentCustomFieldMappingCollection aptCustomMaps = sc.Storage.Appointments.CustomFieldMappings;


            ent.S_AllDay = apt.AllDay;
            ent.S_Description = apt.Description;
            ent.S_End = apt.End;
            ent.S_Label = apt.LabelId;
            ent.S_Location = apt.Location;
            ent.S_Start = apt.Start;
            ent.S_Status = apt.StatusId;
            ent.S_Subject = apt.Subject;
            ent.S_Type =(int) apt.Type;
            ent.Position = CUtil.TryParserV2<String>(apt.ResourceId, "");
            ent.CompletedPercent = apt.PercentComplete;
            ent.RecId = CUtil.TryParserV2<long>(apt.Id, 0);
            var ptys=ent.GetType().GetProperties();
            foreach (var item in aptCustomMaps)
            {
                var pty=ptys.FirstOrDefault(it=>it.Name==item.Name);
                if(pty==null)continue;
                pty.SetValue(ent, item.GetValue(apt), null);
            }

        }

        private List<GA_Task> LoadRangeAppointmentList()
        {
            var sc = schedulerControl1;
            var bTime = sc.LimitInterval.Start;
            var eTime = sc.LimitInterval.End;
            var where = string.Format("it.S_Start>=DateTime'{0}' And it.S_Start<=DateTime'{1}'", bTime.ToString("yyyy-MM-dd HH:mm:ss"), eTime.ToString("yyyy-MM-dd HH:mm:ss"));
            var list = Fetch<IGA_TaskService>().GetList(where, "it.RecId");
            return list;
        }
        private void frmGA_PlanAdmin_Load(object sender, EventArgs e)
        {
            LoadData();
        }

        private void schedulerControl1_EditAppointmentFormShowing(object sender, AppointmentFormEventArgs e)
        {
            DevExpress.XtraScheduler.SchedulerControl scheduler = ((DevExpress.XtraScheduler.SchedulerControl)(sender));
            com.geelyhd.MFG.WR.UI.GA.CustomAppointmentForm form = new com.geelyhd.MFG.WR.UI.GA.CustomAppointmentForm(scheduler, e.Appointment, e.OpenRecurrenceForm);
            try
            {
                e.DialogResult = form.ShowDialog();
                e.Handled = true;
            }
            finally
            {
                form.Dispose();
            }

        }
    }
}