diff --git a/src/template/web.code.js/demo.js b/src/template/web.code.js/demo.js index 308755b..731a375 100644 --- a/src/template/web.code.js/demo.js +++ b/src/template/web.code.js/demo.js @@ -1,8 +1,7 @@ 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)]}, - {view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.user_name]}, + {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]}, ] }) }, diff --git a/src/yingxiaotuiguang/bonus.go b/src/yingxiaotuiguang/bonus.go new file mode 100644 index 0000000..423bc20 --- /dev/null +++ b/src/yingxiaotuiguang/bonus.go @@ -0,0 +1,26 @@ +package yingxiaotuiguang + +import ( + "shylinux.com/x/ice" +) + +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"` + remove string `name:"remove" role:"leader"` +} + +func (s bonus) List(m *ice.Message, arg ...string) { + if s.BonusFields(m).ValueList(m, arg); s.IsLeader(m) { + m.PushAction(s.Modify, s.Remove) + } else { + m.PushAction() + } + s.WaitLeaderCreate(m, "奖励激励") +} + +func init() { ice.TeamCtxCmd(bonus{}) } diff --git a/src/yingxiaotuiguang/bonus.js b/src/yingxiaotuiguang/bonus.js new file mode 100644 index 0000000..447393c --- /dev/null +++ b/src/yingxiaotuiguang/bonus.js @@ -0,0 +1,12 @@ +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.spaceView(can, value), + can.onimport.moneyView(can, value), "/", value.count, can.onimport.titleAction(can, value), + ]}, can.onimport.metaView(can, value), + {view: html.OUTPUT, list: [value.content||value.product_content]}, + ] }) + }, +}) \ No newline at end of file diff --git a/src/yingxiaotuiguang/bonus.png b/src/yingxiaotuiguang/bonus.png new file mode 100644 index 0000000..fd280b9 Binary files /dev/null and b/src/yingxiaotuiguang/bonus.png differ diff --git a/src/yingxiaotuiguang/channel.go b/src/yingxiaotuiguang/channel.go new file mode 100644 index 0000000..df6756d --- /dev/null +++ b/src/yingxiaotuiguang/channel.go @@ -0,0 +1,33 @@ +package yingxiaotuiguang + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/enterprise/src/yingxiaotuiguang/model" +) + +type channel struct { + Table + order string `data:"2"` + fields string `data:"icon,name,info,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"` +} + +func (s channel) List(m *ice.Message, arg ...string) { + s.ValueList(m, arg).Display("").Table(func(value ice.Maps) { + button := []ice.Any{} + defer func() { m.PushButton(button...) }() + if s.IsLeader(m) { + if button = append(button, s.Modify); kit.Int(value[model.INVITE_COUNT]) == 0 { + button = append(button, s.Remove) + } + } + }) + s.WaitLeaderCreate(m, "渠道") + s.OtherListCmd(m, s.InviteList, s.BonusList) +} + +func init() { ice.TeamCtxCmd(channel{}) } diff --git a/src/yingxiaotuiguang/channel.js b/src/yingxiaotuiguang/channel.js new file mode 100644 index 0000000..352194c --- /dev/null +++ b/src/yingxiaotuiguang/channel.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.name, can.onimport.titleAction(can, value)]}, can.onimport.metaView(can, value), + {view: html.STATUS, list: [can.onimport.unitView(can, value, "invite_count")]}, + {view: html.OUTPUT, list: [value.info]}, + ] }) + }, +}) \ No newline at end of file diff --git a/src/yingxiaotuiguang/channel.png b/src/yingxiaotuiguang/channel.png new file mode 100644 index 0000000..4a7eed9 Binary files /dev/null and b/src/yingxiaotuiguang/channel.png differ diff --git a/src/yingxiaotuiguang/common.go b/src/yingxiaotuiguang/common.go index 3a55fa6..dbe4d3f 100644 --- a/src/yingxiaotuiguang/common.go +++ b/src/yingxiaotuiguang/common.go @@ -10,7 +10,11 @@ import ( type Table struct { guanlixitong.Table - list string `name:"list promotion_uid uid auto" role:"void"` + 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"` } func (s Table) Inputs(m *ice.Message, arg ...string) { @@ -19,6 +23,10 @@ func (s Table) Inputs(m *ice.Message, arg ...string) { s.InputsListRole(m, UserPromotionRoleList, arg...) case model.PROMOTION_TYPE: s.InputsList(m, PromotionTypeList, arg...) + case model.PRODUCT_UID: + s.InputsListCmd(m, product{}) + case model.CHANNEL_UID: + s.InputsListCmd(m, channel{}) default: s.Table.Inputs(m, arg...) } @@ -35,7 +43,40 @@ func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message { }) return s.Table.RewriteAppend(m) } +func (s Table) InviteList(m *ice.Message, arg ...string) { + s.InviteFields(m).OtherList(m, invite{}) +} +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) InviteFields(m *ice.Message, arg ...string) Table { + m.Display("invite.js") + s.Tables(m, product{}, channel{}).FieldsWithCreatedAT(m, invite{}, + 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.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, + 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)) + return s +} -type Tables struct { Table } +type Tables struct{ Table } -func (s Tables) BeforeMigrate(m *ice.Message, arg ...string) {} \ No newline at end of file +func (s Tables) BeforeMigrate(m *ice.Message, arg ...string) {} diff --git a/src/yingxiaotuiguang/invite.go b/src/yingxiaotuiguang/invite.go new file mode 100644 index 0000000..ff80699 --- /dev/null +++ b/src/yingxiaotuiguang/invite.go @@ -0,0 +1,56 @@ +package yingxiaotuiguang + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/enterprise/src/yingxiaotuiguang/model" +) + +type invite struct { + Table + order string `data:"3"` + 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"` +} + +func (s invite) Create(m *ice.Message, arg ...string) { + s.Transaction(m, func() { + s.ValueCreate(m, arg...) + s.TargetAddCount(m, product{}) + s.TargetAddCount(m, channel{}) + }) +} +func (s invite) Remove(m *ice.Message, arg ...string) { + s.Transaction(m, func() { + s.ValueRemove(m, arg...) + s.TargetAddCount(m, product{}) + s.TargetAddCount(m, channel{}) + }) +} +func (s invite) List(m *ice.Message, arg ...string) { + s.InviteFields(m).ValueList(m, arg).Table(func(value ice.Maps) { + button := []ice.Any{s.Enter, s.Publish} + defer func() { m.PushButton(button...) }() + if value[model.USER_UID] == m.Option(ice.MSG_USERUID) || s.IsLeader(m) { + 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) +} +func (s invite) Enter(m *ice.Message, arg ...string) { + defer m.Cmd(stat{}, 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))) +} +func (s invite) Publish(m *ice.Message, arg ...string) { + m.ProcessField(publish{}, []string{m.Option(model.PLACE_UID), m.Option(model.UID)}, arg...) +} + +func init() { ice.TeamCtxCmd(invite{}) } diff --git a/src/yingxiaotuiguang/invite.js b/src/yingxiaotuiguang/invite.js new file mode 100644 index 0000000..91b5e95 --- /dev/null +++ b/src/yingxiaotuiguang/invite.js @@ -0,0 +1,10 @@ +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)]}, + {view: html.OUTPUT, list: [value.content||value.product_content]}, can.onimport.titleAction(can, value), + ] }) + }, +}) \ No newline at end of file diff --git a/src/yingxiaotuiguang/invite.png b/src/yingxiaotuiguang/invite.png new file mode 100644 index 0000000..13b5270 Binary files /dev/null and b/src/yingxiaotuiguang/invite.png differ diff --git a/src/yingxiaotuiguang/model/model.go b/src/yingxiaotuiguang/model/model.go index 7094c40..b4c5a8b 100644 --- a/src/yingxiaotuiguang/model/model.go +++ b/src/yingxiaotuiguang/model/model.go @@ -3,18 +3,46 @@ package model import "shylinux.com/x/mysql-story/src/db" const ( - UID = "uid" - NAME = "name" - INFO = "info" - TYPE = "type" - TITLE = "title" - CONTENT = "content" - USER_UID = "user_uid" + UID = "uid" + NAME = "name" + INFO = "info" + ICON = "icon" + TYPE = "type" + STATUS = "status" + COUNT = "count" + PRICE = "price" + LINK = "link" + TITLE = "title" + CONTENT = "content" + USER_UID = "user_uid" USER_PROMOTION_ROLE = "user_promotion_role" PROMOTION_UID = "promotion_uid" PROMOTION_NAME = "promotion_name" PROMOTION_TYPE = "promotion_type" - PRODUCT_UID = "product_uid" + PRODUCT_UID = "product_uid" + PRODUCT_ICON = "product_icon" + PRODUCT_NAME = "product_name" + PRODUCT_TITLE = "product_title" + PRODUCT_CONTENT = "product_content" + CHANNEL_UID = "channel_uid" + CHANNEL_NAME = "channel_name" + INVITE_UID = "invite_uid" + INVITE_COUNT = "invite_count" + VISITE_COUNT = "visite_count" + SERVICE_UID = "service_uid" + RECENT_UID = "recent_uid" + LOCATION = "location" + IP = "ip" + UA = "ua" + AGENT = "agent" + SYSTEM = "system" + PLACE_UID = "place_uid" + PLACE_NAME = "place_name" + PLACE_AVATAR = "place_avatar" + BEGIN_TIME = "begin_time" + END_TIME = "end_time" + SPACE = "space" + INDEX = "index" ) type UserPromotion struct { @@ -28,7 +56,48 @@ type Promotion struct { type Product struct { db.ModelContent PromotionUID string `gorm:"type:char(32);index"` + ServiceUID string `gorm:"type:char(32)"` + PlaceUID string `gorm:"type:char(32)"` + Space string `gorm:"type:varchar(128)"` + Index string `gorm:"type:varchar(128)"` + Name string `gorm:"type:varchar(32)"` + Icon string `gorm:"type:varchar(255)"` + InviteCount int `gorm:"default:0"` + BeginTime db.Time + EndTime db.Time +} +type Channel struct { + db.ModelNameInfo + PromotionUID string `gorm:"type:char(32);index"` + Icon string `gorm:"type:varchar(255)"` + InviteCount int `gorm:"default:0"` +} +type Invite struct { + db.ModelContent + PromotionUID string `gorm:"type:char(32);index"` + ProductUID string `gorm:"type:char(32);index"` + 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 { + db.ModelContent + PromotionUID string `gorm:"type:char(32);index"` + InviteUID string `gorm:"type:char(32);index"` + Location string `gorm:"type:varchar(128)"` + IP string `gorm:"type:varchar(16)"` + UA string `gorm:"type:varchar(255)"` + Agent string `gorm:"type:varchar(32)"` + System string `gorm:"type:varchar(32)"` } - -func init() { db.CmdModels("", &UserPromotion{}, &Promotion{}, &Product{}) } \ No newline at end of file +func init() { + db.CmdModels("", &UserPromotion{}, &Promotion{}, &Product{}, &Channel{}, &Invite{}, &Bonus{}, &Stat{}) +} diff --git a/src/yingxiaotuiguang/portal.json b/src/yingxiaotuiguang/portal.json index d0e8621..6580f15 100644 --- a/src/yingxiaotuiguang/portal.json +++ b/src/yingxiaotuiguang/portal.json @@ -1,14 +1,30 @@ { "portal": "营销推广", - "product": "场景应用", + "product": "产品管理", "channel": "渠道管理", "invite": "推广链接", "bonus": "奖励激励", "stat": "数据统计", + "publish": "发布邀请", + "inviteList": "推广链接", "bonusList": "奖励激励", "statList": "数据统计", "icons": { - "product": "https://img.icons8.com/officel/80/activity-grid.png" + "product": "product.png", + "channel": "channel.png", + "invite": "invite.png", + "bonus": "bonus.png", + "stat": "stat.png" }, "input": { - "My Promotion": "我的场景", + "My Promotion": "我的营销", "user_promotion_role": "成员角色", - "promotion_name": "场景名称", - "promotion_type": "场景类型" + "promotion_name": "营销名称", + "promotion_type": "营销类型", + "product_uid": "产品", + "product_icon": "产品图标", + "product_name": "产品名称", + "product_title": "产品标题", + "product_content": "产品内容", + "channel_uid": "渠道", + "channel_name": "渠道名称", + "invite_count": "邀请数量", + "visite_count": "访客数量", + "recent_uid": "产品" }, "value": { "user_promotion_role": { @@ -21,11 +37,6 @@ "creator": "danger", "leader": "danger" } - }, - "promotion_type": { - "RD": "研发群", - "OP": "运维群", - "HR": "人力群" } } } \ No newline at end of file diff --git a/src/yingxiaotuiguang/portal.png b/src/yingxiaotuiguang/portal.png new file mode 100644 index 0000000..1ab2d07 Binary files /dev/null and b/src/yingxiaotuiguang/portal.png differ diff --git a/src/yingxiaotuiguang/product.go b/src/yingxiaotuiguang/product.go index 0229015..a0eb08d 100644 --- a/src/yingxiaotuiguang/product.go +++ b/src/yingxiaotuiguang/product.go @@ -1,15 +1,44 @@ package yingxiaotuiguang -import "shylinux.com/x/ice" +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/enterprise/src/yingxiaotuiguang/model" +) type product struct { Table order string `data:"1"` - fields string `data:"title,content,user_uid"` - create string `name:"create title* content*" role:"leader"` + 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"` } -func (s product) List(m *ice.Message, arg ...string) { s.ValueList(m, arg).Display("") } +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))...) +} +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 { + button = append(button, s.Remove) + } + } + }) + s.WaitLeaderCreate(m, "产品") + s.OtherListCmd(m, s.InviteList, s.BonusList, s.StatList) +} +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))) +} -func init() { ice.TeamCtxCmd(product{}) } \ No newline at end of file +func init() { ice.TeamCtxCmd(product{}) } diff --git a/src/yingxiaotuiguang/product.js b/src/yingxiaotuiguang/product.js index 8041e96..26c41f6 100644 --- a/src/yingxiaotuiguang/product.js +++ b/src/yingxiaotuiguang/product.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.title||value.name]}, - {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.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]}, ] }) }, }) \ No newline at end of file diff --git a/src/yingxiaotuiguang/product.png b/src/yingxiaotuiguang/product.png new file mode 100644 index 0000000..4bfe5d1 Binary files /dev/null and b/src/yingxiaotuiguang/product.png differ diff --git a/src/yingxiaotuiguang/promotion.go b/src/yingxiaotuiguang/promotion.go index 4632635..204fb40 100644 --- a/src/yingxiaotuiguang/promotion.go +++ b/src/yingxiaotuiguang/promotion.go @@ -20,4 +20,4 @@ var PromotionTypeList = map[PromotionType]string{ PromotionHR: "HR", } -func (s PromotionType) String() string { return PromotionTypeList[s] } \ No newline at end of file +func (s PromotionType) String() string { return PromotionTypeList[s] } diff --git a/src/yingxiaotuiguang/publish.go b/src/yingxiaotuiguang/publish.go new file mode 100644 index 0000000..7ede023 --- /dev/null +++ b/src/yingxiaotuiguang/publish.go @@ -0,0 +1,21 @@ +package yingxiaotuiguang + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/enterprise/src/yingxiaotuiguang/model" +) + +type publish struct{ Tables } + +func (s publish) List(m *ice.Message, arg ...string) { + m.Cmdy(invite{}, arg).PushAction(s.Enter).Display("") + 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 init() { ice.TeamCtxCmd(publish{}) } diff --git a/src/yingxiaotuiguang/publish.js b/src/yingxiaotuiguang/publish.js new file mode 100644 index 0000000..8b64fa7 --- /dev/null +++ b/src/yingxiaotuiguang/publish.js @@ -0,0 +1,10 @@ +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.Select(can, can._output, html.INPUT_BUTTON, function(target) { + target.onclick = function(event) { can.runAction(can.request(event, value), target.name, []) } + }) + }, +}) \ No newline at end of file diff --git a/src/yingxiaotuiguang/stat.go b/src/yingxiaotuiguang/stat.go new file mode 100644 index 0000000..092432b --- /dev/null +++ b/src/yingxiaotuiguang/stat.go @@ -0,0 +1,33 @@ +package yingxiaotuiguang + +import ( + "shylinux.com/x/ice" + "shylinux.com/x/icebergs/base/web" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/enterprise/src/yingxiaotuiguang/model" +) + +type stat struct { + Table + order string `data:"5"` + role string `data:"leader,worker"` + 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) { + 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() { + 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() + kit.If(m.Length() == 0, func() { m.SetResult("请等待用户访问") }) +} + +func init() { ice.TeamCtxCmd(stat{}) } diff --git a/src/yingxiaotuiguang/stat.js b/src/yingxiaotuiguang/stat.js new file mode 100644 index 0000000..d2465ac --- /dev/null +++ b/src/yingxiaotuiguang/stat.js @@ -0,0 +1,10 @@ +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), + {view: html.STATUS, list: [value.agent, value.system, value.ip, value.location]}, + {view: html.OUTPUT, list: [value.ua]}, + ] }) + }, +}) \ No newline at end of file diff --git a/src/yingxiaotuiguang/stat.png b/src/yingxiaotuiguang/stat.png new file mode 100644 index 0000000..25771e9 Binary files /dev/null and b/src/yingxiaotuiguang/stat.png differ diff --git a/src/yingxiaotuiguang/userPromotion.go b/src/yingxiaotuiguang/userPromotion.go index f1726f2..62bf78d 100644 --- a/src/yingxiaotuiguang/userPromotion.go +++ b/src/yingxiaotuiguang/userPromotion.go @@ -12,4 +12,4 @@ func init() { ice.TeamCtxCmd(userPromotion{}) } type UserPromotionRole = guanlixitong.UserGroupRole -var UserPromotionRoleList = guanlixitong.UserGroupRoleList \ No newline at end of file +var UserPromotionRoleList = guanlixitong.UserGroupRoleList diff --git a/usr/local/export/web.team.yingxiaotuiguang.portal/hash.json b/usr/local/export/web.team.yingxiaotuiguang.portal/hash.json index ecd83c6..012a72c 100644 --- a/usr/local/export/web.team.yingxiaotuiguang.portal/hash.json +++ b/usr/local/export/web.team.yingxiaotuiguang.portal/hash.json @@ -1,4 +1,13 @@ { + "08bb8fc76a2241a3f2659a05a97da6ac": { + "meta": { + "icons": "src/yingxiaotuiguang/channel.png", + "index": "web.team.yingxiaotuiguang.channel", + "name": "渠道管理", + "order": "2", + "time": "2025-06-01 15:01:20.866" + } + }, "0bf2c78440fe6242369f63e19b2a5a6e": { "meta": { "icons": "bi bi-card-checklist", @@ -39,9 +48,9 @@ }, "4f06a96950d5a4e0c708cb4085f6a2cf": { "meta": { - "icons": "https://img.icons8.com/officel/80/activity-grid.png", + "icons": "src/yingxiaotuiguang/product.png", "index": "web.team.yingxiaotuiguang.product", - "name": "场景应用", + "name": "产品管理", "order": "1", "time": "2025-05-26 18:53:25.218" } @@ -95,6 +104,16 @@ "time": "2025-05-26 18:53:25.234" } }, + "7816ee4fa117f3d070a549b0d6743338": { + "meta": { + "icons": "src/yingxiaotuiguang/invite.png", + "index": "web.team.yingxiaotuiguang.invite", + "name": "推广链接", + "order": "3", + "portal": "true", + "time": "2025-06-01 16:12:38.809" + } + }, "80bb1d681ca253c02b4a3540d0989056": { "meta": { "icons": "/p/src/gonganxitong/member.png?pod=20240724-community", @@ -169,6 +188,16 @@ "time": "2025-05-26 18:53:25.226" } }, + "a8695f4e8b1d0424e122fafd652a4070": { + "meta": { + "icons": "src/yingxiaotuiguang/stat.png", + "index": "web.team.yingxiaotuiguang.stat", + "name": "数据统计", + "order": "5", + "role": "worker", + "time": "2025-06-01 16:37:52.991" + } + }, "ab5274a2914805c93d8e3cd98763815a": { "meta": { "icons": "/p/src/gonganxitong/credit.png?pod=20240724-community", @@ -178,6 +207,16 @@ "time": "2025-05-26 18:53:25.235" } }, + "ca19d176c2ce004af2279129281e79a2": { + "meta": { + "icons": "src/yingxiaotuiguang/bonus.png", + "index": "web.team.yingxiaotuiguang.bonus", + "name": "奖励激励", + "order": "4", + "role": "worker", + "time": "2025-06-01 15:43:44.408" + } + }, "e48240c89af0f68522a33e2b19de84d6": { "meta": { "icons": "bi bi-ubuntu",