diff --git a/base/web/html/html.go b/base/web/html/html.go index 5672465b..3101786e 100644 --- a/base/web/html/html.go +++ b/base/web/html/html.go @@ -57,6 +57,8 @@ const ( CHECKBOX = "checkbox" SELECT = "select" BUTTON = "button" + IMAGE = "image" + SUBMIT = "submit" CHROME = "chrome" STYLE = "style" diff --git a/base/web/share.go b/base/web/share.go index 92d72363..2dcb5b90 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -165,7 +165,9 @@ func ShareLocalFile(m *ice.Message, arg ...string) { return } default: - if m.Option(ice.POD) == "" && !aaa.Right(m, ls) { + if m.Option(ice.MSG_USERNAME) != "" && strings.HasPrefix(p, nfs.USR_LOCAL_IMAGE+m.Option(ice.MSG_USERNAME)) { + + } else if m.Option(ice.POD) == "" && !aaa.Right(m, ls) { return } } diff --git a/base/web/spide.go b/base/web/spide.go index a2a96df4..81159521 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -206,7 +206,11 @@ func _spide_save(m *ice.Message, action, file, uri string, res *http.Response) { kit.For(data[ice.MSG_APPEND], func(k string) { kit.For(data[k], func(v string) { m.Push(k, v) }) }) m.Resultv(data[ice.MSG_RESULT]) case SPIDE_SAVE: - _cache_download(m, res, file, m.OptionCB(SPIDE)) + if strings.HasSuffix(file, "/") { + file += kit.Select("", kit.Split(m.Option("Content-Disposition"), ";="), -1) + m.Info("save file %v", file) + } + m.Echo(_cache_download(m, res, file, m.OptionCB(SPIDE))) case SPIDE_CACHE: m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(html.ContentType), uri, kit.Dict(RESPONSE, res), m.OptionCB(SPIDE)) m.Echo(m.Append(mdb.HASH)) diff --git a/core/chat/oauth/client.go b/core/chat/oauth/client.go index edd559c9..6801dfed 100644 --- a/core/chat/oauth/client.go +++ b/core/chat/oauth/client.go @@ -140,9 +140,8 @@ func (s Client) Login2(m *ice.Message, arg ...string) { if state, code := m.Option(STATE), m.Option(CODE); !m.WarnNotValid(state == "" || code == "") { s.Hash.List(m.Spawn(), m.Option(mdb.HASH, state)).Table(func(value ice.Maps) { m.Options(value) }) m.Options(GRANT_TYPE, AUTHORIZATION_CODE, REDIRECT_URI, s.RedirectURI(m)) - if res := s.Get(m, m.Option(mdb.HASH), m.Option(GRANT_URL), kit.Simple(m.OptionSimple(GRANT_TYPE, CODE, CLIENT_ID), - "appid", m.Option(CLIENT_ID), "secret", m.Option(CLIENT_SECRET), - )...); !m.WarnNotValid(res == nil) { + m.Option(ACCESS_TOKEN, "") + if res := s.Get(m, m.Option(mdb.HASH), m.Option(GRANT_URL), kit.Simple(m.OptionSimple(GRANT_TYPE, CODE), "appid", m.Option(CLIENT_ID), "secret", m.Option(CLIENT_SECRET))...); !m.WarnNotValid(res == nil) { kit.Value(res, EXPIRES_IN, m.Time(kit.Format("%vs", kit.Int(kit.Value(res, EXPIRES_IN))))) m.Info("what %v", kit.Format(res)) m.Options(res) diff --git a/core/code/vimer.go b/core/code/vimer.go index c9d42e53..8dedceb0 100644 --- a/core/code/vimer.go +++ b/core/code/vimer.go @@ -138,6 +138,7 @@ func init() { m.Cmdy(TEMPLATE, kit.Ext(m.Option(mdb.FILE)), m.Option(nfs.FILE), m.Option(nfs.PATH)) }}, COMPLETE: {Hand: func(m *ice.Message, arg ...string) { + return m.Cmdy(COMPLETE, kit.Ext(m.Option(mdb.FILE)), m.Option(nfs.FILE), m.Option(nfs.PATH)) }}, COMPILE: {Hand: func(m *ice.Message, arg ...string) { diff --git a/misc/wx/access.go b/misc/wx/access.go index 79c14f7f..85d7cedd 100644 --- a/misc/wx/access.go +++ b/misc/wx/access.go @@ -12,6 +12,7 @@ import ( "shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/log" "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/base/web/html" @@ -23,9 +24,10 @@ 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" WXACODE_UNLIMIT = "/wxa/getwxacodeunlimit" + QRCODE_CREATE = "qrcode/create" MENU_CREATE = "menu/create" + MEDIA_GET = "media/get" USER_REMARK = "user/info/updateremark" USER_INFO = "user/info" USER_GET = "user/get" @@ -45,6 +47,11 @@ const ( EXPIRES = "expires" EXPIRE = "expire" TICKET = "ticket" + OAUTH = "oauth" + MEDIA = "media" + + STABLE_TOKEN = "stable_token" + STABLE_TOKEN_EXPIRE = "stable_token_expire" ) const ACCESS = "access" @@ -65,40 +72,41 @@ func init() { m.Echo(ice.TRUE) } }}, + STABLE_TOKEN: {Hand: func(m *ice.Message, arg ...string) { + spideToken(m, STABLE_TOKEN, STABLE_TOKEN, STABLE_TOKEN_EXPIRE, "grant_type", "client_credential") + }}, 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_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)) + spideToken(m, TOKEN_CREDENTIAL, TOKENS, EXPIRES) }}, 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, 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)) + spideToken(m, TICKET_GETTICKET, TICKET, EXPIRE, oauth.ACCESS_TOKEN, m.Cmdx(ACCESS, TOKENS)) }}, AGENT: {Hand: func(m *ice.Message, arg ...string) { ctx.OptionFromConfig(m, ACCESS, APPID) }}, - "oauth": {Icon: "bi bi-shield-fill-check", Hand: func(m *ice.Message, arg ...string) { + "api": {Name: "api method=GET,POST path params", Hand: func(m *ice.Message, arg ...string) { + switch m.Option("method") { + case "POST": + res := SpidePost(m, m.Option(nfs.PATH), kit.Split(m.Option("params"))) + m.Echo(kit.Formats(res)) + case "GET": + res := SpideGet(m, m.Option(nfs.PATH), kit.Split(m.Option("params"))) + m.Echo(kit.Formats(res)) + } + }}, + MEDIA: {Hand: func(m *ice.Message, arg ...string) { + m.OptionDefault(ACCESS, mdb.Config(m, ACCESS)) + m.Cmdy(web.SPIDE, WX, web.SPIDE_SAVE, arg[1], http.MethodGet, MEDIA_GET, oauth.ACCESS_TOKEN, m.Cmdx(ACCESS, TOKENS), "media_id", arg[0]) + }}, + OAUTH: {Icon: "bi bi-shield-fill-check", Hand: func(m *ice.Message, arg ...string) { oauth := m.Cmdx("web.chat.oauth.client", mdb.CREATE, - "domain", "https://api.weixin.qq.com", - "client_id", m.Option("appid"), "client_secret", m.Option("secret"), - "oauth_url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+m.Option("appid"), + "domain", "https://api.weixin.qq.com", "client_id", m.Option(APPID), "client_secret", m.Option(SECRET), + "oauth_url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+m.Option(APPID), "scope", "snsapi_userinfo", "login", "login2", "grant_url", "/sns/oauth2/access_token", "token_url", "/sns/oauth2/refresh_token", - "users_url", "/sns/userinfo", - "scope", "snsapi_userinfo", - "login", "login2", - "user_key", "openid", "nick_key", "nickname", "icon_key", "headimgurl", + "users_url", "/sns/userinfo", "user_key", "openid", "nick_key", "nickname", "icon_key", "headimgurl", ) - m.Cmd("agent", "oauth", m.Cmdx("web.chat.oauth.client", "link", oauth)) + m.Cmd(AGENT, OAUTH, m.Cmdx("web.chat.oauth.client", web.LINK, oauth)) }}, web.SSO: {Name: "sso name*=weixin help*=微信扫码 order=11 env=release,trial,develop wifi", Hand: func(m *ice.Message, arg ...string) { m.Cmd(web.CHAT_HEADER, mdb.CREATE, mdb.TYPE, mdb.PLUGIN, m.OptionSimple(mdb.NAME, mdb.HELP, mdb.ORDER), @@ -127,7 +135,7 @@ func init() { }, gdb.EventsAction(web.SPACE_GRANT, web.SPACE_LOGIN_CLOSE), mdb.ExportHashAction( mdb.SHORT, ACCESS, mdb.FIELD, "time,type,access,icons,usernick,appid,secret,token", tcp.SERVER, CGI_BIN, )), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, arg...).PushAction("oauth", web.SSO, mdb.REMOVE).StatusTimeCount(mdb.ConfigSimple(m, ACCESS, APPID), web.SERVE, m.MergeLink("/chat/wx/login/")) + mdb.HashSelect(m, arg...).PushAction(OAUTH, web.SSO, TICKET, TOKENS, STABLE_TOKEN, "api", mdb.REMOVE).StatusTimeCount(mdb.ConfigSimple(m, ACCESS, APPID), web.SERVE, m.MergeLink("/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 @@ -135,14 +143,32 @@ func init() { }}, }) } +func spideToken(m *ice.Message, api string, token, expire string, arg ...string) { + msg := mdb.HashSelect(m.Spawn(), m.OptionDefault(ACCESS, mdb.Config(m, ACCESS))) + if msg.Append(token) == "" || m.Time() > msg.Append(expire) { + kit.If(api != TICKET_GETTICKET, func() { arg = append(arg, msg.AppendSimple(APPID, SECRET)...) }) + res := m.Cmd(web.SPIDE, WX, kit.Select(http.MethodGet, http.MethodPost, api == STABLE_TOKEN), api, arg) + if m.Warn(!kit.IsIn(res.Append("errcode"), "0", ""), res.Append("errmsg")) { + return + } + m.Debug("res: %v", res.FormatMeta()) + mdb.HashModify(m, m.OptionSimple(ACCESS), expire, m.Time(kit.Format("%vs", res.Append(oauth.EXPIRES_IN))), token, res.Append(kit.Select(oauth.ACCESS_TOKEN, TICKET, api == TICKET_GETTICKET))) + msg = mdb.HashSelect(m.Spawn(), m.Option(ACCESS)) + } + m.Echo(msg.Append(token)).Status(msg.AppendSimple(expire)) +} func spidePost(m *ice.Message, api string, arg ...ice.Any) *ice.Message { return m.Cmd(web.SPIDE, WX, web.SPIDE_RAW, http.MethodPost, 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)) + res := kit.UnMarshal(m.Cmdx(web.SPIDE, WX, web.SPIDE_RAW, http.MethodPost, kit.MergeURL(api, oauth.ACCESS_TOKEN, m.Cmdx(ACCESS, TOKENS)), arg)) + m.Info("res: %v", kit.Format(res)) + return res } 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)) + res := kit.UnMarshal(m.Cmdx(web.SPIDE, WX, web.SPIDE_RAW, http.MethodGet, kit.MergeURL(api, oauth.ACCESS_TOKEN, m.Cmdx(ACCESS, TOKENS)), arg)) + m.Info("res: %v", kit.Format(res)) + return res } func Meta() ice.Map { return kit.Dict(ice.CTX_TRANS, kit.Dict(html.INPUT, kit.Dict( diff --git a/misc/wx/agent.js b/misc/wx/agent.js index 52a34495..ae0ffa59 100644 --- a/misc/wx/agent.js +++ b/misc/wx/agent.js @@ -7,6 +7,7 @@ Volcanos(chat.ONIMPORT, { msg.Option(ice.MSG_ACTION, ""), can.require([msg.Option(nfs.SCRIPT)], function(can) { var debug = msg.isDebug() && can.user.info.userrole == aaa.TECH; debug && can.onmotion.toggle(can, can._fields, true) wx.config({debug: debug, signature: msg.Option("signature"), timestamp: msg.Option("timestamp"), nonceStr: msg.Option("noncestr"), appId: msg.Option("appid"), + openTagList: ["wx-open-subscribe"], jsApiList: can.core.Item({ 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) }) @@ -21,6 +22,9 @@ Volcanos(chat.ONIMPORT, { 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) } }) }, + uploadImage: function(can, id, cb) { wx.uploadImage({ localId: id, isShowProgressTips: 1, success: function (res) { + can.base.isFunc(cb) && cb(res.serverId) + } }) }, }, function(key, value) { return can.user.agent[key] = value, key }).concat([ // "updateAppMessageShareData", "updateTimelineShareData", ]), @@ -28,75 +32,77 @@ Volcanos(chat.ONIMPORT, { }) }, }) -Volcanos(chat.ONACTION, {list: [ - "getLocation", "openLocation", "openAddress", - "scanQRCode", "scanQRCode1", "uploadImage", "chooseImage", "previewImage", - "updateAppMessageShareData", "updateTimelineShareData", -], -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"]}) -}, -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 - } }) -}, -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 +Volcanos(chat.ONACTION, { + list: [ + "getLocation", "openLocation", "openAddress", + "scanQRCode", "scanQRCode1", + "chooseImage", "uploadImage", "previewImage", + "updateAppMessageShareData", "updateTimelineShareData", + ], + 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) } }) - }) }}) -}, -chooseImage: function(event, can, button) { - 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", - ]}) -}, -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) }, - }) -}, + }, + 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"]}) + }, + 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 + } }) + }, + 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: ["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", + ]}) + }, + 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) }, + }) + }, }) diff --git a/misc/wx/ocr.go b/misc/wx/ocr.go new file mode 100644 index 00000000..e157502e --- /dev/null +++ b/misc/wx/ocr.go @@ -0,0 +1,31 @@ +package wx + +import ( + "strings" + + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" + kit "shylinux.com/x/toolkits" +) + +func init() { + Index.MergeCommands(ice.Commands{ + "ocr": {Name: "ocr access path type auto", Hand: func(m *ice.Message, arg ...string) { + if len(arg) == 0 { + m.Cmdy(ACCESS) + } else if len(arg) == 1 || strings.HasSuffix(arg[1], "/") { + m.Cmdy(nfs.DIR, arg[1:]) + } else if arg[1] != "" { + res := SpidePost(m, "/cv/ocr/"+kit.Select("idcard", arg, 2), web.SPIDE_PART, "img", "@"+arg[1]) + if len(arg) > 2 && arg[2] == "comm" { + kit.For(kit.Value(res, "items"), func(value ice.Map) { m.Push(mdb.TEXT, value[mdb.TEXT]) }) + } else { + m.PushDetail(res) + } + m.EchoImages(m.Resource(arg[1])) + } + }}, + }) +} diff --git a/misc/wx/template.go b/misc/wx/template.go new file mode 100644 index 00000000..4985c25d --- /dev/null +++ b/misc/wx/template.go @@ -0,0 +1,28 @@ +package wx + +import ( + ice "shylinux.com/x/icebergs" + kit "shylinux.com/x/toolkits" +) + +const TEMPLATE = "template" + +func init() { + Index.MergeCommands(ice.Commands{ + TEMPLATE: {Name: "template access template_id openid auto", Hand: func(m *ice.Message, arg ...string) { + if len(arg) == 0 { + m.Cmdy(ACCESS) + } else if m.Option(ACCESS, arg[0]); len(arg) == 1 { + res := SpideGet(m, "template/get_all_private_template") + kit.For(kit.Value(res, "template_list"), func(value ice.Map) { + m.Push("", value) + }) + m.Cut("template_id,title,content,example") + } else if len(arg) > 4 { + args := []ice.Any{"template_id", arg[1], "touser", arg[2], "url", arg[3]} + kit.For(arg[4:], func(k, v string) { args = append(args, kit.Keys("data", k, "value"), v) }) + SpidePost(m, "message/template/send", args...) + } + }}, + }) +}