package production import ( "path" "strconv" "strings" "shylinux.com/x/ice" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" "shylinux.com/x/community/src/gonganxitong" "shylinux.com/x/enterprise/src/guanlixitong" "shylinux.com/x/operation/src/production/model" ) type Table struct { guanlixitong.Table remove string `name:"remove" role:"worker"` reject string `name:"reject" role:"leader"` approve string `name:"approve" role:"leader"` process string `name:"process" role:"worker"` submit string `name:"submit link*" role:"worker"` finish string `name:"finish" role:"leader"` reback string `name:"reback" role:"leader"` cancel string `name:"cancel" role:"leader"` trash string `name:"trash" role:"leader"` list string `name:"list story_uid uid auto" role:"void"` preview string `name:"preview" role:"worker"` program string `name:"program" role:"worker"` discuss string `name:"discuss meet_type* title* content meet_link* date* time*" role:"leader"` addNote string `name:"addNote title content to_user_uid:select" help:"备注" role:"worker"` setScore string `name:"setScore score" help:"评分" role:"leader"` payfor string `name:"payfor price* title* content" role:"leader"` upload string `name:"upload" role:"worker"` download string `name:"download" style:"notice" role:"worker"` fileCreate string `name:"fileCreate title* content file_type*:select file_link*@upload" help:"上传附件" role:"worker"` dateInsert string `name:"dateInsert" help:"约会" role:"leader"` planList string `name:"planList" role:"worker"` issueList string `name:"issueList" role:"worker"` designList string `name:"designList" role:"worker"` taskList string `name:"taskList" role:"worker"` caseList string `name:"caseList" role:"worker"` noteList string `name:"noteList" role:"worker"` fileList string `name:"fileList" role:"worker"` meetList string `name:"meetList" role:"worker"` dealList string `name:"dealList" role:"worker"` userInfo string `name:"userInfo" help:"所有项目" role:"worker"` } func (s Table) Inputs(m *ice.Message, arg ...string) { switch arg[0] { case model.USER_STORY_ROLE: s.InputsListRole(m, UserStoryRoleList, arg...) case model.STORY_TYPE: s.InputsList(m, StoryTypeList, arg...) case model.PLAN_UID: s.InputsUID(m, arg, Plan{}, m.OptionSimple(model.STORY_UID)...) case model.PLAN_TYPE: s.InputsList(m, PlanTypeList, arg...) case model.ISSUE_UID: s.InputsUID(m, arg, Issue{}, m.OptionSimple(model.STORY_UID)...) case model.ISSUE_TYPE: s.InputsList(m, IssueTypeList, arg...) case model.TASK_UID: s.InputsUID(m, arg, Task{}, m.OptionSimple(model.STORY_UID)...) case model.MEET_TYPE: s.InputsList(m, MeetTypeList, arg...) case model.FILE_TYPE: s.InputsList(m, FileTypeList, arg...) case model.LEVEL: s.InputsList(m, LevelList, arg...) case model.VERSION: m.Push(arg[0], "v1", "v2", "v3", "v4", "v5") case nfs.PATH: m.Option(ice.MSG_USERROLE, aaa.TECH) m.Cmdy(web.SPACE, m.Option(web.SPACE), nfs.DIR, nfs.SRC, nfs.PATH) case ctx.INDEX: msg := m.Spawn() s.Table.Inputs(msg, arg...) msg.Table(func(value ice.Maps) { if strings.HasSuffix(value[arg[0]], ".portal") { m.Push(arg[0], value[arg[0]]) } }) default: switch m.Option(ctx.ACTION) { case "discuss": switch arg[0] { case "date": for i := 0; i < 5; i++ { m.Push(arg[0], strings.Split(m.Time(kit.Format("%dh", i*24)), " ")[0]) } case "time": for i := 38; i < 48; i++ { m.Push(arg[0], kit.Format("%02d:%s", i/2, kit.Select("30", "00", i%2 == 0))) } } default: s.Table.Inputs(m, arg...) } } } func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message { m.RewriteAppend(func(value, key string, index int) string { if _, e := strconv.ParseInt(value, 10, 64); e != nil { return value } switch key { case model.USER_STORY_ROLE: value = UserStoryRole(kit.Int(value)).String() case model.STORY_TYPE: value = StoryType(kit.Int(value)).String() case model.PLAN_TYPE: value = PlanType(kit.Int(value)).String() case model.PLAN_STATUS: value = PlanStatus(kit.Int(value)).String() case model.ISSUE_TYPE: value = IssueType(kit.Int(value)).String() case model.ISSUE_STATUS, model.DESIGN_STATUS, model.TASK_STATUS, model.CASE_STATUS, model.STATUS: value = IssueStatus(kit.Int(value)).String() case model.MEET_TYPE: value = MeetType(kit.Int(value)).String() case model.FILE_TYPE: value = FileType(kit.Int(value)).String() case model.FILE_SIZE: value = kit.FmtSize(kit.Int(value)) case model.LEVEL: value = Level(kit.Int(value)).String() } return value }) return s.Table.RewriteAppend(m) } func (s Table) CheckRole(m *ice.Message, arg ...string) { role := UserStoryRole(s.UserPlaceRole(m)) m.WarnNotRight(!kit.IsIn(role.String(), append(arg, UserStoryCreator.String())...), role.String()) } func (s Table) DateInsert(m *ice.Message, arg ...string) { m.ProcessField(Date{}, []string{m.Option(model.STORY_UID)}, m.OptionSimple(model.ISSUE_UID)...) } func (s Table) PushIssueButton(m *ice.Message, value ice.Maps, arg ...ice.Any) { user_uid := m.Option(ice.MSG_USERUID) button := []ice.Any{} defer func() { m.PushButton(button...) }() isCreator, isLeader, isWorker := s.IsCreator(m), s.IsLeader(m), s.IsWorker(m) isLeaderApproved := isCreator || (isLeader && s.SettingIsOn(m, LEADER_APPROVED)) isLeaderFinish := isCreator || (isLeader && s.SettingIsOn(m, LEADER_FINISH)) isLeaderPayfor := isCreator || (isLeader && s.SettingIsOn(m, LEADER_PAYFOR)) kit.If(value[model.PLAN_TITLE] == "", func() { button = append(button, s.BindPlan) }) switch IssueStatus(kit.Int(value[model.STATUS])) { case IssueCreate: if isLeader { button = append(button, s.DateInsert) } if isLeader { button = append(button, s.AddNote) } if isLeaderApproved { button = append(button, s.Approve) } if isLeader { button = append(button, s.Reject) } if user_uid == value[model.USER_UID] { button = append(button, s.Modify, s.Remove) } case IssueRejected: if isLeaderApproved { button = append(button, s.Trash) } case IssueApproved: if user_uid == value[model.USER_UID] { button = append(button, s.Process) } case IssueProcess: if user_uid == value[model.USER_UID] { button = append(button, s.Submit) } if isWorker { button = append(button, arg...) } if isLeaderFinish { button = append(button, s.Cancel) } case IssueSubmit: if isWorker && value[model.LINK] != "" { button = append(button, s.Preview) } if isLeader { button = append(button, s.AddNote) } if isWorker { button = append(button, s.FileCreate) } if isWorker { button = append(button, arg...) } if isLeaderFinish { button = append(button, s.Finish) } if isLeader { button = append(button, s.Reback) } case IssueFinish: if isWorker && value[model.LINK] != "" { button = append(button, s.Preview) } if value[model.USER_UID] == m.Option(ice.MSG_USERUID) && PlanStatus(kit.Int(value[model.PLAN_STATUS])) != PlanFinish { button = append(button, s.FileCreate) } else if isLeader { button = append(button, s.FileCreate) } if isWorker { button = append(button, arg...) } if isLeaderPayfor && value[model.SCORE] == "0" { button = append(button, s.SetScore) } if isLeaderPayfor && PlanStatus(kit.Int(value[model.PLAN_STATUS])) != PlanFinish { button = append(button, s.Payfor) } kit.If(m.FieldsIsDetail(), func() { s.DoneMessage(m) }) case IssueCancel: if isLeaderApproved { button = append(button, s.Trash) } } } func (s Table) PushTaskButton(m *ice.Message, value ice.Maps, arg ...ice.Any) { user_uid := m.Option(ice.MSG_USERUID) button := []ice.Any{} defer func() { m.PushButton(button...) }() isCreator, isLeader, isWorker := s.IsCreator(m), s.IsLeader(m), s.IsWorker(m) isLeaderFinish := isCreator || (isLeader && s.SettingIsOn(m, LEADER_FINISH)) switch IssueStatus(kit.Int(value[model.STATUS])) { case IssueCreate: if user_uid == value[model.USER_UID] { button = append(button, s.Process, s.Modify, s.Remove) } case IssueProcess: if isWorker { button = append(button, arg...) } if user_uid == value[model.USER_UID] { button = append(button, s.Finish) } if isLeaderFinish { button = append(button, s.Cancel) } case IssueFinish: if isWorker { button = append(button, arg...) } kit.If(m.FieldsIsDetail(), func() { s.DoneMessage(m) }) } } func (s Table) SelectJoinPlan(m *ice.Message, arg ...string) { s.SelectJoin(m, Plan{}, model.TITLE, model.STATUS) } func (s Table) StatusPrice(m *ice.Message, arg ...string) { if m.Length() > 0 && len(arg) < 2 { msg := m.Spawn() s.Fields(msg, "sum(price) AS price") s.Select(msg, model.STORY_UID, arg[0]).Table(func(value ice.Maps) { m.Echo(model.PRICE).Echo(": ").Echo(kit.Format(kit.Int(value[model.PRICE]) / 100)).Echo(" 元") }) } } func (s Table) UserInfo(m *ice.Message, arg ...string) { m.ProcessField(care{}, []string{m.Option(model.STORY_UID), m.Option(model.UID)}, arg...) } func (s care) UserInfo(m *ice.Message, arg ...string) { m.Cmdy(s.PrefixPortal(m), s.UserInfo, arg) } func (s Table) Reject(m *ice.Message, arg ...string) { s.changeStatus(m, IssueCreate, IssueRejected) s.sendTemplate(m, "", "", "") } func (s Table) Approve(m *ice.Message, arg ...string) { s.changeStatus(m, IssueCreate, IssueApproved) s.sendTemplate(m, "", "", "", arg...) } func (s Table) Process(m *ice.Message, arg ...string) { s.changeStatus(m, IssueApproved, IssueProcess) } func (s Table) Submit(m *ice.Message, arg ...string) { s.ChangeStatus(m, int(IssueProcess), int(IssueSubmit), arg...) } func (s Table) Finish(m *ice.Message, arg ...string) { s.changeStatus(m, IssueSubmit, IssueFinish) s.sendTemplate(m, "", "", "") } func (s Table) Reback(m *ice.Message, arg ...string) { s.ChangeStatus(m, int(IssueSubmit), int(IssueProcess)) s.sendTemplate(m, "", "", "") } func (s Table) Cancel(m *ice.Message, arg ...string) { s.ChangeStatus(m, int(IssueProcess), int(IssueCancel)) s.sendTemplate(m, "", "", "") } func (s Table) Trash(m *ice.Message, arg ...string) { s.Delete(m, m.OptionSimple(model.UID, model.STORY_UID)...) } func (s Table) Preview(m *ice.Message, arg ...string) { m.OptionDefault(model.LINK, m.Option(model.MEET_LINK)) m.ProcessOpen(m.OptionDefault(model.LINK, web.S(m.Option(web.SPACE))+web.C(m.Option(ctx.INDEX)))) } func (s Table) sendTemplate(m *ice.Message, from, to, title string, arg ...string) { msg := s.Select(m.Spawn(), m.OptionSimple(model.UID)...) s.SendTemplate(m, from, msg.Append(model.USER_UID), title, arg...) } func (s Table) coderLink(m *ice.Message, arg ...string) string { p := path.Base(m.Option(nfs.PATH)) return kit.MergeURL(web.S(m.Option(web.SPACE))+web.C("web.team.production.coder"), nfs.PATH, nfs.SRC, nfs.FILE, path.Join(p, "portal.go"), m.OptionSimple(model.STORY_UID, model.ISSUE_UID), ) } func (s Table) Program(m *ice.Message, arg ...string) { m.ProcessOpen(s.coderLink(m)) } func (s Table) Discuss(m *ice.Message, arg ...string) { s.issueOtherCreate(m, Meet{}, arg...) } func (s Issue) Discuss(m *ice.Message, arg ...string) { s.commonOtherCreate(m, Meet{}, arg...) } func (s Table) AddNote(m *ice.Message, arg ...string) { m.Cmd(Note{}, s.Create, arg) } func (s Issue) AddNote(m *ice.Message, arg ...string) { m.Cmd(Note{}, s.Create, arg, model.ISSUE_UID, m.Option(model.UID), m.OptionSimple(model.PLAN_UID)) } func (s Design) AddNote(m *ice.Message, arg ...string) { m.Cmd(Note{}, s.Create, arg, m.OptionSimple(model.ISSUE_UID), m.OptionSimple(model.PLAN_UID)) } func (s Table) SetScore(m *ice.Message, arg ...string) { s.Update(m, arg, m.OptionSimple(model.UID, model.STORY_UID)...) } func (s Table) Payfor(m *ice.Message, arg ...string) { s.issueOtherCreate(m, Deal{}, arg...) } func (s Issue) Payfor(m *ice.Message, arg ...string) { s.commonOtherCreate(m, Deal{}, arg...) } func (s Table) Upload(m *ice.Message, arg ...string) { up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)) m.Echo(m.UploadSave("usr/local/storage/" + up[0])) } func (s Table) FileCreate(m *ice.Message, arg ...string) { s.issueOtherCreate(m, File{}, arg...) msg := m.Cmd(Plan{}, s.Select, model.UID, m.Option(model.PLAN_UID)) s.sendTemplate(m, "", msg.Append(model.USER_UID), "") } func (s Issue) FileCreate(m *ice.Message, arg ...string) { s.commonOtherCreate(m, File{}, arg...) } func (s Table) issueOtherCreate(m *ice.Message, target ice.Any, arg ...string) { s.OtherCreate(m, target, kit.Simple(m.OptionSimple(model.ISSUE_UID), arg)...) } func (s Table) commonOtherCreate(m *ice.Message, target ice.Any, arg ...string) { s.OtherCreate(m, target, kit.Simple(m.CommandKey()+"_uid", m.Option(model.UID), arg)...) } func (s Table) OtherCreate(m *ice.Message, target ice.Any, arg ...string) { if m.ActionKeyIsIn(s.Discuss, s.Payfor) { msg := s.Select(m, model.UID, m.Option(model.UID)) arg = append(arg, model.FROM_USER_UID, m.Option(model.USER_UID), model.TO_USER_UID, msg.Append(model.USER_UID)) } kit.If(m.CommandKey() != "plan", func() { arg = append(arg, m.OptionSimple(model.PLAN_UID)...) }) m.Cmdy(target, s.Create, arg) kit.If(!m.IsErr(), func() { m.ProcessField(target, []string{m.Option(model.STORY_UID), m.Result()}) }) } func (s Table) OtherList(m *ice.Message, target ice.Any, arg ...string) { m.Cmdy(target, s.Select, arg).Display(kit.Select("", strings.Split(ice.GetTypeKey(target), "."), -1) + ".js") m.Option("_other_cmd", ice.GetTypeKey(target)) } func (s Table) commonOtherList(m *ice.Message, target ice.Any, arg ...string) *ice.Message { if m.Option(model.ISSUE_UID) == "" { s.OtherList(m, target, kit.Simple(m.CommandKey()+"_uid", m.Option(model.UID))...) } else if ice.GetTypeKey(target) == ice.GetTypeKey(Issue{}) { s.OtherList(m, target, model.UID, m.Option(model.ISSUE_UID)) } else { s.OtherList(m, target, model.ISSUE_UID, m.Option(model.ISSUE_UID)) } if kit.IndexOf(m.Appendv(ice.MSG_APPEND), model.USER_UID) == -1 { m.RenameAppend(model.TO_USER_UID, model.USER_UID) } return m } func (s Table) otherListButton(m *ice.Message, arg ...string) { m.Table(func(value ice.Maps) { switch IssueStatus(kit.Int(value[model.STATUS])) { case IssueSubmit, IssueFinish: if value[web.LINK] != "" { m.PushButton(s.Preview) break } fallthrough default: m.PushButton() } }) } func (s Table) PlanList(m *ice.Message, arg ...string) { s.OtherList(m, Plan{}, model.UID, m.Option(model.PLAN_UID)) } func (s Table) IssueList(m *ice.Message, arg ...string) { s.commonOtherList(m, Issue{}) s.otherListButton(m) } func (s Table) DesignList(m *ice.Message, arg ...string) { s.commonOtherList(m, Design{}) s.otherListButton(m) } func (s Table) TaskList(m *ice.Message, arg ...string) { s.commonOtherList(m, Task{}).RenameAppend(model.STATUS, model.TASK_STATUS) m.PushAction(s.Program) } func (s Table) CaseList(m *ice.Message, arg ...string) { s.commonOtherList(m, Case{}).RenameAppend(model.STATUS, model.CASE_STATUS) m.PushAction(s.Preview) } func (s Table) NoteList(m *ice.Message, arg ...string) { s.commonOtherList(m, Note{}) } func (s Table) FileList(m *ice.Message, arg ...string) { if s.commonOtherList(m, File{}); s.IsLeader(m) { m.PushAction(s.Download) } } func (s Table) MeetList(m *ice.Message, arg ...string) { s.commonOtherList(m, Meet{}) m.PushAction(s.Preview) } func (s Table) DealList(m *ice.Message, arg ...string) { s.commonOtherList(m, Deal{}) } func (s Table) finishCheck(m *ice.Message, target ice.Any, name string, arg ...string) bool { count := m.Cmd(target, s.Select, m.CommandKey()+"_uid = ? AND status != ? AND status != ? AND status != ?", m.Option(model.UID), IssueRejected, IssueFinish, IssueCancel).Length() if m.WarnNotValid(count > 0, kit.Format("还有 %v 个未完成的%s", count, name)) { return true } return false } func (s Table) changeStatus(m *ice.Message, from, to IssueStatus) { s.ChangeStatus(m, int(from), int(to), m.ActionKey()+"_time", m.Time()) } func (s Table) ChangeStatus(m *ice.Message, from, to int, arg ...string) { if !s.IsLeader(m) { msg := s.Select(m.Spawn(), m.OptionSimple(model.STORY_UID, model.UID)...) if m.WarnNotRight(msg.Append(model.USER_UID) != m.Option(model.USER_UID)) { return } } s.Table.ChangeStatus(m, m.Option(model.STORY_UID), m.Option(model.UID), from, to, arg...) s.RecordEventWithName(m, "") s.DashboardUpdate(m) } func (s Table) addCount(m *ice.Message, target ice.Any) Table { UID := s.Keys(target, model.UID) if m.IsErr() || m.Option(UID) == "" { return s } m.Cmd(target, s.AddCount, m.CommandKey()+"_count", kit.Select("-1", "1", m.ActionKey() == mdb.CREATE), m.Option(UID)) return s } func (s Table) planCount(m *ice.Message) Table { return s.addCount(m, Plan{}) } func (s Table) issueCount(m *ice.Message) Table { return s.addCount(m, Issue{}) } func (s Table) taskCount(m *ice.Message) Table { return s.addCount(m, Task{}) } type Tables struct{ Table } func (s Tables) BeforeMigrate(m *ice.Message, arg ...string) {} func NewPortal(userPlace gonganxitong.UserPlacer, place gonganxitong.Placer) Portal { return Portal{Portal: guanlixitong.NewPortal(userPlace, place)} }