diff --git a/base/aaa/sess.go b/base/aaa/sess.go
index 940fa9a9..cdc02851 100644
--- a/base/aaa/sess.go
+++ b/base/aaa/sess.go
@@ -55,9 +55,9 @@ func SessAuth(m *ice.Message, value ice.Any, arg ...string) *ice.Message {
value = kit.Dict(USERNICK, kit.Select("", val, 0), USERNAME, kit.Select("", val, 1), USERROLE, kit.Select("", val, 2))
}
return m.Auth(
- USERNICK, m.Option(ice.MSG_USERNICK, kit.Value(value, USERNICK)),
- USERNAME, m.Option(ice.MSG_USERNAME, kit.Value(value, USERNAME)),
- USERROLE, m.Option(ice.MSG_USERROLE, kit.Value(value, USERROLE)),
+ USERNICK, m.Option(ice.MSG_USERNICK, kit.Format(kit.Value(value, USERNICK))),
+ USERNAME, m.Option(ice.MSG_USERNAME, kit.Format(kit.Value(value, USERNAME))),
+ USERROLE, m.Option(ice.MSG_USERROLE, kit.Format(kit.Value(value, USERROLE))),
arg, logs.FileLineMeta(kit.Select(logs.FileLine(-1), m.Option("aaa.checker"))),
)
}
diff --git a/base/aaa/user.go b/base/aaa/user.go
index d9570dfb..29e9c8fe 100644
--- a/base/aaa/user.go
+++ b/base/aaa/user.go
@@ -56,6 +56,7 @@ func init() {
}
func UserInfo(m *ice.Message, name ice.Any, key, meta string) (value string) {
+
if m.Cmd(USER, kit.Select(m.Option(ice.MSG_USERNAME), name), func(val ice.Maps) { value = val[key] }).Length() == 0 && kit.Format(name) == m.Option(ice.MSG_USERNAME) {
return m.Option(meta)
}
diff --git a/base/cli/cli.go b/base/cli/cli.go
index 9d5d2f93..df68cf21 100644
--- a/base/cli/cli.go
+++ b/base/cli/cli.go
@@ -1,9 +1,14 @@
package cli
-import ice "shylinux.com/x/icebergs"
+import (
+ ice "shylinux.com/x/icebergs"
+ kit "shylinux.com/x/toolkits"
+)
const CLI = "cli"
var Index = &ice.Context{Name: CLI, Help: "命令模块"}
+func Prefix(arg ...string) string { return kit.Keys(CLI, arg) }
+
func init() { ice.Index.Register(Index, nil, RUNTIME, SYSTEM, DAEMON, FOREVER, MIRRORS, QRCODE) }
diff --git a/base/cli/qrcode.go b/base/cli/qrcode.go
index 8b335613..8279ba18 100644
--- a/base/cli/qrcode.go
+++ b/base/cli/qrcode.go
@@ -50,7 +50,7 @@ func init() {
QRCODE: {Name: "qrcode text fg@key bg@key size auto", Help: "二维码", Actions: ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
ice.AddRender(ice.RENDER_QRCODE, func(m *ice.Message, args ...ice.Any) string {
- return m.Cmd(QRCODE, kit.Simple(args...)).Result()
+ return m.Cmd(Prefix(QRCODE), kit.Simple(args...)).Result()
})
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
diff --git a/base/gdb/event.go b/base/gdb/event.go
index c42e4114..64a505c1 100644
--- a/base/gdb/event.go
+++ b/base/gdb/event.go
@@ -44,13 +44,13 @@ var list map[string]int = map[string]int{}
func Watch(m *ice.Message, key string, arg ...string) *ice.Message {
kit.If(len(arg) == 0, func() { arg = append(arg, m.PrefixKey()) })
- return m.Cmd(EVENT, LISTEN, EVENT, key, ice.CMD, kit.Join(arg, ice.SP))
+ return m.Cmd(Prefix(EVENT), LISTEN, EVENT, key, ice.CMD, kit.Join(arg, ice.SP))
}
func Event(m *ice.Message, key string, arg ...ice.Any) *ice.Message {
if key = kit.Select(kit.Keys(m.CommandKey(), m.ActionKey()), key); list[key] == 0 {
return m
}
- return m.Cmdy(EVENT, HAPPEN, EVENT, key, arg, logs.FileLineMeta(-1))
+ return m.Cmdy(Prefix(EVENT), HAPPEN, EVENT, key, arg, logs.FileLineMeta(-1))
}
func EventDeferEvent(m *ice.Message, key string, arg ...ice.Any) func(string, ...ice.Any) {
Event(m, key, arg...)
diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go
index 5c11729c..5876dfa4 100644
--- a/base/gdb/gdb.go
+++ b/base/gdb/gdb.go
@@ -49,4 +49,6 @@ const GDB = "gdb"
var Index = &ice.Context{Name: GDB, Help: "事件模块"}
+func Prefix(arg ...string) string { return kit.Keys(GDB, arg) }
+
func init() { ice.Index.Register(Index, &Frame{}, SIGNAL, EVENT, TIMER, ROUTINE) }
diff --git a/base/mdb/lock.go b/base/mdb/lock.go
index 81110341..5736ff7d 100644
--- a/base/mdb/lock.go
+++ b/base/mdb/lock.go
@@ -30,6 +30,12 @@ func RLock(m configMessage, arg ...string) func() { return getLock(m, arg...).RL
func Config(m configMessage, key string, arg ...Any) string {
return kit.Format(Configv(m, key, arg...))
}
+func ConfigSimple(m configMessage, key ...string) (res []string) {
+ for _, key := range key {
+ res = append(res, key, kit.Format(Configv(m, key)))
+ }
+ return
+}
func Configv(m configMessage, key string, arg ...Any) Any {
kit.If(len(arg) > 0, func() { Confv(m, m.PrefixKey(), kit.Keym(key), arg[0]) })
return Confv(m, m.PrefixKey(), kit.Keym(key))
diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go
index 9291910d..4dd60712 100644
--- a/base/mdb/mdb.go
+++ b/base/mdb/mdb.go
@@ -92,6 +92,7 @@ const (
STORE = kit.MDB_STORE
FSIZE = kit.MDB_FSIZE
+ ICONS = "icons"
TOOLS = "tools"
SOURCE = "_source"
TARGET = "_target"
@@ -101,6 +102,7 @@ const (
INPUTS = "inputs"
CREATE = "create"
REMOVE = "remove"
+ UPDATE = "update"
INSERT = "insert"
DELETE = "delete"
MODIFY = "modify"
diff --git a/base/web/share.go b/base/web/share.go
index b56f6e88..197b9c10 100644
--- a/base/web/share.go
+++ b/base/web/share.go
@@ -185,3 +185,9 @@ func ProxyUpload(m *ice.Message, pod string, p string) string {
m.Cmd(SPACE, pod, SPIDE, PROXY, URL, url, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, mdb.AT+p)
return kit.Select(p, pp, file.ExistsFile(pp))
}
+func ShareLocal(m *ice.Message, p string) string {
+ if kit.HasPrefix(p, nfs.PS, HTTP) {
+ return p
+ }
+ return MergeLink(m, "/share/local/"+p)
+}
diff --git a/core/chat/favor.go b/core/chat/favor.go
index 009cc6d4..af1164cf 100644
--- a/core/chat/favor.go
+++ b/core/chat/favor.go
@@ -23,7 +23,7 @@ const FAVOR = "favor"
func init() {
Index.MergeCommands(ice.Commands{
- FAVOR: {Help: "收藏夹", Icon: "favor.png", Actions: ice.MergeActions(ice.Actions{
+ FAVOR: {Name: "favor hash auto", Help: "收藏夹", Icon: "favor.png", Actions: ice.MergeActions(ice.Actions{
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
if mdb.IsSearchPreview(m, arg) {
m.Cmds("", func(value ice.Maps) {
@@ -58,7 +58,7 @@ func init() {
"scanQRCode": {Name: "favor create", Help: "扫码"},
"record1": {Name: "favor upload", Help: "截图"},
"record2": {Name: "favor upload", Help: "录屏"},
- mdb.CREATE: {Name: "create type name text", Hand: func(m *ice.Message, arg ...string) {
+ mdb.CREATE: {Name: "create type name text*", Hand: func(m *ice.Message, arg ...string) {
if strings.HasPrefix(m.Option(mdb.TEXT), ice.HTTP) {
m.OptionDefault(mdb.TYPE, mdb.LINK, mdb.NAME, kit.ParseURL(m.Option(mdb.TEXT)).Host)
}
@@ -81,7 +81,7 @@ func init() {
}
}},
cli.OPENS: {Hand: func(m *ice.Message, arg ...string) { cli.Opens(m, m.Option(mdb.TEXT)) }},
- }, FavorAction(), mdb.ExportHashAction()), Hand: func(m *ice.Message, arg ...string) {
+ }, FavorAction(), mdb.ExportHashAction(mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,hash,type,name,text")), Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 0 && arg[0] == ctx.ACTION {
if m.Option(ice.MSG_INDEX) == m.PrefixKey() {
m.Option(mdb.TYPE, mdb.HashSelects(m.Spawn(), m.Option(mdb.HASH)).Append(mdb.TYPE))
@@ -98,6 +98,7 @@ func init() {
} else {
m.Action(mdb.CREATE, web.UPLOAD, "getClipboardData", "record1", "record2")
}
+ m.SortStrR(mdb.TIME)
} else {
if web.PodCmd(m, web.SPACE, arg...) {
return
diff --git a/core/chat/header.go b/core/chat/header.go
index 67b1c8cc..94871174 100644
--- a/core/chat/header.go
+++ b/core/chat/header.go
@@ -99,7 +99,7 @@ func init() {
m.Option("language.list", m.Cmd(nfs.DIR, nfs.TemplatePath(m, aaa.LANGUAGE)+nfs.PS, nfs.FILE).Appendv(nfs.FILE))
m.Option("theme.list", m.Cmd(nfs.DIR, nfs.TemplatePath(m, aaa.THEME)+nfs.PS, nfs.FILE).Appendv(nfs.FILE))
m.Option(nfs.REPOS, m.Cmdv(web.SPIDE, nfs.REPOS, web.CLIENT_URL))
- m.Option(ICONS, mdb.Conf(m, ICONS, kit.Keym(nfs.PATH)))
+ m.Option("icons", mdb.Conf(m, ICON, kit.Keym(nfs.PATH)))
m.Option(MENUS, mdb.Config(m, MENUS))
m.Echo(mdb.Config(m, TITLE))
if mdb.HashSelect(m); m.Length() == 0 {
diff --git a/core/chat/icons.go b/core/chat/icon.go
similarity index 78%
rename from core/chat/icons.go
rename to core/chat/icon.go
index 43c78573..9d6563a8 100644
--- a/core/chat/icons.go
+++ b/core/chat/icon.go
@@ -11,11 +11,11 @@ import (
kit "shylinux.com/x/toolkits"
)
-const ICONS = "icons"
+const ICON = "icon"
func init() {
Index.MergeCommands(ice.Commands{
- ICONS: {Help: "图标", Actions: ctx.ConfAction(nfs.PATH, "bootstrap-icons/font/bootstrap-icons.css"), Hand: func(m *ice.Message, arg ...string) {
+ ICON: {Help: "图标", Actions: ctx.ConfAction(nfs.PATH, "bootstrap-icons/font/bootstrap-icons.css"), Hand: func(m *ice.Message, arg ...string) {
m.Cmd(lex.SPLIT, ice.USR_MODULES+mdb.Config(m, nfs.PATH), kit.Dict(lex.SPLIT_SPACE, " {:;}"), func(text string, ls []string) {
if len(ls) > 2 && ls[2] == nfs.CONTENT {
name := "bi " + strings.TrimPrefix(ls[0], nfs.PT)
diff --git a/core/chat/location/amap.go b/core/chat/location/amap.go
index a3d4ed02..efe554cd 100644
--- a/core/chat/location/amap.go
+++ b/core/chat/location/amap.go
@@ -1,4 +1,4 @@
-package chat
+package location
import (
"path"
diff --git a/core/chat/location/bmap.go b/core/chat/location/bmap.go
index 4695b011..6bead919 100644
--- a/core/chat/location/bmap.go
+++ b/core/chat/location/bmap.go
@@ -1,4 +1,4 @@
-package chat
+package location
import (
ice "shylinux.com/x/icebergs"
diff --git a/core/chat/location/location.go b/core/chat/location/location.go
index cf0ef004..4a25786d 100644
--- a/core/chat/location/location.go
+++ b/core/chat/location/location.go
@@ -1,4 +1,4 @@
-package chat
+package location
import (
ice "shylinux.com/x/icebergs"
@@ -17,6 +17,7 @@ const (
CITY = "city"
DISTRICT = "district"
STREET = "street"
+ SCALE = "scale"
)
const LOCATION = "location"
diff --git a/core/chat/location/tmap.go b/core/chat/location/tmap.go
index 2d0ecafe..59a931d6 100644
--- a/core/chat/location/tmap.go
+++ b/core/chat/location/tmap.go
@@ -1,4 +1,4 @@
-package chat
+package location
import (
"net/http"
diff --git a/core/mall/goods.go b/core/mall/goods.go
index e13e03cd..f78ad88f 100644
--- a/core/mall/goods.go
+++ b/core/mall/goods.go
@@ -2,6 +2,7 @@ package mall
import (
ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
@@ -21,7 +22,7 @@ func init() {
mdb.CREATE: {Name: "create zone* name* text price* count*=1 units*=件,个,份,斤 image*=4@img"},
mdb.MODIFY: {Name: "modify zone* name* text price* count*=1 units*=件,个,份,斤 image*=4@img"},
ORDER: {Name: "order count*=1", Help: "选购", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(CART, mdb.INSERT, arg) }},
- }, web.ExportCacheAction(nfs.IMAGE), mdb.ExportHashAction(ctx.TOOLS, kit.Fields(Prefix(CART), Prefix(ORDER)), mdb.FIELD, "time,hash,zone,name,text,price,count,units,image")), Hand: func(m *ice.Message, arg ...string) {
+ }, aaa.RoleAction(), web.ExportCacheAction(nfs.IMAGE), mdb.ExportHashAction(ctx.TOOLS, kit.Fields(Prefix(CART), Prefix(ORDER)), mdb.FIELD, "time,hash,zone,name,text,price,count,units,image")), Hand: func(m *ice.Message, arg ...string) {
kit.If(len(arg) == 0 && m.IsMobileUA(), func() { m.OptionDefault(ice.MSG_FIELDS, "zone,name,price,count,units,text,hash,time,image") })
mdb.HashSelect(m, arg...).PushAction(ORDER).Action("filter:text")
web.PushPodCmd(m, "", arg...).Sort("zone,name")
diff --git a/misc/wx/access.go b/misc/wx/access.go
index d470a30e..02a255f7 100644
--- a/misc/wx/access.go
+++ b/misc/wx/access.go
@@ -4,96 +4,84 @@ import (
"crypto/sha1"
"net/http"
"strings"
- "time"
ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/ctx"
- "shylinux.com/x/icebergs/base/gdb"
"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/chat"
+ "shylinux.com/x/icebergs/base/web/html"
+ "shylinux.com/x/icebergs/core/chat/oauth"
kit "shylinux.com/x/toolkits"
)
-func _wx_sign(m *ice.Message, nonce, stamp string) string {
- return kit.Format(sha1.Sum([]byte(kit.Join(kit.Sort(kit.Simple(
- kit.Format("jsapi_ticket=%s", m.Cmdx(ACCESS, TICKET)),
- kit.Format("url=%s", m.Option(ice.MSG_USERWEB)),
- kit.Format("timestamp=%s", stamp),
- kit.Format("noncestr=%s", nonce),
- )), "&"))))
-}
-func _wx_config(m *ice.Message, nonce string) {
- m.Option("signature", _wx_sign(m, m.Option("noncestr", nonce), m.Option("timestamp", kit.Format(time.Now().Unix()))))
- ctx.OptionFromConfig(m, APPID, nfs.SCRIPT)
-}
-func _wx_check(m *ice.Message) {
- check := kit.Sort([]string{mdb.Config(m, TOKEN), m.Option("timestamp"), m.Option("nonce")})
- if sig := kit.Format(sha1.Sum([]byte(strings.Join(check, "")))); !m.Warn(sig != m.Option("signature"), ice.ErrNotRight, check) {
- kit.If(m.Option("echostr") != "", func() { m.RenderResult(m.Option("echostr")) }, func() { m.Echo(ice.TRUE) })
- }
-}
-
const (
APPID = "appid"
- APPMM = "appmm"
+ SECRET = "secret"
TOKEN = "token"
TOKENS = "tokens"
EXPIRES = "expires"
TICKET = "ticket"
EXPIRE = "expire"
- CONFIG = "config"
- CHECK = "check"
)
const (
- ERRCODE = "errcode"
- ERRMSG = "errmsg"
+ CGI_BIN = "https://api.weixin.qq.com/cgi-bin/"
+ QRCODE_CREATE = "qrcode/create"
+ MENU_CREATE = "menu/create"
+ USER_INFO = "user/info"
+ USER_GET = "user/get"
)
const ACCESS = "access"
func init() {
Index.MergeCommands(ice.Commands{
- ACCESS: {Name: "access appid auto ticket tokens login", Help: "认证", Actions: ice.MergeActions(ice.Actions{
- ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Cmd(web.SPIDE, mdb.CREATE, WX, mdb.Config(m, tcp.SERVER))
- gdb.Watch(m, chat.HEADER_AGENT, m.PrefixKey())
+ ACCESS: {Help: "认证", Meta: Meta(), Actions: ice.MergeActions(ice.Actions{
+ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(web.SPIDE, mdb.CREATE, WX, mdb.Config(m, tcp.SERVER)) }},
+ mdb.CREATE: {Name: "login usernick access* appid* secret* token* icons", Help: "登录", Hand: func(m *ice.Message, arg ...string) {
+ mdb.HashCreate(m, m.OptionSimple(aaa.USERNICK, ACCESS, APPID, SECRET, TOKEN, mdb.ICONS))
+ ctx.ConfigFromOption(m, ACCESS, APPID, TOKEN)
}},
- chat.HEADER_AGENT: {Hand: func(m *ice.Message, arg ...string) {
- if strings.Index(m.Option(ice.MSG_USERUA), "MicroMessenger") > -1 {
- _wx_config(m, mdb.Config(m, APPID))
+ aaa.CHECK: {Hand: func(m *ice.Message, arg ...string) {
+ check := kit.Sort([]string{mdb.Config(m, TOKEN), m.Option(TIMESTAMP), m.Option(NONCE)})
+ if sig := kit.Format(sha1.Sum([]byte(strings.Join(check, "")))); !m.Warn(sig != m.Option(SIGNATURE), ice.ErrNotRight, check) {
+ m.Echo(ice.TRUE)
}
}},
- LOGIN: {Name: "login appid appmm token", Help: "登录", Hand: func(m *ice.Message, arg ...string) {
- ctx.ConfigFromOption(m, APPID, APPMM, TOKEN)
- }},
- TOKENS: {Help: "令牌", Hand: func(m *ice.Message, arg ...string) {
- if now := time.Now().Unix(); mdb.Config(m, TOKENS) == "" || now > kit.Int64(mdb.Config(m, EXPIRES)) {
- msg := m.Cmd(web.SPIDE, WX, http.MethodGet, "/cgi-bin/token?grant_type=client_credential", APPID, mdb.Config(m, APPID), "secret", mdb.Config(m, APPMM))
- if m.Warn(msg.Append(ERRCODE) != "", msg.Append(ERRCODE), msg.Append(ERRMSG)) {
- return
- }
- mdb.Config(m, EXPIRES, now+kit.Int64(msg.Append("expires_in")))
- mdb.Config(m, TOKENS, msg.Append("access_token"))
+ AGENT: {Hand: func(m *ice.Message, arg ...string) { ctx.OptionFromConfig(m, ACCESS, APPID) }},
+ TOKENS: {Hand: func(m *ice.Message, arg ...string) {
+ msg := mdb.HashSelect(m.Spawn(), m.Option(ACCESS))
+ if msg.Append(TOKENS) == "" || m.Time() > msg.Append(EXPIRES) {
+ res := m.Cmd(web.SPIDE, WX, http.MethodGet, "token?grant_type=client_credential", msg.AppendSimple(APPID, SECRET))
+ mdb.HashModify(m, m.OptionSimple(ACCESS), EXPIRES, m.Time(kit.Format("%vs", res.Append(oauth.EXPIRES_IN))), TOKENS, res.Append(oauth.ACCESS_TOKEN))
+ msg = mdb.HashSelect(m.Spawn(), m.Option(ACCESS))
}
- m.Echo(mdb.Config(m, TOKENS)).Status(EXPIRES, time.Unix(kit.Int64(mdb.Config(m, EXPIRES)), 0).Format(ice.MOD_TIME))
+ m.Echo(msg.Append(TOKENS)).Status(msg.AppendSimple(EXPIRES))
}},
- TICKET: {Help: "票据", Hand: func(m *ice.Message, arg ...string) {
- if now := time.Now().Unix(); mdb.Config(m, TICKET) == "" || now > kit.Int64(mdb.Config(m, EXPIRE)) {
- msg := m.Cmd(web.SPIDE, WX, http.MethodGet, "/cgi-bin/ticket/getticket?type=jsapi", "access_token", m.Cmdx("", TOKENS))
- if m.Warn(msg.Append(ERRCODE) != "0", msg.Append(ERRCODE), msg.Append(ERRMSG)) {
- return
- }
- mdb.Config(m, EXPIRE, now+kit.Int64(msg.Append("expires_in")))
- mdb.Config(m, TICKET, msg.Append(TICKET))
+ TICKET: {Hand: func(m *ice.Message, arg ...string) {
+ msg := mdb.HashSelect(m.Spawn(), m.Option(ACCESS))
+ if msg.Append(TICKET) == "" || m.Time() > msg.Append(EXPIRE) {
+ res := m.Cmd(web.SPIDE, WX, http.MethodGet, "ticket/getticket?type=jsapi", arg, oauth.ACCESS_TOKEN, m.Cmdx(ACCESS, TOKENS))
+ mdb.HashModify(m, m.OptionSimple(ACCESS), EXPIRE, m.Time(kit.Format("%vs", res.Append(oauth.EXPIRES_IN))), TICKET, res.Append(TICKET))
+ msg = mdb.HashSelect(m.Spawn(), m.Option(ACCESS))
}
- m.Echo(mdb.Config(m, TICKET)).Status(EXPIRE, time.Unix(kit.Int64(mdb.Config(m, EXPIRE)), 0).Format(ice.MOD_TIME))
+ m.Echo(msg.Append(TICKET)).Status(msg.AppendSimple(EXPIRE))
}},
- CONFIG: {Hand: func(m *ice.Message, arg ...string) { _wx_config(m, mdb.Config(m, APPID)) }},
- CHECK: {Hand: func(m *ice.Message, arg ...string) { _wx_check(m) }},
- }, mdb.HashAction(tcp.SERVER, "https://api.weixin.qq.com", nfs.SCRIPT, "/plugin/local/chat/wx.js")), Hand: func(m *ice.Message, arg ...string) {
- m.Echo(mdb.Config(m, APPID))
+ }, mdb.ImportantHashAction(mdb.SHORT, ACCESS, mdb.FIELD, "time,access,usernick,appid,icons", tcp.SERVER, CGI_BIN)), Hand: func(m *ice.Message, arg ...string) {
+ mdb.HashSelect(m, arg...).StatusTimeCount(mdb.ConfigSimple(m, ACCESS, APPID), web.LINK, web.MergeURL2(m, "/chat/wx/login/"))
}},
})
}
+func SpideGet(m *ice.Message, api string, arg ...ice.Any) ice.Any {
+ return kit.UnMarshal(m.Cmdx(web.SPIDE, WX, web.SPIDE_RAW, http.MethodGet, kit.MergeURL(api, oauth.ACCESS_TOKEN, m.Cmdx(ACCESS, TOKENS)), arg))
+}
+func SpidePost(m *ice.Message, api string, arg ...ice.Any) ice.Any {
+ return kit.UnMarshal(m.Cmdx(web.SPIDE, WX, web.SPIDE_RAW, http.MethodPost, kit.MergeURL(api, oauth.ACCESS_TOKEN, m.Cmdx(ACCESS, TOKENS)), arg))
+}
+func Meta() ice.Map {
+ return kit.Dict(ice.CTX_TRANS, kit.Dict(html.INPUT, kit.Dict(
+ ACCESS, "账号", APPID, "应用", SECRET, "密码",
+ EXPIRE_SECONDS, "有效期",
+ SCENE, "场景", RIVER, "一级", STORM, "二级",
+ )))
+}
diff --git a/misc/wx/agent.go b/misc/wx/agent.go
new file mode 100644
index 00000000..450322d7
--- /dev/null
+++ b/misc/wx/agent.go
@@ -0,0 +1,46 @@
+package wx
+
+import (
+ "crypto/sha1"
+ "strings"
+ "time"
+
+ ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/gdb"
+ "shylinux.com/x/icebergs/base/mdb"
+ "shylinux.com/x/icebergs/base/web"
+ "shylinux.com/x/icebergs/core/chat"
+ "shylinux.com/x/icebergs/core/chat/location"
+ kit "shylinux.com/x/toolkits"
+)
+
+func _wx_sign(m *ice.Message, nonce, stamp string) string {
+ return kit.Format(sha1.Sum([]byte(kit.Join(kit.Sort(kit.Simple(
+ kit.Format("jsapi_ticket=%s", m.Cmdx(ACCESS, TICKET)),
+ kit.Format("url=%s", m.R.Header.Get(web.Referer)),
+ kit.Format("timestamp=%s", stamp),
+ kit.Format("noncestr=%s", nonce),
+ )), "&"))))
+}
+
+const (
+ SIGNATURE = "signature"
+ TIMESTAMP = "timestamp"
+ NONCESTR = "noncestr"
+ NONCE = "nonce"
+)
+const AGENT = "agent"
+
+func init() {
+ Index.MergeCommands(ice.Commands{
+ AGENT: {Name: "agent auto", Actions: ice.MergeActions(ice.Actions{
+ chat.HEADER_AGENT: {Hand: func(m *ice.Message, arg ...string) {
+ kit.If(strings.Index(m.Option(ice.MSG_USERUA), "MicroMessenger") > -1, func() { m.Option(mdb.PLUGIN, m.PrefixKey()) })
+ }},
+ "scanQRCode1": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(chat.FAVOR, mdb.CREATE, arg) }},
+ "getLocation": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(location.LOCATION, mdb.CREATE, arg) }},
+ }, gdb.EventsAction(chat.HEADER_AGENT)), Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(ACCESS, AGENT).Options(SIGNATURE, _wx_sign(m, m.Option(NONCESTR, "some"), m.Option(TIMESTAMP, kit.Format(time.Now().Unix())))).Display("")
+ }},
+ })
+}
diff --git a/misc/wx/agent.js b/misc/wx/agent.js
new file mode 100644
index 00000000..ccd847ec
--- /dev/null
+++ b/misc/wx/agent.js
@@ -0,0 +1,111 @@
+Volcanos(chat.ONIMPORT, {
+ _init: function(can, msg) { msg.Option(ice.MSG_ACTION, ""), can.require(["https://res.wx.qq.com/open/js/jweixin-1.6.0.js"], function(can) {
+ wx.config({debug: msg.Option("debug") == ice.TRUE, signature: msg.Option("signature"), timestamp: msg.Option("timestamp"), nonceStr: msg.Option("noncestr"), appId: msg.Option("appid"),
+ jsApiList: can.core.Item({
+ scanQRCode: function(can, cb) { wx.scanQRCode({needResult: cb? 1: 0, scanType: ["qrCode","barCode"], success: function (res) {
+ can.base.isFunc(cb) && cb(can.base.ParseJSON(res.resultStr))
+ } }) },
+ getLocation: function(can, cb) { wx.getLocation({type: "gcj02", success: function (res) {
+ can.base.isFunc(cb) && cb({type: "gcj02", name: "当前位置", text: "当前位置", latitude: parseInt(res.latitude*100000), longitude: parseInt(res.longitude*100000) })
+ } }) },
+ openLocation: function(can, msg) { wx.openLocation({
+ name: msg.Option(mdb.NAME), address: msg.Option(mdb.TEXT), infoUrl: msg.Option(mdb.LINK),
+ longitude: parseFloat(msg.Option("longitude")), latitude: parseFloat(msg.Option("latitude")), scale: msg.Option("scale")||14,
+ }) },
+ chooseImage: function(can, cb, count) { wx.chooseImage({count: count||9, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: function (res) {
+ can.base.isFunc(cb) && cb(res.localIds)
+ } }) },
+ }, function(key, value) { return can.user.agent[key] = value, key }).concat([
+ // "uploadImage", "previewImage",
+ // "updateAppMessageShareData", "updateTimelineShareData",
+ ]),
+ })
+ }) },
+})
+Volcanos(chat.ONACTION, {list: [
+ "scanQRCode", "scanQRCode1", "getLocation", "openLocation",
+ "uploadImage", "chooseImage", "previewImage",
+ "updateAppMessageShareData", "updateTimelineShareData",
+ "openAddress",
+],
+ scanQRCode: function(event, can, button) {
+ wx.scanQRCode({needResult: 0, scanType: ["qrCode","barCode"]})
+ },
+ scanQRCode1: function(event, can, button) {
+ wx.scanQRCode({needResult: 1, scanType: ["qrCode","barCode"], success: function (res) {
+ can.run(event, [ctx.ACTION, button, mdb.TEXT, res.resultStr], function() {})
+ can._output.innerHTML = res.resultStr
+ } })
+ },
+ getLocation: function(event, can, button) {
+ wx.getLocation({type: "gcj02", success: function (res) {
+ can.run(event, [ctx.ACTION, button, mdb.NAME, "current", "longitude", res.longitude.toFixed(6), "latitude", res.latitude.toFixed(6)], function() {})
+ can._output.innerHTML = JSON.stringify(res)
+ } })
+ },
+ openLocation: function(event, can, button) {
+ wx.getLocation({type: "gcj02", success: function (res) { wx.openLocation(res) }})
+ },
+ uploadImage: function(event, can, button) {
+ wx.chooseImage({success: function (res) {
+ can.core.List(res.localIds, function(item) {
+ wx.uploadImage({
+ localId: item, isShowProgressTips: 1,
+ success: function (res) {
+ var serverId = res.serverId;
+ can._output.innerHTML = serverId
+ }
+ })
+
+ })
+ }})
+ },
+ chooseImage: function(event, can, button) {
+ wx.chooseImage({
+ // count: 9, sourceType: ['album', 'camera'], sizeType: ['original', 'compressed'],
+ success: function (res) {
+ can.page.Append(can, can._output, can.core.List(res.localIds, function(item) {
+ return {img: item, style: {"max-width": can.ConfWidth()}}
+ }))
+ }
+ })
+ },
+ previewImage: function(event, can, button) {
+ wx.previewImage({
+ urls: [
+ 'https://2021.shylinux.com/share/local/usr/icons/timg.png',
+ "https://2021.shylinux.com/share/local/usr/icons/mall.png",
+ ],
+ })
+ },
+ updateAppMessageShareData: function(event, can, button) {
+ wx.updateAppMessageShareData({
+ title: document.title, desc: "工具系统", link: location.href,
+ imgUrl: 'https://2021.shylinux.com/share/local/usr/icons/timg.png',
+ success: function (res) { can._output.innerHTML = JSON.stringify(res) },
+ })
+ },
+ updateTimelineShareData: function(event, can, button) {
+ wx.updateTimelineShareData({
+ title: document.title, desc: "工具系统", link: location.href,
+ imgUrl: 'https://2021.shylinux.com/share/local/usr/icons/timg.png',
+ success: function (res) { can._output.innerHTML = JSON.stringify(res) },
+ })
+ },
+ openAddress: function(event, can, button) {
+ wx.openAddress({
+ success: function (res) {
+ can._output.innerHTML = JSON.stringify(res)
+
+ var userName = res.userName; // 收货人姓名
+ var postalCode = res.postalCode; // 邮编
+ var provinceName = res.provinceName; // 国标收货地址第一级地址(省)
+ var cityName = res.cityName; // 国标收货地址第二级地址(市)
+ var countryName = res.countryName; // 国标收货地址第三级地址(国家)
+ var detailInfo = res.detailInfo; // 详细收货地址信息
+ var nationalCode = res.nationalCode; // 收货地址国家码
+ var telNumber = res.telNumber; // 收货人手机号码
+ }
+ })
+ },
+})
diff --git a/misc/wx/event.go b/misc/wx/event.go
deleted file mode 100644
index 8178a286..00000000
--- a/misc/wx/event.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package wx
-
-import (
- ice "shylinux.com/x/icebergs"
-)
-
-const EVENT = "event"
-
-func init() {
- Index.MergeCommands(ice.Commands{
- EVENT: {Name: "event", Help: "事件", Actions: ice.Actions{
- "subscribe": {Help: "订阅", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(MENU, "home") }},
- "unsubscribe": {Help: "取关", Hand: func(m *ice.Message, arg ...string) {}},
- }},
- })
-}
diff --git a/misc/wx/events.go b/misc/wx/events.go
new file mode 100644
index 00000000..1ff1a3dc
--- /dev/null
+++ b/misc/wx/events.go
@@ -0,0 +1,48 @@
+package wx
+
+import (
+ ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/ctx"
+ "shylinux.com/x/icebergs/base/mdb"
+ "shylinux.com/x/icebergs/base/nfs"
+ "shylinux.com/x/icebergs/base/web"
+ kit "shylinux.com/x/toolkits"
+)
+
+const EVENTS = "events"
+
+func init() {
+ const (
+ SUBSCRIBE = "subscribe"
+ UNSUBSCRIBE = "unsubscribe"
+ SCAN = "scan"
+ SCANCODE_WAITMSG = "scancode_waitmsg"
+ CLICK = "click"
+ )
+ Index.MergeCommands(ice.Commands{
+ EVENTS: {Help: "事件", Actions: ice.Actions{
+ SUBSCRIBE: {Help: "订阅", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(TEXT, web.LINK, kit.MergeURL2(m.Option(ice.MSG_USERWEB), nfs.PS))
+ }},
+ UNSUBSCRIBE: {Help: "取关", Hand: func(m *ice.Message, arg ...string) {}},
+ SCAN: {Help: "扫码", Hand: func(m *ice.Message, arg ...string) {
+ msg := m.Cmd(QRCODE, m.Option(ACCESS), arg[0])
+ m.Options(ice.MSG_USERPOD, msg.Append(web.SPACE))
+ link := m.Cmd(web.SHARE, mdb.CREATE, mdb.TYPE, web.FIELD, mdb.NAME, msg.Append(ctx.INDEX), mdb.TEXT, msg.Append(ctx.ARGS)).Option(web.LINK)
+ m.Cmdy(TEXT, web.LINK, link, msg.Append(mdb.NAME), msg.Append(mdb.TEXT), msg.Append(mdb.ICONS))
+ }},
+ SCANCODE_WAITMSG: {Help: "扫码", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(TEXT, web.LINK, m.Option("ScanResult"))
+ }},
+ CLICK: {Help: "菜单", Hand: func(m *ice.Message, arg ...string) {
+ msg := m.Cmd(MENU, m.Option(ACCESS), arg[0])
+ m.Options(mdb.ICONS, msg.Append(mdb.ICONS), mdb.NAME, msg.Append(mdb.NAME), mdb.TEXT, kit.Select(msg.Append(ctx.INDEX), msg.Append(mdb.TEXT)))
+ if msg.Append(ctx.INDEX) == "" {
+ m.Cmdy(TEXT, web.LINK, kit.MergeURL2(m.Option(ice.MSG_USERWEB), nfs.PS))
+ } else {
+ m.Cmdy(TEXT, web.LINK, m.MergePodCmd("", msg.Append(ctx.INDEX), kit.Split(msg.Append(ctx.ARGS))))
+ }
+ }},
+ }},
+ })
+}
diff --git a/misc/wx/favor.go b/misc/wx/favor.go
deleted file mode 100644
index 2f85a0ac..00000000
--- a/misc/wx/favor.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package wx
-
-import (
- ice "shylinux.com/x/icebergs"
- "shylinux.com/x/icebergs/base/aaa"
- "shylinux.com/x/icebergs/base/mdb"
- kit "shylinux.com/x/toolkits"
-)
-
-const FAVOR = "favor"
-
-func init() {
- Index.MergeCommands(ice.Commands{
- FAVOR: {Name: "favor text:text auto create", Help: "收藏", Actions: mdb.HashAction(
- mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,type,name,text", mdb.LINK, "https://open.weixin.qq.com/qr/code",
- ), Hand: func(m *ice.Message, arg ...string) {
- mdb.HashSelect(m, arg...).Table(func(value ice.Maps) {
- m.PushQRCode(mdb.SCAN, kit.MergeURL(mdb.Config(m, mdb.LINK), aaa.USERNAME, value[mdb.TEXT]))
- })
- }},
- })
-}
diff --git a/misc/wx/login.go b/misc/wx/login.go
index d051d12d..47a63be0 100644
--- a/misc/wx/login.go
+++ b/misc/wx/login.go
@@ -4,13 +4,16 @@ import (
"bytes"
"encoding/xml"
"io/ioutil"
+ "strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
+ "shylinux.com/x/icebergs/base/ctx"
+ "shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/core/chat"
- "shylinux.com/x/icebergs/core/wiki"
+ "shylinux.com/x/icebergs/core/chat/location"
kit "shylinux.com/x/toolkits"
)
@@ -22,70 +25,80 @@ func _wx_parse(m *ice.Message) {
MsgType string
MsgId int64
Event string
+ EventKey string
Content string
- Title string
- Description string
- Url string
- PicUrl string
Location_X float64
Location_Y float64
Scale string
Label string
+ Title string
+ Description string
+ MediaId int64
+ PicUrl string
+ Url string
+ ScanCodeInfo struct {
+ ScanType string
+ ScanResult string
+ }
}{}
defer m.R.Body.Close()
buf, _ := ioutil.ReadAll(m.R.Body)
- m.Debug("buf: %+v", string(buf))
xml.NewDecoder(bytes.NewBuffer(buf)).Decode(&data)
+ m.Option("debug", "true")
+ m.Debug("buf: %+v", string(buf))
m.Debug("data: %+v", data)
- m.Option("FromUserName", data.FromUserName)
- m.Option("ToUserName", data.ToUserName)
+ m.Option(ACCESS, data.ToUserName)
m.Option("CreateTime", data.CreateTime)
- m.Option("MsgId", data.MsgId)
+ m.Option(aaa.USERNAME, data.FromUserName)
+ m.Option(mdb.TYPE, data.MsgType)
+ m.Option(mdb.ID, data.MsgId)
m.Option("Event", data.Event)
- m.Option("MsgType", data.MsgType)
- m.Option("Content", data.Content)
- m.Option("Title", data.Title)
- m.Option("Description", data.Description)
- m.Option("URL", data.Url)
- m.Option("URL", data.PicUrl)
- m.Option("LocationX", kit.Int(data.Location_X*100000))
- m.Option("LocationY", kit.Int(data.Location_Y*100000))
- m.Option("Scale", data.Scale)
+ m.Option("EventKey", data.EventKey)
+ m.Option(mdb.TEXT, data.Content)
+ m.Option(web.LINK, kit.Select(data.Url, data.PicUrl))
+ m.Option(location.LATITUDE, kit.Format("%0.6f", data.Location_X))
+ m.Option(location.LONGITUDE, kit.Format("%0.6f", data.Location_Y))
+ m.Option(location.SCALE, data.Scale)
m.Option("Label", data.Label)
+ m.Option("Title", data.Title)
+ m.Option("MediaId", data.MediaId)
+ m.Option("Description", data.Description)
+ m.Option("ScanResult", data.ScanCodeInfo.ScanResult)
}
const LOGIN = "login"
func init() {
+ web.Index.MergeCommands(ice.Commands{
+ "/MP_verify_0xp0zkW3fIzIq2Bo.txt": {Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { m.RenderResult("0xp0zkW3fIzIq2Bo") }},
+ })
Index.MergeCommands(ice.Commands{
web.PP(LOGIN): {Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) {
- if m.Cmdx(ACCESS, CHECK) == "" {
+ if m.Cmdx(ACCESS, aaa.CHECK) == "" {
+ return
+ } else if m.Option("echostr") != "" {
+ m.RenderResult(m.Option("echostr"))
return
}
_wx_parse(m)
- m.Option(ice.MSG_USERZONE, WX)
- aaa.SessAuth(m, kit.Dict(aaa.USERNAME, m.Option("FromUserName"), aaa.USERROLE, aaa.UserRole(m, m.Option("FromUserName"))))
- switch m.Option("MsgType") {
- case EVENT:
- m.Cmdy(EVENT, m.Option("Event"))
+ aaa.SessAuth(m.Options(ice.MSG_USERZONE, WX), kit.Dict(aaa.USERNAME, m.Option(aaa.USERNAME), aaa.USERROLE, aaa.UserRole(m, m.Option(aaa.USERNAME))))
+ switch m.Option(mdb.TYPE) {
+ case gdb.EVENT:
+ m.Cmdy(EVENTS, strings.ToLower(m.Option("Event")), kit.Split(m.Option("EventKey")))
+ case location.LOCATION:
+ m.Cmdy(location.LOCATION, mdb.CREATE, mdb.TEXT, m.Option("Label"), m.OptionSimple(location.LONGITUDE, location.LATITUDE, location.SCALE))
case TEXT:
- if cmds := kit.Split(m.Option("Content")); aaa.Right(m, cmds) {
- m.Cmdy(TEXT, cmds)
- } else {
- m.Cmdy(MENU, "home")
+ if cmds := kit.Split(m.Option(mdb.TEXT)); aaa.Right(m, cmds) {
+ m.Cmdy(TEXT, ctx.CMDS, cmds)
+ break
}
- case mdb.LINK:
- m.Cmdy(chat.FAVOR, mdb.CREATE, mdb.TYPE, mdb.LINK, mdb.NAME, m.Option("Title"), mdb.TEXT, m.Option("URL"))
- case wiki.IMAGE:
- m.Cmdy(chat.FAVOR, mdb.CREATE, mdb.TYPE, wiki.IMAGE, mdb.NAME, m.Option("Title"), mdb.TEXT, m.Option("URL"))
- case chat.LOCATION:
- m.Cmdy(chat.LOCATION, mdb.CREATE, mdb.TYPE, "", mdb.NAME, m.Option("Label"), mdb.TEXT, m.Option("Label"),
- "latitude", m.Option("LocationX"), "longitude", m.Option("LocationY"), "scale", m.Option("Scale"),
- )
+ fallthrough
+ default:
+ m.Cmdy(chat.FAVOR, mdb.CREATE, mdb.TYPE, m.Option(mdb.TYPE), mdb.NAME, m.Option("Title"), mdb.TEXT, kit.Select(m.Option(mdb.TEXT), m.Option(web.LINK)))
}
}},
- LOGIN: {Name: "login", Help: "登录", Actions: ice.Actions{
- mdb.CREATE: {Name: "create appid appmm token", Hand: func(m *ice.Message, arg ...string) { m.Cmd(ACCESS, LOGIN, arg) }},
- }},
+ LOGIN: {Name: "login list", Help: "登录", Actions: ice.Actions{
+ mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(ACCESS, mdb.CREATE, arg) }},
+ }, Hand: func(m *ice.Message, arg ...string) { m.Cmdy(ACCESS) }},
})
}
diff --git a/misc/wx/menu.go b/misc/wx/menu.go
index f695c753..6fad515d 100644
--- a/misc/wx/menu.go
+++ b/misc/wx/menu.go
@@ -4,43 +4,37 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/web"
- "shylinux.com/x/icebergs/core/wiki"
kit "shylinux.com/x/toolkits"
)
-func _wx_action(m *ice.Message) (count int) {
- m.SetResult().RenderResult()
- m.Echo(`
-
-
-%s
-
-`, m.Option("ToUserName"), m.Option("FromUserName"), m.Option("CreateTime"), "news")
- m.Table(func(value ice.Maps) { count++ })
- m.Echo(`%d`, count).Echo(``)
- share := m.Cmdx(web.SHARE, mdb.CREATE, mdb.TYPE, web.LOGIN)
- m.Table(func(value ice.Maps) {
- m.Echo(`-
-
-
-
-
-
-`, value[wiki.TITLE], value[wiki.SPARK], value[wiki.IMAGE], kit.MergeURL2(kit.Format(value[wiki.REFER]), "/share/"+share))
- }).Echo(``).Echo(``)
- m.Debug("echo: %v", m.Result())
- return
-}
-
+const (
+ SCENE = "scene"
+ RIVER = "river"
+ STORM = "storm"
+)
const MENU = "menu"
func init() {
Index.MergeCommands(ice.Commands{
- MENU: {Name: "menu zone id auto insert", Help: "菜单", Actions: ice.MergeActions(ice.Actions{
- mdb.INSERT: {Name: "insert zone=home title=hi refer=hello image"},
- }, mdb.ZoneAction(mdb.FIELDS, "time,id,title,refer,image")), Hand: func(m *ice.Message, arg ...string) {
- if mdb.ZoneSelect(m, arg...); len(arg) > 0 {
- _wx_action(m)
+ MENU: {Name: "menu access hash auto", Help: "菜单", Meta: Meta(), Actions: ice.MergeActions(ice.Actions{
+ mdb.CREATE: {Name: "create scene*=main river*=1,2,3 storm*=1,2,3,4,5,6 type*=click,view,scancode_push,scancode_waitmsg,pic_sysphoto,pic_photo_or_album,pic_weixin,location_select name* text icons space index args"},
+ mdb.UPDATE: {Name: "update scene*", Hand: func(m *ice.Message, arg ...string) {
+ list := kit.Dict()
+ m.Cmd("", m.Option(ACCESS), func(value ice.Maps) {
+ if value[SCENE] == m.Option(SCENE) {
+ key := kit.Keys("button", kit.Int(value[RIVER])-1)
+ kit.If(value[STORM] != "1", func() { key = kit.Keys(key, "sub_button", kit.Int(value[STORM])-2) })
+ kit.If(value[mdb.TYPE] == "view", func() { value[mdb.TEXT] = web.MergeLink(m, value[mdb.TEXT]) })
+ kit.Value(list, key, kit.Dict(mdb.TYPE, value[mdb.TYPE], mdb.NAME, value[mdb.NAME], mdb.KEY, value[mdb.HASH], web.URL, value[mdb.TEXT]))
+ }
+ })
+ m.Echo(kit.Formats(SpidePost(m, MENU_CREATE, web.SPIDE_DATA, kit.Formats(list))))
+ }},
+ }, mdb.ExportHashAction(mdb.SHORT, "scene,river,storm", mdb.FIELD, "time,hash,scene,river,storm,type,name,text,icons,space,index,args")), Hand: func(m *ice.Message, arg ...string) {
+ if len(arg) == 0 {
+ m.Cmdy(ACCESS).PushAction("").Option(ice.MSG_ACTION, "")
+ } else {
+ mdb.HashSelect(m, arg[1:]...).Sort(mdb.Config(m, mdb.SHORT), ice.STR, ice.INT, ice.INT).Action(mdb.CREATE, mdb.UPDATE)
}
}},
})
diff --git a/misc/wx/qrcode.go b/misc/wx/qrcode.go
new file mode 100644
index 00000000..77fdf4a6
--- /dev/null
+++ b/misc/wx/qrcode.go
@@ -0,0 +1,31 @@
+package wx
+
+import (
+ ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/mdb"
+ "shylinux.com/x/icebergs/base/web"
+ kit "shylinux.com/x/toolkits"
+)
+
+const (
+ EXPIRE_SECONDS = "expire_seconds"
+)
+const QRCODE = "qrcode"
+
+func init() {
+ Index.MergeCommands(ice.Commands{
+ QRCODE: {Name: "qrcode access hash auto", Help: "桌牌", Meta: Meta(), Actions: ice.MergeActions(ice.Actions{
+ mdb.CREATE: {Name: "create type=QR_STR_SCENE,QR_LIMIT_STR_SCENE name*=1 text* icons expire_seconds=3600 space index* args", Hand: func(m *ice.Message, arg ...string) {
+ h := mdb.HashCreate(m.Spawn(), arg)
+ res := SpidePost(m, QRCODE_CREATE, "action_name", m.Option(mdb.TYPE), "action_info.scene.scene_str", h, m.OptionSimple(EXPIRE_SECONDS))
+ mdb.HashModify(m, mdb.HASH, h, mdb.LINK, kit.Value(res, web.URL), mdb.TIME, m.Time(kit.Format("%ss", kit.Select("60", m.Option(EXPIRE_SECONDS)))))
+ }},
+ }, mdb.ExportHashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,name,text,icons,space,index,args,type,link")), Hand: func(m *ice.Message, arg ...string) {
+ if len(arg) == 0 {
+ m.Cmdy(ACCESS).PushAction("").Option(ice.MSG_ACTION, "")
+ } else if mdb.HashSelect(m, arg[1:]...); len(arg) > 1 {
+ kit.If(m.Time() < m.Append(mdb.TIME), func() { m.PushQRCode(QRCODE, m.Append(mdb.LINK)) })
+ }
+ }},
+ })
+}
diff --git a/misc/wx/text.go b/misc/wx/text.go
index f12cd3c3..c76eed5f 100644
--- a/misc/wx/text.go
+++ b/misc/wx/text.go
@@ -6,35 +6,29 @@ import (
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
+ "shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
)
-func _wx_reply(m *ice.Message, tmpl string) {
- if res, err := kit.Render(mdb.Config(m, nfs.TEMPLATE), m); err == nil {
- m.SetResult().RenderResult(string(res))
- }
-}
-
const TEXT = "text"
func init() {
Index.MergeCommands(ice.Commands{
- TEXT: {Name: "text", Help: "文本", Actions: ice.MergeActions(ice.Actions{
- MENU: {Name: "menu name=home", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(MENU, m.Option(mdb.NAME)) }},
- }, ctx.ConfAction(nfs.TEMPLATE, text)), Hand: func(m *ice.Message, arg ...string) {
- if m.Cmdy(arg); m.IsErrNotFound() {
- m.SetResult().Cmdy(cli.SYSTEM, arg)
- }
- kit.If(m.Result() == "", func() { m.TableEcho() })
- _wx_reply(m, m.CommandKey())
+ TEXT: {Help: "文本", Actions: ice.Actions{
+ ctx.CMDS: {Hand: func(m *ice.Message, arg ...string) {
+ msg := m.Cmd(arg)
+ kit.If(msg.IsErrNotFound(), func() { msg.SetResult().Cmdy(cli.SYSTEM, arg) })
+ kit.If(msg.Result() == "", func() { msg.TableEcho() })
+ m.Cmdy("", msg.Result())
+ }},
+ web.LINK: {Name: "link link name text icons", Hand: func(m *ice.Message, arg ...string) {
+ kit.If(m.Option(mdb.ICONS) == "", func() { m.Option(mdb.ICONS, m.Cmdv(ACCESS, m.Option(ACCESS), mdb.ICONS)) })
+ m.Option(mdb.ICONS, web.ShareLocal(m, m.Option(mdb.ICONS)))
+ m.Cmdy("", m.OptionDefault(mdb.TEXT, "工具系统"), "link.xml")
+ }},
+ }, Hand: func(m *ice.Message, arg ...string) {
+ m.Echo(nfs.Template(m.Options(mdb.TEXT, arg[0]), kit.Select("welcome.xml", arg, 1))).RenderResult()
+ m.Debug("text: %v", m.Result())
}},
})
}
-
-var text = `
-
-
-{{.Option "CreateTime"}}
-
-
-`
diff --git a/misc/wx/users.go b/misc/wx/users.go
new file mode 100644
index 00000000..26c61eee
--- /dev/null
+++ b/misc/wx/users.go
@@ -0,0 +1,35 @@
+package wx
+
+import (
+ "time"
+
+ ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/aaa"
+ "shylinux.com/x/icebergs/base/mdb"
+ kit "shylinux.com/x/toolkits"
+)
+
+const (
+ OPENID = "openid"
+)
+const USERS = "users"
+
+func init() {
+ Index.MergeCommands(ice.Commands{
+ USERS: {Name: "users access openid auto", Help: "用户", Meta: Meta(), Hand: func(m *ice.Message, arg ...string) {
+ if len(arg) == 0 {
+ m.Cmdy(ACCESS).PushAction("").Option(ice.MSG_ACTION, "")
+ } else if m.Options(ACCESS, arg[0]); len(arg) == 1 {
+ res := SpideGet(m, USER_GET)
+ kit.For(kit.Value(res, "data.openid"), func(value string) {
+ res := SpideGet(m, USER_INFO, OPENID, value)
+ m.Push(mdb.TIME, time.Unix(kit.Int64(kit.Value(res, "subscribe_time")), 0).Format(ice.MOD_TIME))
+ m.Push("", res, []string{OPENID, "sex", aaa.USERNICK, aaa.LANGUAGE, aaa.PROVINCE, aaa.CITY})
+ })
+ m.StatusTimeCountTotal(kit.Value(res, mdb.TOTAL), mdb.NEXT, kit.Value(res, "next_openid"))
+ } else {
+ m.Push(ice.FIELDS_DETAIL, SpideGet(m, USER_INFO, OPENID, arg[1]))
+ }
+ }},
+ })
+}
diff --git a/misc/wx/wx.go b/misc/wx/wx.go
index 4e12282a..a208ebc5 100644
--- a/misc/wx/wx.go
+++ b/misc/wx/wx.go
@@ -8,6 +8,6 @@ import (
const WX = "wx"
-var Index = &ice.Context{Name: WX, Help: "公众号"}
+var Index = &ice.Context{Name: WX, Help: "微信公众号"}
func init() { chat.Index.Register(Index, &web.Frame{}) }
diff --git a/misc/wx/wx.shy b/misc/wx/wx.shy
index 71200d14..0e415b18 100644
--- a/misc/wx/wx.shy
+++ b/misc/wx/wx.shy
@@ -2,25 +2,35 @@ title "微信公众号"
refer `
官网 https://weixin.qq.com/
后台 https://mp.weixin.qq.com/
+测试 https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
文档 https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html
`
+
+chapter "配置"
+field web.chat.wx.access
+field web.chat.wx.qrcode
+field web.chat.wx.menu
+field web.chat.wx.users
+
+chapter "数据"
+field web.chat.favor
+field web.chat.location
+return
+order `
+wx.go
+wx.shy
+access.go
+qrcode.go
+menu.go
+text.go
+login.go
+events.go
+users.go
+agent.go
+agent.js
+`
+
qrcode `http://weixin.qq.com/r/_B1-Z7TEXOkjrfAE90jq`
-chapter "应用"
-field "访问" web.chat.wx.access
-field "收藏" web.chat.wx.favor
-field "菜单" web.chat.wx.menu
-field "位置" web.chat.location
-
-chapter "权限"
-field "共享" web.share
-field "会话" aaa.sess
-field "用户" aaa.user
-
chapter "企业微信"
field "机器人" web.chat.wework.bot
-
-chapter "项目"
-field "源代码" web.code.inner args `usr/icebergs/ misc/wx/login.go`
-field "趋势图" web.code.git.trend args `icebergs`
-field "架构图" web.code.git.spide args `icebergs`