mirror of
https://shylinux.com/x/operation
synced 2025-07-01 21:21:19 +08:00
436 lines
15 KiB
Go
436 lines
15 KiB
Go
package production
|
|
|
|
import (
|
|
"path"
|
|
"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/operation/src/operation"
|
|
"shylinux.com/x/operation/src/production/model"
|
|
)
|
|
|
|
type Table struct {
|
|
operation.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"`
|
|
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"`
|
|
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"`
|
|
fileList string `name:"fileList" role:"worker"`
|
|
meetList string `name:"meetList" role:"worker"`
|
|
dealList string `name:"dealList" role:"worker"`
|
|
dateInsert string `name:"dateInsert" help:"约会" role:"leader"`
|
|
}
|
|
|
|
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 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 {
|
|
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) 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 && m.Option("leader_approved") == "on")
|
|
isLeaderFinish := isCreator || (isLeader && m.Option("leader_finish") == "on")
|
|
isLeaderPayfor := isCreator || (isLeader && m.Option("leader_payfor") == "on")
|
|
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 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...)
|
|
}
|
|
case IssueSubmit:
|
|
if isWorker {
|
|
button = append(button, s.Preview)
|
|
}
|
|
if isWorker {
|
|
button = append(button, s.FileCreate)
|
|
}
|
|
if isWorker {
|
|
button = append(button, arg...)
|
|
}
|
|
if isLeaderFinish {
|
|
button = append(button, s.Finish, s.Reback, s.Cancel)
|
|
}
|
|
case IssueFinish:
|
|
if isWorker {
|
|
button = append(button, s.Preview)
|
|
}
|
|
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...) }()
|
|
isWorker := s.IsWorker(m)
|
|
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)
|
|
}
|
|
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) StatusCount(m *ice.Message, arg ...string) {
|
|
if m.Length() > 0 && len(arg) < 2 {
|
|
msg := m.Spawn()
|
|
s.Fields(msg, "status, count(*) AS count").Groups(msg, model.STATUS).Orders(msg, model.STATUS)
|
|
s.Select(msg, model.STORY_UID, arg[0]).Table(func(value ice.Maps) {
|
|
switch status := kit.Int(value[model.STATUS]); m.CommandKey() {
|
|
case "plan":
|
|
m.Echo(PlanStatus(status).String()).Echo(": ")
|
|
case "issue", "design", "task", "case":
|
|
m.Echo(IssueStatus(status).String()).Echo(": ")
|
|
}
|
|
m.Echo(value[model.COUNT]).Echo("\n")
|
|
})
|
|
}
|
|
}
|
|
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)
|
|
}
|
|
func (s Table) Approve(m *ice.Message, arg ...string) {
|
|
s.changeStatus(m, IssueCreate, IssueApproved)
|
|
}
|
|
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)
|
|
}
|
|
func (s Table) Reback(m *ice.Message, arg ...string) {
|
|
s.ChangeStatus(m, int(IssueSubmit), int(IssueProcess))
|
|
}
|
|
func (s Table) Cancel(m *ice.Message, arg ...string) {
|
|
s.ChangeStatus(m, int(IssueSubmit), int(IssueCancel))
|
|
}
|
|
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) Program(m *ice.Message, arg ...string) {
|
|
p := path.Base(m.Option(nfs.PATH))
|
|
m.ProcessOpen(kit.MergeURL(web.S(m.Option(web.SPACE))+web.C(web.VIMER), nfs.PATH, nfs.SRC, nfs.FILE, path.Join(p, "portal.go")))
|
|
}
|
|
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) 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...)
|
|
}
|
|
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))
|
|
}
|
|
m.RenameAppend(model.TO_USER_UID, model.USER_UID)
|
|
return m
|
|
}
|
|
func (s Table) OtherListCmd(m *ice.Message, arg ...ice.Any) *ice.Message {
|
|
kit.If(m.FieldsIsDetail() && m.Length() > 0 && s.IsWorker(m), func() { m.Option("otherList", kit.Fields(arg...)) })
|
|
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) 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) {}
|