forked from x/icebergs
add wx.shy
This commit is contained in:
parent
798dfd62aa
commit
ab8de9ba49
@ -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"))),
|
||||
)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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) }
|
||||
|
@ -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) {
|
||||
|
@ -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...)
|
||||
|
@ -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) }
|
||||
|
@ -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))
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package location
|
||||
|
||||
import (
|
||||
"path"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package location
|
||||
|
||||
import (
|
||||
ice "shylinux.com/x/icebergs"
|
||||
|
@ -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"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package location
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
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(msg.Append(TOKENS)).Status(msg.AppendSimple(EXPIRES))
|
||||
}},
|
||||
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
|
||||
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))
|
||||
}
|
||||
mdb.Config(m, EXPIRES, now+kit.Int64(msg.Append("expires_in")))
|
||||
mdb.Config(m, TOKENS, msg.Append("access_token"))
|
||||
}
|
||||
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(TICKET)).Status(msg.AppendSimple(EXPIRE))
|
||||
}},
|
||||
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))
|
||||
}
|
||||
m.Echo(mdb.Config(m, TICKET)).Status(EXPIRE, time.Unix(kit.Int64(mdb.Config(m, EXPIRE)), 0).Format(ice.MOD_TIME))
|
||||
}},
|
||||
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, "二级",
|
||||
)))
|
||||
}
|
||||
|
46
misc/wx/agent.go
Normal file
46
misc/wx/agent.go
Normal file
@ -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("")
|
||||
}},
|
||||
})
|
||||
}
|
111
misc/wx/agent.js
Normal file
111
misc/wx/agent.js
Normal file
@ -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; // 收货人手机号码
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
@ -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) {}},
|
||||
}},
|
||||
})
|
||||
}
|
48
misc/wx/events.go
Normal file
48
misc/wx/events.go
Normal file
@ -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))))
|
||||
}
|
||||
}},
|
||||
}},
|
||||
})
|
||||
}
|
@ -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]))
|
||||
})
|
||||
}},
|
||||
})
|
||||
}
|
@ -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) }},
|
||||
})
|
||||
}
|
||||
|
@ -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(`<xml>
|
||||
<FromUserName><![CDATA[%s]]></FromUserName>
|
||||
<ToUserName><![CDATA[%s]]></ToUserName>
|
||||
<CreateTime>%s</CreateTime>
|
||||
<MsgType><![CDATA[%s]]></MsgType>
|
||||
`, m.Option("ToUserName"), m.Option("FromUserName"), m.Option("CreateTime"), "news")
|
||||
m.Table(func(value ice.Maps) { count++ })
|
||||
m.Echo(`<ArticleCount>%d</ArticleCount>`, count).Echo(`<Articles>`)
|
||||
share := m.Cmdx(web.SHARE, mdb.CREATE, mdb.TYPE, web.LOGIN)
|
||||
m.Table(func(value ice.Maps) {
|
||||
m.Echo(`<item>
|
||||
<Title><![CDATA[%s]]></Title>
|
||||
<Description><![CDATA[%s]]></Description>
|
||||
<PicUrl><![CDATA[%s]]></PicUrl>
|
||||
<Url><![CDATA[%s]]></Url>
|
||||
</item>
|
||||
`, value[wiki.TITLE], value[wiki.SPARK], value[wiki.IMAGE], kit.MergeURL2(kit.Format(value[wiki.REFER]), "/share/"+share))
|
||||
}).Echo(`</Articles>`).Echo(`</xml>`)
|
||||
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)
|
||||
}
|
||||
}},
|
||||
})
|
||||
|
31
misc/wx/qrcode.go
Normal file
31
misc/wx/qrcode.go
Normal file
@ -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)) })
|
||||
}
|
||||
}},
|
||||
})
|
||||
}
|
@ -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 = `<xml>
|
||||
<FromUserName><![CDATA[{{.Option "ToUserName"}}]]></FromUserName>
|
||||
<ToUserName><![CDATA[{{.Option "FromUserName"}}]]></ToUserName>
|
||||
<CreateTime>{{.Option "CreateTime"}}</CreateTime>
|
||||
<MsgType><![CDATA[text]]></MsgType>
|
||||
<Content><![CDATA[{{.Result}}]]></Content>
|
||||
</xml>`
|
||||
|
35
misc/wx/users.go
Normal file
35
misc/wx/users.go
Normal file
@ -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]))
|
||||
}
|
||||
}},
|
||||
})
|
||||
}
|
@ -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{}) }
|
||||
|
@ -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`
|
||||
|
Loading…
x
Reference in New Issue
Block a user