diff --git a/src/gonganxitong/common.go b/src/gonganxitong/common.go index ab371ee..f8b5426 100644 --- a/src/gonganxitong/common.go +++ b/src/gonganxitong/common.go @@ -2,6 +2,7 @@ package gonganxitong import ( "path" + "reflect" "shylinux.com/x/ice" icebergs "shylinux.com/x/icebergs" @@ -52,8 +53,6 @@ func (s Table) Init(m *ice.Message, arg ...string) { func (s Table) Exit(m *ice.Message, arg ...string) { s.Table.Exit(m, arg...) } -func (s Table) AfterMigrate(m *ice.Message, arg ...string) { -} func (s Table) Inputs(m *ice.Message, arg ...string) { switch arg[0] { case model.PLACE_TYPE: @@ -74,6 +73,22 @@ func (s Table) Inputs(m *ice.Message, arg ...string) { s.Table.Inputs(m, arg...) } } +func (s Table) InputsList(m *ice.Message, list ice.Any, arg ...string) { + it := reflect.ValueOf(list).MapRange() + for it.Next() { + m.Push(arg[0], it.Key().Int()).Push(model.NAME, it.Value().String()) + } + m.SortInt(arg[0]).DisplayInputKeyNameIconTitle() +} +func (s Table) InputsListRole(m *ice.Message, list ice.Any, arg ...string) { + it := reflect.ValueOf(list).MapRange() + for it.Next() { + if it.Key().Int() > 1 { + m.Push(arg[0], it.Key().Int()).Push(model.NAME, it.Value().String()) + } + } + m.SortInt(arg[0]).DisplayInputKeyNameIconTitle() +} func (s Table) List(m *ice.Message, arg ...string) *ice.Message { if m.IsTech() { if len(arg) == 0 { @@ -114,8 +129,9 @@ func (s Table) SelectJoinUser(m *ice.Message) *ice.Message { func (s Table) SelectJoinCity(m *ice.Message) *ice.Message { return s.SelectJoin(m, city{}, model.NAME) } -func (s Table) CheckRole(m *ice.Message, arg ...string) { - m.ErrorNotImplement() +func (s Table) RenameAppend(m *ice.Message, arg ...string) Table { + m.RenameAppend(arg...) + return s } func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message { m.RewriteAppend(func(value, key string, index int) string { @@ -127,9 +143,8 @@ func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message { }) return m } -func (s Table) RenameAppend(m *ice.Message, arg ...string) Table { - m.RenameAppend(arg...) - return s +func (s Table) CheckRole(m *ice.Message, arg ...string) { + m.ErrorNotImplement() } func (s Table) TransValue(m *ice.Message, key string, arg ...string) string { if value := kit.Select(m.Option(key), arg, 0); m.IsEnglish() { @@ -154,8 +169,21 @@ func (s Table) Update(m *ice.Message, data ice.Map, arg ...string) { data[model.OPERATOR] = m.Option(model.USER_UID) s.Table.Update(m, data, arg...) } -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) RecordEvent(m *ice.Message, place_uid, info string, arg ...string) { + event{}.Record(m.Spawn(kit.Dict(model.PLACE_UID, place_uid)), info, arg...) +} +func (s Table) RecordEventWithName(m *ice.Message, place_uid, info string, arg ...string) { + uid := kit.Select(m.Result(), m.Option(model.UID)) + kit.If(info == "", func() { info = m.ActionCmdTitle() }) + s.RecordEvent(m, place_uid, kit.JoinWord(info, kit.Cut(uid, 6), m.Option(model.NAME)), uid) +} +func (s Table) AddRecent(m *ice.Message, arg ...string) { + cmd := m.GetCommand() + m.Cmd(recent{}, s.Create, mdb.NAME, cmd.Help, mdb.ICON, m.Resource(kit.Select(ice.Info.NodeIcon, cmd.Icon)), web.SPACE, m.Option(ice.MSG_USERPOD), ctx.INDEX, m.PrefixKey(), ctx.ARGS, kit.Join(arg)) +} +func (s Table) SendMessage(m *ice.Message, to_user_uid string, arg ...string) { + cmd := m.GetCommand() + m.Cmd(message{}, s.Create, model.TO_USER_UID, to_user_uid, mdb.NAME, cmd.Help, mdb.ICON, cmd.Icon, web.SPACE, m.Option(ice.MSG_USERPOD), ctx.INDEX, m.PrefixKey(), ctx.ARGS, kit.Join(arg)) } func (s Table) SendTemplate(m *ice.Message, from, user_uid, title string, arg ...string) { if m.IsErr() { @@ -248,4 +276,7 @@ func PortalCmd(portal ice.Any) { cmd("event", event{Table: table}) cmd("member", placeUser{Tables: Tables{Table: table}}) cmd("service", service{Table: table}) + cmd("recent", recent{}) + cmd("message", message{}) + cmd("support", support{}) } diff --git a/src/gonganxitong/common.js b/src/gonganxitong/common.js index ab9404e..d2712db 100644 --- a/src/gonganxitong/common.js +++ b/src/gonganxitong/common.js @@ -1,13 +1,15 @@ Volcanos(chat.ONIMPORT, { - _init: function(can, msg) { + _init: function(can, msg) { can.onimport.shareTitle(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]}, + {view: html.TITLE, list:[{text: [value.title||value.name||value.user_name]}, can.onimport.textView(can, value, PLACE_TYPE, mdb.TYPE), can.onimport.textView(can, value, USER_PLACE_ROLE, aaa.ROLE), ]}, {view: html.STATUS, list: [value.uid && {text: value.uid.slice(0, 6)}, {text: can.base.TimeTrim(value.created_at||value.updated_at)}]}, value.address && {view: html.STATUS, list: [{text: value.address}]}, + value.content && {view: html.OUTPUT, list: [{text: value.content}]}, + value.info && {view: html.OUTPUT, list: [{text: value.info}]}, ] }) }, diff --git a/src/gonganxitong/message.go b/src/gonganxitong/message.go new file mode 100644 index 0000000..945bfb6 --- /dev/null +++ b/src/gonganxitong/message.go @@ -0,0 +1,57 @@ +package gonganxitong + +import ( + "shylinux.com/x/ice" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/community/src/gonganxitong/model" +) + +type message struct { + Table + domain string `data:"gonganxitong"` + read string `name:"read" role:"void"` + done string `name:"done" role:"void"` +} + +func (s message) Create(m *ice.Message, arg ...string) { + s.Table.Create(m, kit.Simple(arg, model.FROM_USER_UID, m.Option(model.USER_UID))...) +} +func (s message) List(m *ice.Message, arg ...string) { + s.Select(m, model.TO_USER_UID, m.Option(model.USER_UID)) + m.Table(func(value ice.Maps) { + switch MessageStatus(kit.Int(value[model.STATUS])) { + case MessageCreate: + m.PushButton(s.Read, s.Done) + case MessageRead: + m.PushButton(s.Done) + default: + m.PushButton() + } + }) + m.Action() +} +func (s message) Read(m *ice.Message, arg ...string) { + s.Table.Update(m, kit.Dict(model.STATUS, MessageRead), m.OptionSimple(model.TO_USER_UID, model.UID)...) +} +func (s message) Done(m *ice.Message, arg ...string) { + s.Table.Update(m, kit.Dict(model.STATUS, MessageDone), m.OptionSimple(model.TO_USER_UID, model.UID)...) +} + +func init() { ice.TeamCtxCmd(message{}) } + +type MessageStatus int + +const ( + MessageCreate MessageStatus = iota + MessageRead + MessageDone +) + +var MessageStatusList = map[MessageStatus]string{ + MessageCreate: "create", + MessageRead: "read", + MessageDone: "done", +} + +func (s MessageStatus) String() string { return MessageStatusList[s] } diff --git a/src/gonganxitong/message.js b/src/gonganxitong/message.js new file mode 100644 index 0000000..2c8b5a5 --- /dev/null +++ b/src/gonganxitong/message.js @@ -0,0 +1,11 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { can.onimport.shareTitle(can, msg) + can.onimport.itemcards(can, msg, function(value) { return [ + {view: html.TITLE, list: [{text: value.name}]}, + {view: html.STATUS, list: [{text: value.uid.slice(0, 6)}, {text: can.base.TimeTrim(value.created_at)}, {text: value.user_name}]}, + {view: html.OUTPUT, list: [{text: value.info}]}, + ] }, function(event, value) { var args = can.core.Split(value.args) + can.onimport._option(can, args[1], value.index, args[0]) + }) + }, +}) \ No newline at end of file diff --git a/src/gonganxitong/model/model.go b/src/gonganxitong/model/model.go index c470aea..f46baf6 100644 --- a/src/gonganxitong/model/model.go +++ b/src/gonganxitong/model/model.go @@ -11,13 +11,10 @@ const ( ROLE = "role" STATUS = "status" CONTENT = "content" - OPERATE = "operate" OPERATOR = "operator" CREATED_AT = "created_at" UPDATED_AT = "updated_at" DELETED_AT = "deleted_at" - BEGIN_TIME = "begin_time" - END_TIME = "end_time" OPEN_ID = "open_id" USER_UID = "user_uid" USER_NAME = "user_name" @@ -36,6 +33,11 @@ const ( APPLY_STATUS = "apply_status" ALLOW_UID = "allow_uid" ALLOW_STATUS = "allow_status" + TO_USER_UID = "to_user_uid" + FROM_USER_UID = "from_user_uid" + BEGIN_TIME = "begin_time" + END_TIME = "end_time" + OPERATE = "operate" TABLES = "tables" EMAIL = "email" AVATAR = "avatar" @@ -51,8 +53,8 @@ type Sess struct { type User struct { db.ModelWithUID OpenID string `gorm:"type:char(32);index"` - Email string `gorm:"type:char(64)"` - Name string `gorm:"type:char(32)"` + Email string `gorm:"type:varchar(64)"` + Name string `gorm:"type:varchar(32)"` Avatar string `gorm:"type:varchar(255)"` } type UserPlace struct { @@ -66,7 +68,7 @@ type UserPlace struct { type Place struct { db.ModelWithUID StreetUID string `gorm:"type:char(32);index"` - Name string `gorm:"type:char(64)"` + Name string `gorm:"type:varchar(64)"` Address string `gorm:"type:varchar(255)"` Type uint8 } @@ -85,16 +87,16 @@ type Event struct { db.ModelWithUID PlaceUID string `gorm:"type:char(32);index:idx_place"` UserUID string `gorm:"type:char(32);index:idx_place"` - Index string `gorm:"type:char(32)"` - Operate string `gorm:"type:char(32)"` - Args string `gorm:"type:char(32)"` + Index string `gorm:"type:varchar(32)"` + Operate string `gorm:"type:varchar(32)"` + Args string `gorm:"type:varchar(32)"` Info string `gorm:"type:varchar(255)"` } type Apply struct { db.ModelWithUID PlaceUID string `gorm:"type:char(32);index:idx_place"` UserUID string `gorm:"type:char(32);index:idx_place"` - Tables string `gorm:"type:char(32)"` + Tables string `gorm:"type:varchar(32)"` Status uint8 Role uint8 BeginTime db.Time @@ -109,19 +111,39 @@ type Allow struct { 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)"` + Icon string `gorm:"type:varchar(32)"` + Name string `gorm:"type:varchar(32)"` + Index string `gorm:"type:varchar(32)"` + Hostname string `gorm:"type:varchar(32)"` + Pathname string `gorm:"type:varchar(255)"` + Nodename string `gorm:"type:varchar(32)"` + Nodetype string `gorm:"type:varchar(32)"` + Portal string `gorm:"type:varchar(255)"` + Domain string `gorm:"type:varchar(255)"` + Module string `gorm:"type:varchar(32)"` + Version string `gorm:"type:varchar(32)"` +} +type Recent struct { + db.ModelWithUID + UserUID string `gorm:"type:char(32);index"` + Name string `gorm:"type:varchar(32)"` + Icon string `gorm:"type:varchar(128)"` + Space string `gorm:"type:varchar(32)"` + Index string `gorm:"type:varchar(64)"` + Args string `gorm:"type:varchar(128)"` +} +type Message struct { + db.ModelWithUID + FromUserUID string `gorm:"type:char(32);index"` + ToUserUID string `gorm:"type:char(32);index"` + Name string `gorm:"type:varchar(32)"` + Icon string `gorm:"type:varchar(128)"` + Space string `gorm:"type:varchar(32)"` + Index string `gorm:"type:varchar(64)"` + Args string `gorm:"type:varchar(128)"` + Status uint `gorm:"default:0"` } func init() { - db.CmdModels("", &Sess{}, &User{}, &UserPlace{}, &Place{}, &Street{}, &City{}, Event{}, Apply{}, Allow{}, Service{}) + db.CmdModels("", &Sess{}, &User{}, &UserPlace{}, &Place{}, &Street{}, &City{}, Event{}, Apply{}, Allow{}, Service{}, Recent{}, Message{}) } diff --git a/src/gonganxitong/portal.css b/src/gonganxitong/portal.css index d52bbab..9987f23 100644 --- a/src/gonganxitong/portal.css +++ b/src/gonganxitong/portal.css @@ -1,22 +1,28 @@ $output { background-color:var(--plugin-bg-color); } -$output>div.list { border-radius:10px; background-color:var(--output-bg-color); padding:10px; margin:10px; overflow-x:hidden; position:relative; } -$output>div.list>div.title { font-weight:bold; display:flex; align-items:center; } -$output>div.list>div.title span:first-child { flex-grow:1; } -$output>div.list>div.title div.action div.item { margin-right:5px; } -$output>div.list>div.title div.action div.item.button.icons input { display:none; } -$output>div.list>div.role:not(.hide) { display:flex; align-items:center; justify-content:space-around; } -$output>div.list>div.role span { padding:5px; cursor:pointer; } -$output>div.list>div.role span.select { border-bottom:var(--box-notice3); } -$output>div.list>div.item.index { padding:10px; display:flex; flex-direction:column; align-items:center; float:left; } -$output>div.list>div.item.index.hide { display:none; } -$output>div.list>div.item.index img { width:100%; } -$output>div.list>div.output { max-height:400px; } -$output>div.list>div.action { display:flex; justify-content:center; } -$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>div.list {background-color:var(--output-bg-color); padding:10px; overflow-x:hidden; position:relative; } +// $output>div.list.myplace { position:sticky; top:10px; } +// $output>div.action { position:sticky; bottom:10px; } +$output>div.output>div.list:last-child { margin-bottom:0; } +$output>div>div.list { border-radius:10px; margin:10px; } +$output>div>div.list>div.title { font-weight:bold; display:flex; align-items:center; } +$output>div>div.list>div.title span:first-child { flex-grow:1; } +$output>div>div.list>div.title div.action div.item { margin-right:5px; } +$output>div>div.list>div.title div.action div.item.button.icons input { display:none; } +$output>div>div.list>div.role:not(.hide) { display:flex; align-items:center; justify-content:space-around; } +$output>div>div.list>div.role span { padding:5px; cursor:pointer; } +$output>div>div.list>div.role span.select { border-bottom:var(--box-notice3); } +$output>div>div.list>div.output>div.item.index { padding:10px; display:flex; flex-direction:column; align-items:center; float:left; } +$output>div>div.list>div.output>div.item.index.hide { display:none; } +$output>div>div.list>div.output>div.item.index img { width:100%; } +// $output>div.list>div.output { max-height:400px; } +$output>div>div.list>div.action { display:flex; justify-content:center; } +$output>div>div.list>div.action div.item { margin-right:5px; } +$output>div>div.list>div.action div.item input[type=button] { color:var(--notice-bg-color); border:none; } +$output>div>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:60px; float:left; } +// $output>div.action div.item.button input[name=create] { background-color:var(--notice-bg-color); color:var(--notice-fg-color); } +// $output>div.action div.item.button input[name=create] { border:var(--box-notice); } $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; } @@ -24,6 +30,8 @@ $output>fieldset table.content td { box-shadow:none; } $output span.type { border:var(--box-notice); color:var(--notice-bg-color); padding:0 3px; } $output span.role { border:var(--box-notice); color:var(--notice-bg-color); padding:0 3px; } // $output span.status { border:var(--box-notice); color:var(--notice-bg-color); } +$output fieldset>div.output>div.code>img { display:block; margin:auto; } +$output fieldset>div.output>div.code { text-align:center; } $output span.type.danger { border:var(--box-danger); color:var(--danger-bg-color); } $output span.role.danger { border:var(--box-danger); color:var(--danger-bg-color); } $output span.status.danger { border:var(--box-danger); color:var(--danger-bg-color); } @@ -36,11 +44,14 @@ $output fieldset.form>div.output>div.code>input[type=button] { font-size:18px; margin:10px; height:36px; } $output fieldset>div.output>div.code>input[type=button] { - border-color:var(--notice-bg-color); color:var(--notice-bg-color); + background-color:var(--notice-bg-color); color:var(--notice-fg-color); margin-right:10px; min-width:80px; float:right; } +$output fieldset>div.output>div.code>input[type=button].danger { + background-color:var(--danger-bg-color); color:var(--danger-fg-color); +} $output fieldset>div.output>div.code>input[type=button][name=cancel] { - border-color:var(--danger-bg-color); color:var(--danger-bg-color); + background-color:var(--danger-bg-color); color:var(--danger-fg-color); } body.en $output>fieldset table.content td:first-child { max-width:180px; width:unset;} $output>fieldset table.content tr.uid { display:none; } diff --git a/src/gonganxitong/portal.go b/src/gonganxitong/portal.go index c792a2f..258d59b 100644 --- a/src/gonganxitong/portal.go +++ b/src/gonganxitong/portal.go @@ -74,6 +74,7 @@ func (s Portal) List(m *ice.Message, arg ...string) { return } if len(arg) == 0 { + s.AddRecent(m) m.Cmdy(s.UserPlace, m.Option(model.USER_UID)).PushAction(s.PlaceRemove).Action(s.PlaceCreate, s.ScanQRCode) kit.If(!m.IsErr() && m.Length() == 0, func() { m.EchoInfoButton(m.Trans("Please Create Your Place", "请添加场所"), s.PlaceCreate, s.ScanQRCode) diff --git a/src/gonganxitong/portal.js b/src/gonganxitong/portal.js index ed50972..5c7bb3b 100644 --- a/src/gonganxitong/portal.js +++ b/src/gonganxitong/portal.js @@ -22,15 +22,22 @@ Volcanos(chat.ONIMPORT, { can.isCmdMode() && (can.db.hash = can.misc.SearchHash(can)), can.db.hash[0] && can.onexport.session(can, PLACE_UID, can.db.hash[0]) if (can.Option(PLACE_UID) == "") { if (can.db.hash.length > 1 && can.db.hash[0]) { return can.Option(PLACE_UID, can.db.hash[0]), can.Option(ctx.INDEX, can.db.hash[1]), can.Update() } - can.ui = can.page.Append(can, can._output, ["myplace.list", "myindex.list"]) + can.ui = can.page.Append(can, can._output, [ + {view: "output", list: ["myplace.list", "myindex.list"]}, + {view: "action", list: ["myorder.list"]}, + ]) can.page.Append(can, can.ui.myplace, [{view: html.TITLE, list: [ {text: can.user.trans(can, "My "+can.base.capital(PLACE_NAME.replace("_name", "")), null, html.INPUT)}, {view: html.ACTION, _init: function(target) { msg.Option(ice.MSG_ACTION) && can.onappend._action(can, msg.Option(ice.MSG_ACTION), target) }} ]}]) var uid = can.onimport.myPlace(can, msg, can.ui.myplace, PLACE_UID, PLACE_NAME, PLACE_TYPE) + can.ui.place_count = msg.Length() msg.Length() > 0 && can.run({}, [uid], function(msg) { can.page.Append(can, can.ui.myindex, [{view: html.TITLE, list: [{text: can.user.trans(can, "My Index", "我的应用")}]}]) - can.onimport.myIndex(can, msg, can.ui.myindex, PLACE_UID, USER_PLACE_ROLE), can.onimport.selectIndex(can, can.sup.current) + can.onimport.myIndex(can, msg, can.ui.myindex, PLACE_UID, USER_PLACE_ROLE) + can.onimport.selectIndex(can, can.sup.current) + can.page.Append(can, can.ui.myorder, [{view: html.TITLE, list: [{text: can.user.trans(can, "My Order", "我的系统")}]}]) + can.onimport.myOrder(can, msg, can.ui.myorder, PLACE_UID, USER_PLACE_ROLE) }) } else { can.onimport.myData(can, msg, can._output, PLACE_UID, PLACE_NAME) @@ -55,16 +62,9 @@ Volcanos(chat.ONIMPORT, { can.page.Append(can, target, [{view: html.ACTION, _init: function(target) { can.onappend._action(can, msg.Option(ice.MSG_ACTION), target) }}]) return place_uid }, - myIndex: function(can, msg, target, PLACE_UID, USER_PLACE_ROLE) { + myList: function(can, msg, target, PLACE_UID, USER_PLACE_ROLE) { 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) - var role = can.page.Append(can, target, [{view: aaa.ROLE, list: can.core.Item(can.Conf("_trans.value."+USER_PLACE_ROLE), function(key, value) { - if (key == "style") { return } - return {text: [can.user.trans(can, key, value), "", key], onclick: function(event) { - can.onimport.selectIndex(can, can.sup.current, key) - can.onmotion.select(can, role, html.SPAN, event.target) - }} - }) }])._target; can.ui.role = role - can.page.Append(can, target||can._output, msg.Table(function(value) { if (value.enable != ice.TRUE) { return } + 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||""), @@ -74,7 +74,29 @@ Volcanos(chat.ONIMPORT, { 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() }} - })) + }))._target + }, + myIndex: function(can, msg, target, PLACE_UID, USER_PLACE_ROLE) { + var role = can.page.Append(can, target, [{view: aaa.ROLE, list: can.core.Item(can.Conf("_trans.value."+USER_PLACE_ROLE), function(key, value) { + if (key == "style") { return } + return {text: [can.user.trans(can, key, value), "", key], onclick: function(event) { + can.onimport.selectIndex(can, can.sup.current, key) + can.onmotion.select(can, role, html.SPAN, event.target) + }} + }) }])._target; can.ui.role = role + var _msg = can.request() + var output = can.page.Append(can, target, [html.OUTPUT])._target + msg.Table(function(value) { if (value.order < 99) { _msg.Push(value) } }) + can.onimport.myList(can, _msg, output, PLACE_UID, USER_PLACE_ROLE) + can.onmotion.delay(can, function() { + can.page.style(can, can.ui.output, html.HEIGHT, can.ConfHeight() - can.ui.action.offsetHeight) + }) + }, + myOrder: function(can, msg, target, PLACE_UID, USER_PLACE_ROLE) { + var _msg = can.request() + msg.Table(function(value) { if (value.order > 99) { _msg.Push(value) } }) + var output = can.page.Append(can, target, [html.OUTPUT])._target + can.onimport.myList(can, _msg, output, PLACE_UID, USER_PLACE_ROLE) }, selectIndex: function(can, value, role) { role = role||value._role can.ui.role && can.onmotion.toggle(can, can.ui.role, value._role == "creator") @@ -112,6 +134,10 @@ Volcanos(chat.ONIMPORT, { can.onexport.hash(can, ""), can.Option(PLACE_UID, ""), can.Option(ctx.INDEX, ""), can.Update() } sub.onexport.output = function(_sub, msg) { can.onappend.style(sub, html.OUTPUT) + _sub.onimport._option = function(_sub, uid, index, place_uid) { + can.Option(PLACE_UID, place_uid), can.Option(ctx.INDEX, index) + can.onexport.hash(can, place_uid||can.Option(PLACE_UID), index||can.Option(ctx.INDEX), uid), can.Update() + } can.onexport.hash(can, can.Option(PLACE_UID), value.index, sub.Option(UID)) 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) @@ -130,6 +156,11 @@ Volcanos(chat.ONIMPORT, { typeStyle: function(can, value, key) { return can.Conf("_lrans.value."+key+".style."+value[key])||"" }, roleStyle: function(can, value, key) { return can.Conf("_trans.value."+key+".style."+value[key])||"" }, textView: function(can, value, key, type) { return value[key] && {text: [can.user.transValue(can, value, key), "", [type, value[key], can.Conf("_trans.value."+key+".style."+value[key])||""]]} }, + shareTitle: function(can, msg, title, content) { + if (msg.IsDetail()) { var value = msg.TableDetail() + msg.Option("_share_title", (value[title]||value.name||value.uid).slice(0, 6)), msg.Option("_share_content", value[content]||value["info"]) + } + }, }) Volcanos(chat.ONEXPORT, { value: function(can, value, PLACE_UID, PLACE_NAME) { diff --git a/src/gonganxitong/portal.json b/src/gonganxitong/portal.json index bd9b5eb..e201ad7 100644 --- a/src/gonganxitong/portal.json +++ b/src/gonganxitong/portal.json @@ -21,7 +21,12 @@ "create": "创建", "project": "项目", "oauth": "授权", - "service": "系统服务", + "message": "消息待办", + "recent": "最近访问", + "service": "服务发现", + "support": "客服支持", + "read": "已读", + "done": "完成", "icons": { "qrcode": "https://img.icons8.com/officel/80/qr-code.png", "apply": "https://img.icons8.com/officel/80/edit-property.png", @@ -30,7 +35,10 @@ "email": "https://img.icons8.com/officel/80/reading-confirmation.png", "placeUser": "https://img.icons8.com/officel/80/person-at-home.png", "member": "https://img.icons8.com/officel/80/person-at-home.png", - "service": "https://img.icons8.com/officel/80/activity-grid.png" + "message": "https://img.icons8.com/officel/80/test-partial-passed.png", + "recent": "https://img.icons8.com/officel/80/multiple-smartphones.png", + "service": "https://img.icons8.com/officel/80/activity-grid.png", + "support": "https://img.icons8.com/officel/80/customer-support.png" }, "style": { "placeRemove": "danger" @@ -82,8 +90,8 @@ } }, "user_place_role": { - "creator": "创建人", "visitor": "访客", + "creator": "创建人", "landlord": "房东", "tenant": "租客", "admin": "管理员", diff --git a/src/gonganxitong/recent.go b/src/gonganxitong/recent.go new file mode 100644 index 0000000..e34158e --- /dev/null +++ b/src/gonganxitong/recent.go @@ -0,0 +1,40 @@ +package gonganxitong + +import ( + "shylinux.com/x/ice" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/web" + kit "shylinux.com/x/toolkits" + + "shylinux.com/x/community/src/gonganxitong/model" +) + +type recent struct { + Table + domain string `data:"gonganxitong"` + create string `name:"create name icon space index args"` + remove string `name:"remove" role:"void"` + open string `name:"open" role:"void"` +} + +func (s recent) Create(m *ice.Message, arg ...string) { + if s.Table.Select(m, m.OptionSimple(model.USER_UID, web.SPACE, ctx.INDEX)...).Length() == 0 { + } + s.Table.Create(m, kit.Simple(arg, m.OptionSimple(model.USER_UID))...) +} +func (s recent) Remove(m *ice.Message, arg ...string) { + s.Table.Delete(m, m.OptionSimple(model.USER_UID, model.UID)...) +} +func (s recent) List(m *ice.Message, arg ...string) { + if len(arg) == 1 { + s.Select(m, model.USER_UID, m.Option(model.USER_UID)) + } else if len(arg) == 2 { + s.SelectDetail(m, model.USER_UID, m.Option(model.USER_UID), model.UID, arg[1]) + } + m.PushAction(s.Open, s.Remove).Action() +} +func (s recent) Open(m *ice.Message, arg ...string) { + m.ProcessOpen(web.S(m.Option(web.SPACE)) + web.C(m.Option(ctx.INDEX))) +} + +func init() { ice.TeamCtxCmd(recent{}) } diff --git a/src/gonganxitong/recent.js b/src/gonganxitong/recent.js new file mode 100644 index 0000000..d0dccc2 --- /dev/null +++ b/src/gonganxitong/recent.js @@ -0,0 +1,11 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { can.onimport.shareTitle(can, msg) + can.onimport.itemcards(can, msg, function(value) { return [ + {view: html.TITLE, list: [value.name]}, + {view: html.STATUS, list: [value.uid.slice(0, 6), can.base.TimeTrim(value.created_at), value.user_name]}, + {view: html.STATUS, list: [value.space]}, + {view: html.STATUS, list: [value.index]}, + {view: html.OUTPUT, list: [value.info]}, + ] }) + }, +}) \ No newline at end of file diff --git a/src/gonganxitong/service.go b/src/gonganxitong/service.go index 4fb85dd..37bcde2 100644 --- a/src/gonganxitong/service.go +++ b/src/gonganxitong/service.go @@ -94,8 +94,12 @@ func (s service) List(m *ice.Message, arg ...string) { } 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) + if m.IsTech() { + m.PushAction(s.Open, s.Conf, s.Project).Action(s.Autogen, s.Compile, s.Oauth) + } else { + m.PushAction(s.Open).Action() + } + m.Display("").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))) diff --git a/src/gonganxitong/support.go b/src/gonganxitong/support.go new file mode 100644 index 0000000..393b409 --- /dev/null +++ b/src/gonganxitong/support.go @@ -0,0 +1,9 @@ +package gonganxitong + +import "shylinux.com/x/ice" + +type support struct{ Tables } + +func (s support) List(m *ice.Message, arg ...string) {} + +func init() { ice.TeamCtxCmd(support{}) } diff --git a/src/gonganxitong/userPlace.go b/src/gonganxitong/userPlace.go index 22b1088..78bf3c0 100644 --- a/src/gonganxitong/userPlace.go +++ b/src/gonganxitong/userPlace.go @@ -25,7 +25,6 @@ func (s userPlace) User(m *ice.Message, arg ...string) { } else { return } - s.RewriteAppend(m) } func (s userPlace) List(m *ice.Message, arg ...string) { s.Tables(m, s.place, s.street, s.city).FieldsWithCreatedAT(m, s, @@ -39,7 +38,6 @@ func (s userPlace) List(m *ice.Message, arg ...string) { } else { return } - s.RewriteAppend(m) } func init() { ice.TeamCtxCmd(userPlace{Table: newTable()}) } @@ -47,16 +45,16 @@ func init() { ice.TeamCtxCmd(userPlace{Table: newTable()}) } type UserPlaceRole int const ( - UserPlaceCreator UserPlaceRole = iota - UserPlaceVisitor + UserPlaceVisitor UserPlaceRole = iota + UserPlaceCreator UserPlaceLandlord UserPlaceTenant UserPlaceAdmin ) var UserPlaceRoleList = map[UserPlaceRole]string{ - UserPlaceCreator: "creator", UserPlaceVisitor: "visitor", + UserPlaceCreator: "creator", UserPlaceLandlord: "landlord", UserPlaceTenant: "tenant", UserPlaceAdmin: "admin", diff --git a/src/main.go b/src/main.go index c49de7e..301d035 100644 --- a/src/main.go +++ b/src/main.go @@ -10,4 +10,4 @@ import ( func main() { print(ice.Run()) } -func init() { ice.Info.Titles = "云社区" } +func init() { ice.Info.Titles = "云社区" } \ No newline at end of file diff --git a/src/template/web.code.js/demo.js b/src/template/web.code.js/demo.js index 963d6a5..b01fe17 100644 --- a/src/template/web.code.js/demo.js +++ b/src/template/web.code.js/demo.js @@ -1,10 +1,9 @@ Volcanos(chat.ONIMPORT, { - _init: function(can, msg) { - if (msg.IsDetail()) { var value = msg.TableDetail(); msg.Option("_share_title", value.title), msg.Option("_share_content", value.content) } + _init: function(can, msg) { can.onimport.shareTitle(can, msg) can.onimport.itemcards(can, msg, function(value) { return [ - {view: html.TITLE, list: [{text: value.title}]}, - {view: html.STATUS, list: [{text: value.uid.slice(0, 6)}, {text: can.base.TimeTrim(value.created_at)}, {text: value.user_name}]}, - {view: html.OUTPUT, list: [{text: value.content}]}, + {view: html.TITLE, list: [value.name||value.title||value.user_name]}, + {view: html.STATUS, list: [value.uid.slice(0, 6), can.base.TimeTrim(value.created_at)]}, + {view: html.OUTPUT, list: [value.info||value.content]}, ] }) }, }) diff --git a/src/yuehaoxitong/portal.json b/src/yuehaoxitong/portal.json index ddc268e..8dfce2a 100644 --- a/src/yuehaoxitong/portal.json +++ b/src/yuehaoxitong/portal.json @@ -46,8 +46,8 @@ }, "value": { "user_queue_role": { - "creator": "创建人", "visitor": "访客", + "creator": "创建人", "manager": "管理员", "worker": "工作员", "waiter": "接待员", diff --git a/src/yuehaoxitong/userQueue.go b/src/yuehaoxitong/userQueue.go index ca7b334..c7fc5c6 100644 --- a/src/yuehaoxitong/userQueue.go +++ b/src/yuehaoxitong/userQueue.go @@ -46,16 +46,16 @@ func init() { ice.TeamCtxCmd(userQueue{Table: newTable()}) } type UserQueueRole int const ( - UserQueueCreator UserQueueRole = iota - UserQueueVisitor + UserQueueVisitor UserQueueRole = iota + UserQueueCreator UserQueueManager UserQueueWorker UserQueueWaiter ) var UserQueueRoleList = map[UserQueueRole]string{ - UserQueueCreator: "creator", UserQueueVisitor: "visitor", + UserQueueCreator: "creator", UserQueueManager: "manager", UserQueueWorker: "worker", UserQueueWaiter: "waiter", diff --git a/usr/local/export/web.chat.wx.menu/hash.json b/usr/local/export/web.chat.wx.menu/hash.json index 5adfbe9..a3854a6 100644 --- a/usr/local/export/web.chat.wx.menu/hash.json +++ b/usr/local/export/web.chat.wx.menu/hash.json @@ -59,7 +59,7 @@ }, "dd6b254ed82967e82736a0b16353dcf5": { "meta": { - "index": "web.team.shengyixitong.portal", + "index": "web.team.gongyinglian.portal", "name": "供应链", "river": "3", "scene": "main", diff --git a/usr/local/export/web.team.gonganxitong.portal/hash.json b/usr/local/export/web.team.gonganxitong.portal/hash.json index 8836d17..45716d4 100644 --- a/usr/local/export/web.team.gonganxitong.portal/hash.json +++ b/usr/local/export/web.team.gonganxitong.portal/hash.json @@ -7,8 +7,8 @@ "enable": "true", "icons": "https://img.icons8.com/officel/80/activity-grid.png", "index": "web.team.gonganxitong.service", - "name": "系统服务", - "order": "100", + "name": "服务发现", + "order": "102", "role": "creator", "time": "2024-08-06 18:45:35.904" } @@ -59,6 +59,7 @@ "_target": [ "d21f8cd636d4b90986a476e4746c1b25" ], + "enable": "true", "icons": "https://img.icons8.com/officel/80/receipt-approved.png", "index": "web.team.gonganxitong.allow", "name": "权限审批", @@ -67,18 +68,14 @@ "time": "2024-08-16 10:29:07.314" } }, - "91dd0e9590d3021944f14f3ec8653beb": { + "a89a7c09e326295aaa7e7ea3d66fb28a": { "meta": { - "_target": [ - "5e5292ec8e95dedb5e23fa5a49ffc1f4" - ], "enable": "true", - "icons": "https://img.icons8.com/officel/80/receipt-approved.png", - "index": "web.team.gonganxitong.order", - "name": "权限审批", - "order": "4", - "role": "creator,landlord", - "time": "2024-08-06 18:40:42.578" + "icons": "https://img.icons8.com/officel/80/customer-support.png", + "index": "web.team.gonganxitong.support", + "name": "客服支持", + "order": "103", + "time": "2024-08-20 12:10:06.186" } }, "bdec92d5849b2a60a8811cff494f2391": { @@ -95,6 +92,16 @@ "time": "2024-08-06 18:45:35.911" } }, + "be08ca65be90feca325df128a06e440f": { + "meta": { + "enable": "true", + "icons": "https://img.icons8.com/officel/80/multiple-smartphones.png", + "index": "web.team.gonganxitong.recent", + "name": "最近访问", + "order": "101", + "time": "2024-08-20 10:37:42.641" + } + }, "e2117b53c036a72fe7e4885449488a6f": { "meta": { "_target": [ @@ -109,6 +116,16 @@ "time": "2024-08-06 18:39:44.988" } }, + "fd1884bbeb1f1a83f4e12f857bfe5b15": { + "meta": { + "enable": "true", + "icons": "https://img.icons8.com/officel/80/test-partial-passed.png", + "index": "web.team.gonganxitong.message", + "name": "消息待办", + "order": "100", + "time": "2024-08-20 10:37:42.648" + } + }, "fd86aad80a667152781bb188fb1249a2": { "meta": { "_target": [ diff --git a/usr/local/export/web.team.guanlixitong.portal/hash.json b/usr/local/export/web.team.guanlixitong.portal/hash.json index 900a9f4..2b974dc 100644 --- a/usr/local/export/web.team.guanlixitong.portal/hash.json +++ b/usr/local/export/web.team.guanlixitong.portal/hash.json @@ -19,7 +19,7 @@ ], "icons": "https://img.icons8.com/officel/80/activity-grid.png", "index": "web.team.guanlixitong.service", - "name": "系统服务", + "name": "服务发现", "order": "100", "role": "creator", "time": "2024-08-07 08:09:16.496" @@ -69,6 +69,14 @@ "time": "2024-08-07 08:09:16.522" } }, + "9fffbe375e2d2a1a8e6cb1f341e35b55": { + "meta": { + "icons": "https://img.icons8.com/officel/80/multiple-smartphones.png", + "index": "web.team.guanlixitong.recent", + "name": "最近访问", + "time": "2024-08-20 11:07:54.831" + } + }, "a4e85767b176b6a07751156a6b73fa94": { "meta": { "_target": [ @@ -101,6 +109,14 @@ "time": "2024-08-07 08:09:16.541" } }, + "d25f3f88261ead2a0079415a26aa6853": { + "meta": { + "icons": "https://img.icons8.com/officel/80/test-partial-passed.png", + "index": "web.team.guanlixitong.message", + "name": "消息待办", + "time": "2024-08-20 11:07:54.833" + } + }, "fa5ff99e330772f88b929de7762a36f1": { "meta": { "_target": [ diff --git a/usr/local/export/web.team.yuehaoxitong.portal/hash.json b/usr/local/export/web.team.yuehaoxitong.portal/hash.json index 67e410e..ab74ac2 100644 --- a/usr/local/export/web.team.yuehaoxitong.portal/hash.json +++ b/usr/local/export/web.team.yuehaoxitong.portal/hash.json @@ -41,6 +41,14 @@ "time": "2024-08-11 09:30:00.526" } }, + "377f3c0dae9dbf423a8e188bfd245b7a": { + "meta": { + "icons": "https://img.icons8.com/officel/80/multiple-smartphones.png", + "index": "web.team.yuehaoxitong.recent", + "name": "最近访问", + "time": "2024-08-20 11:07:54.840" + } + }, "3b6da44aaf19fdb06c84fe352569359f": { "meta": { "_target": [ @@ -96,6 +104,14 @@ "time": "2024-08-11 09:30:00.538" } }, + "98d6d53a44113b33a82c4e914cb23489": { + "meta": { + "icons": "https://img.icons8.com/officel/80/test-partial-passed.png", + "index": "web.team.yuehaoxitong.message", + "name": "消息待办", + "time": "2024-08-20 11:07:54.887" + } + }, "a56cb18131ff45616849e4555e29d35d": { "meta": { "_target": [ @@ -173,7 +189,7 @@ "enable": "true", "icons": "https://img.icons8.com/officel/80/activity-grid.png", "index": "web.team.yuehaoxitong.service", - "name": "系统服务", + "name": "服务发现", "order": "100", "role": "creator", "time": "2024-08-11 09:30:00.529"