From 7d138f103037a243fa68967593c557f393764800 Mon Sep 17 00:00:00 2001 From: shy Date: Fri, 10 Nov 2023 17:34:04 +0800 Subject: [PATCH] add wx.shy --- base/aaa/user.go | 13 ++-- base/web/html/html.go | 1 + core/chat/location/location.js | 2 +- core/chat/location/tmap.js | 2 +- core/code/parse.go | 2 +- misc.go | 6 +- misc/disk/client.go | 4 +- misc/wx/access.go | 61 ++++++++++++------ misc/wx/agent.go | 9 ++- misc/wx/agent.js | 114 ++++++++++++++------------------- misc/wx/events.go | 13 ++-- misc/wx/login.go | 3 +- misc/wx/menu.go | 13 ++-- misc/wx/{qrcode.go => scan.go} | 12 ++-- misc/wx/tags.go | 48 ++++++++++++++ misc/wx/users.go | 53 +++++++++++---- misc/wx/wx.shy | 12 ++-- 17 files changed, 233 insertions(+), 135 deletions(-) rename misc/wx/{qrcode.go => scan.go} (68%) create mode 100644 misc/wx/tags.go diff --git a/base/aaa/user.go b/base/aaa/user.go index 29e9c8fe..6ab85722 100644 --- a/base/aaa/user.go +++ b/base/aaa/user.go @@ -19,12 +19,14 @@ const ( GENDER = "gender" MOBILE = "mobile" SECRET = "secret" + THEME = "theme" - CITY = "city" - COUNTRY = "country" - PROVINCE = "province" - LANGUAGE = "language" - THEME = "theme" + LANGUAGE = "language" + LONGITUDE = "longitude" + LATITUDE = "latitude" + PROVINCE = "province" + COUNTRY = "country" + CITY = "city" ) const ( USERNICK = "usernick" @@ -56,7 +58,6 @@ 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/web/html/html.go b/base/web/html/html.go index b63482cf..ed0ba5e1 100644 --- a/base/web/html/html.go +++ b/base/web/html/html.go @@ -25,6 +25,7 @@ const ( VIEW = "view" INPUT = "input" + VALUE = "value" OUTPUT = "output" LAYOUT = "layout" RESIZE = "resize" diff --git a/core/chat/location/location.js b/core/chat/location/location.js index b3ab7a7e..42d49ea1 100644 --- a/core/chat/location/location.js +++ b/core/chat/location/location.js @@ -80,4 +80,4 @@ Volcanos(chat.ONACTION, { rotation: function(event, can) { can.ui.map.setRotation(can.Action("rotation")) }, center: function(can, item) {}, }) -Volcanos(chat.ONEXPORT, {list: ["province", "city", "district", "street", "longitude", "latitude", "type", "name", "text", "space", "weather", "temperature", "humidity", "windPower"]}) +Volcanos(chat.ONEXPORT, {list: ["province", "city", "district", "street", aaa.LONGITUDE, aaa.LATITUDE, "type", "name", "text", "space", "weather", "temperature", "humidity", "windPower"]}) diff --git a/core/chat/location/tmap.js b/core/chat/location/tmap.js index 9296ea8c..65f89106 100644 --- a/core/chat/location/tmap.js +++ b/core/chat/location/tmap.js @@ -124,7 +124,7 @@ Volcanos(chat.ONACTION, { }, create: function(event, can) { can.request(event, can.ui.current.item) can.user.input(event, can, can.core.Split("type,name,text"), function(args) { var p = can.onexport.center(can) - can.runAction(event, mdb.CREATE, args.concat("latitude", p.latitude, "longitude", p.longitude), function(msg) { + can.runAction(event, mdb.CREATE, args.concat(aaa.LATITUDE, p.latitude, aaa.LONGITUDE, p.longitude), function(msg) { can.onimport._item(can, can.base.Copy(p, {name: msg.Option(mdb.NAME), text: msg.Option(mdb.TEXT)})) }, true) }) diff --git a/core/code/parse.go b/core/code/parse.go index 7d589b74..12fd0159 100644 --- a/core/code/parse.go +++ b/core/code/parse.go @@ -58,7 +58,7 @@ func init() { if i > math.MaxInt32 { m.Echo(time.Unix(i/1000, i%1000*1000000).Format(ice.MOD_TIME)) } else { - m.Echo(time.Unix(i, 0).Format(ice.MOD_TIME)) + m.Echo(kit.TimeUnix(i)) } } case aaa.BASE64: diff --git a/misc.go b/misc.go index afba7946..bab28d6f 100644 --- a/misc.go +++ b/misc.go @@ -104,7 +104,11 @@ func (m *Message) RewriteAppend(cb func(value, key string, index int) string) *M m.Table(func(index int, value Maps, head []string) { for _, key := range head { v := cb(value[key], key, index) - m.index(key, index, v) + if m.FieldsIsDetail() { + m.Append(key, v) + } else { + m.index(key, index, v) + } } }) return m diff --git a/misc/disk/client.go b/misc/disk/client.go index c505156f..735d21db 100644 --- a/misc/disk/client.go +++ b/misc/disk/client.go @@ -1,8 +1,6 @@ package disk import ( - "time" - "shylinux.com/x/ice" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" @@ -50,7 +48,7 @@ func (s Client) List(m *ice.Message, arg ...string) { } res := s.Client.Get(m, arg[0], "https://pan.baidu.com/rest/2.0/xpan/file?method=list", "dir", kit.Select("", arg, 1)) kit.For(kit.Value(res, mdb.LIST), func(value ice.Map) { - m.Push(mdb.TIME, time.Unix(kit.Int64(value["server_mtime"]), 0)) + m.Push(mdb.TIME, kit.TimeUnix(value["server_mtime"])) m.Push(nfs.PATH, kit.Format(value[nfs.PATH])+kit.Select("", nfs.PS, kit.Format(value["isdir"]) == "1")) m.Push(nfs.SIZE, kit.FmtSize(kit.Int(value[nfs.SIZE]))) m.Push(mdb.ID, value["fs_id"]) diff --git a/misc/wx/access.go b/misc/wx/access.go index 02a255f7..03869806 100644 --- a/misc/wx/access.go +++ b/misc/wx/access.go @@ -7,6 +7,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" + "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/tcp" @@ -16,6 +17,23 @@ import ( kit "shylinux.com/x/toolkits" ) +const ( + CGI_BIN = "https://api.weixin.qq.com/cgi-bin/" + TOKEN_CREDENTIAL = "token?grant_type=client_credential" + TICKET_GETTICKET = "ticket/getticket?type=jsapi" + QRCODE_CREATE = "qrcode/create" + MENU_CREATE = "menu/create" + USER_REMARK = "user/info/updateremark" + USER_INFO = "user/info" + USER_GET = "user/get" + USER_TAG_GET = "user/tag/get" + TAGS_CREATE = "tags/create" + TAGS_DELETE = "tags/delete" + TAGS_UPDATE = "tags/update" + TAGS_GET = "tags/get" + TAGS_MEMBERS_BATCHTAGGING = "tags/members/batchtagging" + TAGS_MEMBERS_BATCHUNTAGGING = "tags/members/batchuntagging" +) const ( APPID = "appid" SECRET = "secret" @@ -25,21 +43,16 @@ const ( TICKET = "ticket" EXPIRE = "expire" ) -const ( - 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: {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)) + 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: "create usernick access* appid* secret* token* icons qrcode", Hand: func(m *ice.Message, arg ...string) { + mdb.HashCreate(m, m.OptionSimple(aaa.USERNICK, ACCESS, APPID, SECRET, TOKEN, mdb.ICONS, cli.QRCODE)) ctx.ConfigFromOption(m, ACCESS, APPID, TOKEN) }}, aaa.CHECK: {Hand: func(m *ice.Message, arg ...string) { @@ -48,11 +61,13 @@ func init() { m.Echo(ice.TRUE) } }}, - AGENT: {Hand: func(m *ice.Message, arg ...string) { ctx.OptionFromConfig(m, ACCESS, APPID) }}, + 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)) + res := m.Cmd(web.SPIDE, WX, http.MethodGet, TOKEN_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)) } @@ -61,27 +76,35 @@ func init() { 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)) + res := m.Cmd(web.SPIDE, WX, http.MethodGet, TICKET_GETTICKET, 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(msg.Append(TICKET)).Status(msg.AppendSimple(EXPIRE)) }}, - }, 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/")) + }, mdb.ImportantHashAction(mdb.SHORT, ACCESS, mdb.FIELD, "time,access,icons,usernick,appid", tcp.SERVER, CGI_BIN)), Hand: func(m *ice.Message, arg ...string) { + mdb.HashSelect(m, arg...).StatusTimeCount(mdb.ConfigSimple(m, ACCESS, APPID), web.SERVE, web.MergeLink(m, "/chat/wx/login/")) + m.RewriteAppend(func(value, key string, index int) string { + kit.If(key == cli.QRCODE, func() { value = ice.Render(m, ice.RENDER_QRCODE, value) }) + return value + }) }}, }) } -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 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 Meta() ice.Map { return kit.Dict(ice.CTX_TRANS, kit.Dict(html.INPUT, kit.Dict( ACCESS, "账号", APPID, "应用", SECRET, "密码", - EXPIRE_SECONDS, "有效期", + TOKEN, "口令", TOKENS, "令牌", TICKET, "票据", + EXPIRES, "令牌有效期", EXPIRE, "票据有效期", EXPIRE_SECONDS, "有效期", SCENE, "场景", RIVER, "一级", STORM, "二级", + SEX, "性别", TAGS, "标签", REMARK, "备注", + "subscribe", "订阅", "subscribe_time", "时间", + "nickname", "昵称", "headimgurl", "头像", ))) } diff --git a/misc/wx/agent.go b/misc/wx/agent.go index 450322d7..2764bd9d 100644 --- a/misc/wx/agent.go +++ b/misc/wx/agent.go @@ -6,8 +6,10 @@ import ( "time" ice "shylinux.com/x/icebergs" + "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/web" "shylinux.com/x/icebergs/core/chat" "shylinux.com/x/icebergs/core/chat/location" @@ -37,10 +39,11 @@ func init() { 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("") + "scanQRCode1": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(chat.FAVOR, mdb.CREATE, arg) }}, + }, gdb.EventsAction(chat.HEADER_AGENT), ctx.ConfAction(nfs.SCRIPT, "https://res.wx.qq.com/open/js/jweixin-1.6.0.js")), Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(ACCESS, AGENT).Options(SIGNATURE, _wx_sign(m, m.Option(NONCESTR, ice.Info.Pathname), m.Option(TIMESTAMP, kit.Format(time.Now().Unix())))).Display("") + ctx.OptionFromConfig(m, nfs.SCRIPT) }}, }) } diff --git a/misc/wx/agent.js b/misc/wx/agent.js index ccd847ec..f4bb5f97 100644 --- a/misc/wx/agent.js +++ b/misc/wx/agent.js @@ -1,33 +1,53 @@ 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"), + _init: function(can, msg) { msg.Option(ice.MSG_ACTION, ""), can.require([msg.Option(nfs.SCRIPT)], function(can) { + wx.config({debug: msg.Option(log.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, + name: msg.Option(mdb.NAME), address: msg.Option(mdb.TEXT), infoUrl: msg.Option(web.LINK), + longitude: parseFloat(msg.Option(aaa.LONGITUDE)), latitude: parseFloat(msg.Option(aaa.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) { + 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)) + } }) }, + chooseImage: function(can, cb, count) { wx.chooseImage({count: count||9, sourceType: ["camera", "album"], sizeType: ["original", "compressed"], 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", + "getLocation", "openLocation", "openAddress", + "scanQRCode", "scanQRCode1", "uploadImage", "chooseImage", "previewImage", "updateAppMessageShareData", "updateTimelineShareData", - "openAddress", ], + getLocation: function(event, can, button) { + wx.getLocation({type: "gcj02", success: function (res) { + can.run(event, [ctx.ACTION, button, mdb.NAME, "current", aaa.LONGITUDE, res.longitude.toFixed(6), aaa.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) }}) + }, + openAddress: function(event, can, button) { + wx.openAddress({success: function (res) { + can._output.innerHTML = JSON.stringify(res) + var userName = res.userName; // 收货人姓名 + var cityName = res.cityName; // 国标收货地址第二级地址(市) + var provinceName = res.provinceName; // 国标收货地址第一级地址(省) + var countryName = res.countryName; // 国标收货地址第三级地址(国家) + var detailInfo = res.detailInfo; // 详细收货地址信息 + var nationalCode = res.nationalCode; // 收货地址国家码 + var postalCode = res.postalCode; // 邮编 + var telNumber = res.telNumber; // 收货人手机号码 + }}) + }, scanQRCode: function(event, can, button) { wx.scanQRCode({needResult: 0, scanType: ["qrCode","barCode"]}) }, @@ -37,75 +57,39 @@ Volcanos(chat.ONACTION, {list: [ 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 - } - }) - - }) - }}) + 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()}} - })) - } - }) + wx.chooseImage({count: 9, sourceType: ["camera", "album"], 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", - ], - }) + 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', + 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', + 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/events.go b/misc/wx/events.go index 1ff1a3dc..24f0e735 100644 --- a/misc/wx/events.go +++ b/misc/wx/events.go @@ -21,20 +21,21 @@ func init() { ) Index.MergeCommands(ice.Commands{ EVENTS: {Help: "事件", Actions: ice.Actions{ - SUBSCRIBE: {Help: "订阅", Hand: func(m *ice.Message, arg ...string) { + SUBSCRIBE: {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]) + UNSUBSCRIBE: {Hand: func(m *ice.Message, arg ...string) { + }}, + SCAN: {Hand: func(m *ice.Message, arg ...string) { + msg := m.Cmd(SCAN, 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) { + SCANCODE_WAITMSG: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(TEXT, web.LINK, m.Option("ScanResult")) }}, - CLICK: {Help: "菜单", Hand: func(m *ice.Message, arg ...string) { + CLICK: {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) == "" { diff --git a/misc/wx/login.go b/misc/wx/login.go index 47a63be0..69405750 100644 --- a/misc/wx/login.go +++ b/misc/wx/login.go @@ -46,7 +46,7 @@ func _wx_parse(m *ice.Message) { xml.NewDecoder(bytes.NewBuffer(buf)).Decode(&data) m.Option("debug", "true") m.Debug("buf: %+v", string(buf)) - m.Debug("data: %+v", data) + m.Debug("data: %+v", kit.Formats(data)) m.Option(ACCESS, data.ToUserName) m.Option("CreateTime", data.CreateTime) m.Option(aaa.USERNAME, data.FromUserName) @@ -62,7 +62,6 @@ func _wx_parse(m *ice.Message) { 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) } diff --git a/misc/wx/menu.go b/misc/wx/menu.go index 6fad515d..86e7a9c4 100644 --- a/misc/wx/menu.go +++ b/misc/wx/menu.go @@ -4,6 +4,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/base/web/html" kit "shylinux.com/x/toolkits" ) @@ -16,8 +17,12 @@ const MENU = "menu" func init() { Index.MergeCommands(ice.Commands{ - 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"}, + MENU: {Name: "menu access hash auto", Help: "菜单", Meta: kit.Merge(Meta(), kit.Dict(ice.CTX_TRANS, kit.Dict(html.VALUE, kit.Dict( + "click", "点击", "view", "链接", "location_select", "定位", + "scancode_waitmsg", "扫码上传", "scancode_push", "扫码", + "pic_photo_or_album", "照片", "pic_sysphoto", "拍照", "pic_weixin", "相册", + )))), 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,location_select,scancode_waitmsg,scancode_push,pic_photo_or_album,pic_sysphoto,pic_weixin 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) { @@ -33,8 +38,8 @@ func init() { }, 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) + } else if mdb.HashSelect(m, arg[1:]...).Sort(mdb.Config(m, mdb.SHORT), ice.STR, ice.INT, ice.INT); len(arg) == 1 { + m.Action(mdb.CREATE, mdb.UPDATE) } }}, }) diff --git a/misc/wx/qrcode.go b/misc/wx/scan.go similarity index 68% rename from misc/wx/qrcode.go rename to misc/wx/scan.go index 77fdf4a6..dcfadc26 100644 --- a/misc/wx/qrcode.go +++ b/misc/wx/scan.go @@ -2,20 +2,24 @@ package wx import ( ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/base/web/html" kit "shylinux.com/x/toolkits" ) const ( EXPIRE_SECONDS = "expire_seconds" ) -const QRCODE = "qrcode" +const SCAN = "scan" 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) { + SCAN: {Name: "scan access hash auto", Help: "桌牌", Meta: kit.Merge(Meta(), kit.Dict(ice.CTX_TRANS, kit.Dict(html.VALUE, kit.Dict( + "QR_STR_SCENE", "临时码", "QR_LIMIT_STR_SCENE", "永久码", + )))), 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))))) @@ -24,7 +28,7 @@ func init() { 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)) }) + kit.If(m.Time() < m.Append(mdb.TIME), func() { m.PushQRCode(cli.QRCODE, m.Append(mdb.LINK)) }) } }}, }) diff --git a/misc/wx/tags.go b/misc/wx/tags.go new file mode 100644 index 00000000..2c2aa3ae --- /dev/null +++ b/misc/wx/tags.go @@ -0,0 +1,48 @@ +package wx + +import ( + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/mdb" + kit "shylinux.com/x/toolkits" +) + +const ( + TAGID = "tagid" +) +const TAGS = "tags" + +func init() { + Index.MergeCommands(ice.Commands{ + TAGS: {Name: "tags access id openid auto", Help: "标签", Meta: Meta(), Actions: ice.Actions{ + mdb.CREATE: {Name: "create name*", Hand: func(m *ice.Message, arg ...string) { + SpidePost(m, TAGS_CREATE, "tag.name", m.Option(mdb.NAME)) + }}, + mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { + SpidePost(m, TAGS_DELETE, "tag.id", m.Option(mdb.ID)) + }}, + mdb.UPDATE: {Name: "update name*", Hand: func(m *ice.Message, arg ...string) { + SpidePost(m, TAGS_UPDATE, "tag.id", m.Option(mdb.ID), "tag.name", m.Option(mdb.NAME)) + }}, + mdb.DELETE: {Hand: func(m *ice.Message, arg ...string) { + SpidePost(m, TAGS_MEMBERS_BATCHUNTAGGING, TAGID, m.Option(mdb.ID), "openid_list.0", m.Option(OPENID)) + }}, + REMARK: {Name: "remark remark", Help: "备注", Hand: func(m *ice.Message, arg ...string) { + SpidePost(m, USER_REMARK, m.OptionSimple(OPENID, REMARK)) + }}, + }, 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, TAGS_GET) + kit.For(kit.Value(res, TAGS), func(value ice.Map) { + m.Push("", value, []string{mdb.ID, mdb.NAME, mdb.COUNT}) + }) + m.PushAction(mdb.UPDATE, mdb.REMOVE).Action(mdb.CREATE) + } else if len(arg) == 2 { + _user_list(m, SpidePost(m, USER_TAG_GET, TAGID, arg[1])).PushAction(REMARK, mdb.DELETE) + } else { + _user_info(m, arg[2]) + } + }}, + }) +} diff --git a/misc/wx/users.go b/misc/wx/users.go index 26c61eee..36d13b63 100644 --- a/misc/wx/users.go +++ b/misc/wx/users.go @@ -1,8 +1,6 @@ package wx import ( - "time" - ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/mdb" @@ -12,24 +10,57 @@ import ( const ( OPENID = "openid" ) +const ( + SUBSCRIBE_TIME = "subscribe_time" + + REMARK = "remark" + SEX = "sex" +) 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) { + USERS: {Name: "users access openid auto", Help: "用户", Meta: Meta(), Actions: ice.MergeActions(ice.Actions{ + mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { + switch arg[0] { + case TAGS: + m.Cmdy(TAGS, m.Option(ACCESS)).CutTo(mdb.NAME, arg[0]) + } + }}, + TAGS: {Name: "tags tags", Help: "标签", Hand: func(m *ice.Message, arg ...string) { + list := map[string]string{} + m.Cmd(TAGS, m.Option(ACCESS), func(value ice.Maps) { list[value[mdb.NAME]] = value[mdb.ID] }) + SpidePost(m, TAGS_MEMBERS_BATCHTAGGING, TAGID, m.Option(TAGID, list[m.Option(TAGS)]), "openid_list.0", m.Option(OPENID)) + }}, + }), 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")) + _user_list(m, SpideGet(m, USER_GET)).PushAction(TAGS) } else { - m.Push(ice.FIELDS_DETAIL, SpideGet(m, USER_INFO, OPENID, arg[1])) + _user_info(m, arg[1]) } }}, }) } +func _user_list(m *ice.Message, res ice.Any) *ice.Message { + list := map[string]string{} + m.Cmd(TAGS, m.Option(ACCESS), func(value ice.Maps) { list[value[mdb.ID]] = value[mdb.NAME] }) + kit.For(kit.Value(res, kit.Keys(mdb.DATA, OPENID)), func(value string) { + res := SpideGet(m, USER_INFO, OPENID, value) + m.Push(mdb.TIME, kit.TimeUnix(kit.Value(res, SUBSCRIBE_TIME))) + m.Push("", res, []string{OPENID, SEX, aaa.USERNICK, aaa.LANGUAGE, aaa.PROVINCE, aaa.CITY}) + m.Push(TAGS, kit.Join(kit.Simple(kit.Value(res, "tagid_list"), func(id string) string { return list[id] }))) + m.Push(REMARK, kit.Format(kit.Value(res, REMARK))) + }) + return m.StatusTimeCount(mdb.NEXT, kit.Value(res, "next_openid")) + return m.StatusTimeCountTotal(kit.Value(res, mdb.TOTAL), mdb.NEXT, kit.Value(res, "next_openid")) +} +func _user_info(m *ice.Message, openid string) *ice.Message { + m.Push(ice.FIELDS_DETAIL, SpideGet(m, USER_INFO, OPENID, openid)) + m.RewriteAppend(func(value, key string, index int) string { + kit.If(key == SUBSCRIBE_TIME, func() { value = kit.TimeUnix(value) }) + return value + }) + return m +} diff --git a/misc/wx/wx.shy b/misc/wx/wx.shy index 0e415b18..ee2d6f0a 100644 --- a/misc/wx/wx.shy +++ b/misc/wx/wx.shy @@ -8,8 +8,9 @@ refer ` chapter "配置" field web.chat.wx.access -field web.chat.wx.qrcode field web.chat.wx.menu +field web.chat.wx.scan +field web.chat.wx.tags field web.chat.wx.users chapter "数据" @@ -20,17 +21,12 @@ order ` wx.go wx.shy access.go -qrcode.go menu.go +scan.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.wework.bot +` \ No newline at end of file