1
0
forked from x/icebergs

add wx.shy

This commit is contained in:
IT 老营长 @云轩领航-创始人 2023-11-10 02:12:48 +08:00
parent 798dfd62aa
commit ab8de9ba49
30 changed files with 481 additions and 224 deletions

View File

@ -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"))),
)
}

View File

@ -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)
}

View File

@ -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) }

View File

@ -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) {

View File

@ -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...)

View File

@ -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) }

View File

@ -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))

View File

@ -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"

View File

@ -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)
}

View File

@ -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

View File

@ -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 {

View File

@ -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)

View File

@ -1,4 +1,4 @@
package chat
package location
import (
"path"

View File

@ -1,4 +1,4 @@
package chat
package location
import (
ice "shylinux.com/x/icebergs"

View File

@ -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"

View File

@ -1,4 +1,4 @@
package chat
package location
import (
"net/http"

View File

@ -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")

View File

@ -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, "二级",
)))
}

46
misc/wx/agent.go Normal file
View 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
View 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; // 收货人手机号码
}
})
},
})

View File

@ -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
View 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))))
}
}},
}},
})
}

View File

@ -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]))
})
}},
})
}

View File

@ -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) }},
})
}

View File

@ -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
View 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)) })
}
}},
})
}

View File

@ -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
View 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]))
}
}},
})
}

View File

@ -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{}) }

View File

@ -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`