This commit is contained in:
IT 老营长 @云轩领航-创始人 2025-05-04 08:49:08 +08:00
parent 099ac2ecd1
commit cb4a4f5eaf
12 changed files with 124 additions and 94 deletions

View File

@ -2,7 +2,6 @@ package production
import (
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
@ -33,11 +32,13 @@ func (s Case) List(m *ice.Message, arg ...string) {
s.ValueList(m, arg)
s.SelectJoinPlan(m)
s.StatusCount(m, arg...)
m.Table(func(value ice.Maps) { s.PushTaskButton(m, value, user_uid, s.Preview) }).Display("")
m.RenameAppend(model.STATUS, model.CASE_STATUS)
}
func (s Case) Preview(m *ice.Message, arg ...string) {
m.ProcessOpen(web.S(m.Option(web.SPACE)) + web.C(m.Option(ctx.INDEX)))
m.Table(func(value ice.Maps) {
if value[web.SPACE] == "" {
s.PushTaskButton(m, value, user_uid)
} else {
s.PushTaskButton(m, value, user_uid, s.Preview)
}
}).Display("").RenameAppend(model.STATUS, model.CASE_STATUS)
}
func (s Case) Process(m *ice.Message, arg ...string) {
s.changeStatus(m, IssueCreate, IssueProcess)

View File

@ -1,9 +1,12 @@
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"
@ -24,13 +27,15 @@ type Table struct {
reback string `name:"reback" role:"leader"`
cancel string `name:"cancel" role:"leader"`
payfor string `name:"payfor price* title* content" role:"leader"`
discuss string `name:"discuss meet_type* title* content date* time* link*" role:"leader"`
discuss string `name:"discuss meet_type* title* content link* date* time*" role:"leader"`
list string `name:"list story_uid uid auto" role:"void"`
designList string `name:"designList" role:"worker"`
taskList string `name:"taskList" role:"worker"`
caseList string `name:"caseList" role:"worker"`
meetList string `name:"meetList" role:"worker"`
dealList string `name:"dealList" role:"worker"`
preview string `name:"preview" role:"worker"`
program string `name:"program" role:"worker"`
}
func (s Table) Inputs(m *ice.Message, arg ...string) {
@ -49,20 +54,25 @@ func (s Table) Inputs(m *ice.Message, arg ...string) {
s.InputsUID(m, arg, Task{}, m.OptionSimple(model.STORY_UID)...)
case model.MEET_TYPE:
s.InputsList(m, MeetTypeList, arg...)
case model.FROM_USER_UID, model.TO_USER_UID:
m.Cmdy("member", m.Option(model.STORY_UID)).Cut(model.USER_UID, model.USER_NAME, model.USER_AVATAR)
m.RenameAppend(model.USER_UID, arg[0], model.NAME, model.USER_NAME, model.USER_AVATAR, mdb.ICONS)
m.DisplayInputKeyNameIconTitle()
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("action") {
switch m.Option(ctx.ACTION) {
case "discuss":
switch arg[0] {
case "date":
for i := 1; i < 5; i++ {
for i := 0; i < 5; i++ {
m.Push(arg[0], strings.Split(m.Time(kit.Format("%dh", i*24)), " ")[0])
}
case "time":
@ -111,7 +121,7 @@ func (s Table) PushIssueButton(m *ice.Message, value ice.Maps, user_uid string,
button = append(button, s.Discuss, s.Payfor)
}
if isCreator {
button = append(button, s.Approve, s.Reject, s.Cancel)
button = append(button, s.Approve, s.Reject, s.Cancel, s.Remove)
}
if user_uid == value[model.USER_UID] {
button = append(button, s.Modify, s.Remove)
@ -121,7 +131,7 @@ func (s Table) PushIssueButton(m *ice.Message, value ice.Maps, user_uid string,
button = append(button, s.Process)
}
case IssueProcess:
if isLeader && kit.Int(value[model.PRICE]) > 0 {
if isLeader {
button = append(button, s.Discuss, s.Payfor)
}
if user_uid == value[model.USER_UID] {
@ -131,13 +141,19 @@ func (s Table) PushIssueButton(m *ice.Message, value ice.Maps, user_uid string,
if isLeader {
button = append(button, s.Discuss, s.Payfor)
}
if isWorker {
button = append(button, s.Preview)
}
if isCreator {
button = append(button, s.Finish, s.Reback, s.Cancel)
}
case IssueFinish:
if isLeader && kit.Int(value[model.PRICE]) > 0 {
if isLeader {
button = append(button, s.Discuss, s.Payfor)
}
if isWorker {
button = append(button, s.Preview)
}
if isWorker {
button = append(button, arg...)
}
@ -213,24 +229,26 @@ 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, IssueSubmit, IssueCancel)
s.ChangeStatus(m, int(IssueSubmit), int(IssueCancel))
}
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) Preview(m *ice.Message, arg ...string) {
m.ProcessOpen(m.OptionDefault(model.LINK, web.S(m.Option(web.SPACE))+web.C(m.Option(ctx.INDEX))))
}
func (s Table) Payfor(m *ice.Message, arg ...string) {
msg := s.Select(m, model.UID, m.Option(model.UID))
s.issueOtherCreate(m, deal{}, kit.Simple(model.FROM_USER_UID, m.Option(model.USER_UID), model.TO_USER_UID, msg.Append(model.USER_UID), arg)...)
s.issueOtherCreate(m, deal{}, arg...)
}
func (s Issue) Payfor(m *ice.Message, arg ...string) {
msg := s.Select(m, model.UID, m.Option(model.UID))
s.commonOtherCreate(m, deal{}, kit.Simple(model.FROM_USER_UID, m.Option(model.USER_UID), model.TO_USER_UID, msg.Append(model.USER_UID), arg)...)
s.commonOtherCreate(m, deal{}, arg...)
}
func (s Table) Discuss(m *ice.Message, arg ...string) {
msg := s.Select(m, model.UID, m.Option(model.UID))
s.issueOtherCreate(m, meet{}, kit.Simple(model.FROM_USER_UID, m.Option(model.USER_UID), model.TO_USER_UID, msg.Append(model.USER_UID), arg)...)
s.issueOtherCreate(m, meet{}, arg...)
}
func (s Issue) Discuss(m *ice.Message, arg ...string) {
msg := s.Select(m, model.UID, m.Option(model.UID))
s.commonOtherCreate(m, meet{}, kit.Simple(model.FROM_USER_UID, m.Option(model.USER_UID), model.TO_USER_UID, msg.Append(model.USER_UID), arg)...)
s.commonOtherCreate(m, meet{}, 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)...)
@ -239,33 +257,55 @@ 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) *ice.Message {
m.Cmdy(target, s.Select, m.OptionSimple(model.STORY_UID), m.CommandKey()+"_uid", m.Option(model.UID)).Option("_command", ice.GetTypeKey(target))
if s.IsLeader(m) {
kit.If(m.ActionKey() == "meetList", func() { m.RenameAppend(model.TO_USER_UID, model.USER_UID) })
kit.If(m.ActionKey() == "dealList", func() { m.RenameAppend(model.TO_USER_UID, model.USER_UID) })
} else {
kit.If(m.ActionKey() == "meetList", func() { m.RenameAppend(model.FROM_USER_UID, model.USER_UID) })
kit.If(m.ActionKey() == "dealList", func() { m.RenameAppend(model.FROM_USER_UID, model.USER_UID) })
if m.ActionKeyIsIn(s.MeetList, s.DealList) {
if s.IsLeader(m) {
m.RenameAppend(model.TO_USER_UID, model.USER_UID)
} else {
m.RenameAppend(model.FROM_USER_UID, model.USER_UID)
}
}
s.SelectJoinUser(m)
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:
m.PushButton(s.Preview)
default:
m.PushButton()
}
})
}
func (s Table) IssueList(m *ice.Message, arg ...string) {
s.OtherList(m, Issue{}).Display("issue.js")
s.otherListButton(m)
}
func (s Table) DesignList(m *ice.Message, arg ...string) {
s.OtherList(m, Design{}).Display("design.js")
s.otherListButton(m)
}
func (s Table) TaskList(m *ice.Message, arg ...string) {
s.OtherList(m, Task{}).Display("task.js")
s.otherListButton(m)
}
func (s Table) CaseList(m *ice.Message, arg ...string) {
s.OtherList(m, Case{}).Display("case.js")
s.otherListButton(m)
}
func (s Table) MeetList(m *ice.Message, arg ...string) {
s.OtherList(m, meet{}).Display("meet.js")
m.PushAction(s.Preview)
}
func (s Table) DealList(m *ice.Message, arg ...string) {
s.OtherList(m, deal{}).Display("deal.js")

View File

@ -11,10 +11,11 @@ type deal struct {
order string `data:"7"`
fields string `data:"from_user_uid,to_user_uid,price,title,content"`
create string `name:"create issue_uid* from_user_uid* to_user_uid* price* title* content" role:"leader"`
modify string `name:"modify price* title* content" role:"leader"`
}
func (s deal) Create(m *ice.Message, arg ...string) {
s.Table.Create(m, arg...)
s.ValueCreate(m, arg...)
s.SendMessage(s.GetCommandUID(m), "", m.Option(model.TO_USER_UID))
}
func (s deal) List(m *ice.Message, arg ...string) {
@ -30,13 +31,12 @@ func (s deal) List(m *ice.Message, arg ...string) {
s.DoneMessage(m)
}
}
if s.IsLeader(m) {
m.PushAction(s.Modify)
if m.Display(""); s.IsLeader(m) {
m.RenameAppend(model.TO_USER_UID, model.USER_UID)
} else {
m.RenameAppend(model.FROM_USER_UID, model.USER_UID)
}
// s.SelectJoinUser(m).
m.Display("")
}
func init() { ice.TeamCtxCmd(deal{}) }

View File

@ -1,9 +1,9 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.title||value.name||value.user_name, can.onimport.moneyView(can, value), can.onimport.titleAction(can, value)]},
{view: html.TITLE, list: [value.title, can.onimport.moneyView(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.user_name]},
{view: html.OUTPUT, list: [value.content||value.info]},
{view: html.OUTPUT, list: [value.content]},
] })
},
})

View File

@ -11,7 +11,7 @@ type Design struct {
Table
order string `data:"3"`
fields string `data:"title,content,status,price,link,begin_time,end_time,process_time,finish_time,issue_uid,plan_uid,user_uid"`
create string `name:"create issue_uid* title* content* price=1000 begin_time:select@date end_time:select@date" role:"worker"`
create string `name:"create issue_uid* title* content* price*=1000 begin_time:select@date end_time:select@date" role:"worker"`
modify string `name:"modify title* content* price* begin_time*:select@date end_time*:select@date" role:"worker"`
}

View File

@ -9,13 +9,12 @@ import (
type Issue struct {
Table
order string `data:"2"`
fields string `data:"title,content,level,issue_type,status,price,link,design_count,task_count,begin_time,end_time,process_time,finish_time,plan_uid,user_uid"`
create string `name:"create plan_uid* title* content* issue_type:select level:select price=1000 begin_time:select@date end_time:select@date" role:"worker"`
modify string `name:"modify title* content* price* begin_time:select@date end_time:select@date" role:"worker"`
// modify string `name:"modify title* content* issue_type*:select level*:select price* begin_time:select@date end_time:select@date" role:"worker"`
order string `data:"2"`
fields string `data:"title,content,issue_type,level,status,price,link,design_count,task_count,begin_time,end_time,process_time,finish_time,plan_uid,user_uid"`
create string `name:"create plan_uid* title* content* issue_type:select level:select price=1000 begin_time:select@date end_time:select@date" role:"worker"`
modify string `name:"modify title* content* price* begin_time:select@date end_time:select@date" role:"worker"`
designCreate string `name:"designCreate title* content* price=1000 begin_time:select@date end_time:select@date" role:"worker"`
taskCreate string `name:"taskCreate title* content* price=1000 begin_time:select@date end_time:select@date" role:"worker"`
taskCreate string `name:"taskCreate title* content* space path begin_time:select@date end_time:select@date" role:"worker"`
applyCreate string `name:"applyCreate" role:"void"`
}
@ -30,7 +29,7 @@ func (s Issue) Remove(m *ice.Message, arg ...string) {
s.planCount(m).DashboardUpdate(m)
}
func (s Issue) Cancel(m *ice.Message, arg ...string) {
s.ChangeStatus(m, int(IssueSubmit), int(IssueCancel))
s.ChangeStatus(m, int(IssueCreate), int(IssueCancel))
s.planCount(m).DashboardUpdate(m)
}
func (s Issue) List(m *ice.Message, arg ...string) {

View File

@ -12,8 +12,8 @@ import (
type meet struct {
Table
order string `data:"6"`
fields string `data:"from_user_uid,to_user_uid,title,content,link,meet_type,begin_time,end_time,issue_uid,plan_uid,company_uid"`
create string `name:"create issue_uid* from_user_uid* to_user_uid* meet_type* title* content* date time link*" role:"leader"`
fields string `data:"from_user_uid,to_user_uid,meet_type,title,content,link,begin_time,end_time,issue_uid,plan_uid,company_uid"`
create string `name:"create issue_uid* from_user_uid* to_user_uid* meet_type* title* content* link* date time" role:"leader"`
remove string `name:"remove" role:"leader"`
}
@ -26,7 +26,6 @@ func (s meet) Create(m *ice.Message, arg ...string) {
}
func (s meet) List(m *ice.Message, arg ...string) {
s.ValueList(m, arg).Display("")
// s.SelectJoinUser(m.RenameAppend(model.TO_USER_UID, model.USER_UID)).Display("")
if s.IsLeader(m) {
m.RenameAppend(model.TO_USER_UID, model.USER_UID)
} else {
@ -43,12 +42,14 @@ const (
MeetTalk MeetType = iota
MeetValue
MeetCheck
MeetPlan
)
var MeetTypeList = map[MeetType]string{
MeetTalk: "需求沟通",
MeetValue: "需求评审",
MeetValue: "原型评审",
MeetCheck: "项目验收",
MeetPlan: "方向规划",
}
func (s MeetType) String() string { return MeetTypeList[s] }

View File

@ -3,16 +3,15 @@ package model
import "shylinux.com/x/mysql-story/src/db"
const (
CREATED_AT = "created_at"
UID = "uid"
NAME = "name"
INFO = "info"
LINK = "link"
TYPE = "type"
LEVEL = "level"
STATUS = "status"
COUNT = "count"
PRICE = "price"
LINK = "link"
TITLE = "title"
CONTENT = "content"
VERSION = "version"
@ -28,19 +27,20 @@ const (
PLAN_STATUS = "plan_status"
DESIGN_STATUS = "design_status"
DESIGN_COUNT = "design_count"
ISSUE_COUNT = "issue_count"
TASK_COUNT = "task_count"
CASE_COUNT = "case_count"
ISSUE_UID = "issue_uid"
ISSUE_TYPE = "issue_type"
ISSUE_STATUS = "issue_status"
ISSUE_COUNT = "issue_count"
TASK_UID = "task_uid"
TASK_STATUS = "task_status"
TASK_COUNT = "task_count"
CASE_STATUS = "case_status"
CASE_COUNT = "case_count"
MEET_TYPE = "meet_type"
MARKET_UID = "market_uid"
CREATED_AT = "created_at"
FROM_USER_UID = "from_user_uid"
TO_USER_UID = "to_user_uid"
MARKET_UID = "market_uid"
BEGIN_TIME = "begin_time"
END_TIME = "end_time"
)
@ -80,10 +80,9 @@ type Design struct {
type Task struct {
Common
IssueUID string `gorm:"type:char(32);index"`
CaseCount int `gorm:"default:0"`
Space string `gorm:"type:varchar(64)"`
Index string `gorm:"type:varchar(64)"`
Path string `gorm:"type:varchar(64)"`
CaseCount int `gorm:"default:0"`
}
type Case struct {
Common

View File

@ -39,17 +39,19 @@ func (s Plan) List(m *ice.Message, arg ...string) {
button = append(button, s.Process, s.Modify, s.Remove)
}
case PlanProcess:
if isLeader && m.Option(model.MARKET_UID) == "" {
// button = append(button, s.MarketInsert)
}
if isWorker {
if kit.Int(value[model.ISSUE_COUNT]) == 0 {
button = append(button, s.IssueCreate)
}
}
if isLeader {
if isLeader && kit.Int(value[model.ISSUE_COUNT]) > 0 {
button = append(button, s.Finish)
// button = append(button, s.Remove)
}
if isLeader && m.Option(model.MARKET_UID) == "" {
button = append(button, s.MarketInsert)
}
if isLeader && kit.Int(value[model.ISSUE_COUNT]) == 0 {
button = append(button, s.Remove)
}
case PlanFinish:
if isLeader && m.Option(model.MARKET_UID) == "" {
@ -80,7 +82,6 @@ func (s Plan) Finish(m *ice.Message, arg ...string) {
s.changeStatus(m, PlanProcess, PlanFinish)
}
func (s Plan) IssueCreate(m *ice.Message, arg ...string) { s.commonOtherCreate(m, Issue{}, arg...) }
func (s Plan) IssueList(m *ice.Message, arg ...string) { s.OtherList(m, Issue{}).Display("issue.js") }
func init() { ice.TeamCtxCmd(Plan{}) }

View File

@ -2,29 +2,28 @@
"portal": "产品迭代", "member": "项目成员",
"plan": "迭代计划", "issue": "产品需求", "design": "界面设计", "task": "开发任务", "case": "测试用例",
"meet": "会议记录", "deal": "支付记录",
"process": "开始", "submit": "提交", "reback": "返工", "finish": "完成", "discuss": "约会", "payfor": "支付",
"issueCreate": "设计原型", "designCreate": "美化界面", "taskCreate": "开发任务", "caseCreate": "测试用例",
"issueList": "设计原型", "designList": "美化界面", "taskList": "开发任务", "caseList": "测试用例",
"dealList": "支付记录",
"meetList": "会议记录",
"program": "编程",
"discuss": "约会", "payfor": "支付", "program": "编程",
"process": "开始", "submit": "提交", "reback": "返工", "finish": "完成",
"issueCreate": "原型设计", "designCreate": "界面设计", "taskCreate": "开发任务", "caseCreate": "测试用例",
"issueList": "原型设计", "designList": "界面设计", "taskList": "开发任务", "caseList": "测试用例",
"meetList": "会议记录", "dealList": "支付记录",
"style": {
"discuss": "notice",
"payfor": "notice",
"program": "notice",
"preview": "notice",
"process": "notice",
"submit": "notice",
"reback": "danger",
"finish": "notice",
"payfor": "notice",
"discuss": "notice",
"issueCreate": "notice",
"designCreate": "notice",
"taskCreate": "notice",
"caseCreate": "notice"
},
"icons": {
"meet": "issue.png",
"deal": "issue.png",
"meet": "meet.png",
"deal": "deal.png",
"plan": "plan.png",
"issue": "issue.png",
"design": "design.png",
@ -32,7 +31,6 @@
"case": "case.png"
},
"input": {
"date": "日期",
"My Story": "我的产品",
"user_story_role": "用户角色",
"story_uid": "产品迭代",
@ -48,15 +46,16 @@
"design_status": "设计状态",
"design_count": "设计数量",
"task_uid": "开发任务",
"meet_type": "会议类型",
"from_user_uid": "付款人",
"to_user_uid": "收款人",
"task_status": "任务状态",
"task_count": "任务数量",
"case_status": "用例状态",
"case_count": "用例数量",
"meet_type": "会议类型",
"from_user_uid": "付款人",
"to_user_uid": "收款人",
"process_time": "开始时间",
"finish_time": "完成时间",
"date": "日期",
"comment": "备注",
"level": "优先级"
},

View File

@ -1,6 +0,0 @@
chapter "产品迭代"
section "迭代计划"
section "产品需求"
section "界面设计"
section "开发任务"
section "测试用例"

View File

@ -1,11 +1,7 @@
package production
import (
"path"
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/operation/src/production/model"
@ -14,7 +10,7 @@ import (
type Task struct {
Table
order string `data:"4"`
fields string `data:"title,content,status,case_count,space,path,begin_time,end_time,process_time,finish_time,issue_uid,plan_uid,user_uid"`
fields string `data:"title,content,status,space,path,case_count,begin_time,end_time,process_time,finish_time,issue_uid,plan_uid,user_uid"`
create string `name:"create issue_uid* title* content* space path begin_time:select@date end_time:select@date" role:"worker"`
modify string `name:"modify title* content* space path begin_time*:select@date end_time*:select@date" role:"worker"`
finish string `name:"finish" role:"worker"`
@ -38,13 +34,13 @@ func (s Task) List(m *ice.Message, arg ...string) {
s.SelectJoinPlan(m)
s.StatusCount(m, arg...)
m.Table(func(value ice.Maps) {
s.PushTaskButton(m, value, user_uid, s.Program, s.CaseCreate)
if IssueStatus(kit.Int(value[model.STATUS])) == IssueFinish {
s.PushTaskButton(m, value, user_uid, s.Program)
} else {
s.PushTaskButton(m, value, user_uid, s.Program, s.CaseCreate)
}
}).RenameAppend(model.STATUS, model.TASK_STATUS).Display("").Option("otherList", "caseList")
}
func (s Task) 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 Task) Process(m *ice.Message, arg ...string) {
s.changeStatus(m, IssueCreate, IssueProcess)
}