diff --git a/src/yingxiaotuiguang/bonus.go b/src/yingxiaotuiguang/bonus.go index 423bc20..59cc1bb 100644 --- a/src/yingxiaotuiguang/bonus.go +++ b/src/yingxiaotuiguang/bonus.go @@ -7,10 +7,9 @@ import ( type bonus struct { Table order string `data:"4"` - role string `data:"leader,worker"` - fields string `data:"product_uid,channel_uid,count,price,user_uid"` - create string `name:"create product_uid*:select channel_uid*:select count* price*" role:"leader"` - modify string `name:"modify count* price*" role:"leader"` + fields string `data:"product_uid,channel_uid,title,content,count,price,user_uid"` + create string `name:"create product_uid*:select channel_uid*:select title content price*=100 count*=10 total*=100" role:"leader"` + modify string `name:"modify title content price* count* total*" role:"leader"` remove string `name:"remove" role:"leader"` } @@ -21,6 +20,7 @@ func (s bonus) List(m *ice.Message, arg ...string) { m.PushAction() } s.WaitLeaderCreate(m, "奖励激励") + s.OtherListCmd(m, s.DealList) } func init() { ice.TeamCtxCmd(bonus{}) } diff --git a/src/yingxiaotuiguang/bonus.js b/src/yingxiaotuiguang/bonus.js index 447393c..4f8502e 100644 --- a/src/yingxiaotuiguang/bonus.js +++ b/src/yingxiaotuiguang/bonus.js @@ -3,8 +3,10 @@ Volcanos(chat.ONIMPORT, { can.onimport.shareTitle(can, msg, "product_name", "product_content", "product_icon") can.onimport.myView(can, msg, function(value) { value.icons = value.product_icon; return [ {view: html.TITLE, list: [ - value.product_name, value.channel_name, can.onimport.spaceView(can, value), - can.onimport.moneyView(can, value), "/", value.count, can.onimport.titleAction(can, value), + value.title||value.product_title||value.product_name, + // value.channel_name, + can.onimport.spaceView(can, value), + can.onimport.moneyView(can, value), "/", value.count, "*", value.total, can.onimport.titleAction(can, value), ]}, can.onimport.metaView(can, value), {view: html.OUTPUT, list: [value.content||value.product_content]}, ] }) diff --git a/src/yingxiaotuiguang/channel.go b/src/yingxiaotuiguang/channel.go index df6756d..52a0148 100644 --- a/src/yingxiaotuiguang/channel.go +++ b/src/yingxiaotuiguang/channel.go @@ -10,7 +10,7 @@ import ( type channel struct { Table order string `data:"2"` - fields string `data:"icon,name,info,invite_count,user_uid"` + fields string `data:"icon,name,info,invite_count AS invite_count,user_uid"` create string `name:"create name* info* icon@img" role:"leader"` modify string `name:"modify name info" role:"leader"` remove string `name:"remove" role:"leader"` @@ -27,7 +27,7 @@ func (s channel) List(m *ice.Message, arg ...string) { } }) s.WaitLeaderCreate(m, "渠道") - s.OtherListCmd(m, s.InviteList, s.BonusList) + s.OtherListCmd(m, s.InviteList, s.VisiteList, s.BonusList) } func init() { ice.TeamCtxCmd(channel{}) } diff --git a/src/yingxiaotuiguang/channel.js b/src/yingxiaotuiguang/channel.js index 352194c..97f58f3 100644 --- a/src/yingxiaotuiguang/channel.js +++ b/src/yingxiaotuiguang/channel.js @@ -1,9 +1,9 @@ Volcanos(chat.ONIMPORT, { _init: function(can, msg) { can.onimport.myView(can, msg, function(value) { return [ - {view: html.TITLE, list: [value.name, can.onimport.titleAction(can, value)]}, can.onimport.metaView(can, value), + {view: html.TITLE, list: [value.name]}, can.onimport.metaView(can, value), {view: html.STATUS, list: [can.onimport.unitView(can, value, "invite_count")]}, - {view: html.OUTPUT, list: [value.info]}, + {view: html.OUTPUT, list: [value.info]}, can.onimport.titleAction(can, value), ] }) }, }) \ No newline at end of file diff --git a/src/yingxiaotuiguang/common.go b/src/yingxiaotuiguang/common.go index dbe4d3f..9cf1c1e 100644 --- a/src/yingxiaotuiguang/common.go +++ b/src/yingxiaotuiguang/common.go @@ -1,6 +1,8 @@ package yingxiaotuiguang import ( + "strconv" + "shylinux.com/x/ice" kit "shylinux.com/x/toolkits" @@ -10,11 +12,14 @@ import ( type Table struct { guanlixitong.Table - list string `name:"list promotion_uid uid auto" role:"void"` - enter string `name:"enter" help:"进入系统" style:"notice" role:"void"` - inviteList string `name:"inviteList" role:"worker"` - bonusList string `name:"bonusList" role:"worker"` - statList string `name:"statList" role:"worker"` + list string `name:"list promotion_uid uid auto" role:"void"` + enter string `name:"enter" help:"进入系统" style:"notice" role:"void"` + documentList string `name:"documentList" role:"worker"` + feedbackList string `name:"feedbackList" role:"worker"` + inviteList string `name:"inviteList" role:"worker"` + visiteList string `name:"visiteList" role:"worker"` + bonusList string `name:"bonusList" role:"worker"` + dealList string `name:"dealList" role:"worker"` } func (s Table) Inputs(m *ice.Message, arg ...string) { @@ -27,12 +32,24 @@ func (s Table) Inputs(m *ice.Message, arg ...string) { s.InputsListCmd(m, product{}) case model.CHANNEL_UID: s.InputsListCmd(m, channel{}) + case model.BONUS_UID: + s.BonusFields(m) + m.Cmdy(bonus{}, s.Select, + s.Key(bonus{}, model.PROMOTION_UID), m.Option(model.PROMOTION_UID), + s.Key(bonus{}, model.PRODUCT_UID), m.Option(model.PRODUCT_UID), + s.Key(bonus{}, model.CHANNEL_UID), m.Option(model.CHANNEL_UID)) + m.Option("_input_args", model.UID, model.PRICE, model.PRODUCT_ICON) + m.Display("bonus.js") + s.RewriteAppend(m) 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_PROMOTION_ROLE: value = UserPromotionRole(kit.Int(value)).String() @@ -43,37 +60,105 @@ func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message { }) return s.Table.RewriteAppend(m) } +func (s Deal) InviteList(m *ice.Message, arg ...string) { + s.InviteFields(m).OtherList(m, invite{}, s.Key(invite{}, model.UID), m.Option(model.INVITE_UID), s.Key(invite{}, model.PROMOTION_UID), m.Option(model.PROMOTION_UID)) +} func (s Table) InviteList(m *ice.Message, arg ...string) { - s.InviteFields(m).OtherList(m, invite{}) + if s.IsLeader(m) { + s.InviteFields(m).OtherList(m, invite{}) + } else { + s.InviteFields(m).OtherList(m, invite{}, s.Key(invite{}, model.PROMOTION_UID), m.Option(model.PROMOTION_UID), s.Key(invite{}, model.USER_UID), m.Option(model.USER_UID)) + } +} +func (s Table) VisiteList(m *ice.Message, arg ...string) { + if s.IsLeader(m) { + s.VisiteFields(m).OtherList(m, visite{}) + } else { + s.VisiteFields(m).OtherList(m, visite{}, s.Key(invite{}, model.PROMOTION_UID), m.Option(model.PROMOTION_UID), s.Key(invite{}, model.USER_UID), m.Option(model.USER_UID)) + } } func (s Table) BonusList(m *ice.Message, arg ...string) { s.BonusFields(m).OtherList(m, bonus{}) } -func (s Table) StatList(m *ice.Message, arg ...string) { - s.StatFields(m).OtherList(m, stat{}) +func (s Table) DocumentList(m *ice.Message, arg ...string) { + s.DocumentFields(m).OtherList(m, document{}) +} +func (s Table) FeedbackList(m *ice.Message, arg ...string) { + s.FeedbackFields(m).OtherList(m, feedback{}) +} +func (s product) FeedbackList(m *ice.Message, arg ...string) { + s.FeedbackFields(m).OtherList(m, feedback{}, model.PRODUCT_UID, m.Option(model.UID)) +} +func (s Table) DealList(m *ice.Message, arg ...string) { + if m.Display("deal.js"); s.IsLeader(m) { + s.OtherList(m, Deal{}) + } else { + s.OtherList(m, Deal{}, model.TO_USER_UID, m.Option(model.USER_UID)) + } + m.RenameAppend(model.TO_USER_UID, model.USER_UID) +} +func (s product) DealList(m *ice.Message, arg ...string) { + s.DealFields(m) + if m.Display("deal.js"); s.IsLeader(m) { + s.OtherList(m, Deal{}, model.PRODUCT_UID, m.Option(model.UID)) + } else { + s.OtherList(m, Deal{}, model.PRODUCT_UID, m.Option(model.UID), model.TO_USER_UID, m.Option(model.USER_UID)) + } + m.RenameAppend(model.TO_USER_UID, model.USER_UID) +} +func (s Table) DealFields(m *ice.Message, arg ...string) Table { + m.Display("invite.js") + s.Tables(m, invite{}, product{}, channel{}).FieldsWithCreatedAT(m, Deal{}, + model.PRODUCT_UID, model.CHANNEL_UID, + model.PRODUCT_ICON, model.PRODUCT_NAME, model.PRODUCT_TITLE, model.PRODUCT_CONTENT, + s.Key(Deal{}, model.TO_USER_UID), + s.Key(Deal{}, model.TITLE), s.Key(Deal{}, model.CONTENT), s.Key(Deal{}, model.PRICE)) + return s } func (s Table) InviteFields(m *ice.Message, arg ...string) Table { m.Display("invite.js") s.Tables(m, product{}, channel{}).FieldsWithCreatedAT(m, invite{}, + model.PRODUCT_UID, model.CHANNEL_UID, model.PRODUCT_ICON, model.PRODUCT_NAME, model.PRODUCT_TITLE, model.PRODUCT_CONTENT, s.Key(invite{}, model.TITLE), s.Key(invite{}, model.CONTENT), - model.VISITE_COUNT, model.BEGIN_TIME, model.END_TIME, model.CHANNEL_NAME, + s.Key(invite{}, model.VISITE_COUNT), model.BEGIN_TIME, model.END_TIME, model.CHANNEL_NAME, s.Key(invite{}, model.USER_UID)) return s } +func (s Table) VisiteFields(m *ice.Message, arg ...string) Table { + m.Display("visite.js") + s.Tables(m, invite{}, product{}, channel{}).FieldsWithCreatedAT(m, visite{}, + model.PRODUCT_UID, model.CHANNEL_UID, + model.PRODUCT_NAME, model.PRODUCT_TITLE, model.CHANNEL_NAME, + model.LOCATION, model.IP, model.UA, model.AGENT, model.SYSTEM, + s.Key(visite{}, model.USER_UID)) + return s +} func (s Table) BonusFields(m *ice.Message, arg ...string) Table { m.Display("bonus.js") s.Tables(m, product{}, channel{}).FieldsWithCreatedAT(m, bonus{}, - model.PRODUCT_ICON, model.PRODUCT_NAME, model.CHANNEL_NAME, model.COUNT, model.PRICE, + model.PRODUCT_UID, model.CHANNEL_UID, + model.PRODUCT_ICON, model.PRODUCT_NAME, model.PRODUCT_TITLE, model.CHANNEL_NAME, + s.Key(bonus{}, model.TITLE), s.Key(bonus{}, model.CONTENT), model.PRICE, model.COUNT, model.TOTAL, s.Key(bonus{}, model.USER_UID)) return s } -func (s Table) StatFields(m *ice.Message, arg ...string) Table { - m.Display("stat.js") - s.Tables(m, invite{}, product{}, channel{}).FieldsWithCreatedAT(m, stat{}, - model.PRODUCT_NAME, model.CHANNEL_NAME, - model.LOCATION, model.IP, model.UA, model.AGENT, model.SYSTEM, - s.Key(stat{}, model.USER_UID)) +func (s Table) DocumentFields(m *ice.Message, arg ...string) Table { + m.Display("document.js") + s.Tables(m, product{}).FieldsWithCreatedAT(m, document{}, + model.PRODUCT_UID, + model.PRODUCT_ICON, model.PRODUCT_NAME, model.PRODUCT_TITLE, + s.Key(document{}, model.TITLE), s.Key(document{}, model.CONTENT), s.Key(document{}, model.LINK), + s.Key(document{}, model.USER_UID)) + return s +} +func (s Table) FeedbackFields(m *ice.Message, arg ...string) Table { + m.Display("feedback.js") + s.Tables(m, invite{}, product{}, channel{}).FieldsWithCreatedAT(m, feedback{}, + model.PRODUCT_UID, model.CHANNEL_UID, + model.PRODUCT_ICON, model.PRODUCT_NAME, model.PRODUCT_TITLE, model.CHANNEL_NAME, + s.Key(feedback{}, model.TITLE), s.Key(feedback{}, model.CONTENT), + s.Key(feedback{}, model.USER_UID)) return s } diff --git a/src/yingxiaotuiguang/deal.go b/src/yingxiaotuiguang/deal.go new file mode 100644 index 0000000..37cf9eb --- /dev/null +++ b/src/yingxiaotuiguang/deal.go @@ -0,0 +1,41 @@ +package yingxiaotuiguang + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/enterprise/src/yingxiaotuiguang/model" +) + +type Deal struct { + Table + order string `data:"13"` + fields string `data:"from_user_uid,to_user_uid,price,title,content,invite_uid"` + create string `name:"create invite_uid* bonus_uid* from_user_uid* to_user_uid* price* title* content" role:"leader"` + modify string `name:"modify title* content" role:"leader"` +} + +func (s Deal) Create(m *ice.Message, arg ...string) { + s.ValueCreate(m, arg...) +} +func (s Deal) List(m *ice.Message, arg ...string) { + if s.IsLeader(m) { + s.ValueList(m, arg) + defer m.PushAction(s.Remove) + } else { + if len(arg) == 1 { + s.Select(m, model.PROMOTION_UID, arg[0], model.TO_USER_UID, m.Option(model.USER_UID)) + kit.If(m.Length() == 0, func() { m.Echo("请等待管理人员支付工钱") }) + } else { + s.SelectDetail(m, model.UID, arg[1], model.PROMOTION_UID, arg[0], model.TO_USER_UID, m.Option(model.USER_UID)) + } + } + if m.PushAction().Action().Display(""); s.IsLeader(m) { + m.RenameAppend(model.TO_USER_UID, model.USER_UID) + } else { + m.RenameAppend(model.FROM_USER_UID, model.USER_UID) + } + s.OtherListCmd(m, s.InviteList) +} + +func init() { ice.TeamCtxCmd(Deal{}) } diff --git a/src/yingxiaotuiguang/deal.js b/src/yingxiaotuiguang/deal.js new file mode 100644 index 0000000..0eeb054 --- /dev/null +++ b/src/yingxiaotuiguang/deal.js @@ -0,0 +1,9 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { + can.onimport.myView(can, msg, function(value) { return [ + {view: html.TITLE, list: [value.title, can.onimport.moneyView(can, value)]}, + {view: html.STATUS, list: [can.onimport.uidView(can, value), can.onimport.timeView(can, value), value.user_name]}, + {view: html.OUTPUT, list: [value.content]}, + ] }) + }, +}) diff --git a/src/yingxiaotuiguang/deal.png b/src/yingxiaotuiguang/deal.png new file mode 100644 index 0000000..89e0d51 Binary files /dev/null and b/src/yingxiaotuiguang/deal.png differ diff --git a/src/yingxiaotuiguang/document.go b/src/yingxiaotuiguang/document.go new file mode 100644 index 0000000..33bd9bf --- /dev/null +++ b/src/yingxiaotuiguang/document.go @@ -0,0 +1,17 @@ +package yingxiaotuiguang + +import "shylinux.com/x/ice" + +type document struct { + Table + order string `data:"11"` + fields string `data:"product_uid,title,content,link,user_uid"` + create string `name:"create product_uid*:select title content link" role:"worker"` + remove string `name:"remove" role:"worker"` +} + +func (s document) List(m *ice.Message, arg ...string) { + s.DocumentFields(m).ValueList(m, arg) +} + +func init() { ice.TeamCtxCmd(document{}) } diff --git a/src/yingxiaotuiguang/document.js b/src/yingxiaotuiguang/document.js new file mode 100644 index 0000000..731a375 --- /dev/null +++ b/src/yingxiaotuiguang/document.js @@ -0,0 +1,8 @@ +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.titleAction(can, value)]}, can.onimport.metaView(can, value), + {view: html.OUTPUT, list: [value.content||value.info]}, + ] }) + }, +}) \ No newline at end of file diff --git a/src/yingxiaotuiguang/document.png b/src/yingxiaotuiguang/document.png new file mode 100644 index 0000000..a170d45 Binary files /dev/null and b/src/yingxiaotuiguang/document.png differ diff --git a/src/yingxiaotuiguang/feedback.go b/src/yingxiaotuiguang/feedback.go new file mode 100644 index 0000000..bafc585 --- /dev/null +++ b/src/yingxiaotuiguang/feedback.go @@ -0,0 +1,17 @@ +package yingxiaotuiguang + +import "shylinux.com/x/ice" + +type feedback struct { + Table + order string `data:"12"` + fields string `data:"invite_uid,title,content,user_uid"` + create string `name:"create invite_uid*:select title* content*" role:"void"` + remove string `name:"remove" role:"void"` +} + +func (s feedback) List(m *ice.Message, arg ...string) { + s.FeedbackFields(m).ValueList(m, arg) +} + +func init() { ice.TeamCtxCmd(feedback{}) } diff --git a/src/yingxiaotuiguang/feedback.js b/src/yingxiaotuiguang/feedback.js new file mode 100644 index 0000000..b092f74 --- /dev/null +++ b/src/yingxiaotuiguang/feedback.js @@ -0,0 +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.titleAction(can, value)]}, can.onimport.metaView(can, value), + {view: html.STATUS, list: ["产品名称: ", value.product_title||value.product_name, "渠道名称: ", value.channel_name]}, + {view: html.OUTPUT, list: [value.content||value.info]}, + ] }) + }, +}) \ No newline at end of file diff --git a/src/yingxiaotuiguang/feedback.png b/src/yingxiaotuiguang/feedback.png new file mode 100644 index 0000000..dc3ec36 Binary files /dev/null and b/src/yingxiaotuiguang/feedback.png differ diff --git a/src/yingxiaotuiguang/invite.go b/src/yingxiaotuiguang/invite.go index 8d1f986..79feb48 100644 --- a/src/yingxiaotuiguang/invite.go +++ b/src/yingxiaotuiguang/invite.go @@ -10,11 +10,13 @@ import ( type invite struct { Table order string `data:"3"` + portal string `data:"true"` fields string `data:"product_uid,channel_uid,title,content,user_uid"` create string `name:"create product_uid*:select channel_uid*:select title content" role:"worker"` modify string `name:"modify title content" role:"worker"` remove string `name:"remove" role:"worker"` - publish string `name:"publish" help:"发布邀请" style:"notice" role:"void"` + publish string `name:"publish" help:"发布邀请" style:"notice" role:"worker"` + payfor string `name:"payfor bonus_uid* title* content" help:"支付" style:"notice" role:"leader"` } func (s invite) Create(m *ice.Message, arg ...string) { @@ -32,20 +34,40 @@ func (s invite) Remove(m *ice.Message, arg ...string) { }) } func (s invite) List(m *ice.Message, arg ...string) { - s.InviteFields(m).ValueList(m, arg).Table(func(value ice.Maps) { + if len(arg) == 1 && !s.IsWorker(m) { + s.ApplyCheck(m, arg...) + return + } + if s.InviteFields(m); s.IsLeader(m) { + s.Orders(m, s.Desc(model.VISITE_COUNT)) + s.ValueList(m, arg) + } else { + if len(arg) == 1 { + s.Select(m, s.Key(s, model.PROMOTION_UID), arg[0], s.Key(s, model.USER_UID), m.Option(model.USER_UID)) + if s.IsWorker(m) && m.Length() == 0 { + m.EchoInfoButton("") + } + } else { + s.SelectDetail(m, s.Key(s, model.UID), arg[1], s.Key(s, model.PROMOTION_UID), arg[0]) + } + } + m.Table(func(value ice.Maps) { button := []ice.Any{s.Enter, s.Publish} defer func() { m.PushButton(button...) }() + if s.IsCreator(m) { + button = append(button, s.Payfor) + } if value[model.USER_UID] == m.Option(ice.MSG_USERUID) || s.IsLeader(m) { - if button = append(button, s.MarketInsert, s.Modify); kit.Int(value[model.VISITE_COUNT]) == 0 { + if button = append(button, s.Modify); kit.Int(value[model.VISITE_COUNT]) == 0 { button = append(button, s.Remove) } } }) s.WaitWorkerCreate(m, "推广链接") - s.OtherListCmd(m, s.StatList) + s.OtherListCmd(m, s.DealList, s.FeedbackList, s.VisiteList) } func (s invite) Enter(m *ice.Message, arg ...string) { - defer m.Cmd(stat{}, s.Create, model.INVITE_UID, m.Option(model.UID)) + defer m.Cmd(visite{}, s.Create, model.INVITE_UID, m.Option(model.UID)) msg := m.Cmd(s, s.Select, m.OptionSimple(model.UID, model.PROMOTION_UID)) m.Cmdy(product{}, m.ActionKey(), kit.Dict(model.UID, msg.Append(model.PRODUCT_UID))) } @@ -56,5 +78,11 @@ func (s invite) MarketInsert(m *ice.Message, arg ...string) { s.GetCommandUID(m, s.Prefix(m, publish{})) s.Table.MarketInsert(m, arg...) } +func (s invite) Payfor(m *ice.Message, arg ...string) { + msg := m.Cmd(bonus{}, s.Select, model.UID, m.Option(model.BONUS_UID)) + s.RewriteAppend(msg) + arg = append(arg, model.PRICE, msg.Append(model.PRICE)) + m.Cmdy(Deal{}, s.Create, model.INVITE_UID, m.Option(model.UID), m.OptionSimple(model.BONUS_UID, model.FROM_USER_UID, model.TO_USER_UID), arg) +} func init() { ice.TeamCtxCmd(invite{}) } diff --git a/src/yingxiaotuiguang/invite.js b/src/yingxiaotuiguang/invite.js index 91b5e95..821b3fd 100644 --- a/src/yingxiaotuiguang/invite.js +++ b/src/yingxiaotuiguang/invite.js @@ -1,9 +1,9 @@ Volcanos(chat.ONIMPORT, { _init: function(can, msg) { - can.onimport.shareTitle(can, msg, "product_name", "product_content", "product_icon") - can.onimport.myView(can, msg, function(value) { value.icons = value.product_icon; return [ - {view: html.TITLE, list: [value.product_name, value.channel_name]}, can.onimport.metaView(can, value), - {view: html.STATUS, list: [can.onimport.unitView(can, value, "visite_count"), "推广期:", can.onimport.beginTime(can, value)]}, + can.onimport.shareTitle(can, msg, msg.Append("product_title")? "product_tile": "product_name", "product_content", "product_icon") + can.onimport.myView(can, msg, function(value) { return [ + {view: html.TITLE, list: [value.title||value.product_title||value.product_name]}, can.onimport.metaView(can, value), + {view: html.STATUS, list: [can.onimport.unitView(can, value, "product_name"), value.channel_name, can.onimport.unitView(can, value, "visite_count")]}, {view: html.OUTPUT, list: [value.content||value.product_content]}, can.onimport.titleAction(can, value), ] }) }, diff --git a/src/yingxiaotuiguang/model/model.go b/src/yingxiaotuiguang/model/model.go index b4c5a8b..5033d00 100644 --- a/src/yingxiaotuiguang/model/model.go +++ b/src/yingxiaotuiguang/model/model.go @@ -43,6 +43,13 @@ const ( END_TIME = "end_time" SPACE = "space" INDEX = "index" + SCORE = "score" + TOTAL = "total" + UPDATED_AT = "updated_at" + NODENAME = "nodename" + FROM_USER_UID = "from_user_uid" + TO_USER_UID = "to_user_uid" + BONUS_UID = "bonus_uid" ) type UserPromotion struct { @@ -79,15 +86,7 @@ type Invite struct { ChannelUID string `gorm:"type:char(32);index"` VisiteCount int `gorm:"default:0"` } -type Bonus struct { - db.ModelContent - PromotionUID string `gorm:"type:char(32);index"` - ProductUID string `gorm:"type:char(32);index"` - ChannelUID string `gorm:"type:char(32);index"` - Count int `gorm:"default:0"` - Price int `gorm:"default:0"` -} -type Stat struct { +type Visite struct { db.ModelContent PromotionUID string `gorm:"type:char(32);index"` InviteUID string `gorm:"type:char(32);index"` @@ -97,7 +96,38 @@ type Stat struct { Agent string `gorm:"type:varchar(32)"` System string `gorm:"type:varchar(32)"` } +type Bonus struct { + db.ModelContent + PromotionUID string `gorm:"type:char(32);index"` + ProductUID string `gorm:"type:char(32);index"` + ChannelUID string `gorm:"type:char(32);index"` + Price int `gorm:"default:0"` + Count int `gorm:"default:0"` + Total int `gorm:"default:0"` + DealCount int `gorm:"default:0"` +} +type Deal struct { + db.ModelContent + CompanyUID string `gorm:"type:char(32);index"` + PromotionUID string `gorm:"type:char(32);index"` + InviteUID string `gorm:"type:char(32);index"` + BonusUID string `gorm:"type:char(32);index"` + FromUserUID string `gorm:"type:char(32);index"` + ToUserUID string `gorm:"type:char(32);index"` + Price int `gorm:"default:0"` +} +type Document struct { + db.ModelContent + PromotionUID string `gorm:"type:char(32);index"` + ProductUID string `gorm:"type:char(32);index"` + Link string `gorm:"type:varchar(255)"` +} +type Feedback struct { + db.ModelContent + PromotionUID string `gorm:"type:char(32);index"` + InviteUID string `gorm:"type:char(32);index"` +} func init() { - db.CmdModels("", &UserPromotion{}, &Promotion{}, &Product{}, &Channel{}, &Invite{}, &Bonus{}, &Stat{}) + db.CmdModels("", &UserPromotion{}, &Promotion{}, &Product{}, &Channel{}, &Invite{}, &Visite{}, &Bonus{}, &Deal{}, &Feedback{}, &Document{}) } diff --git a/src/yingxiaotuiguang/portal.json b/src/yingxiaotuiguang/portal.json index 39a2a60..b7c1916 100644 --- a/src/yingxiaotuiguang/portal.json +++ b/src/yingxiaotuiguang/portal.json @@ -1,15 +1,20 @@ { "portal": "营销推广", - "product": "产品管理", "channel": "渠道管理", "invite": "推广链接", "bonus": "奖励激励", "stat": "数据统计", + "product": "产品管理", "channel": "渠道管理", "invite": "推广链接", "visite": "访问记录", "bonus": "奖励激励", "deal": "支付记录", + "inviteList": "推广链接", "visiteList": "访问记录", "bonusList": "奖励激励", "dealList": "支付记录", "publish": "发布邀请", - "inviteList": "推广链接", "bonusList": "奖励激励", "statList": "数据统计", + "document": "文档教程", "feedback": "体验反馈", + "documentList": "文档教程", "feedbackList": "体验反馈", "icons": { "product": "product.png", "channel": "channel.png", "invite": "invite.png", "publish": "invite.png", + "visite": "visite.png", "bonus": "bonus.png", - "stat": "stat.png" + "document": "document.png", + "feedback": "feedback.png", + "deal": "deal.png" }, "input": { "My Promotion": "我的营销", diff --git a/src/yingxiaotuiguang/product.go b/src/yingxiaotuiguang/product.go index a0eb08d..d717d7e 100644 --- a/src/yingxiaotuiguang/product.go +++ b/src/yingxiaotuiguang/product.go @@ -4,41 +4,70 @@ import ( "shylinux.com/x/ice" kit "shylinux.com/x/toolkits" + "shylinux.com/x/community/src/gonganxitong" "shylinux.com/x/enterprise/src/yingxiaotuiguang/model" ) type product struct { Table - order string `data:"1"` - fields string `data:"icon,name,title,content,invite_count,begin_time,end_time,user_uid"` - create string `name:"create recent_uid*:select title content begin_time:select@date end_time:select@date" role:"leader"` - modify string `name:"modify title content" role:"leader"` - remove string `name:"remove" role:"leader"` + order string `data:"1"` + fields string `data:"icon,name,title,content,invite_count AS invite_count,begin_time,end_time,user_uid"` + create string `name:"create service_uid*:select place_uid:select title content begin_time:select@date end_time:select@date" role:"leader"` + modify string `name:"modify title content" role:"leader"` + remove string `name:"remove" role:"leader"` + document string `name:"document title content link" role:"leader"` } +func (s product) Inputs(m *ice.Message, arg ...string) { + switch arg[0] { + case model.SERVICE_UID: + m.Cmdy(s.PrefixService(m), s.Select, model.STATUS, gonganxitong.ServiceOnline) + m.Cut(model.UID, model.NAME, model.ICON).RenameAppend(model.UID, arg[0]) + m.DisplayInputKeyNameIconTitle() + case model.PLACE_UID: + s.Orders(m, s.Desc(model.SCORE), s.Desc(model.UPDATED_AT)) + m.Cmdy(s.PrefixRecent(m), s.Select, m.OptionSimple(model.SERVICE_UID, model.USER_UID)) + m.Cut(model.PLACE_UID, model.PLACE_NAME, model.PLACE_AVATAR).RenameAppend(model.PLACE_NAME, model.NAME, model.PLACE_AVATAR, model.ICON) + m.DisplayInputKeyNameIconTitle() + default: + s.Table.Inputs(m, arg...) + } +} func (s product) Create(m *ice.Message, arg ...string) { - m.OptionDefault(model.BEGIN_TIME, m.Time(), model.END_TIME, m.Time("720h")) - msg := m.Cmd(s.PrefixRecent(m), m.Option(model.PLACE_UID), m.Option(model.RECENT_UID)) - s.ValueCreate(m, kit.Simple(msg.AppendSimple(model.SERVICE_UID, model.PLACE_UID, model.SPACE, model.INDEX), - model.ICON, msg.Append(model.PLACE_AVATAR), model.NAME, msg.Append(model.PLACE_NAME), - m.OptionSimple(model.TITLE, model.CONTENT, model.BEGIN_TIME, model.END_TIME))...) + m.Options(arg).OptionDefault(model.BEGIN_TIME, m.Time(), model.END_TIME, m.Time("720h")) + if m.Option(model.PLACE_UID) == "" { + msg := m.Cmd(s.PrefixService(m), s.Select, model.UID, m.Option(model.SERVICE_UID)).RenameAppend(model.NODENAME, model.SPACE) + s.ValueCreate(m, kit.Simple(msg.AppendSimple(model.SERVICE_UID, model.SPACE, model.INDEX, model.NAME, model.ICON), + m.OptionSimple(model.TITLE, model.CONTENT, model.BEGIN_TIME, model.END_TIME))...) + } else { + msg := m.Cmd(s.PrefixRecent(m), s.Select, m.OptionSimple(model.PLACE_UID, model.SERVICE_UID, model.USER_UID)) + s.SelectJoinService(msg) + s.ValueCreate(m, kit.Simple(msg.AppendSimple(model.SERVICE_UID, model.PLACE_UID, model.SPACE, model.INDEX), + model.ICON, msg.Append(model.PLACE_AVATAR), model.NAME, msg.Append(model.PLACE_NAME), + m.OptionSimple(model.TITLE, model.CONTENT, model.BEGIN_TIME, model.END_TIME))...) + } } func (s product) List(m *ice.Message, arg ...string) { s.ValueList(m, arg).Display("").Table(func(value ice.Maps) { button := []ice.Any{s.Enter} defer func() { m.PushButton(button...) }() if s.IsLeader(m) { - if button = append(button, s.Modify); kit.Int(value[model.INVITE_COUNT]) == 0 { + if button = append(button, s.Document, s.Modify); kit.Int(value[model.INVITE_COUNT]) == 0 { button = append(button, s.Remove) } } }) s.WaitLeaderCreate(m, "产品") - s.OtherListCmd(m, s.InviteList, s.BonusList, s.StatList) + s.OtherListCmd(m, s.DocumentList, s.FeedbackList, s.BonusList, s.DealList, s.InviteList, s.VisiteList) } func (s product) Enter(m *ice.Message, arg ...string) { s.Fields(m, model.SPACE, model.INDEX, model.PLACE_UID).Select(m, m.OptionSimple(model.UID, model.PROMOTION_UID)...) - m.ProcessOpen(s.SpaceLink(m, m.Append(model.SPACE), m.Append(model.INDEX), m.Append(model.PLACE_UID))) + if m.Append(model.INDEX) != "" { + m.ProcessOpen(s.SpaceLink(m, m.Append(model.SPACE), m.Append(model.INDEX), m.Append(model.PLACE_UID))) + } +} +func (s product) Document(m *ice.Message, arg ...string) { + m.Cmdy(document{}, s.Create, model.PRODUCT_UID, m.Option(model.UID), arg) } func init() { ice.TeamCtxCmd(product{}) } diff --git a/src/yingxiaotuiguang/product.js b/src/yingxiaotuiguang/product.js index 55c50d4..5dea422 100644 --- a/src/yingxiaotuiguang/product.js +++ b/src/yingxiaotuiguang/product.js @@ -3,8 +3,13 @@ Volcanos(chat.ONIMPORT, { can.onimport.myView(can, msg, function(value) { return [ {view: html.TITLE, list: [value.title||value.name]}, can.onimport.metaView(can, value), {view: html.STATUS, list: [can.onimport.unitView(can, value, "invite_count"), "推广期:", can.onimport.beginTime(can, value)]}, - {view: html.OUTPUT, list: [value.content]}, - can.onimport.titleAction(can, value), + {view: html.OUTPUT, list: [value.content]}, can.onimport.titleAction(can, value), ] }) }, +}) +Volcanos(chat.ONACTION, { + beforeInputs: function(event, can, button, sub) { + sub.Option("service_uid", "") + sub.Option("place_uid", "") + }, }) \ No newline at end of file diff --git a/src/yingxiaotuiguang/publish.css b/src/yingxiaotuiguang/publish.css new file mode 100644 index 0000000..287bc8a --- /dev/null +++ b/src/yingxiaotuiguang/publish.css @@ -0,0 +1,3 @@ +$output div.info.action { + display:flex; flex-direction:column; align-items:center; row-gap:10px; +} \ No newline at end of file diff --git a/src/yingxiaotuiguang/publish.go b/src/yingxiaotuiguang/publish.go index 7ede023..02f3f86 100644 --- a/src/yingxiaotuiguang/publish.go +++ b/src/yingxiaotuiguang/publish.go @@ -7,15 +7,21 @@ import ( "shylinux.com/x/enterprise/src/yingxiaotuiguang/model" ) -type publish struct{ Tables } +type publish struct { + Tables + feedback string `name:"feedback title content" help:"体验反馈" role:"void"` +} func (s publish) List(m *ice.Message, arg ...string) { - m.Cmdy(invite{}, arg).PushAction(s.Enter).Display("") + m.Cmdy(invite{}, arg).PushAction(s.Enter, s.Feedback).Display("").DisplayCSS("") s.EchoQRCodeIcon(m, s.Link(m, arg[0], m.PrefixKey(), arg[1]), m.Append(model.PRODUCT_ICON), kit.Select(m.Append(model.PRODUCT_NAME), m.Append(model.PRODUCT_TITLE), m.Append(model.TITLE))) } func (s publish) Enter(m *ice.Message, arg ...string) { m.Cmdy(invite{}, m.ActionKey(), arg) } +func (s publish) Feedback(m *ice.Message, arg ...string) { + m.Cmd(feedback{}, s.Create, model.INVITE_UID, m.Option(model.UID), arg) +} func init() { ice.TeamCtxCmd(publish{}) } diff --git a/src/yingxiaotuiguang/publish.js b/src/yingxiaotuiguang/publish.js index 8b64fa7..c5fada4 100644 --- a/src/yingxiaotuiguang/publish.js +++ b/src/yingxiaotuiguang/publish.js @@ -2,9 +2,11 @@ Volcanos(chat.ONIMPORT, { _init: function(can, msg) { var value = msg.TableDetail(); can.onappend.board(can, msg) can.page.Append(can, can._output, [{view: "info", inner: value.content||value.product_content}]) can.page.Append(can, can._output, [{view: "info", list: [{text: "推广期: "}, {text: can.onimport.beginTime(can, value)}]}]) - can.page.Append(can, can._output, [{view: "info", inner: value.action}]) + can.page.Append(can, can._output, [{view: "info action", inner: value.action}]) can.page.Select(can, can._output, html.INPUT_BUTTON, function(target) { - target.onclick = function(event) { can.runAction(can.request(event, value), target.name, []) } + target.onclick = function(event) { + can.run(can.request(event, value), [ctx.ACTION, target.name]) + } }) }, }) \ No newline at end of file diff --git a/src/yingxiaotuiguang/stat.go b/src/yingxiaotuiguang/visite.go similarity index 50% rename from src/yingxiaotuiguang/stat.go rename to src/yingxiaotuiguang/visite.go index 092432b..ee3a72a 100644 --- a/src/yingxiaotuiguang/stat.go +++ b/src/yingxiaotuiguang/visite.go @@ -8,26 +8,38 @@ import ( "shylinux.com/x/enterprise/src/yingxiaotuiguang/model" ) -type stat struct { +type visite struct { Table - order string `data:"5"` - role string `data:"leader,worker"` + order string `data:"4"` fields string `data:"invite_uid,user_uid"` create string `name:"create invite_uid*" role:"leader"` remove string `name:"remove" role:"leader"` } -func (s stat) Create(m *ice.Message, arg ...string) { +func (s visite) Create(m *ice.Message, arg ...string) { arg = append(arg, m.Options(web.ParseUA(m.Message)).OptionSimple(model.IP, model.UA, model.AGENT, model.SYSTEM)...) arg = append(arg, model.LOCATION, kit.Format(web.PublicIP(m.Message, m.Option(ice.MSG_USERIP)))) s.Transaction(m, func() { + if s.Select(m.Spawn(), m.OptionSimple(model.USER_UID, model.PROMOTION_UID)...).Length() > 0 { + return + } s.ValueCreate(m, arg...) s.TargetAddCount(m, invite{}, model.VISITE_COUNT) }) } -func (s stat) List(m *ice.Message, arg ...string) { - s.StatFields(m).ValueList(m, arg).PushAction().Action() +func (s visite) List(m *ice.Message, arg ...string) { + s.Limit(m, 3000) + if s.VisiteFields(m); s.IsLeader(m) { + s.ValueList(m, arg) + } else { + if len(arg) == 1 { + s.Select(m, s.Key(s, model.PROMOTION_UID), arg[0], s.Key(invite{}, model.USER_UID), m.Option(model.USER_UID)) + } else { + s.SelectDetail(m, s.Key(s, model.UID), arg[1], s.Key(s, model.PROMOTION_UID), arg[0], s.Key(invite{}, model.USER_UID), m.Option(model.USER_UID)) + } + } + m.PushAction().Action() kit.If(m.Length() == 0, func() { m.SetResult("请等待用户访问") }) } -func init() { ice.TeamCtxCmd(stat{}) } +func init() { ice.TeamCtxCmd(visite{}) } diff --git a/src/yingxiaotuiguang/stat.js b/src/yingxiaotuiguang/visite.js similarity index 54% rename from src/yingxiaotuiguang/stat.js rename to src/yingxiaotuiguang/visite.js index d2465ac..5191628 100644 --- a/src/yingxiaotuiguang/stat.js +++ b/src/yingxiaotuiguang/visite.js @@ -1,8 +1,8 @@ Volcanos(chat.ONIMPORT, { _init: function(can, msg) { can.onimport.shareTitle(can, msg, "product_name", "product_content", "product_icon") - can.onimport.myView(can, msg, function(value) { return [ - {view: html.TITLE, list: [value.product_name, value.channel_name, can.onimport.titleAction(can, value)]}, can.onimport.metaView(can, value), + can.onimport.myViewTabs(can, "system", msg, function(value) { return [ + {view: html.TITLE, list: [value.product_title||value.product_name, value.channel_name, can.onimport.titleAction(can, value)]}, can.onimport.metaView(can, value), {view: html.STATUS, list: [value.agent, value.system, value.ip, value.location]}, {view: html.OUTPUT, list: [value.ua]}, ] }) diff --git a/src/yingxiaotuiguang/stat.png b/src/yingxiaotuiguang/visite.png similarity index 100% rename from src/yingxiaotuiguang/stat.png rename to src/yingxiaotuiguang/visite.png diff --git a/usr/local/export/web.team.gonganxitong.portal/hash.json b/usr/local/export/web.team.gonganxitong.portal/hash.json index 39e8b9c..d0ad6a5 100644 --- a/usr/local/export/web.team.gonganxitong.portal/hash.json +++ b/usr/local/export/web.team.gonganxitong.portal/hash.json @@ -8,6 +8,16 @@ "time": "2025-06-04 14:06:42.767" } }, + "1cfd36a7b8906ba77781b4f85d0a6190": { + "meta": { + "icons": "bi bi-people", + "index": "web.team.gonganxitong.sess", + "name": "会话管理", + "order": "605", + "role": "tech", + "time": "2025-06-16 08:06:41.996" + } + }, "27c6988eeb07c78cbb49aa15c577cfa4": { "meta": { "icons": "bi bi-pencil-square", @@ -56,6 +66,26 @@ "time": "2025-06-04 14:06:42.769" } }, + "b07b1f652f5b2557c0b20e813fcf99d2": { + "meta": { + "icons": "bi bi-buildings", + "index": "web.team.gonganxitong.street", + "name": "街道管理", + "order": "601", + "role": "tech", + "time": "2025-06-16 08:06:42.011" + } + }, + "ba00879066bbcea83e30cda292d28a91": { + "meta": { + "icons": "bi bi-people", + "index": "web.team.gonganxitong.user", + "name": "用户管理", + "order": "604", + "role": "tech", + "time": "2025-06-16 08:06:42.001" + } + }, "bdec92d5849b2a60a8811cff494f2391": { "meta": { "icons": "bi bi-calendar4-week", @@ -85,11 +115,21 @@ "time": "2025-06-04 14:06:42.765" } }, + "d8443c1034bfe5917c52126a3306c328": { + "meta": { + "icons": "bi bi-buildings", + "index": "web.team.gonganxitong.city", + "name": "城市管理", + "order": "602", + "role": "tech", + "time": "2025-06-16 08:06:42.000" + } + }, "d86e4e63183c8fae4ceb50498b0bcfde": { "meta": { "icons": "bi bi-grid-3x2-gap", "index": "web.team.gonganxitong.domain", - "name": "领域分类", + "name": "领域管理", "order": "508", "role": "tech", "time": "2025-06-04 14:06:42.766" diff --git a/usr/local/export/web.team.yingxiaotuiguang.portal/hash.json b/usr/local/export/web.team.yingxiaotuiguang.portal/hash.json index 654d5e8..9578b52 100644 --- a/usr/local/export/web.team.yingxiaotuiguang.portal/hash.json +++ b/usr/local/export/web.team.yingxiaotuiguang.portal/hash.json @@ -8,6 +8,15 @@ "time": "2025-06-04 14:06:42.247" } }, + "0a864d87da6a4a4547dc50fa06849fad": { + "meta": { + "icons": "src/yingxiaotuiguang/feedback.png", + "index": "web.team.yingxiaotuiguang.feedback", + "name": "体验反馈", + "order": "12", + "time": "2025-06-16 08:09:11.031" + } + }, "0bf2c78440fe6242369f63e19b2a5a6e": { "meta": { "icons": "bi bi-card-checklist", @@ -93,12 +102,23 @@ "time": "2025-06-04 14:06:42.254" } }, + "67a9d7f5a02349f08deb34ea88574f40": { + "meta": { + "icons": "src/yingxiaotuiguang/deal.png", + "index": "web.team.yingxiaotuiguang.deal", + "name": "支付记录", + "order": "13", + "role": "leader,worker", + "time": "2025-06-15 11:06:33.207" + } + }, "7816ee4fa117f3d070a549b0d6743338": { "meta": { "icons": "src/yingxiaotuiguang/invite.png", "index": "web.team.yingxiaotuiguang.invite", "name": "推广链接", "order": "3", + "portal": "true", "time": "2025-06-04 14:06:42.258" } }, @@ -122,6 +142,15 @@ "time": "2025-06-04 14:06:42.251" } }, + "a0972419cbc887652430e7d888100ad8": { + "meta": { + "icons": "src/yingxiaotuiguang/document.png", + "index": "web.team.yingxiaotuiguang.document", + "name": "文档教程", + "order": "11", + "time": "2025-06-16 08:09:11.032" + } + }, "a6c4ec094caea0612aa66f5137927877": { "meta": { "icons": "bi bi-pencil-square", @@ -142,16 +171,6 @@ "time": "2025-06-04 14:06:42.250" } }, - "a8695f4e8b1d0424e122fafd652a4070": { - "meta": { - "icons": "src/yingxiaotuiguang/stat.png", - "index": "web.team.yingxiaotuiguang.stat", - "name": "数据统计", - "order": "5", - "role": "leader,worker", - "time": "2025-06-04 14:06:42.256" - } - }, "ab5274a2914805c93d8e3cd98763815a": { "meta": { "icons": "/p/src/gonganxitong/credit.png?pod=20240724-community", @@ -161,6 +180,15 @@ "time": "2025-06-04 14:06:42.256" } }, + "b5db2d49aef7fc93f2573bc477b8e818": { + "meta": { + "icons": "src/yingxiaotuiguang/visite.png", + "index": "web.team.yingxiaotuiguang.visite", + "name": "访问记录", + "order": "4", + "time": "2025-06-14 15:25:02.976" + } + }, "c72c03674dfc11931215813632da5bce": { "meta": { "icons": "src/yingxiaotuiguang/invite.png", @@ -174,8 +202,7 @@ "icons": "src/yingxiaotuiguang/bonus.png", "index": "web.team.yingxiaotuiguang.bonus", "name": "奖励激励", - "order": "4", - "role": "leader,worker", + "order": "5", "time": "2025-06-04 14:06:42.248" } },