From 9c887c773e551e40bb5a68e6f1eeac9d003f4fd8 Mon Sep 17 00:00:00 2001 From: shylinux Date: Mon, 10 Jun 2019 09:47:45 +0800 Subject: [PATCH] add qrcode --- etc/init.shy | 3 +- src/contexts/aaa/aaa.go | 4 +- src/contexts/ssh/ssh.go | 44 ++++++++---- src/contexts/web/web.go | 24 ++++++- src/examples/chat/chat.go | 86 +++++++++++++++++----- usr/librarys/chat.css | 11 +++ usr/librarys/chat.js | 103 +++++++++++++++++++++++---- usr/librarys/example.js | 33 +++++---- usr/librarys/plugin/initQRCode.js | 9 +++ usr/librarys/toolkit.js | 27 ++++--- usr/librarys/{wexin.js => weixin.js} | 7 +- 11 files changed, 272 insertions(+), 79 deletions(-) create mode 100644 usr/librarys/plugin/initQRCode.js rename usr/librarys/{wexin.js => weixin.js} (91%) diff --git a/etc/init.shy b/etc/init.shy index 1f427453..31631229 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -6,9 +6,10 @@ config load tmp/cert.json work flow trust ~wiki config load tmp/wiki.json wiki_visit - source etc/common.shy ~ssh remote auto +~cli + plugin sort.go sort source local.shy diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index ad617fce..b4564d0a 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -776,8 +776,8 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", // 生成证书 template := x509.Certificate{ - SerialNumber: big.NewInt(1), - IsCA: true, + SerialNumber: big.NewInt(1), + IsCA: true, BasicConstraintsValid: true, KeyUsage: x509.KeyUsageCertSign, Subject: pkix.Name{CommonName: kit.Format(common)}, diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index b5974dd7..3e57a24a 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -46,28 +46,35 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", "timer": &ctx.Config{Name: "timer", Value: map[string]interface{}{"interval": "10s", "timer": ""}, Help: "断线重连"}, "componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{ "index": []interface{}{ - map[string]interface{}{"componet_name": "salary", "componet_help": "salary", "componet_tmpl": "componet", - "componet_type": "public", - "componet_view": "Salary", "componet_init": "", - "componet_ctx": "web.chat", "componet_cmd": "salary", "componet_args": []interface{}{"@text", "@total"}, "inputs": []interface{}{ + map[string]interface{}{"componet_name": "salary", "componet_help": "计算工资", + "componet_tmpl": "componet", "componet_view": "Salary", "componet_init": "", + "componet_type": "public", "componet_ctx": "web.chat", "componet_cmd": "salary", + "componet_args": []interface{}{}, "inputs": []interface{}{ map[string]interface{}{"label": "total", "type": "text", "name": "text"}, map[string]interface{}{"label": "base", "type": "text", "name": "total"}, }, }, - map[string]interface{}{"componet_name": "pwd", "componet_help": "pwd", "componet_tmpl": "componet", - "componet_type": "protected", - "componet_view": "FlashList", "componet_init": "initFlashList.js", - "componet_ctx": "nfs", "componet_cmd": "pwd", "componet_args": []interface{}{"@text"}, "inputs": []interface{}{ + map[string]interface{}{"componet_name": "qrcode", "componet_help": "生成二维码", + "componet_tmpl": "componet", "componet_view": "QRCode", "componet_init": "initQRCode.js", + "componet_type": "public", "componet_ctx": "web.chat", "componet_cmd": "login", + "componet_args": []interface{}{"qrcode"}, "inputs": []interface{}{ + map[string]interface{}{"label": "content", "type": "text", "name": "content"}, + }, + }, + map[string]interface{}{"componet_name": "pwd", "componet_help": "pwd", + "componet_tmpl": "componet", "componet_view": "FlashList", "componet_init": "initFlashList.js", + "componet_type": "protected", "componet_ctx": "nfs", "componet_cmd": "pwd", + "componet_args": []interface{}{}, "inputs": []interface{}{ map[string]interface{}{"type": "button", "value": "当前", "click": "show"}, map[string]interface{}{"type": "button", "value": "所有", "click": "show"}, map[string]interface{}{"type": "text", "name": "text"}, }, "display_result": "", "display_append": "", }, - map[string]interface{}{"componet_name": "dir", "componet_help": "dir", "componet_tmpl": "componet", - "componet_type": "private", - "componet_view": "FlashList", "componet_init": "initFlashList.js", - "componet_ctx": "nfs", "componet_cmd": "dir", "componet_args": []interface{}{"@text"}, "inputs": []interface{}{ + map[string]interface{}{"componet_name": "dir", "componet_help": "dir", + "componet_tmpl": "componet", "componet_view": "FlashList", "componet_init": "initFlashList.js", + "componet_type": "private", "componet_ctx": "nfs", "componet_cmd": "dir", + "componet_args": []interface{}{}, "inputs": []interface{}{ map[string]interface{}{"type": "text", "name": "text"}, }, "display_result": "", "display_append": "", @@ -134,6 +141,11 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", return } switch arg[0] { + case "init": // 创建用户 + if m.Confs("runtime", "user.cert") && m.Confs("runtime", "user.key") { + break + } + fallthrough case "create": // 创建用户 m.Cmd("aaa.auth", "username", m.Conf("runtime", "user.name"), "delete", "node") if len(arg) == 1 { @@ -231,8 +243,14 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", m.Echo("private componet of %s", m.Conf("runtime", "work.name")) break } + msg := m.Find(kit.Format(tool["componet_ctx"])) - msg.Cmd(tool["componet_cmd"], arg[4:]).CopyTo(m) + + args := []string{} + for _, v := range kit.Trans(tool["componet_args"]) { + args = append(args, msg.Parse(v)) + } + msg.Cmd(tool["componet_cmd"], args, arg[4:]).CopyTo(m) default: m.Confm("componet", arg[0:], func(value map[string]interface{}) { diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index f9b2e4eb..eef0e85d 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -5,6 +5,7 @@ import ( "contexts/ctx" "encoding/json" "fmt" + "github.com/skip2/go-qrcode" // "github.com/PuerkitoBio/goquery" "github.com/go-cas/cas" "html/template" @@ -136,6 +137,10 @@ func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request) if msg.Options("sessid") { msg.Log("info", "sessid: %s", msg.Option("sessid")) msg.Log("info", "username: %s", msg.Option("username", msg.Cmd("aaa.sess", "user").Append("meta"))) + msg.Log("info", "nickname: %s", msg.Option("nickname", msg.Cmdx("aaa.auth", "username", msg.Option("username"), "data", "nickname"))) + if !msg.Options("nickname") { + msg.Option("nickname", msg.Option("username")) + } } if !msg.Options("username") && msg.Options("relay") { @@ -167,7 +172,9 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { // 请求环境 msg.Option("dir_root", msg.Cap("directory")) for _, v := range r.Cookies() { - msg.Option(v.Name, v.Value) + if v.Value != "" { + msg.Option(v.Name, v.Value) + } } // 请求参数 @@ -223,10 +230,19 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { switch { case msg.Has("redirect"): http.Redirect(w, r, msg.Append("redirect"), http.StatusTemporaryRedirect) + case msg.Has("directory"): http.ServeFile(w, r, msg.Append("directory")) + case msg.Has("componet"): msg.Spawn().Add("option", "componet_group", msg.Meta["componet"]).Cmd("/render") + + case msg.Has("qrcode"): + w.Header().Set("Content-Type", "image/png") + qr, e := qrcode.New(msg.Append("qrcode"), qrcode.Medium) + m.Assert(e) + m.Assert(qr.Write(256, w)) + case msg.Has("append"): meta := map[string]interface{}{} if len(msg.Meta["result"]) > 0 { @@ -915,7 +931,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", accept_json := strings.HasPrefix(m.Option("accept"), "application/json") w := m.Optionv("response").(http.ResponseWriter) if accept_json { - w.Header().Add("Content-Type", "application/json") + // w.Header().Add("Content-Type", "application/json") } else { w.Header().Add("Content-Type", "text/html") } @@ -1022,7 +1038,9 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } // 添加响应 - if msg.Appends("directory") { + if msg.Appends("qrcode") { + m.Append("qrcode", msg.Append("qrcode")) + } else if msg.Appends("directory") { m.Append("download_file", fmt.Sprintf("/download/%s", msg.Append("directory"))) return } else if accept_json { diff --git a/src/examples/chat/chat.go b/src/examples/chat/chat.go index 928665ed..fe38c459 100644 --- a/src/examples/chat/chat.go +++ b/src/examples/chat/chat.go @@ -9,6 +9,7 @@ import ( "encoding/xml" "fmt" "net/http" + "net/url" "sort" "strings" "time" @@ -117,6 +118,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", "chat": &ctx.Config{Name: "chat", Value: map[string]interface{}{ "appid": "", "appmm": "", "token": "", "site": "https://shylinux.com", + "auth": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STATE#wechat_redirect", "access": map[string]interface{}{"token": "", "expire": 0, "url": "/cgi-bin/token?grant_type=client_credential"}, "ticket": map[string]interface{}{"value": "", "expire": 0, "url": "/cgi-bin/ticket/getticket?type=jsapi"}, }, Help: "聊天记录"}, @@ -128,21 +130,46 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", }, Help: "聊天记录"}, }, Commands: map[string]*ctx.Command{ + "/qrcode": &ctx.Command{Name: "qrcode text", Help: "登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + m.Append("qrcode", m.Option("text")) + return + }}, "login": &ctx.Command{Name: "login [username password]", Help: "登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) > 1 { - if m.Cmds("ssh.work", "share", arg[0]) { - if m.Cmds("aaa.auth", "username", arg[0], "password", arg[1]) { - m.Option("username", arg[0]) - m.Copy(m.Cmd("aaa.user", "session", "select"), "result") - m.Option("sessid", m.Result(0)) - if !m.Cmds("aaa.auth", "username", arg[0], "data", "chat.default") && m.Option("username") != m.Conf("runtime", "work.name") { - m.Cmds("aaa.auth", "username", arg[0], "data", "chat.default", m.Spawn().Cmd(".ocean", "spawn", "", m.Option("username")+"@"+m.Conf("runtime", "work.name"))) + if len(arg) > 0 { // 非登录态 + switch arg[0] { + case "weixin": + m.Cmdy(".js_token") + case "qrcode": + m.Append("qrcode", arg[1]) + case "rename": + default: + if m.Cmds("ssh.work", "share", arg[0]) { + if m.Cmds("aaa.auth", "username", arg[0], "password", arg[1]) { + m.Option("username", arg[0]) + m.Copy(m.Cmd("aaa.user", "session", "select"), "result") + m.Option("sessid", m.Result(0)) + if !m.Cmds("aaa.auth", "username", arg[0], "data", "chat.default") && m.Option("username") != m.Conf("runtime", "work.name") { + m.Cmds("aaa.auth", "username", arg[0], "data", "chat.default", m.Spawn().Cmdx(".ocean", "spawn", "", m.Option("username")+"@"+m.Conf("runtime", "work.name"))) + } } } } - } else if m.Options("sessid") { - m.Echo(m.Option("username")) } + + // 登录检查 + if !m.Options("sessid") && !m.Options("username") { + return + } + if len(arg) > 0 { + switch arg[0] { + case "rename": + m.Cmd("aaa.auth", "username", m.Option("username"), "data", "nickname", arg[1]) + } + } + + m.Append("remote_ip", m.Option("remote_ip")) + m.Append("nickname", m.Option("nickname")) + m.Echo(m.Option("username")) return }}, "ocean": &ctx.Command{Name: "ocean", Help: "海洋", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { @@ -172,6 +199,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", "conf": map[string]interface{}{ "create_user": m.Option("username"), "create_time": m.Time(), + "update_time": m.Time(), "name": kit.Select("what", arg, 2), "route": kit.Select(m.Conf("runtime", "node.route"), m.Option("node.route"), arg[1] != ""), }, @@ -194,6 +222,14 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", if !m.Options("sessid") || !m.Options("username") { return } + + if m.Options("river") { + if m.Confs("flow", m.Option("river")) && !m.Confs("flow", []string{m.Option("river"), "user", m.Option("username")}) { + u := m.Cmdx("ssh._route", m.Conf("runtime", "work.route"), "_check", "work", m.Option("username")) + m.Conf("flow", []string{m.Option("river"), "user", m.Option("username"), "user"}, u) + } + } + if len(arg) == 0 { m.Confm("flow", func(key string, value map[string]interface{}) { if kit.Chain(value, []string{"user", m.Option("username")}) == nil { @@ -204,6 +240,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", m.Add("append", "name", kit.Chains(value, "conf.name")) m.Add("append", "create_user", kit.Chains(value, "conf.create_user")) m.Add("append", "create_time", kit.Chains(value, "conf.create_time")) + m.Add("append", "update_time", kit.Chains(value, "conf.update_time")) if list, ok := kit.Chain(value, "text.list").([]interface{}); ok { m.Add("append", "count", len(list)) @@ -211,7 +248,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", m.Add("append", "count", 0) } }) - m.Table() + m.Sort("name").Sort("update_time", "time_r").Table() return } @@ -224,6 +261,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", m.Add("append", "text", value["text"]) m.Add("append", "create_time", value["create_time"]) m.Add("append", "create_user", value["create_user"]) + m.Add("append", "create_nick", value["create_nick"]) }) m.Table() return @@ -238,11 +276,14 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", m.Conf("flow", []string{arg[1], "text.list.-2"}, map[string]interface{}{ "create_user": m.Option("username"), + "create_nick": m.Option("nickname"), "create_time": m.Time(), "type": arg[2], "text": arg[3], }) + m.Conf("flow", []string{arg[1], "conf.update_time"}, m.Time()) + count := m.Confi("flow", []string{arg[1], "text.count"}) + 1 m.Confi("flow", []string{arg[1], "text.count"}, count) m.Append("create_user", m.Option("username")) @@ -266,7 +307,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", m.Add("append", "key", key) m.Add("append", "count", kit.Len(value["list"])) }) - m.Table() + m.Sort("key").Table() return } if len(arg) == 2 { @@ -380,18 +421,22 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", m.Option("selfname", data.ToUserName) // 创建会话 - if m.Option("sessid", m.Cmd("aaa.user", m.Option("username", data.FromUserName), "chat").Append("key")) == "" { - m.Cmd("aaa.sess", m.Option("sessid", m.Cmdx("aaa.sess", "chat", "ip", "what")), m.Option("username"), "ppid", "what") - } + m.Option("sessid", m.Cmdx("aaa.user", "session", "select")) + m.Option("bench", m.Cmdx("aaa.sess", "bench", "select")) - // 创建空间 - if m.Option("bench", m.Cmd("aaa.sess", m.Option("sessid"), "bench").Append("key")) == "" { - m.Option("bench", m.Cmdx("aaa.work", m.Option("sessid"), "chat")) - } m.Option("current_ctx", kit.Select("chat", m.Magic("bench", "current_ctx"))) switch data.MsgType { case "text": + m.Echo(web.Merge(m, map[string]interface{}{"path": "chat"}, m.Conf("chat", "site"), "sessid", m.Option("sessid"))) + if !m.Cmds("aaa.auth", "username", m.Option("usernmae"), "data", "chat.default") && m.Option("username") != m.Conf("runtime", "work.name") { + if m.Cmds("ssh.work", "share", m.Option("username")) { + m.Cmd("aaa.auth", "username", m.Option("username"), "data", "nickname", "someone") + m.Cmds("aaa.auth", "username", m.Option("username"), "data", "chat.default", m.Spawn().Cmdx(".ocean", "spawn", "", m.Option("username")+"@"+m.Conf("runtime", "work.name"))) + } + } + Marshal(m, "text") + return // 执行命令 cmd := strings.Split(data.Content, " ") if !m.Cmds("aaa.work", m.Option("bench"), "right", data.FromUserName, "chat", cmd[0]) { @@ -440,6 +485,9 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", m.Append("signature", hex.EncodeToString(h[:])) m.Append("appid", m.Conf("chat", "appid")) + m.Append("remote_ip", m.Option("remote_ip")) + m.Append("auth2.0", fmt.Sprintf(m.Conf("chat", "auth"), m.Conf("chat", "appid"), + url.QueryEscape(fmt.Sprintf("%s%s", m.Conf("chat", "site"), m.Option("index_url"))), kit.Select("snsapi_base", m.Option("scope")))) return }}, "share": &ctx.Command{Name: "share", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { diff --git a/usr/librarys/chat.css b/usr/librarys/chat.css index 2b5f0dee..b0229f1f 100644 --- a/usr/librarys/chat.css +++ b/usr/librarys/chat.css @@ -1,3 +1,14 @@ +fieldset.Login { + font-size:28px; +} +fieldset.Login input { + font-size:18px; + height:28px; +} +fieldset.Login button { + font-size:18px; + height:28px; +} fieldset.Ocean div.create pre:hover { background-color:red; } diff --git a/usr/librarys/chat.js b/usr/librarys/chat.js index 3fce9ee3..5c5a5744 100644 --- a/usr/librarys/chat.js +++ b/usr/librarys/chat.js @@ -80,23 +80,77 @@ var page = Page({ {label: "username"}, {input: ["username"]}, {type: "br"}, {label: "password"}, {password: ["password"]}, {type: "br"}, {button: ["login", function(event) { + if (!ui.username.value) { + ui.username.focus() + return + } + if (!ui.password.value) { + ui.password.focus() + return + } form.Run([ui.username.value, ui.password.value], function(msg) { if (msg.result && msg.result[0]) { pane.ShowDialog(1, 1) ctx.Cookie("sessid", msg.result[0]) - page.header.State("user", ui.username.value) - page.river.Show() + location.reload() return } page.alert("用户或密码错误") }) - }]} + }]}, + {button: ["scan", function(event) { + scan(event, function(text) { + alert(text) + }) + }]}, + {type: "br"}, + {type: "img", data: {"src": "/chat/qrcode?text=hi"}} ]) + + if (true||kit.isWeiXin) { + pane.Run(["weixin"], function(msg) { + // if (!ctx.Search("state")) { + // location.href = msg["auth2.0"][0] + // } + // return + kit.AppendChild(document.body, [{include: ["https://res.wx.qq.com/open/js/jweixin-1.4.0.js", function(event) { + kit.AppendChild(document.body, [{include: ["/static/librarys/weixin.js", function(event) { + wx.error(function(res){ + }) + wx.ready(function(){ + wx.getNetworkType({success: function (res) { + }}) + return + wx.getLocation({ + success: function (res) { + page.footer.State("site", parseInt(res.latitude*10000)+","+parseInt(res.longitude*10000)) + }, + }) + }) + wx.config({ + appId: msg.appid[0], + timestamp: msg.timestamp[0], + nonceStr: msg.nonce[0], + signature: msg.signature[0], + jsApiList: [ + "scanQRCode", + "chooseImage", + "closeWindow", + "openAddress", + "getNetworkType", + "getLocation", + ] + }) + }]}]) + }]}]) + }) + } form.Run([], function(msg) { if (msg.result && msg.result[0]) { - page.header.State("user", msg.result[0]) + page.header.State("user", msg.nickname[0]) page.river.Show() + page.footer.State("ip", msg.remote_ip[0]) return } pane.ShowDialog(1, 1) @@ -193,7 +247,7 @@ var page = Page({ }, initRiver: function(page, pane, form, output) { pane.Show = function() { - output.Update([], "text", ["name", "count"], "key", true) + output.Update([], "text", ["name", "count"], "key", ctx.Search("river")||true, function(line, index, event) {}) } pane.Action = { "创建": function(event) { @@ -213,9 +267,10 @@ var page = Page({ pane.Show = function() { var cmds = ["brow", river, 0] - output.innerHTML = "", pane.Times(100, cmds, function(line, index, msg) { + output.innerHTML = "", pane.Times(1000, cmds, function(line, index, msg) { output.Append("", line, ["text"], "index", fun) cmds[2] = parseInt(line.index)+1 + page.footer.State("text", cmds[2]) }) } @@ -293,7 +348,7 @@ var page = Page({ output.Update([river, storm], "plugin", ["node", "name"], "index", false, function(line, index, event, args, cbs) { event.shiftKey? page.target.Send("field", JSON.stringify({ - name: line.name, view: line.view, init: line.init, + name: line.name, help: line.help, view: line.view, init: line.init, node: line.node, group: line.group, index: line.index, inputs: line.inputs, args: args, })): form.Run([river, storm, index].concat(args), function(msg) { @@ -343,7 +398,7 @@ var page = Page({ }, } pane.Show = function() { - output.Update([river], "text", ["key", "count"], "key", true) + output.Update([river], "text", ["key", "count"], "key", ctx.Search("storm")||true) } pane.Next = function() { var next = output.querySelector("div.item.select").nextSibling @@ -490,13 +545,17 @@ var page = Page({ output.Select(index), pane.which.set(line[which]) typeof cb == "function" && cb(line, index, event, cmds, cbs) }) - list.push(ui.last), pane.scrollBy(0, pane.scrollHeight) + list.push(ui.last), pane.scrollBy(0, pane.scrollHeight+100) return ui } output.Update = function(cmds, type, key, which, first, cb) { output.Clear(), form.Runs(cmds, function(line, index, msg) { var ui = output.Append(type, line, key, which, cb) - first && index == 0 && ui.first.click() + if (typeof first == "string") { + (line.key == first || line.name == first) && ui.first.click() + } else { + first && index == 0 && ui.first.click() + } }) } @@ -519,9 +578,27 @@ var page = Page({ }) page.onlayout(null, page.conf.layout) - page.footer.Order({"action": "", "text": ""}, ["action", "text"]) - page.header.Order({"user": ""}, ["user"], function(event, item, value) { - page.confirm("logout?") && page.login.Exit() + kit.isMobile && page.action.Action["最宽"]() + + page.footer.Order({"text": "", "ip": ""}, ["ip", "text"]) + kit.isMobile && page.footer.Order({"text": "", "site": "", "ip": ""}, ["ip", "text", "site"]) + page.header.Order({"user": "", "logout": "logout"}, ["logout", "user"], function(event, item, value) { + switch (item) { + case "title": + ctx.Search({"river": page.river.which.get(), "storm": page.storm.which.get()}) + break + case "user": + var name = page.prompt("new name") + name && page.login.Run(["rename", name], function(msg) { + page.header.State("user", name) + }) + break + case "logout": + page.confirm("logout?") && page.login.Exit() + break + default: + } }) + }, }) diff --git a/usr/librarys/example.js b/usr/librarys/example.js index 1a5b52b5..b06445d8 100644 --- a/usr/librarys/example.js +++ b/usr/librarys/example.js @@ -55,7 +55,9 @@ function Page(page) { var text = line switch (type) { case "icon": - result = [{view: ["item", "div"], list: [{type: "img", data: {src: line[key[0]]}}, {}]}] + result = [{view: ["item", "div"], list: [{img: [line[key[0]], function(event) { + event.target.scrollIntoView() + }]}]}] break case "text": @@ -81,29 +83,32 @@ function Page(page) { case "plugin": var id = "plugin"+page.ID() - result = [{view: [text.view, "fieldset"], data: {id: id}, list: [ - {text: [text.name, "legend"]}, + result = [{name: "field", view: [text.view, "fieldset"], data: {id: id}, list: [ + {text: [text.name+"("+text.help+")", "legend"]}, {name: "option", view: ["option", "form"], data: {Run: cb}, list: [{type: "input", style: {"display": "none"}}]}, {name: "output", view: ["output", "div"]}, - {script: "Plugin("+id+","+text.inputs+","+"["+(text.args||"")+"]"+","+(text.init||"")+")"}, + {script: "Plugin("+id+","+text.inputs+","+"[\""+(text.args||[]).join("\",\"")+"\"]"+","+(text.init||"")+")"}, ]}] break } if (parent.DisplayUser) { ui = kit.AppendChild(parent, [{view: ["item"], list:[ - {view: ["user", "div", line.create_user]}, + {view: ["user", "div", line.create_nick]}, {view: ["text"], list:result} ]}]) } else { ui = kit.AppendChild(parent, [{view: ["item"], list:result}]) } - ui.last.Meta = line + ui.field && (ui.field.Meta = text) return ui }, alert: function(text) { alert(text) }, + prompt: function(text) { + return prompt(text) + }, confirm: function(text) { return confirm(text) }, @@ -225,7 +230,9 @@ function Page(page) { } pane.Show = function() { output.innerHTML = "", kit.AppendChild(output, [ - {"view": ["title", "div", "shycontext"]}, + {"view": ["title", "div", "shycontext"], click: function(event) { + cb(event, "title", "shycontext") + }}, {"view": ["state"], list: list.map(function(item) {return {text: [state[item], "div"], click: function(event) { cb(event, item, state[item]) }}})}, @@ -342,7 +349,7 @@ function Page(page) { }) timer = setTimeout(loop, time) } - timer = setTimeout(loop, time) + time && (timer = setTimeout(loop, time)) } form.onsubmit = function(event) { event.preventDefault() @@ -377,7 +384,7 @@ function Plugin(field, inputs, args, plugin) { var option = field.querySelector("form.option") var output = field.querySelector("div.output") - function run(event) { + option.Runs = function(event) { var args = [] option.querySelectorAll("input").forEach(function(item, index){ item.type == "text" && args.push(item.value) @@ -390,14 +397,14 @@ function Plugin(field, inputs, args, plugin) { })(msg) }) } + field.onclick = function(event) { page.plugin = field - page.footer.State("action", field.id) } var ui = kit.AppendChild(option, inputs.map(function(item, index, inputs) { item.type == "button"? item.onclick = function(event) { - plugin[item.click]? plugin[item.click](event, item, option, field): run(event) + plugin[item.click]? plugin[item.click](event, item, option, field): option.Runs(event) }: (item.onkeyup = function(event) { page.oninput(event, function(event) { @@ -430,7 +437,7 @@ function Plugin(field, inputs, args, plugin) { } return true }) - event.key == "Enter" && (index == inputs.length-1? run(event): event.target.parentNode.nextSibling.childNodes[1].focus()) + event.key == "Enter" && (index == inputs.length-1? option.Runs(event): event.target.parentNode.nextSibling.childNodes[1].focus()) }, field.Select = function() { ui.last.childNodes[1].focus() }) @@ -442,6 +449,6 @@ function Plugin(field, inputs, args, plugin) { show: function() {}, init: function() {}, } - plugin.init(page, page.action, field, option, output) + plugin.init(page, page.action, field, option, output, ui) page[field.id] = plugin } diff --git a/usr/librarys/plugin/initQRCode.js b/usr/librarys/plugin/initQRCode.js new file mode 100644 index 00000000..6708c4d3 --- /dev/null +++ b/usr/librarys/plugin/initQRCode.js @@ -0,0 +1,9 @@ +{ + init: function(page, pane, plug, form, output, ui) { + form.Runs = function(event) { + var url = "/chat/?componet_group=index&componet_name=login&cmds=qrcode&cmds="+ui.content.value + output.innerHTML = "", kit.AppendChild(output, [{img: [url]}]) + event.ctrlKey? page.target.Send("icon", url): form.Run(event, [ui.content.value]) + } + }, +} diff --git a/usr/librarys/toolkit.js b/usr/librarys/toolkit.js index 65935738..c6a6ab7e 100644 --- a/usr/librarys/toolkit.js +++ b/usr/librarys/toolkit.js @@ -1,5 +1,8 @@ kit = toolkit = { isMobile: navigator.userAgent.indexOf("Mobile") > -1, + isWeiXin: navigator.userAgent.indexOf("MicroMessenger") > -1, + isMacOSX: navigator.userAgent.indexOf("Mac OS X") > -1, + isIPhone: navigator.userAgent.indexOf("iPhone") > -1, isSpace: function(c) { return c == " " || c == "Enter" }, @@ -156,19 +159,16 @@ kit = toolkit = { return elm } - // name - // value - // inner - // style - // dataset - // click + // 基本属性: name value inner style // - // button input label - // 树状结构: tree, fork, leaf - // 普通视图: view, text, code + // dataset click + // button input label img + // + // 树状结构: tree fork leaf + // 普通视图: view text code // 加载文件: include require styles // - // 基本结构: type, data, list + // 基本结构: type data list var kit = this @@ -227,7 +227,12 @@ kit = toolkit = { } else if (child.label) { child.type = "label" - child.data["innerText"] = child.label + child.data["innerText"] = child.label + + } else if (child.img) { + child.type = "img" + child.data["src"] = child.img[0] + child.img.length > 1 && (child.data["onload"] = child.img[1]) } else if (child.tree) { child.type = "ul" diff --git a/usr/librarys/wexin.js b/usr/librarys/weixin.js similarity index 91% rename from usr/librarys/wexin.js rename to usr/librarys/weixin.js index 3c350a4b..e3b65c83 100644 --- a/usr/librarys/wexin.js +++ b/usr/librarys/weixin.js @@ -1,11 +1,10 @@ -function scan(event) { - alert("begin scan") +function scan(event, cb) { wx.scanQRCode({ - needResult: 0, + needResult: 1, scanType: ["qrCode", "barCode"], desc: "what", success: function(res) { - alert(res.resultStr) + cb(res.resultStr) }, fail: function(res) { alert(res.errMsg)