diff --git a/src/gonganxitong/apply.go b/src/gonganxitong/apply.go index 3493f75..8252ede 100644 --- a/src/gonganxitong/apply.go +++ b/src/gonganxitong/apply.go @@ -69,7 +69,7 @@ func (s apply) List(m *ice.Message, arg ...string) { } }) s.UserPlace.RewriteAppend(m) - s.Display(m) + s.Display(m, "") } func (s apply) Cancel(m *ice.Message, arg ...string) { msg := s.status(m, ApplyCreate, ApplyCancel) diff --git a/src/gonganxitong/common.go b/src/gonganxitong/common.go index db3fa1d..c1bbc4e 100644 --- a/src/gonganxitong/common.go +++ b/src/gonganxitong/common.go @@ -5,7 +5,8 @@ import ( "shylinux.com/x/ice" icebergs "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" @@ -15,6 +16,7 @@ import ( type Tabler interface { Inputs(m *ice.Message, arg ...string) + Select(m *ice.Message, arg ...string) *ice.Message RewriteAppend(m *ice.Message, arg ...string) *ice.Message TransValue(m *ice.Message, key string, arg ...string) string TransRole(m *ice.Message, arg ...string) string @@ -49,11 +51,21 @@ func (s Table) Inputs(m *ice.Message, arg ...string) { } } m.SortInt(arg[0]).DisplayInputKeyNameIconTitle() + case ctx.INDEX: + mdb.HashInputs(m.Message, arg) default: s.Table.Inputs(m, arg...) } } -func (s Table) List(m *ice.Message, arg ...string) { +func (s Table) List(m *ice.Message, arg ...string) *ice.Message { + if m.IsTech() { + if len(arg) == 0 { + s.Select(m) + } else if len(arg) == 2 { + s.SelectDetail(m, model.UID, arg[1]) + } + } + return m } func (s Table) TablesWithRole(m *ice.Message, arg []string, target, userPlace, place Tabler, fields ...ice.Any) *ice.Message { s.Tables(m, kit.JoinWord("LEFT JOIN", s.TableName(kit.TypeName(userPlace)), @@ -62,20 +74,38 @@ func (s Table) TablesWithRole(m *ice.Message, arg []string, target, userPlace, p )).FieldsWithCreatedAT(m, target, append([]ice.Any{s.Key(target, model.USER_UID), s.AS(s.Key(userPlace, model.ROLE), s.Keys(userPlace, model.ROLE))}, fields...)...) if len(arg) == 1 { s.Table.Select(m, s.Key(target, s.Keys(place, model.UID)), arg[0]) + m.Action(s.Create) } else if len(arg) == 2 { - s.Table.Select(m, s.Key(target, s.Keys(place, model.UID)), arg[0], s.Key(target, model.UID), arg[1]) + s.Table.SelectDetail(m, s.Key(target, s.Keys(place, model.UID)), arg[0], s.Key(target, model.UID), arg[1]) } else { return m } userPlace.RewriteAppend(m) return s.SelectJoinUser(m) } +func (s Table) Select(m *ice.Message, arg ...string) *ice.Message { + defer s.Display(m, "") + defer m.PushAction(s.Delete) + return s.Table.Select(m, arg...) +} +func (s Table) SelectDetail(m *ice.Message, arg ...string) *ice.Message { + defer s.Display(m, "") + defer m.PushAction(s.Delete) + return s.Table.SelectDetail(m, arg...) +} func (s Table) SelectJoinUser(m *ice.Message) *ice.Message { return s.SelectJoin(m, user{}, model.NAME, model.AVATAR) } func (s Table) SelectJoinCity(m *ice.Message) *ice.Message { return s.SelectJoin(m, city{}, model.NAME) } +func (s Table) ChangeStatus(m *ice.Message, uid string, from, to int, arg ...string) *ice.Message { + msg := s.Select(m.Spawn(), model.UID, uid) + if !m.WarnNotValid(kit.Int(msg.Append(mdb.STATUS)) != int(from)) { + s.Update(m, kit.Dict(mdb.STATUS, to, arg), model.UID, uid) + } + return m +} func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message { m.RewriteAppend(func(value, key string, index int) string { kit.If(key == model.PLACE_TYPE, func() { value = PlaceType(kit.Int(value)).String() }) @@ -102,25 +132,40 @@ func (s Table) TransRole(m *ice.Message, arg ...string) string { role := s.Place.TransValue(m, s.Keys(s.UserPlace, model.ROLE), arg...) return kit.Format(`%s`, value, role) } +func (s Table) RecordEvent(m *ice.Message, uid, info string, arg ...string) { + event{}.Record(m.Spawn(kit.Dict(model.PLACE_UID, uid)), info, arg...) +} func (s Table) SendTemplate(m *ice.Message, from, user_uid, title string) { if !m.IsErr() { - m.Cmd(user{}, user{}.SendTemplate, from, user_uid, Portal{}.Link(m, m.Option(s.Keys(s.Place, model.UID)), m.PrefixKey(), m.Option(model.UID)), + m.Cmd(user{}, s.SendTemplate, from, user_uid, Portal{}.Link(m, m.Option(s.Keys(s.Place, model.UID)), m.PrefixKey(), m.Option(model.UID)), title, m.Option(s.Keys(s.Place, model.NAME))+" "+s.Place.TransValue(m, s.Keys(s.UserPlace, model.ROLE)), kit.Cut(m.Option(model.UID), 6)) } } -func (s Table) Display(m *ice.Message) *ice.Message { - m.Option("_place_uid", s.ToLower(kit.TypeName(s.Place))+"_uid") - m.Option("_place_name", s.ToLower(kit.TypeName(s.Place))+"_name") - m.Option("_place_type", s.ToLower(kit.TypeName(s.Place))+"_type") - m.Option("_user_place_role", s.ToLower(kit.TypeName(s.UserPlace))+"_role") - m.Option("_street_name", s.ToLower(kit.TypeName(s.Street))+"_name") - file := "" - kit.If(file == "", func() { file = m.CommandKey() + ".js" }) - if !kit.HasPrefix(file, nfs.PS, web.HTTP) { - file = m.Resource(path.Join(path.Dir(kit.FileLine(1, 100)), file)) +func (s Table) Display(m *ice.Message, file string) *ice.Message { + if s.Place != nil { + m.Option("_place_uid", s.ToLower(kit.TypeName(s.Place))+"_uid") + m.Option("_place_name", s.ToLower(kit.TypeName(s.Place))+"_name") + m.Option("_place_type", s.ToLower(kit.TypeName(s.Place))+"_type") + m.Option("_user_place_role", s.ToLower(kit.TypeName(s.UserPlace))+"_role") } - m.Display(file) - return m + if s.Street != nil { + m.Option("_street_name", s.ToLower(kit.TypeName(s.Street))+"_name") + } + base := path.Dir(kit.FileLine(1, 100)) + sub := path.Dir(kit.FileLine(-1, 100)) + return m.Display(kit.Format(mdb.Cache(m.Message, kit.Keys(m.PrefixKey(), ctx.DISPLAY, file), func() ice.Any { + if file == "" { + file = m.Resource(path.Join(sub, m.CommandKey()+".js")) + } + if m.Template(file) == "" { + if m.CommandKey() == web.PORTAL { + file = m.Resource(path.Join(base, "portal.js")) + } else { + file = m.Resource(path.Join(base, "common.js")) + } + } + return file + }))) } type Tables struct { @@ -159,12 +204,15 @@ func PortalCmd(portal ice.Any) { cmd := func(name string, data ice.Any) { _, cmd := ice.Cmd(kit.Keys(p, name), data) cmd.RawHand = path.Join(path.Dir(h), name+".go") - h := cmd.Actions["beforeMigrate"].Hand - cmd.Actions["beforeMigrate"].Hand = func(m *icebergs.Message, arg ...string) { - ice.LoadTrans(m.Cmd("web.team.gonganxitong.apply"), cmd) - ice.LoadTrans(m, cmd) - h(m, arg...) - } + cmd.Actions[ice.CTX_INIT].Hand = icebergs.MergeHand(cmd.Actions[ice.CTX_INIT].Hand, func(m *icebergs.Message, arg ...string) { + msg := m.Cmd("web.team.gonganxitong.apply") + ice.LoadTrans(msg, m.CommandKey(), cmd) + ice.LoadTrans(m, m.CommandKey(), cmd) + kit.If(mdb.Config(m, web.PORTAL) == ice.TRUE, func() { Portal{}.Show(&ice.Message{Message: m}, m.PrefixKey()) }) + }) + cmd.Actions["afterMigrate"].Hand = icebergs.MergeHand(cmd.Actions["afterMigrate"].Hand, func(m *icebergs.Message, arg ...string) { + kit.If(mdb.Config(m, web.PORTAL) == ice.TRUE, func() { Portal{}.Show(&ice.Message{Message: m}, m.PrefixKey()) }) + }) } table := portal.(interface{ getTable() Table }).getTable() cmd("portal", portal) diff --git a/src/gonganxitong/common.js b/src/gonganxitong/common.js new file mode 100644 index 0000000..ce6e1be --- /dev/null +++ b/src/gonganxitong/common.js @@ -0,0 +1,14 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { + var PLACE_NAME = msg.Option("_place_name"), PLACE_TYPE = msg.Option("_place_type"), USER_PLACE_ROLE = msg.Option("_user_place_role") + can.onimport.itemcards(can, msg, function(value) { value._style = [value[PLACE_TYPE]||"", value[USER_PLACE_ROLE]||""] + return [ + {view: html.TITLE, list:[{text: [value.name||value.user_name]}, + value[PLACE_TYPE] && {text: [value[PLACE_TYPE]||"", "", [mdb.TYPE, value[PLACE_TYPE]||""]]}, + value[USER_PLACE_ROLE] && {text: [value[USER_PLACE_ROLE]||"", "", [aaa.ROLE, value[UESR_PLACE_ROLE]||""]]}, + ]}, + {view: html.STATUS, list: [value.uid && {text: value.uid.slice(0, 6)}, {text: can.base.TimeTrim(value.created_at||value.updated_at)}]}, + ] + }) + }, +}) \ No newline at end of file diff --git a/src/gonganxitong/event.go b/src/gonganxitong/event.go index 4fed455..43b8025 100644 --- a/src/gonganxitong/event.go +++ b/src/gonganxitong/event.go @@ -28,7 +28,7 @@ func (s event) List(m *ice.Message, arg ...string) { return } m.PushAction().Action() - s.Display(m) + s.Display(m, "") } func init() { ice.TeamCtxCmd(event{Table: newTable()}) } diff --git a/src/gonganxitong/model/model.go b/src/gonganxitong/model/model.go index a91ca27..84fc53a 100644 --- a/src/gonganxitong/model/model.go +++ b/src/gonganxitong/model/model.go @@ -80,19 +80,6 @@ type City struct { Name string `gorm:"type:char(32);index"` } -type Service struct { - db.ModelWithUID - Icon string `gorm:"type:char(32)"` - Name string `gorm:"type:char(32)"` - Index string `gorm:"type:char(32)"` - Hostname string `gorm:"type:char(32)"` - Pathname string `gorm:"type:char(255)"` - Nodename string `gorm:"type:char(32)"` - Nodetype string `gorm:"type:char(32)"` - Domain string `gorm:"type:char(255)"` - Module string `gorm:"type:char(32)"` - Version string `gorm:"type:char(32)"` -} type Event struct { db.ModelWithUID PlaceUID string `gorm:"type:char(32);index"` @@ -119,6 +106,21 @@ type Order struct { Status uint8 } +type Service struct { + db.ModelWithUID + Icon string `gorm:"type:char(32)"` + Name string `gorm:"type:char(32)"` + Index string `gorm:"type:char(32)"` + Hostname string `gorm:"type:char(32)"` + Pathname string `gorm:"type:char(255)"` + Nodename string `gorm:"type:char(32)"` + Nodetype string `gorm:"type:char(32)"` + Portal string `gorm:"type:char(255)"` + Domain string `gorm:"type:char(255)"` + Module string `gorm:"type:char(32)"` + Version string `gorm:"type:char(32)"` +} + func init() { db.CmdModels("", &Sess{}, &User{}, &UserPlace{}, &Place{}, &Street{}, &City{}, Event{}, Apply{}, Order{}, Service{}) } diff --git a/src/gonganxitong/order.go b/src/gonganxitong/order.go index a316e9b..3213ba6 100644 --- a/src/gonganxitong/order.go +++ b/src/gonganxitong/order.go @@ -66,7 +66,7 @@ func (s order) List(m *ice.Message, arg ...string) { } }).Action() s.UserPlace.RewriteAppend(m) - s.Display(m) + s.Display(m, "") } func init() { ice.TeamCtxCmd(order{Table: newTable()}) } diff --git a/src/gonganxitong/portal.css b/src/gonganxitong/portal.css index 556f886..624f85b 100644 --- a/src/gonganxitong/portal.css +++ b/src/gonganxitong/portal.css @@ -13,13 +13,21 @@ $output>div.list>div.action div.item { margin-right:5px; } $output>div.list>div.action div.item input[type=button] { color:var(--notice-bg-color); border:none; } $output>div.list>div.action div.item i { display:none; } $output>div.action div.item.button { margin-right:5px; } -$output>div.action div.item.button input { border:none; color:var(--notice-bg-color); min-width:80px; float:left; } +$output>div.action div.item.button input { border:none; color:var(--notice-bg-color); min-width:60px; float:left; } +$output>div.action div.item.button input:hover { background-color:var(--hover-bg-color); } +$output>div.action div.item.button i { display:none; } $output>div.action div.item.button span { display:none; } $output>fieldset table.content td { box-shadow:none; } -$output span.role { border:var(--box-notice); color:var(--notice-bg-color); padding:2px 5px; } +$output span.role { border:var(--box-notice); color:var(--notice-bg-color); } +$output span.role.creator { border-color:var(--box-danger); color:var(--danger-bg-color); } $output span.role.landlord { border-color:var(--box-danger); color:var(--danger-bg-color); } $output span.role.teacher { border-color:var(--box-danger); color:var(--danger-bg-color); } $output span.role.leader { border-color:var(--box-danger); color:var(--danger-bg-color); } +$output span.role.manager { border-color:var(--box-danger); color:var(--danger-bg-color); } +$output table.content.detail tr.action input.icons { display:unset; } +$output table.content.detail tr.action i { display:none; } +$output table.content td.action i { display:none; } +$output table.content td.action input.icons { display:unset; } body.en $output>fieldset table.content td:first-child { max-width:180px; width:unset;} $output>fieldset table.content tr.uid { display:none; } $output>fieldset table.content tr.order_uid { display:none; } diff --git a/src/gonganxitong/portal.go b/src/gonganxitong/portal.go index 2de7d85..d1365e4 100644 --- a/src/gonganxitong/portal.go +++ b/src/gonganxitong/portal.go @@ -20,19 +20,24 @@ type Portal struct { short string `data:"index"` field string `data:"time,name,icons,index,order,enable,type,role,view"` list string `name:"list place_uid index uid auto" role:"void"` - create string `name:"create name icons index"` + create string `name:"create index name icons"` placeCreate string `name:"placeCreate city_name* street_name* place_type*:select name* address*" icon:"bi bi-plus-square-dotted" role:"void"` placeRemove string `name:"placeRemove uid*" role:"void"` scanQRCode string `name:"scanQRCode type text" icon:"bi bi-qr-code-scan" role:"void"` setIcons string `name:"setIcons icons" icon:"bi bi-info-square"` } +func (s Portal) Init(m *ice.Message, arg ...string) { + s.Hash.Init(m, arg...) +} +func (s Portal) Exit(m *ice.Message, arg ...string) { + s.Hash.Exit(m, arg...) +} func (s Portal) BeforeMigrate(m *ice.Message, arg ...string) { } func (s Portal) AfterMigrate(m *ice.Message, arg ...string) { m.GoSleep("30ms", func() { - m.Option(ctx.INDEX, m.PrefixKey()) - m.Cmdy(s.service, s.Update, m.ConfigSimple(mdb.ICON, mdb.NAME)) + m.Cmdy(s.service, s.Update, m.ConfigSimple(mdb.NAME), mdb.ICON, kit.Select(ice.Info.NodeIcon, m.Config(mdb.ICON)), ctx.INDEX, m.PrefixKey()) }) } func (s Portal) Inputs(m *ice.Message, arg ...string) { @@ -52,7 +57,7 @@ func (s Portal) List(m *ice.Message, arg ...string) { m.EchoInfoButton(m.Trans("Please Create Your Place", "请添加场所"), s.PlaceCreate, s.ScanQRCode) }) } else if len(arg) == 2 { - msg := m.Cmd(s.Place, s.Select, model.UID, arg[0]) + msg := m.Cmd(s.Place, s.Place.Select, model.UID, arg[0]) m.Option(s.Keys(s.Place, model.NAME), msg.Append(model.NAME)) m.Cmdy(ctx.COMMAND, arg[1]).Push(ctx.ARGS, arg[0]) } else if len(arg) == 1 { @@ -60,14 +65,13 @@ func (s Portal) List(m *ice.Message, arg ...string) { } else { m.FieldsSetDetail().Cmdy(arg[1], mdb.SELECT, model.UID, arg[2]).PushAction().Action() } - s.Display(m).DisplayCSS("") + s.Display(m, "").DisplayCSS("") } func (s Portal) PlaceCreate(m *ice.Message, arg ...string) { defer m.ToastProcess()() if s.city.FindOrCreateByName(m, arg...); m.IsErr() { return - } - if s.Street.FindOrCreateByName(m, arg...); m.IsErr() { + } else if s.Street.FindOrCreateByName(m, arg...); m.IsErr() { return } arg = kit.TransArgKeys(arg, s.Keys(s.Place, model.TYPE), model.TYPE) @@ -76,6 +80,7 @@ func (s Portal) PlaceCreate(m *ice.Message, arg ...string) { } args := kit.Simple(m.OptionSimple(model.USER_UID), s.Keys(s.Place, model.UID), m.Result(), model.ROLE, UserPlaceCreator) m.Cmdy(s.UserPlace, s.Create, args).ProcessRefresh() + s.RecordEvent(m, m.Result(), kit.Format(m.Trans("create", "创建")), arg...) } func (s Portal) PlaceRemove(m *ice.Message, arg ...string) { defer m.ToastProcess()() @@ -90,7 +95,7 @@ func (s Portal) ScanQRCode(m *ice.Message, arg ...string) { } else if m.Option(mdb.TYPE) == web.LINK { args := m.ParseURL(m.Option(mdb.TEXT)) if len(args) > 1 && args[1] == m.Prefix("apply") { - args := kit.Simple(m.OptionSimple(model.USER_UID), s.Key(s.Place, model.UID), args[0]) + args := kit.Simple(m.OptionSimple(model.USER_UID), s.Keys(s.Place, model.UID), args[0]) m.Cmdy(s.UserPlace, s.Create, args, model.ROLE, UserPlaceVisitor) } } @@ -105,12 +110,15 @@ type portal struct { func init() { ice.TeamCtxCmd(portal{Portal: Portal{Table: newTable()}}) } +func (s Portal) Create(m *ice.Message, arg ...string) { + var _cmd *ice.Command + m.Search(m.Option(ctx.INDEX), func(key string, cmd *ice.Command) { _cmd = cmd }) + msg := s.Hash.Select(m.Spawn(), m.Option(ctx.INDEX)) + s.Hash.Create(m, ctx.INDEX, m.Option(ctx.INDEX), mdb.NAME, _cmd.Help, mdb.ICONS, _cmd.Icon, mdb.TIME, msg.Append(mdb.TIME)) +} func (s Portal) Show(m *ice.Message, arg ...string) { - m.GoSleep("30ms", func() { - cmd := m.GetCommand() - msg := m.Cmd(m.Prefix(web.PORTAL), s.Select, m.PrefixKey()) - m.Cmd(m.Prefix(web.PORTAL), s.Create, mdb.NAME, cmd.Help, mdb.ICONS, cmd.Icon, ctx.INDEX, m.PrefixKey(), mdb.TIME, msg.Append(mdb.TIME)) - }) + key := m.PrefixKey() + m.GoSleep("300ms", func() { m.Cmd(m.Prefix(web.PORTAL), s.Create, ctx.INDEX, key) }) } func (s Portal) Link(m *ice.Message, arg ...string) string { return m.MergePodCmd("", m.Prefix(web.PORTAL)) + "?debug=true" + diff --git a/src/gonganxitong/portal.js b/src/gonganxitong/portal.js index 8fae6c3..b905fac 100644 --- a/src/gonganxitong/portal.js +++ b/src/gonganxitong/portal.js @@ -8,7 +8,7 @@ Volcanos(chat.ONIMPORT, { return [ {view: html.TITLE, list: [{text: value._name}, {text: [value.__type, "", [mdb.TYPE, value._type]]}, - value._role != "creator" && {text: [value.__role, "", [aaa.ROLE, value._role]]}, + value._role != "visitor" && {text: [value.__role, "", [aaa.ROLE, value._role]]}, ]}, {view: html.STATUS, list: [ {text: value._uid.slice(0, 6)}, {text: value.city_name}, {text: value._street}, @@ -53,15 +53,15 @@ Volcanos(chat.ONIMPORT, { }, myIndex: function(can, msg, target, PLACE_UID) { var width = (can.ConfWidth()-40)/parseInt((can.ConfWidth()-40)/100), height = width+20; can.user.isMobile && !can.user.isLandscape() && (width = (can.ConfWidth()-40)/4, height = width+20) - can.page.Append(can, target||can._output, msg.Table(function(value) { if (value.enable != ice.TRUE) { return } + can.page.Append(can, target||can._output, msg.Table(function(value) { + // if (value.enable != ice.TRUE) { return } return {view: [[html.ITEM, ctx.INDEX].concat( value.type? [mdb.TYPE]: [], can.core.Split(value.type||""), value.role? [aaa.ROLE]: [], can.core.Split(value.role||""), )], style: {height: height, width: width}, list: [ {img: can.misc.ResourceIcons(can, value.icons)}, {text: can.user.trans(can, value.index.split(".").pop(), value.name)}, ], onclick: function(event) { - can.page.ClassList.del(can, can._fields, "_back") - can.page.ClassList.add(can, can._fields, "_goto") + can.page.ClassList.del(can, can._fields, "_back"), can.page.ClassList.add(can, can._fields, "_goto") can.Option(PLACE_UID, can.onexport.session(can, PLACE_UID)), can.Option(ctx.INDEX, value.index), can.Update() }} })) @@ -89,7 +89,7 @@ Volcanos(chat.ONIMPORT, { can.core.List(["_trans", "_icons", "_style", "_trans.input", "_trans.value"], function(key) { var value = sub.Conf(key); value && can.core.Item(can.Conf(key), function(k, v) { value[k] = value[k]||v }) }) - can.onexport.title(can, value.help, sub.Conf(PLACE_NAME, msg.Option(PLACE_NAME))) + can.onexport.title(can, sub.Conf(PLACE_NAME, msg.Option(PLACE_NAME)), value.help) sub.onexport.title = function(sub) { can.onexport.title.apply(can.onexport, [can].concat(can.core.List(arguments).slice(1))) } sub.onexport._output = function(_sub, msg) { can.core.Item(can.onimport, function(key, value) { _sub.onimport[key] = _sub.onimport[key]||value }) @@ -101,7 +101,7 @@ Volcanos(chat.ONIMPORT, { } sub.onexport.output = function(_sub, msg) { can.onappend.style(sub, html.OUTPUT) can.onexport.hash(can, can.Option(PLACE_UID), value.index, sub.Option(UID)) - can.onexport.title(can, sub.ConfHelp(), sub.Conf(PLACE_NAME), msg.Option("_share_title")||"") + can.onexport.title(can, sub.Conf(PLACE_NAME), sub.ConfHelp(), msg.Option("_share_title")||"") can.user.agent.init(can, msg.Option("_share_content"), msg.Option("_share_icons")||value.icons) can.page.Appends(can, ui.action, list), msg.Option(ice.MSG_ACTION) && can.onappend._action(sub, msg.Option(ice.MSG_ACTION), ui.action, null, true) back = function() { can.page.ClassList.add(can, can._fields, "_back") @@ -119,7 +119,7 @@ Volcanos(chat.ONIMPORT, { Volcanos(chat.ONEXPORT, { value: function(can, value, PLACE_UID, PLACE_NAME) { can.page.Select(can, can.ui._target, "div.item.card.uid-"+value._uid, function(item) { can.onmotion.select(can, can.ui._target, html.DIV_ITEM, item) }) - can.sup.current = value, can.onimport.selectIndex(can, can.sup.current), can.onexport.title(can, value[PLACE_NAME]) + can.sup.current = value, can.onimport.selectIndex(can, can.sup.current), can.onexport.title(can, value[PLACE_NAME], can.ConfHelp()) can.onexport.session(can, PLACE_UID, value[PLACE_UID]), can.onexport.hash(can, value[PLACE_UID]), can.user.agent.init(can) }, share_title: function(can, msg, title, role) { diff --git a/src/gonganxitong/portal.json b/src/gonganxitong/portal.json index 8c27334..e6a6db0 100644 --- a/src/gonganxitong/portal.json +++ b/src/gonganxitong/portal.json @@ -13,8 +13,13 @@ "placeUser": "场景用户", "cancel": "取消", "submit": "提交", + "finish": "完成", "reject": "驳回", "approve": "通过", + "autogen": "生成", + "compile": "编译", + "project": "项目", + "oauth": "授权", "icons": { "service": "https://img.icons8.com/officel/80/activity-grid.png", "qrcode": "https://img.icons8.com/officel/80/qr-code.png", @@ -28,12 +33,17 @@ "placeRemove": "danger" }, "input": { + "class": "基类", + "table": "应用", "My Place": "我的场景", "apply_status": "申请状态", "order_status": "审批状态", "begin_time": "起始时间", "end_time": "结束时间", + "cancel_time": "取消时间", + "finish_time": "完成时间", "operate": "操作", + "user_uid": "用户", "user_name": "用户昵称", "user_avatar": "用户头像", "user_place_role": "用户角色", @@ -42,6 +52,8 @@ "place_type": "场景类型", "place_address": "场景地址", "street_name": "街道名称", + "school_name": "学校名称", + "company_name": "公司名称", "city_name": "城市名称" }, "value": { diff --git a/src/gonganxitong/portal.shy b/src/gonganxitong/portal.shy index 57d346f..389fb79 100644 --- a/src/gonganxitong/portal.shy +++ b/src/gonganxitong/portal.shy @@ -3,7 +3,7 @@ refer ` ICON https://igoutu.cn/icons/officel GORM https://gorm.io/docs/indexes.html ` - +field web.chat.wx.access field web.code.mysql.client field web.code.mysql.query args `mysql gonganxitong` field web.code.db.database diff --git a/src/gonganxitong/service.go b/src/gonganxitong/service.go index d64991c..f9f60a1 100644 --- a/src/gonganxitong/service.go +++ b/src/gonganxitong/service.go @@ -1,11 +1,17 @@ package gonganxitong 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/tcp" "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/core/code" kit "shylinux.com/x/toolkits" "shylinux.com/x/community/src/gonganxitong/model" @@ -13,26 +19,80 @@ import ( type service struct { Table - portal string `data:"true"` - domain string `data:"gonganxitong"` - create string `name:"create name help table"` + portal string `data:"true"` + domain string `data:"gonganxitong"` + update string `name:"update name icon index"` + autogen string `name:"autogen name* help* class* table*" icon:"bi bi-plus-square-dotted"` + oauth string `name:"oauth" icon:"bi bi-shield-fill-check"` + open string `name:"open" role:"void"` + conf string `name:"conf" role:"void"` } func (s service) Update(m *ice.Message, arg ...string) { uid := kit.Hashs(ice.Info.Hostname, ice.Info.Pwd, m.Option(ctx.INDEX)) - s.Table.Create(m, model.UID, uid, tcp.HOSTNAME, ice.Info.Hostname, nfs.PATHNAME, ice.Info.Pwd, ctx.INDEX, m.Option(ctx.INDEX)) - s.Table.Update(m, kit.Dict(arg, web.DOMAIN, ice.Info.Make.Domain, - tcp.NODENAME, ice.Info.NodeName, tcp.NODETYPE, ice.Info.NodeType, + if s.Table.Select(m.Spawn(), model.UID, uid).Length() == 0 { + s.Table.Create(m, kit.Simple(model.UID, uid, m.OptionSimple(mdb.NAME, mdb.ICON), tcp.HOSTNAME, ice.Info.Hostname, nfs.PATHNAME, ice.Info.Pwd, m.OptionSimple(ctx.INDEX))...) + m.Cmd(m.Prefix(web.PORTAL)).Table(func(value ice.Maps) { m.Cmd(m.Prefix(web.PORTAL), mdb.MODIFY, value[ctx.INDEX], mdb.ENABLE, ice.TRUE) }) + } + s.Table.Update(m, kit.Dict(arg, m.OptionSimple(mdb.NAME, mdb.ICON), nfs.MODULE, ice.Info.Make.Module, nfs.VERSION, ice.Info.Make.Versions(), + tcp.NODENAME, ice.Info.NodeName, tcp.NODETYPE, ice.Info.NodeType, + web.DOMAIN, ice.Info.Make.Domain, + web.PORTAL, ctx.GetCmdFile(m.Message, m.Prefix(web.PORTAL)), ), model.UID, uid) } +func (s service) Autogen(m *ice.Message, arg ...string) { + m.Option("CLASS", strings.ToUpper(m.Option(mdb.CLASS))) + m.Option("Class", kit.Capital(m.Option(mdb.CLASS))) + m.Option("class", kit.LowerCapital(m.Option(mdb.CLASS))) + m.Option("TABLE", strings.ToUpper(m.Option(mdb.TABLE))) + m.Option("Table", kit.Capital(m.Option(mdb.TABLE))) + m.Option("table", kit.LowerCapital(m.Option(mdb.TABLE))) + code.AutogenImport(m.Message, m.Option(mdb.NAME)) + m.Option(nfs.MODULE, path.Join(code.AutogenMod(m.Message), nfs.SRC, m.Option(mdb.NAME))) + p, from := path.Join(nfs.SRC, m.Option(mdb.NAME)), "template/" + m.Cmd(nfs.DEFS, path.Join(p, "model/model.go"), m.Template(from+"model/model.go")) + m.Cmd(nfs.DEFS, path.Join(p, "common.go"), m.Template(from+"common.go")) + m.Cmd(nfs.DEFS, path.Join(p, "portal.go"), m.Template(from+"portal.go")) + m.Cmd(nfs.DEFS, path.Join(p, "portal.json"), m.Template(from+"portal.json")) + m.Cmd(nfs.DEFS, path.Join(p, "user"+m.Option("Class")+".go"), m.Template(from+"userClass.go")) + m.Cmd(nfs.DEFS, path.Join(p, m.Option("class")+".go"), m.Template(from+"class.go")) + kit.For(kit.Split(m.Option(mdb.TABLE)), func(table string) { + m.Option(mdb.TABLE, kit.LowerCapital(table)) + m.Cmd(nfs.DEFS, path.Join(p, m.Option(mdb.TABLE)+".go"), m.Template(from+"homework.go")) + m.Cmd(nfs.DEFS, path.Join(p, m.Option(mdb.TABLE)+".js"), m.Template(from+"homework.js")) + }) +} +func (s service) Compile(m *ice.Message, arg ...string) { + m.Cmdy(code.VIMER, code.COMPILE) +} +func (s service) Oauth(m *ice.Message, arg ...string) { + defer m.ToastProcess()() + m.Options(m.Cmd(web.CHAT_WX_ACCESS).AppendSimple()) + m.Option("user_cmd", kit.JoinWord(m.Prefix(aaa.USER), mdb.CREATE)) + m.Option("sess_cmd", kit.JoinWord(m.Prefix(aaa.SESS), mdb.CREATE)) + m.Cmd(web.CHAT_WX_ACCESS, web.OAUTH) + m.Cmd(web.SPACE, ice.OPS, ctx.CONFIG, web.CHAT_WX_AGENT, web.SPACE, m.Option(ice.MSG_USERPOD)) + m.ProcessHold() +} func (s service) List(m *ice.Message, arg ...string) { if len(arg) == 2 { s.Table.SelectDetail(m, model.UID, arg[1]) } else { s.Orders(m, s.Desc(model.UPDATED_AT)).Select(m) } - m.PushAction(s.Open, s.Conf).Display("") + list := m.CmdMap(web.SPACE, ice.OPS, web.SPACE, mdb.NAME) + m.Table(func(value ice.Maps) { + if _, ok := list[value[tcp.NODENAME]]; ok && value[ctx.INDEX] != "" { + if m.Cmd(web.SPACE, ice.OPS, web.SPACE, value[tcp.NODENAME], value[ctx.INDEX], kit.Dict(mdb.VIEW, mdb.TABLE)).Length() > 0 { + m.Push(mdb.STATUS, web.ONLINE) + return + } + } + m.Push(mdb.STATUS, "") + }) + m.PushAction(s.Open, s.Conf, s.Project).Action(s.Autogen, s.Compile, s.Oauth).Display("") + m.Sort("status,updated_at", []string{web.ONLINE}, ice.STR_R) } func (s service) Open(m *ice.Message, arg ...string) { m.ProcessOpen(web.S(m.Option(tcp.NODENAME)) + web.C(m.Option(ctx.INDEX))) @@ -40,5 +100,8 @@ func (s service) Open(m *ice.Message, arg ...string) { func (s service) Conf(m *ice.Message, arg ...string) { m.ProcessOpen(web.S(m.Option(tcp.NODENAME)) + web.C(m.Option(ctx.INDEX)) + "?view=table") } +func (s service) Project(m *ice.Message, arg ...string) { + m.ProcessOpen(web.S(m.Option(tcp.NODENAME)) + web.C(web.CODE_VIMER) + "?path=src/&file=" + strings.Split(kit.Select("", strings.Split(m.Option(web.PORTAL), "/src/"), 1), "?")[0]) +} func init() { ice.TeamCtxCmd(service{}) } diff --git a/src/gonganxitong/service.js b/src/gonganxitong/service.js index 681ec46..b4841dd 100644 --- a/src/gonganxitong/service.js +++ b/src/gonganxitong/service.js @@ -1,12 +1,12 @@ Volcanos(chat.ONIMPORT, { _init: function(can, msg) { - can.onimport.itemcards(can, msg, function(value) { value._style = [value.nodetype] + can.onimport.itemcards(can, msg, function(value) { value._style = [value.nodetype, value.status] return [ - {view: html.TITLE, list: [{text: value.name}, {text: [value.nodetype, "", mdb.TYPE]}]}, + {view: html.TITLE, list: [{text: value.name}, {text: [value.nodetype, "", mdb.TYPE]}, value.status && {text: [value.status, "", mdb.STATUS]}]}, {view: html.STATUS, list: [{text: value.uid.slice(0, 6)}, {text: can.base.TimeTrim(value.updated_at)}]}, {view: html.STATUS, list: [{text: value.index}]}, {view: html.STATUS, list: [{text: value.module}, {text: value.version}]}, - // {view: html.STATUS, list: [{text: value.domain}]}, + {view: html.STATUS, list: [{text: value.domain.split("?")[0]}]}, // {view: html.STATUS, list: [{text: value.hostname}, {text: value.pathname}]}, ] }) diff --git a/src/gonganxitong/template/class.go b/src/gonganxitong/template/class.go new file mode 100644 index 0000000..bfed976 --- /dev/null +++ b/src/gonganxitong/template/class.go @@ -0,0 +1,25 @@ +package {{.Option "name"}} + +import "shylinux.com/x/ice" + +type {{.Option "class"}} struct{ Table } + +func init() { ice.TeamCtxCmd({{.Option "class"}}{}) } + +type {{.Option "Class"}}Type int + +const ( + {{.Option "Class"}}Term {{.Option "Class"}}Type = iota + {{.Option "Class"}}Weekly + {{.Option "Class"}}Step + {{.Option "Class"}}Free +) + +var {{.Option "Class"}}TypeList = map[{{.Option "Class"}}Type]string{ + {{.Option "Class"}}Term: "term", + {{.Option "Class"}}Weekly: "weekly", + {{.Option "Class"}}Step: "step", + {{.Option "Class"}}Free: "free", +} + +func (s {{.Option "Class"}}Type) String() string { return {{.Option "Class"}}TypeList[s] } diff --git a/src/gonganxitong/template/common.go b/src/gonganxitong/template/common.go new file mode 100644 index 0000000..3da9b69 --- /dev/null +++ b/src/gonganxitong/template/common.go @@ -0,0 +1,46 @@ +package {{.Option "name"}} + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/enterprise/src/guanlixitong" + "{{.Option "module"}}/model" +) + +type Tables struct { + guanlixitong.Tables + list string `name:"list {{.Option "class"}}_uid uid auto" role:"void"` +} +type Table struct { + guanlixitong.Table + list string `name:"list {{.Option "class"}}_uid uid auto" role:"void"` +} + +func (s Table) Inputs(m *ice.Message, arg ...string) { + switch arg[0] { + case model.{{.Option "CLASS"}}_TYPE: + for k, v := range {{.Option "Class"}}TypeList { + m.Push(arg[0], k).Push(model.NAME, v) + } + m.SortInt(arg[0]).DisplayInputKeyNameIconTitle() + case model.USER_{{.Option "CLASS"}}_ROLE: + for k, v := range User{{.Option "Class"}}RoleList { + if k != User{{.Option "Class"}}Creator && k != User{{.Option "Class"}}Visitor { + m.Push(arg[0], k).Push(model.NAME, v) + } + } + m.SortInt(arg[0]).DisplayInputKeyNameIconTitle() + 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 { + kit.If(key == model.{{.Option "CLASS"}}_TYPE, func() { value = {{.Option "Class"}}Type(kit.Int(value)).String() }) + kit.If(key == model.USER_{{.Option "CLASS"}}_ROLE, func() { value = User{{.Option "Class"}}Role(kit.Int(value)).String() }) + return value + }) + s.Table.RewriteAppend(m) + return m +} diff --git a/src/gonganxitong/template/homework.go b/src/gonganxitong/template/homework.go new file mode 100644 index 0000000..bc6617d --- /dev/null +++ b/src/gonganxitong/template/homework.go @@ -0,0 +1,25 @@ +package {{.Option "name"}} + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "{{.Option "module"}}/model" +) + +type {{.Option "table"}} struct { + Table + {{.Option "class"}} {{.Option "class"}} + user{{.Option "Class"}} user{{.Option "Class"}} + portal string `data:"true"` + create string `name:"create content*" role:"void"` +} + +func (s {{.Option "table"}}) Create(m *ice.Message, arg ...string) { + s.Table.Create(m, kit.Simple(arg, m.OptionSimple(model.USER_UID, model.{{.Option "CLASS"}}_UID))...) +} +func (s {{.Option "table"}}) List(m *ice.Message, arg ...string) { + s.TablesWithRole(m, arg, s, s.user{{.Option "Class"}}, s.{{.Option "class"}}, model.CONTENT).Display("") +} + +func init() { ice.TeamCtxCmd({{.Option "table"}}{}) } diff --git a/src/gonganxitong/template/homework.js b/src/gonganxitong/template/homework.js new file mode 100644 index 0000000..c04503a --- /dev/null +++ b/src/gonganxitong/template/homework.js @@ -0,0 +1,11 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { + can.onimport.itemcards(can, msg, function(value) { return [ + {view: html.TITLE, list: [{text: value.user_name}, + {text: [can.user.transValue(can, value, "user_{{.Option "class"}}_role"), "", aaa.ROLE]}, + ]}, + {view: html.STATUS, list: [{text: value.uid.slice(0, 6)}, {text: can.base.TimeTrim(value.created_at)},]}, + {view: html.OUTPUT, list: [{text: value.content}]}, + ] }) + }, +}) \ No newline at end of file diff --git a/src/gonganxitong/template/model/model.go b/src/gonganxitong/template/model/model.go new file mode 100644 index 0000000..30c6a43 --- /dev/null +++ b/src/gonganxitong/template/model/model.go @@ -0,0 +1,41 @@ +package model + +import "shylinux.com/x/mysql-story/src/db" + +const ( + UID = "uid" + NAME = "name" + TYPE = "type" + ROLE = "role" + CONTENT = "content" + USER_UID = "user_uid" + USER_{{.Option "CLASS"}}_ROLE = "user_{{.Option "class"}}_role" + {{.Option "CLASS"}}_UID = "{{.Option "class"}}_uid" + {{.Option "CLASS"}}_NAME = "{{.Option "class"}}_name" + {{.Option "CLASS"}}_TYPE = "{{.Option "class"}}_type" + {{.Option "TABLE"}}_UID = "{{.Option "table"}}_uid" + COMPANY_UID = "company_uid" + CITY_UID = "city_uid" +) + +type User{{.Option "Class"}} struct { + db.ModelWithUID + UserUID string `gorm:"type:char(32);index"` + {{.Option "Class"}}UID string `gorm:"type:char(32);index"` + Role uint8 +} +type {{.Option "Class"}} struct { + db.ModelWithUID + CompanyUID string `gorm:"type:char(32);index"` + Name string `gorm:"type:varchar(255)"` + Type uint8 +} +type {{.Option "Table"}} struct { + db.ModelWithUID + {{.Option "Class"}}UID string `gorm:"type:char(32);index"` + UserUID string `gorm:"type:char(32);index"` + Content string `gorm:"type:varchar(255)"` +} + + +func init() { db.CmdModels("", &User{{.Option "Class"}}{}, &{{.Option "Class"}}{}, &{{.Option "Table"}}{}) } diff --git a/src/gonganxitong/template/portal.go b/src/gonganxitong/template/portal.go new file mode 100644 index 0000000..8360358 --- /dev/null +++ b/src/gonganxitong/template/portal.go @@ -0,0 +1,17 @@ +package {{.Option "name"}} + +import ( + "shylinux.com/x/community/src/gonganxitong" + "shylinux.com/x/enterprise/src/guanlixitong" +) + +type Portal struct { + gonganxitong.Portal + name string `data:"{{.Option "help"}}"` + list string `name:"list {{.Option "class"}}_uid index uid auto" role:"void"` + placeCreate string `name:"placeCreate city_name* company_name* name*" role:"void"` +} + +func init() { + gonganxitong.PortalCmd(Portal{Portal: gonganxitong.NewPortal(user{{.Option "Class"}}{}, {{.Option "class"}}{}, guanlixitong.Company{})}) +} diff --git a/src/gonganxitong/template/portal.json b/src/gonganxitong/template/portal.json new file mode 100644 index 0000000..e85db6a --- /dev/null +++ b/src/gonganxitong/template/portal.json @@ -0,0 +1,29 @@ +{ + "portal": "{{.Option "help"}}", + "placeCreate": "创建场景", + "placeRemove": "删除场景", + "{{.Option "table"}}": "场景应用", + "icons": { + "{{.Option "table"}}": "https://img.icons8.com/officel/80/activity-grid.png", + "service": "https://img.icons8.com/officel/80/activity-grid.png" + }, + "input": { + "My {{.Option "Class"}}": "我的场景", + "user_{{.Option "class"}}_role": "用户角色", + "{{.Option "class"}}_uid": "场景", + "{{.Option "class"}}_name": "场景名称", + "{{.Option "class"}}_type": "场景类型" + }, + "value": { + "user_{{.Option "class"}}_role": { + "creator": "创建人", + "visitor": "访客" + }, + "{{.Option "class"}}_type": { + "term": "学期制", + "weekly": "周期性", + "step": "阶段性", + "free": "自由式" + } + } +} diff --git a/src/gonganxitong/template/userClass.go b/src/gonganxitong/template/userClass.go new file mode 100644 index 0000000..f4624bb --- /dev/null +++ b/src/gonganxitong/template/userClass.go @@ -0,0 +1,57 @@ +package {{.Option "name"}} + +import ( + "shylinux.com/x/ice" + + "{{.Option "module"}}/model" +) + +type user{{.Option "Class"}} struct { + Table + {{.Option "class"}} {{.Option "class"}} +} + +func (s user{{.Option "Class"}}) User(m *ice.Message, arg ...string) { + if len(arg) == 1 { + s.Select(m, model.{{.Option "CLASS"}}_UID, arg[0]) + } else if len(arg) == 2 { + s.Select(m, model.{{.Option "CLASS"}}_UID, arg[0], model.UID, arg[1]) + } else { + return + } + m.RenameAppend(model.ROLE, model.USER_{{.Option "CLASS"}}_ROLE) + s.SelectJoinUser(m) + s.RewriteAppend(m) +} +func (s user{{.Option "Class"}}) List(m *ice.Message, arg ...string) { + s.Tables(m, s.{{.Option "class"}}).FieldsWithCreatedAT(m, s, + model.{{.Option "CLASS"}}_NAME, model.{{.Option "CLASS"}}_TYPE, model.USER_{{.Option "CLASS"}}_ROLE, + model.{{.Option "CLASS"}}_UID, model.COMPANY_UID, + ) + if len(arg) == 1 { + s.Select(m, model.USER_UID, arg[0]) + } else if len(arg) == 2 { + s.SelectDetail(m, model.USER_UID, arg[0], s.Key(s.{{.Option "class"}}, model.UID), arg[1]) + } else { + return + } + s.SelectJoinCompany(m) + s.SelectJoinCity(m) + s.RewriteAppend(m) +} + +func init() { ice.TeamCtxCmd(user{{.Option "Class"}}{}) } + +type User{{.Option "Class"}}Role int + +const ( + User{{.Option "Class"}}Creator User{{.Option "Class"}}Role = iota + User{{.Option "Class"}}Visitor +) + +var User{{.Option "Class"}}RoleList = map[User{{.Option "Class"}}Role]string{ + User{{.Option "Class"}}Creator: "creator", + User{{.Option "Class"}}Visitor: "visitor", +} + +func (s User{{.Option "Class"}}Role) String() string { return User{{.Option "Class"}}RoleList[s] } diff --git a/src/gonganxitong/user.go b/src/gonganxitong/user.go index 8798d3f..fd0c935 100644 --- a/src/gonganxitong/user.go +++ b/src/gonganxitong/user.go @@ -30,6 +30,18 @@ func (s user) Create(m *ice.Message, arg ...string) { func (s user) Email(m *ice.Message, arg ...string) { s.Table.Update(m, kit.Dict(m.OptionSimple(model.EMAIL)), model.UID, m.Option(model.USER_UID)) } +func (s user) List(m *ice.Message, arg ...string) { + s.Table.List(m, arg...).Table(func(value ice.Maps) { + if value[model.UID] != m.Option(model.USER_UID) { + m.PushButton(s.SetCookie) + } else { + m.PushButton() + } + }) +} +func (s user) SetCookie(m *ice.Message, arg ...string) { + m.ProcessCookie(model.USER_UID, m.Option(model.UID)) +} func (s user) SendTemplate(m *ice.Message, arg ...string) { // from uid url type name hash msg := s.Select(m, model.UID, arg[1]) m.Cmdy("web.chat.wx.template", "", m.Config(nfs.TEMPLATE), msg.Append(model.OPEN_ID), kit.Select("", arg, 2), diff --git a/src/main.go b/src/main.go index 73d74e3..2761b79 100644 --- a/src/main.go +++ b/src/main.go @@ -5,6 +5,8 @@ import ( _ "shylinux.com/x/community/src/gonganxitong" _ "shylinux.com/x/community/src/gonganxitong/express" + + _ "shylinux.com/x/community/src/yuehaoxitong" ) func main() { print(ice.Run()) } diff --git a/src/template/web.code.js/demo.js b/src/template/web.code.js/demo.js new file mode 100644 index 0000000..c8c3552 --- /dev/null +++ b/src/template/web.code.js/demo.js @@ -0,0 +1,10 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { + can.onimport.itemcards(can, msg, function(value) { + return [ + {view: html.TITLE, list:[{text: [value.name||value.user_name]}]}, + {view: html.STATUS, list: [value.uid && {text: value.uid.slice(0, 6)}, {text: can.base.TimeTrim(value.created_at||value.updated_at)}]}, + ] + }) + }, +}) diff --git a/src/yuehaoxitong/call.go b/src/yuehaoxitong/call.go new file mode 100644 index 0000000..542622b --- /dev/null +++ b/src/yuehaoxitong/call.go @@ -0,0 +1,55 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/community/src/yuehaoxitong/model" +) + +type call struct { + Tables + schedule schedule + reception reception + call string `name:"call" role:"void"` + expire string `name:"expire" role:"void"` + finish string `name:"finish" role:"void"` + list string `name:"list queue_uid uid reception_uid auto"` +} + +func (s call) Call(m *ice.Message, arg ...string) { + if !m.WarnNotRight(!s.CheckRole(m, UserQueueCreator, UserQueueServer)) { + m.Cmdy(s.schedule, s.schedule.Call) + m.PushAction(s.Expire, s.Finish) + } +} +func (s call) Expire(m *ice.Message, arg ...string) { + if !m.WarnNotRight(!s.CheckRole(m, UserQueueCreator, UserQueueServer)) { + m.Cmdy(s.schedule, s.schedule.Expire) + m.ProcessRefresh() + } +} +func (s call) Finish(m *ice.Message, arg ...string) { + if !m.WarnNotRight(!s.CheckRole(m, UserQueueCreator, UserQueueServer)) { + m.Cmdy(s.schedule, s.schedule.Finish) + m.ProcessRefresh() + } +} +func (s call) List(m *ice.Message, arg ...string) { + if len(arg) == 1 { + m.Cmdy(s.schedule, s.schedule.SelectByStatus, arg[0], ScheduleTake).PushAction().Action(s.Call) + kit.If(m.Length() == 0, func() { m.Echo(m.Trans("not found order", "没有等待")) }) + } else if len(arg) == 2 { + m.Cmdy(s.schedule, arg[0], arg[1]).Table(func(value ice.Maps) { + if value[model.SCHEDULE_STATUS] == ScheduleCall.String() { + m.PushButton(s.Expire, s.Finish) + } else { + m.PushButton() + } + }).Action(s.Call) + } else if len(arg) == 3 { + m.Cmdy(s.schedule, s.Select, model.QUEUE_UID, arg[0], model.STATUS, ScheduleTake, model.RECEPTION_UID, arg[2]).PushAction().Action(s.Call) + } +} + +func init() { ice.TeamCtxCmd(call{}) } diff --git a/src/yuehaoxitong/common.go b/src/yuehaoxitong/common.go new file mode 100644 index 0000000..7131d20 --- /dev/null +++ b/src/yuehaoxitong/common.go @@ -0,0 +1,65 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/community/src/yuehaoxitong/model" + "shylinux.com/x/enterprise/src/guanlixitong" +) + +type Tables struct { + guanlixitong.Tables + list string `name:"list queue_uid uid auto" role:"void"` +} + +func (s Tables) CheckRole(m *ice.Message, arg ...UserQueueRole) bool { + return Table{}.CheckRole(m, arg...) +} +func (s Tables) RewriteAppend(m *ice.Message, arg ...string) *ice.Message { + return Table{}.RewriteAppend(m, arg...) +} + +type Table struct { + guanlixitong.Table + list string `name:"list queue_uid uid auto" role:"void"` +} + +func (s Table) Inputs(m *ice.Message, arg ...string) { + switch arg[0] { + case model.QUEUE_TYPE: + for k, v := range QueueTypeList { + m.Push(arg[0], k).Push(model.NAME, v) + } + m.SortInt(arg[0]).DisplayInputKeyNameIconTitle() + case model.USER_QUEUE_ROLE: + for k, v := range UserQueueRoleList { + if k != UserQueueCreator && k != UserQueueVisitor { + m.Push(arg[0], k).Push(model.NAME, v) + } + } + m.SortInt(arg[0]).DisplayInputKeyNameIconTitle() + default: + s.Table.Inputs(m, arg...) + } +} +func (s Table) CheckRole(m *ice.Message, arg ...UserQueueRole) bool { + kit.If(len(arg) == 0, func() { arg = append(arg, UserQueueCreator, UserQueueManager) }) + role := UserQueueRole(kit.Int(m.Cmd(userQueue{}, s.Select, m.OptionSimple(model.QUEUE_UID, model.USER_UID)).Append(model.ROLE))) + for _, v := range arg { + if role == v { + return true + } + } + return false +} +func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message { + m.RewriteAppend(func(value, key string, index int) string { + kit.If(key == model.QUEUE_TYPE, func() { value = QueueType(kit.Int(value)).String() }) + kit.If(key == model.USER_QUEUE_ROLE, func() { value = UserQueueRole(kit.Int(value)).String() }) + kit.If(key == model.SCHEDULE_STATUS, func() { value = ScheduleStatus(kit.Int(value)).String() }) + return value + }) + s.Table.RewriteAppend(m) + return m +} diff --git a/src/yuehaoxitong/history.go b/src/yuehaoxitong/history.go new file mode 100644 index 0000000..051660a --- /dev/null +++ b/src/yuehaoxitong/history.go @@ -0,0 +1,16 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" +) + +type history struct { + Tables + schedule schedule +} + +func (s history) List(m *ice.Message, arg ...string) { + m.Cmdy(s.schedule, arg) +} + +func init() { ice.TeamCtxCmd(history{}) } diff --git a/src/yuehaoxitong/model/model.go b/src/yuehaoxitong/model/model.go new file mode 100644 index 0000000..fc11c31 --- /dev/null +++ b/src/yuehaoxitong/model/model.go @@ -0,0 +1,74 @@ +package model + +import "shylinux.com/x/mysql-story/src/db" + +const ( + UID = "uid" + NAME = "name" + TYPE = "type" + ROLE = "role" + STATUS = "status" + CONTENT = "content" + CREATED_AT = "created_at" + USER_UID = "user_uid" + USER_QUEUE_ROLE = "user_queue_role" + QUEUE_UID = "queue_uid" + QUEUE_NAME = "queue_name" + QUEUE_TYPE = "queue_type" + RECEPTION_UID = "reception_uid" + RECEPTION_NAME = "reception_name" + SCHEDULE_UID = "schedule_uid" + SCHEDULE_STATUS = "schedule_status" + COMPANY_UID = "company_uid" + BEGIN_TIME = "begin_time" + END_TIME = "end_time" + CANCEL_TIME = "cancel_time" + TAKE_TIME = "take_time" + CALL_TIME = "call_time" + FINISH_TIME = "finish_time" + AMOUNT = "amount" + COUNT = "count" +) + +type UserQueue struct { + db.ModelWithUID + UserUID string `gorm:"type:char(32);index"` + QueueUID string `gorm:"type:char(32);index"` + Role uint8 +} +type Queue struct { + db.ModelWithUID + CompanyUID string `gorm:"type:char(32);index"` + Name string `gorm:"type:varchar(255)"` + Type uint8 +} +type Reception struct { + db.ModelWithUID + QueueUID string `gorm:"type:char(32);index"` + Name string `gorm:"type:varchar(255)"` +} +type Volume struct { + db.ModelWithUID + QueueUID string `gorm:"type:char(32);index"` + ReceptionUID string `gorm:"type:char(32)"` + BeginTime db.Time + EndTime db.Time + Amount int + Count int +} +type Schedule struct { + db.ModelWithUID + QueueUID string `gorm:"type:char(32);index:idx_queue"` + ReceptionUID string `gorm:"type:char(32);index:idx_queue"` + VolumeUID string `gorm:"type:char(32);index:idx_queue"` + UserUID string `gorm:"type:char(32);index"` + BeginTime db.Time + EndTime db.Time + CancelTime db.Time + TakeTime db.Time + CallTime db.Time + FinishTime db.Time + Status uint8 +} + +func init() { db.CmdModels("", &UserQueue{}, &Queue{}, &Reception{}, Volume{}, &Schedule{}) } diff --git a/src/yuehaoxitong/open.go b/src/yuehaoxitong/open.go new file mode 100644 index 0000000..aba9afe --- /dev/null +++ b/src/yuehaoxitong/open.go @@ -0,0 +1,32 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" + + "shylinux.com/x/community/src/yuehaoxitong/model" +) + +type open struct { + Tables + volume volume + create string `name:"plan reception_uid* amount* begin_time@date end_time@date" role:"void"` +} + +func (s open) Create(m *ice.Message, arg ...string) { + if !m.WarnNotRight(!s.CheckRole(m)) { + m.Cmd(s.volume, s.Create, arg, m.OptionSimple(model.QUEUE_UID)) + } +} +func (s open) List(m *ice.Message, arg ...string) { + if !m.WarnNotRight(!s.CheckRole(m.Options(model.QUEUE_UID, arg[0]))) { + m.Cmdy(s.volume, arg) + if m.Length() == 0 { + m.SetResult() + m.EchoInfoButton(m.Trans("please create open", "请创建放号"), s.Create) + } else { + m.Action(s.Create) + } + } +} + +func init() { ice.TeamCtxCmd(open{}) } diff --git a/src/yuehaoxitong/plan.go b/src/yuehaoxitong/plan.go new file mode 100644 index 0000000..ac73b55 --- /dev/null +++ b/src/yuehaoxitong/plan.go @@ -0,0 +1,29 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/community/src/yuehaoxitong/model" +) + +type plan struct { + Tables + volume volume + schedule schedule + create string `name:"create reception_uid* volume_uid*" role:"void"` + cancel string `name:"cancel" role:"void"` +} + +func (s plan) Create(m *ice.Message, arg ...string) { + m.Cmd(s.schedule, s.Create, arg, m.OptionSimple(model.QUEUE_UID, model.USER_UID), model.STATUS, SchedulePlan) +} +func (s plan) Cancel(m *ice.Message, arg ...string) { + m.Cmd(s.schedule, s.Cancel) +} +func (s plan) List(m *ice.Message, arg ...string) { + m.Cmdy(s.schedule, s.schedule.SelectByStatus, arg[0], SchedulePlan, m.OptionSimple(model.USER_UID)).PushAction(s.Cancel) + kit.If(m.Length() == 0, func() { m.EchoInfoButton(m.Trans("please create schedule", "请创建预约"), s.Create) }) +} + +func init() { ice.TeamCtxCmd(plan{}) } diff --git a/src/yuehaoxitong/portal.go b/src/yuehaoxitong/portal.go new file mode 100644 index 0000000..609749c --- /dev/null +++ b/src/yuehaoxitong/portal.go @@ -0,0 +1,17 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/community/src/gonganxitong" + "shylinux.com/x/enterprise/src/guanlixitong" +) + +type Portal struct { + gonganxitong.Portal + name string `data:"约号系统"` + list string `name:"list queue_uid index uid auto" role:"void"` + placeCreate string `name:"placeCreate city_name* company_name* name*" role:"void"` +} + +func init() { + gonganxitong.PortalCmd(Portal{Portal: gonganxitong.NewPortal(userQueue{}, queue{}, guanlixitong.Company{})}) +} diff --git a/src/yuehaoxitong/portal.json b/src/yuehaoxitong/portal.json new file mode 100644 index 0000000..0fb49f0 --- /dev/null +++ b/src/yuehaoxitong/portal.json @@ -0,0 +1,64 @@ +{ + "portal": "约号系统", + "placeCreate": "创建场景", + "placeRemove": "删除场景", + "reception": "服务接待", + "volume": "服务计划", + "schedule": "订单数据", + "history": "我的订单", + "open": "放号", + "plan": "约号", + "take": "取号", + "call": "叫号", + "expire": "过号", + "finish": "完成", + "icons": { + "reception": "https://img.icons8.com/officel/80/meeting-room.png", + "volume": "https://img.icons8.com/officel/80/combo-chart.png", + "schedule": "https://img.icons8.com/officel/80/List-of-parts.png", + "history": "https://img.icons8.com/officel/80/order-history.png", + "open": "https://img.icons8.com/officel/80/open-sign.png", + "plan": "https://img.icons8.com/officel/80/calendar-plus.png", + "take": "https://img.icons8.com/officel/80/receipt.png", + "call": "https://img.icons8.com/officel/80/calling.png" + }, + "style": { + "expire": "danger" + }, + "input": { + "My Queue": "我的场景", + "user_queue_role": "用户角色", + "queue_uid": "场景", + "queue_name": "场景名称", + "queue_type": "场景类型", + "reception_uid": "服务接待", + "reception_name": "服务接待", + "volume_uid": "服务时间", + "schedule_status": "订单状态", + "amount": "放号总量", + "count": "约号数量", + "take_time": "取号时间", + "call_time": "叫号时间" + }, + "value": { + "schedule_status": { + "plan": "已预约", + "cancel": "已取消", + "take": "已取号", + "call": "已叫号", + "expire": "已过号", + "finish": "已完成" + }, + "user_queue_role": { + "creator": "创建人", + "visitor": "访客", + "manager": "管理员", + "server": "服务员", + "waiter": "接待员" + }, + "queue_type": { + "public": "公开预约", + "private": "会员预约" + } + } +} \ No newline at end of file diff --git a/src/yuehaoxitong/portal.shy b/src/yuehaoxitong/portal.shy new file mode 100644 index 0000000..a93a93c --- /dev/null +++ b/src/yuehaoxitong/portal.shy @@ -0,0 +1,3 @@ +chapter "约号系统" + +field web.code.mysql.query args `mysql yuehaoxitong` \ No newline at end of file diff --git a/src/yuehaoxitong/queue.go b/src/yuehaoxitong/queue.go new file mode 100644 index 0000000..fe055d1 --- /dev/null +++ b/src/yuehaoxitong/queue.go @@ -0,0 +1,21 @@ +package yuehaoxitong + +import "shylinux.com/x/ice" + +type queue struct{ Table } + +func init() { ice.TeamCtxCmd(queue{}) } + +type QueueType int + +const ( + QueuePublic QueueType = iota + QueuePrivate +) + +var QueueTypeList = map[QueueType]string{ + QueuePublic: "public", + QueuePrivate: "private", +} + +func (s QueueType) String() string { return QueueTypeList[s] } diff --git a/src/yuehaoxitong/reception.go b/src/yuehaoxitong/reception.go new file mode 100644 index 0000000..d240f7e --- /dev/null +++ b/src/yuehaoxitong/reception.go @@ -0,0 +1,52 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" + "shylinux.com/x/icebergs/base/mdb" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/community/src/yuehaoxitong/model" +) + +type reception struct { + Table + userQueue userQueue + portal string `data:"true"` + create string `name:"create name*" role:"void"` + rename string `name:"rename name*" role:"void"` + delete string `name:"delete" role:"void"` +} + +func (s reception) Create(m *ice.Message, arg ...string) { + if !m.WarnNotRight(!s.CheckRole(m)) { + s.Table.Create(m, append(arg, m.OptionSimple(model.QUEUE_UID)...)...) + s.RecordEvent(m, m.Option(model.QUEUE_UID), kit.Format(m.Trans("create reception %s", "创建服务接待 %s"), m.Option(mdb.NAME)), arg...) + } +} +func (s reception) Rename(m *ice.Message, arg ...string) { + if !m.WarnNotRight(!s.CheckRole(m)) { + s.Table.Rename(m.Spawn()) + s.RecordEvent(m, m.Option(model.QUEUE_UID), kit.Format(m.Trans("rename reception %s", "重命名服务接待 %s"), m.Option(mdb.NAME)), arg...) + } +} +func (s reception) Delete(m *ice.Message, arg ...string) { + if !m.WarnNotRight(!s.CheckRole(m)) { + s.Table.Delete(m.Spawn(), m.OptionSimple(model.UID)...) + s.RecordEvent(m, m.Option(model.QUEUE_UID), kit.Format(m.Trans("delete reception %s", "删除服务接待 %s"), m.Option(mdb.NAME)), arg...) + } +} +func (s reception) List(m *ice.Message, arg ...string) { + s.Table.Fields(m, model.UID, model.NAME, model.CREATED_AT) + if len(arg) == 0 { + if m.Option(model.QUEUE_UID) != "" { + s.Table.Select(m, m.OptionSimple(model.QUEUE_UID)...) + } + } else if len(arg) == 1 { + s.Table.Select(m, model.QUEUE_UID, arg[0]).Action(s.Create) + } else if len(arg) == 2 { + s.Table.SelectDetail(m, model.QUEUE_UID, arg[0], model.UID, arg[1]) + } + m.PushAction(s.Rename, s.Delete) +} + +func init() { ice.TeamCtxCmd(reception{}) } diff --git a/src/yuehaoxitong/schedule.go b/src/yuehaoxitong/schedule.go new file mode 100644 index 0000000..57d0eb4 --- /dev/null +++ b/src/yuehaoxitong/schedule.go @@ -0,0 +1,104 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/community/src/yuehaoxitong/model" +) + +type schedule struct { + Table + queue queue + userQueue userQueue + volume volume + reception reception + portal string `data:"true"` + plan string `name:"plan begin_time@date end_time@date"` +} + +func (s schedule) Plan(m *ice.Message, arg ...string) { + arg = kit.TransArgValueTime(arg, model.BEGIN_TIME, model.END_TIME) + s.Table.Create(m, append(arg, m.OptionSimple(model.QUEUE_UID, model.USER_UID)...)...) +} +func (s schedule) Call(m *ice.Message, arg ...string) { + s.Orders(m, model.TAKE_TIME).Limit(m, 1) + s.SelectByStatus(m, m.Option(model.QUEUE_UID), kit.Format(ScheduleTake)) + // s.Select(m, kit.Simple(m.OptionSimple(model.QUEUE_UID, model.RECEPTION_UID), mdb.STATUS, ScheduleTake)...) + if m.WarnNotFound(m.Length() == 0) { + return + } + s.ChangeStatus(m, m.Append(model.UID), "", ScheduleTake, ScheduleCall, arg...) +} +func (s schedule) SelectByStatus(m *ice.Message, arg ...string) { + s.Tables(m, s.volume).FieldsWithCreatedAT(m, s, + model.SCHEDULE_STATUS, s.Key(s.volume, model.BEGIN_TIME), s.Key(s.volume, model.END_TIME), s.Key(s, model.RECEPTION_UID), model.USER_UID, + ).Orders(m, s.Desc(model.BEGIN_TIME)) + s.Select(m, kit.Simple(s.Key(s, model.QUEUE_UID), arg[0], model.STATUS, arg[1], arg[2:])...) + s.RewriteAppend(m) + s.SelectJoin(m, s.reception) + s.SelectJoinUser(m) +} +func (s schedule) List(m *ice.Message, arg ...string) { + if s.CheckRole(m.Options(model.QUEUE_UID, arg[0]), UserQueueCreator, UserQueueServer) { + if len(arg) == 1 { + s.Select(m, model.QUEUE_UID, arg[0]) + } else if len(arg) == 2 { + s.SelectDetail(m, model.QUEUE_UID, arg[0], model.UID, arg[1]) + } + } else { + if len(arg) == 1 { + s.Select(m, model.QUEUE_UID, arg[0], model.USER_UID, m.Option(model.USER_UID)) + } else if len(arg) == 2 { + s.SelectDetail(m, model.QUEUE_UID, arg[0], model.USER_UID, m.Option(model.USER_UID), model.UID, arg[1]) + } + } + m.RenameAppend(model.STATUS, model.SCHEDULE_STATUS) + s.RewriteAppend(m) + s.SelectJoin(m, s.reception) + s.SelectJoinUser(m) + kit.If(m.Length() == 0, func() { m.Echo(m.Trans("not found", "没有预约")) }) + m.PushAction().Action() +} +func (s schedule) Take(m *ice.Message, arg ...string) { + s.ChangeStatus(m, m.Option(model.UID), "", SchedulePlan, ScheduleTake, arg...) +} +func (s schedule) Cancel(m *ice.Message, arg ...string) { + s.ChangeStatus(m, m.Option(model.UID), "", SchedulePlan, ScheduleTake, arg...) +} +func (s schedule) Expire(m *ice.Message, arg ...string) { + s.ChangeStatus(m, m.Option(model.UID), "", ScheduleCall, ScheduleExpire, arg...) +} +func (s schedule) Finish(m *ice.Message, arg ...string) { + s.ChangeStatus(m, m.Option(model.UID), "", ScheduleCall, ScheduleFinish, arg...) +} + +func init() { ice.TeamCtxCmd(schedule{}) } + +func (s schedule) ChangeStatus(m *ice.Message, uid, key string, from, to ScheduleStatus, arg ...string) *ice.Message { + kit.If(key == "", func() { key = m.ActionKey() + "_time" }) + s.Table.ChangeStatus(m, uid, int(from), int(to), kit.TransArgValueTime(append(arg, key, m.Time()), key)...) + return m +} + +type ScheduleStatus int + +const ( + SchedulePlan ScheduleStatus = iota + ScheduleCancel + ScheduleTake + ScheduleCall + ScheduleExpire + ScheduleFinish +) + +var ScheduleStatusList = map[ScheduleStatus]string{ + SchedulePlan: "plan", + ScheduleCancel: "cancel", + ScheduleTake: "take", + ScheduleCall: "call", + ScheduleExpire: "expire", + ScheduleFinish: "finish", +} + +func (s ScheduleStatus) String() string { return ScheduleStatusList[s] } diff --git a/src/yuehaoxitong/schedule.js b/src/yuehaoxitong/schedule.js new file mode 100644 index 0000000..d779786 --- /dev/null +++ b/src/yuehaoxitong/schedule.js @@ -0,0 +1,17 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { + can.onimport.itemcards(can, msg, function(value) { + return [ + {view: html.TITLE, list:[{text: [value.name||value.user_name]}, {text: value.reception_name}, + {text: [can.user.transValue(can, value, "schedule_status"), "", [mdb.STATUS, value.schedule_status]]}, + ]}, + {view: html.STATUS, list: [value.uid && {text: value.uid.slice(0, 6)}, {text: can.base.TimeTrim(value.created_at||value.updated_at)}]}, + value.begin_time && {view: html.TITLE, list: [{text: "开始时间:"}, {text: value.begin_time}]}, + value.end_time && {view: html.TITLE, list: [{text: "结束时间:"}, {text: value.end_time}]}, + value.take_time && {view: html.TITLE, list: [{text: "取号时间:"}, {text: value.take_time}]}, + value.call_time && {view: html.TITLE, list: [{text: "叫号时间:"}, {text: value.call_time}]}, + value.finish_time && {view: html.TITLE, list: [{text: "完成时间:"}, {text: value.finish_time}]}, + ] + }) + }, +}) \ No newline at end of file diff --git a/src/yuehaoxitong/take.go b/src/yuehaoxitong/take.go new file mode 100644 index 0000000..cfa75dc --- /dev/null +++ b/src/yuehaoxitong/take.go @@ -0,0 +1,24 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/community/src/yuehaoxitong/model" +) + +type take struct { + Tables + schedule schedule + take string `name:"take" role:"void"` +} + +func (s take) Take(m *ice.Message, arg ...string) { + m.Cmd(s.schedule, s.schedule.Take) +} +func (s take) List(m *ice.Message, arg ...string) { + m.Cmdy(s.schedule, s.schedule.SelectByStatus, arg[0], SchedulePlan, m.OptionSimple(model.USER_UID)).PushAction(s.Take).Action() + kit.If(m.Length() == 0, func() { m.Echo(m.Trans("not found plan", "没有预约")) }) +} + +func init() { ice.TeamCtxCmd(take{}) } diff --git a/src/yuehaoxitong/userQueue.go b/src/yuehaoxitong/userQueue.go new file mode 100644 index 0000000..46d8fac --- /dev/null +++ b/src/yuehaoxitong/userQueue.go @@ -0,0 +1,63 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" + + "shylinux.com/x/community/src/yuehaoxitong/model" +) + +type userQueue struct { + Table + queue queue +} + +func (s userQueue) User(m *ice.Message, arg ...string) { + if len(arg) == 1 { + s.Select(m, model.QUEUE_UID, arg[0]) + } else if len(arg) == 2 { + s.Select(m, model.QUEUE_UID, arg[0], model.UID, arg[1]) + } else { + return + } + m.RenameAppend(model.ROLE, model.USER_QUEUE_ROLE) + s.SelectJoinUser(m) + s.RewriteAppend(m) +} +func (s userQueue) List(m *ice.Message, arg ...string) { + s.Tables(m, s.queue).FieldsWithCreatedAT(m, s, + model.QUEUE_NAME, model.QUEUE_TYPE, model.USER_QUEUE_ROLE, + model.QUEUE_UID, model.COMPANY_UID, + ) + if len(arg) == 1 { + s.Select(m, model.USER_UID, arg[0]) + } else if len(arg) == 2 { + s.SelectDetail(m, model.USER_UID, arg[0], s.Key(s.queue, model.UID), arg[1]) + } else { + return + } + s.SelectJoinCompany(m) + s.SelectJoinCity(m) + s.RewriteAppend(m) +} + +func init() { ice.TeamCtxCmd(userQueue{}) } + +type UserQueueRole int + +const ( + UserQueueCreator UserQueueRole = iota + UserQueueVisitor + UserQueueManager + UserQueueServer + UserQueueWaiter +) + +var UserQueueRoleList = map[UserQueueRole]string{ + UserQueueCreator: "creator", + UserQueueVisitor: "visitor", + UserQueueManager: "manager", + UserQueueServer: "server", + UserQueueWaiter: "waiter", +} + +func (s UserQueueRole) String() string { return UserQueueRoleList[s] } diff --git a/src/yuehaoxitong/volume.go b/src/yuehaoxitong/volume.go new file mode 100644 index 0000000..2ce6928 --- /dev/null +++ b/src/yuehaoxitong/volume.go @@ -0,0 +1,38 @@ +package yuehaoxitong + +import ( + "shylinux.com/x/ice" + "shylinux.com/x/toolkits" + + "shylinux.com/x/community/src/yuehaoxitong/model" +) + +type volume struct { + Table + reception reception + portal string `data:"true"` +} + +func (s volume) List(m *ice.Message, arg ...string) { + if len(arg) == 0 { + if m.Option(model.RECEPTION_UID) != "" { + s.Fields(m, model.UID, model.BEGIN_TIME) + s.Select(m, m.OptionSimple(model.QUEUE_UID, model.RECEPTION_UID)...) + } + } else { + s.Tables(m, s.reception).FieldsWithCreatedAT(m, s, + model.RECEPTION_NAME, + model.AMOUNT, model.COUNT, + model.BEGIN_TIME, model.END_TIME, + ) + if len(arg) == 1 { + s.Select(m, s.Key(s, model.QUEUE_UID), arg[0]) + } else if len(arg) == 2 { + s.SelectDetail(m, s.Key(s, model.QUEUE_UID), arg[0], s.Key(s, model.UID), arg[1]) + } + kit.If(m.Length() == 0, func() { m.Echo(m.Trans("not found", "没有放号")) }) + m.Action() + } +} + +func init() { ice.TeamCtxCmd(volume{}) } diff --git a/src/yuehaoxitong/volume.js b/src/yuehaoxitong/volume.js new file mode 100644 index 0000000..9ee267c --- /dev/null +++ b/src/yuehaoxitong/volume.js @@ -0,0 +1,12 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { + can.onimport.itemcards(can, msg, function(value) { + return [ + {view: html.TITLE, list:[{text: value.reception_name}]}, + {view: html.STATUS, list:[{text: "放号量: "}, {text: value.amount}, {text: "预约量: "}, {text: value.count||"0"}]}, + {view: html.TITLE, list:[{text: "开始时间:"}, {text: value.begin_time}]}, + {view: html.TITLE, list:[{text: "结束时间:"}, {text: value.end_time}]}, + ] + }) + }, +}) \ No newline at end of file diff --git a/usr/local/export/mdb.export/hash.json b/usr/local/export/mdb.export/hash.json index bbaac3f..9d6babf 100644 --- a/usr/local/export/mdb.export/hash.json +++ b/usr/local/export/mdb.export/hash.json @@ -1,4 +1,11 @@ { + "258cd1f28422794acd8081ae19aa2e4c": { + "meta": { + "index": "web.team.yuehaoxitong5.portal", + "time": "2024-08-07 13:12:40.469", + "type": "hash" + } + }, "2f91065050f787e1e3b8aa5338ddd16b": { "meta": { "index": "web.chat.email.client", @@ -6,6 +13,13 @@ "type": "hash" } }, + "4b1e97b62a44419c00caf65e297abd18": { + "meta": { + "index": "web.team.guanlixitong.portal", + "time": "2024-08-07 08:09:09.541", + "type": "hash" + } + }, "63c64bf8b1b104e2db3493f457fd48a7": { "meta": { "index": "aaa.asign", @@ -13,11 +27,67 @@ "type": "hash" } }, + "6460b54238e104a6be50a397439850f7": { + "meta": { + "index": "web.team.yuehaoxitong20.portal", + "time": "2024-08-07 19:38:04.852", + "type": "hash" + } + }, + "858d6327b7710c5c11df1d4f8a1eb754": { + "meta": { + "index": "web.team.yuehaoxitong2.portal", + "time": "2024-08-07 12:51:44.501", + "type": "hash" + } + }, + "9a78f21b2809d8bf2bd0f4fad444a88f": { + "meta": { + "index": "web.team.yuehaoxitong4.portal", + "time": "2024-08-07 13:09:37.550", + "type": "hash" + } + }, "9da3f877eb2450316371f4edc1c93b26": { "meta": { "index": "web.team.gonganxitong.portal", "time": "2024-07-28 15:51:31.253", "type": "hash" } + }, + "a6bcf58de9f87b0af0d842a52ba9d89a": { + "meta": { + "index": "web.team.yuehaoxitong11.portal", + "time": "2024-08-07 18:29:15.954", + "type": "hash" + } + }, + "a9d7661af8cea7074062565dbd27ff83": { + "meta": { + "index": "web.team.yuehaoxitong.portal", + "time": "2024-08-07 08:09:09.554", + "type": "hash" + } + }, + "b71940bd397870fd772e2cbe8ce8f0d3": { + "meta": { + "index": "web.team.yuehaoxitong3.portal", + "time": "2024-08-07 13:05:16.811", + "type": "hash" + } + }, + "ea215091c9be95050ec8bcda532e95fe": { + "meta": { + "index": "web.team.yuehaoxitong1.portal", + "time": "2024-08-07 11:44:12.464", + "type": "hash" + } + }, + "faed481fec1a5ad8dd3ad44f0577e903": { + "meta": { + "index": "web.team.yuehaoxitong10.portal", + "time": "2024-08-07 18:05:36.247", + "type": "hash" + } } } diff --git a/usr/local/export/web.team.gonganxitong.portal/hash.json b/usr/local/export/web.team.gonganxitong.portal/hash.json index d2d4ef1..9ce8219 100644 --- a/usr/local/export/web.team.gonganxitong.portal/hash.json +++ b/usr/local/export/web.team.gonganxitong.portal/hash.json @@ -25,7 +25,7 @@ "index": "web.team.gonganxitong.express.express", "name": "收发快递", "order": "6", - "time": "2024-08-06 18:55:46.304" + "time": "2024-08-07 23:29:49.682" } }, "58724bdcc3cae3e26700cb3199e0602c": { @@ -36,7 +36,7 @@ "name": "场景用户", "order": "5", "role": "creator,landlord", - "time": "2024-08-06 18:55:46.299" + "time": "2024-08-07 19:32:54.758" } }, "91dd0e9590d3021944f14f3ec8653beb": { @@ -77,7 +77,7 @@ "icons": "https://img.icons8.com/officel/80/reading-confirmation.png", "index": "web.team.gonganxitong.email", "name": "邮箱配置", - "time": "2024-08-06 18:35:38.637" + "time": "2024-08-07 00:38:52.287" } } }