diff --git a/const.js b/const.js index d4ee457f..5a8faa36 100644 --- a/const.js +++ b/const.js @@ -41,7 +41,7 @@ var ice = { MSG_USERNICK: "user.nick", MSG_USERNAME: "user.name", MSG_USERROLE: "user.role", MSG_LANGUAGE: "user.lang", MSG_MODE: "sess.mode", MSG_THEME: "sess.theme", MSG_TITLE: "sess.title", MSG_RIVER: "sess.river", MSG_STORM: "sess.storm", MSG_DAEMON: "sess.daemon", LOG_DISABLE: "log.disable", LOG_TRACEID: "log.id", - + ErrWarn: "warn: ", ErrNotLogin: "not login: ", ErrNotRight: "not right: ", ErrNotValid: "not valid: ", ErrNotFound: "not found: ", NFS: "nfs", USR: "usr", CAN_PLUGIN: "can._plugin", } @@ -78,7 +78,7 @@ var web = {CHAT: "chat", PORTAL: "portal", STUDIO: "studio", SERVICE: "service", DRAW: "draw", PLAY: "play", CLEAR: "clear", REFRESH: "refresh", RESIZE: "resize", FILTER: "filter", CANCEL: "cancel", SUBMIT: "submit", UPLOAD: "upload", DOWNLOAD: "download", TOIMAGE: "toimage", CONFIRM: "confirm", - + CHAT_SSO: "/chat/sso/", CHAT_POD: "/chat/pod/", CHAT_CMD: "/chat/cmd/", @@ -255,7 +255,8 @@ var http = { GET: "GET", PUT: "PUT", POST: "POST", DELETE: "DELETE", Accept: "Accept", ContentType: "Content-Type", ApplicationJSON: "application/json", ApplicationFORM: "application/x-www-form-urlencoded", } -var html = {PLUGIN_MARGIN: 10, ACTION_HEIGHT: 32, ACTION_MARGIN: 200, +var html = { + PLUGIN_MARGIN: 10, ACTION_HEIGHT: 32, ACTION_MARGIN: 200, FIELDSET: "fieldset", LEGEND: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status", OPTION_ARGS: "select.args,input.args,textarea.args", INPUT_ARGS: "input.args,textarea.args", INPUT_BUTTON: "input[type=button]", INPUT_FILE: "input[type=file]", FORM_OPTION: "form.option", DIV_ACTION: "div.action", DIV_OUTPUT: "div.output", DIV_STATUS: "div.status", @@ -291,7 +292,7 @@ var html = {PLUGIN_MARGIN: 10, ACTION_HEIGHT: 32, ACTION_MARGIN: 200, CLASS: "class", DARK: "dark", LIGHT: "light", WHITE: "white", BLACK: "black", FILTER: "filter", TOGGLE: "toggle", EXPAND: "expand", SPEED: "speed", HOVER: "hover", HOVER_SELECT: "hover,select", NOT_HIDE: ":not(.hide)", - + PAGE: "page", TABS: "tabs", MENU: "menu", NODE: "node", PLUG: "plug", ZONE: "zone", LIST: "list", ITEM: "item", NAME: "name", ICON: "icon", VIEW: "view", HEAD: "head", LEFT: "left", MAIN: "main", FOOT: "foot", AUTO: "auto", SHOW: "show", HIDE: "hide", diff --git a/lib/core.js b/lib/core.js index b12379cb..b2bd0438 100644 --- a/lib/core.js +++ b/lib/core.js @@ -119,7 +119,7 @@ Volcanos("core", { }, Timer: shy("定时器, value, [1,2,3,4], {delay, interval, length}", function(interval, cb, cbs) { var timer = {stop: false} function loop(i) { timer.stop || i >= interval.length && interval.length >= 0 || cb(timer, interval.interval||interval[i], i, interval)? - typeof cbs == code.FUNCTION && cbs(timer, interval): setTimeout(function() { loop(i+1) }, interval.interval||interval[i+1]) + typeof cbs == code.FUNCTION && cbs(timer, interval): setTimeout(function() { loop(i+1) }, interval.interval||interval[i+1]) } interval = typeof interval == code.OBJECT? interval: [interval]; if (interval.interval == 0) { return cb(), timer } var delay = interval.delay||interval.interval/2||interval[0] return typeof cb == code.FUNCTION && (timer._timer = setTimeout(function() { loop(0) }, delay)), timer diff --git a/lib/user.js b/lib/user.js index 30730b6d..4cbb1db1 100644 --- a/lib/user.js +++ b/lib/user.js @@ -1,7 +1,5 @@ Volcanos("user", { agent: { - chooseImage: function(can, cb) { can.base.isFunc(cb) && cb([]) }, - scanQRCode: function(can, cb) { can.user.input(event, can, [{type: html.TEXTAREA, name: mdb.TEXT, text: ""}], function(list) { cb(can.base.ParseJSON(list[0])) }) }, getLocation: function(can, cb) { var call = arguments.callee; if (call._res) { return cb(call._res) } navigator.geolocation.getCurrentPosition(function(res) { cb(call._res = {type: "ip", name: "当前位置", text: "某某大街", latitude: res.coords.latitude.toFixed(6), longitude: res.coords.longitude.toFixed(6)}) @@ -11,6 +9,8 @@ Volcanos("user", { window.open("https://map.baidu.com/search/"+encodeURIComponent(msg.Option(mdb.TEXT)) +"/@12958750.085,4825785.55,16z?querytype=s&da_src=shareurl&wd="+encodeURIComponent(msg.Option(mdb.TEXT))) }, + scanQRCode: function(can, cb) { can.user.input(event, can, [{type: html.TEXTAREA, name: mdb.TEXT, text: ""}], function(list) { cb(can.base.ParseJSON(list[0])) }) }, + chooseImage: function(can, cb) { can.base.isFunc(cb) && cb([]) }, }, info: {}, isTesla: navigator.userAgent.indexOf("Tesla") > -1, isChrome: navigator.userAgent.indexOf("Chrome") > -1, diff --git a/publish/client/mp/app.js b/publish/client/mp/app.js index c8eb280d..7172d74b 100644 --- a/publish/client/mp/app.js +++ b/publish/client/mp/app.js @@ -1,128 +1,11 @@ -const kit = require("utils/kit.js") +const base = require("utils/lib/base.js") +const core = require("utils/lib/core.js") +const misc = require("utils/lib/misc.js") +const page = require("utils/lib/page.js") +const user = require("utils/lib/user.js") App({ - data: {}, conf: {serve: "https://shylinux.com/chat", space: ""}, - requests: function(cmd, data, cb) { wx.showLoading() - this.request(cmd, data, function(msg) { wx.hideLoading(), typeof cb == "function" && cb(msg) }) - }, - request: function(cmd, data, cb) { var app = this; data.sessid_443 = app.conf.sessid, data.pod = app.conf.space - wx.request({method: "POST", url: app.conf.serve+"/"+cmd, data: data, success: function(res) { var msg = res.data - if (res.statusCode == 401) { return app.usercode(function() { app.request(cmd, data, cb) }) } - console.log("POST", cmd, msg) - - var proto = { - Result: function() { return msg.result && msg.result.length > 0 && msg.result.join("") || "" }, - Length: function() { var max = 0; if (!msg.append) { return max } - for (var i = 0; i < msg.append.length; i++) { - var len = msg[msg.append[i]].length; len > max && (max = len) - }; return max - }, - Table: function(cb) { var res = [] - if (msg.append && msg.append[0] == "key" && msg.append[1] == "value") { - var line = {}; kit.List(msg.key, function(key, index) { - line[key] = msg.value[index] - }) - typeof cb == "function" && cb(line, 0, 1) - return res.push(line), res - } - - for (var i = 0; i < msg.Length(); i++) { var line = {} - for (var k in msg.append) { line[msg.append[k]] = msg[msg.append[k]][i] } - typeof cb == "function" && cb(line, i, msg.Length()) - res.push(line) - }; return res - }, - Data: function(item, index) { - var text = msg[item]&&msg[item][index]||"" - var data = {_type: "text", _text: text} - if (text.indexOf("<") != 0) { return [data] } - - var res = [], list = kit.Split(text, " ", "<=/>") - for (var i = 0; i < list.length; i++) { - if (list[i] == "<") { data = {} - if (list[i] == "/") { i++ } else { res.push(data) } - data._type = list[i+1], data._text = text, i++ - continue - } else if (list[i] == ">") { - continue - } - - if (list[i+1] == "=") { - data[list[i]] = list[i+2], i += 2 - } else { - data[list[i]] = list[i] - } - } - return res.length == 0? [data]: res - }, - }; for (var k in proto) { msg[k] = proto[k] } - - msg._index = []; for (var i = 0; i < msg.Length(); i++) { msg._index.push(i) } - msg._view = {}, msg["append"] && kit.List(msg["append"], function(k) { msg._view[k] = {} - for (var i in msg[k]) { msg._view[k][i] = msg.Data(k, i) } - }) - typeof cb == "function" && cb(msg) - }}) - }, - download: function(cmd, data, cb) { var app = this; data.sessid = app.conf.sessid - wx.downloadFile({url: app.conf.serve+"/"+cmd, data: data, success: cb}) - }, - - usercode: function(cb) { var app = this - wx.login({success: function(res) { app.request("mp/login/action/sess", {code: res.code}, function(msg) { - wx.setStorage({key: "sessid", data: app.conf.sessid = msg.Result()}) - typeof cb == "function" && cb() - })}}) - }, - userinfo: function(cb) { var app = this - app.conf.userInfo? app.request("mp/login/action/user", app.conf.userInfo, function(msg) { - typeof cb == "function" && cb(app.conf.userInfo) - }): app.usercode(function() { wx.getSetting({success: function(res) { - res.authSetting['scope.userInfo'] && wx.getUserInfo({success: function(res) { - app.request("mp/login/user", app.conf.userInfo = res.userInfo, function(msg) { - typeof cb == "function" && cb(app.conf.userInfo) - }) - }}) - }}) }) - }, - - title: function(title) { wx.setNavigationBarTitle({title: title, success: function() {}})}, - modal: function(title, content, cb) { wx.showModal({title: title||"", content: content||"", success: cb})}, - toast: function(title, content) { wx.showToast({title: title, content: content||""})}, - jumps: function(url, args, cb) { var next = "/pages/"+kit.Args(url, args) - console.log("jump", next), wx.navigateTo({url: next, success: cb}) - }, - scans: function(cb) { var app = this - wx.scanCode({success: function(res) { var data = kit.parseJSON(res.result) - if (typeof cb == "function" && cb(data)) { return } - - switch (data.type) { - case "auth": - app.userinfo(function(userInfo) { - app.modal("授权登录", data.name, function(res) { - res.confirm && app.request("mp/login/scan", data, function(msg) { - app.toast("授权成功") - }) - }) - }) - break - default: app.request("mp/login/scan", data) - } - }}) - }, - clipboard: function(cb) { wx.getClipboardData({success: function(res) { - typeof cb == "function" && cb(kit.parseJSON(res.data)) - }}) }, - location: function(cb) { wx.chooseLocation({success: function(res) { - typeof cb == "function" && cb({ - type: "gcj02", name: res.name, text: res.address, - longitude: parseInt(res.longitude * 100000), - latitude: parseInt(res.latitude * 100000), - }) - }}) }, - - onLaunch: function() { - this.conf.sessid = wx.getStorageSync("sessid") - console.log("load", "sessid", this.conf.sessid) - }, + data: {}, conf: {serve: "https://2021.shylinux.com/chat"}, + base: base, core: core, misc: misc, page: page, user: user, + onLaunch: function() { console.log("app load", this.conf) }, }) diff --git a/publish/client/mp/app.wxml b/publish/client/mp/app.wxml index ad2ce65b..00029c3c 100644 --- a/publish/client/mp/app.wxml +++ b/publish/client/mp/app.wxml @@ -1,78 +1,70 @@ - - - diff --git a/publish/client/mp/app.wxss b/publish/client/mp/app.wxss index 318a1187..6997bb4a 100644 --- a/publish/client/mp/app.wxss +++ b/publish/client/mp/app.wxss @@ -1,66 +1,17 @@ -page { - background-color:#272822; color:white; - font-size:14px; font-family:monospace; -} -view.title { - font-size:18px; font-weight:bold; - margin-top:20px; margin-bottom:10px; -} - -view.output { - max-width:-webkit-fill-available; - overflow:auto; - clear:both; -} -view.output view.item { - font-size:18px; text-align:center; - padding:10px; border:solid 1px green; -} -view.output view.list view.item { - background-color:darkgray; - margin-left:20px; -} -view.output view.code { - margin-left:10px; padding:10px; - border-left:solid 2px cyan; -} - -view.action view.item { - float:left; padding:0; -} -view.option view.item { - border:0; padding:0; - float:left; margin:2px; -} -view.option view.item.textarea { - border:solid 1px green; - width:calc(100% - 2px); - clear:both; -} -view.option view.item.select { - border:solid 1px green; padding:6px; -} -view.option view.item button { - height:29px; -} -view.option view.item input { - border:solid 1px green; - width:80px; -} - -tr { - text-align:center; white-space:nowrap; - display:flex; -} -th { - border:solid 1px red; padding:5px; - width:100%; -} -td { - border:solid 1px green; padding:5px; - width:100%; -} -td view.which { - float:left; -} - +view { box-sizing: border-box; } +page { background-color:black; color:white; } +view.action view.item { padding:0; margin-right:10px; float:left; } +view.output { max-width:-webkit-fill-available; overflow:auto; clear:both; } +view.output view.item { font-size:18px; text-align:center; padding:10px; border:solid 1px green; } +view.output view.list view.item { background-color:darkgray; margin-left:20px; } +view.legend { font-size:18px; font-weight:bold; margin-top:20px; margin-bottom:10px; } +view.option view.item { padding:0; border:0; margin:2px; height:32px; float:left; } +view.option view.item.textarea { border:solid 1px green; width:calc(100% - 2px); clear:both; } +view.option view.item.select { border:solid 1px green; } +view.option view.item input { border:solid 1px green; height:32px; width:80px; } +view.option view.item button { height:32px; } +view.output view.code { white-space:pre; padding:10px; border-left:solid 2px cyan; margin-left:10px; } +table { display:table; } +tr { display:table-row; text-align:center; white-space:nowrap; } +th { display:table-cell; padding:5px; border:solid 1px red; } +td { display:table-cell; padding:5px; border:solid 1px green; vertical-align:middle; } diff --git a/publish/client/mp/pages/action/action.js b/publish/client/mp/pages/action/action.js index e650d723..563f5b79 100644 --- a/publish/client/mp/pages/action/action.js +++ b/publish/client/mp/pages/action/action.js @@ -1,216 +1,109 @@ -const kit = require("../../utils/kit.js") -const app = getApp() - -Page({ - name: "action", - data: { - river: "", storm: "", title: "", - action: ["刷新", "扫码", "清屏", "串行", "并行"], - list: [], back: [], - }, - action: { - "刷新": function(event, page) { var list = [] - app.data[[page.data.river, page.data.storm].join(".")] = page.data.list = list, page.data.back = [] - app.requests(page.name, {cmds: [page.data.river, page.data.storm]}, function(msg) { - msg.Table(function(line, index) { - list.push(line), page.data.back.push([]) - line.feature = kit.parseJSON(line.meta, {}) - line.inputs = kit.parseJSON(line.list,[]) - line.name = line.name.split(" ")[0] - - if (!line.inputs || line.inputs.length === 0) { - line.inputs = [{type: "text"}, {type: "button", value: "执行"}] - } - - line.inputs.forEach(function(input) { input.action = input.action || input.value - input.value = kit.Value(line, "feature._trans."+input.name) || input.value - input.value == "auto" && (input.value = "") - - if (input.value && input.value.indexOf("@") == 0) { - input.action = input.value.slice(1), input.value = "" - } - if (input.type == "select") { - input.values = input.values || kit.Split(input.value) - } - - input.type == "button" && input.action == "auto" && kit.Timer(100, function() { page.run(event, index) }) - }) - }), page.setData({list: list}) - }) - }, - "扫码": function(event, page) { - app.scans(function(res) { - switch (res.type) { - case "button": res.name && page.onaction(event, res); break - default: return false - } return true - }) - }, - "清屏": function(event, page) { - kit.List(page.data.list, function(item) { delete(item.msg) }) - page.setData({list: page.data.list}) - }, - "串行": function(event, page) { - function cb(i) { - page.run(event, i, null, function() { i < page.data.list.length - 1 && cb(i+1) }) - }; cb(0) - }, - "并行": function(event, page) { - kit.List(page.data.list, function(item, index) { page.run(event, index) }) - }, - }, - onaction: function(event, data) { data = data || event.target.dataset - console.log("action", this.name, data.name) - this.action[data.name](event, this) - }, - run: function(event, order, cmd, cb) { var page = this, field = page.data.list[order] - var cmds = [page.data.river, page.data.storm, field.id||field.key]; if (!cmd) { - var cmd = kit.List(field.inputs, function(input) { if (input.type != "button") { return input.value } }) - kit.EQ(page.data.back[page.data.back.length-1], cmd) || page.data.back[order].push(cmd) - }; cmds = cmds.concat(cmd) - - for (var i = cmds.length-1; i > 0; i--) { if (cmds[i] === "") { cmds.pop() } else { break } } - - var option = event._option||{}; option.cmds = cmds - app.requests("action?="+field.name, option, function(msg) { - field.msg = msg, page.setData({list: page.data.list}) - typeof cb == "function" && cb(msg) - }) - }, - onInput: function(event) { var page = this, data = event.target.dataset - var input = page.data.list[data.order].inputs[data.index] - input.value = event.detail.value - }, - onChange: function(event) { var page = this, data = event.target.dataset - var input = page.data.list[data.order].inputs[data.index] - input.value = input.values[parseInt(event.detail.value)] - }, - onClick: function(event) { var page = this, data = event.target.dataset - var field = page.data.list[data.order]; var input = field.inputs[data.index] - - if (field.feature[input.name]) { - app.data.insert = {field: field, input: input, list: field.feature[input.name], cb: function(res) { - page.run(event, data.order, kit.Simple("action", input.name, res)) - }} - app.jumps("insert/insert", {river: page.data.river, storm: page.data.storm, title: field.name}) - return - } - - switch (input.name) { - case "back": // 恢复命令 - page.data.back[data.order].pop(); var line = page.data.back[data.order].pop() - kit.List(field.inputs, function(input, index) { - if (input.type != "button") { input.value = line&&line[index] || "" } - }) - case "run": // 执行命令 - case "刷新": // 执行命令 - case "list": page.run(event, data.order); break - default: - var cb = page.plugin[input.name]; typeof cb == "function"? cb(event, page, data.order, input.name): - page.run(event, data.order, ["action", input.name].concat(kit.List(field.inputs, function(input) { - if (input.type != "button") { return input.value } - }))) - } - }, - onWhich: function(event) { var page = this, data = event.currentTarget.dataset - var field = page.data.list[data.order]; if (!field) { return } - - var input = data.input; if (input && input.type == "button") { var option = {} - kit.List(field.inputs, function(input) { input.type != "button" && (option[input.name] = input.value) }) - if (field.msg.append[0] == "key" && field.msg.append[1] == "value") { - kit.List(field.msg.key, function(key, index) { option[key] = field.msg.value[index] }) - } else { - kit.List(field.msg.append, function(key) { option[key] = field.msg[key][data.index] }) - } - event._option = option - - var cb = page.plugin[input.name]; typeof cb == "function"? cb(event, page, data.order, input.name): - page.run(event, data.order, ["action", input.name]) - return - } - - field.inputs.forEach(function(input, index) { - if (input.name == data.key) { input.value = data.value - page.setData({list: page.data.list}) - input.action == "auto" && page.run(event, data.order) - } - }) - }, - plugin: { - scanQRCode: function(event, page, order, cmd) { app.scans(function(res) { - page.run(event, order, kit.Simple("action", cmd, res), function(msg) { - app.toast("添加成功"), page.run(event, order) - }) - return true - }) }, - getClipboardData: function(event, page, order, cmd) { app.clipboard(function(res) { - page.run(event, order, kit.Simple("action", cmd, res), function() { - app.toast("添加成功"), page.run(event, order) - }) - }) }, - startLocalServiceDiscovery: function(event, page, order, cmd) { - wx.onLocalServiceFound(function(res) { - console.log(res) - }) - - wx.showLoading() - wx.startLocalServiceDiscovery({ - serviceType: '_http._tcp.', - success: function(res) { - wx.hideLoading() - console.log(res) - }, - }) - }, - - getLocation: function(event, page, order, cmd) { app.location(function(res) { - page.run(event, order, kit.Simple("action", cmd, res), function() { - app.toast("添加成功"), page.run(event, order) - }) - }) }, - chooseLocation: function(event, page, order, cmd) { - wx.chooseLocation({success: function(res) { res.text = res.address, delete(res.address) - page.run(event, order, kit.Simple("action", cmd, res), function() { - app.toast("添加成功"), page.run(event, order) - }) - }}) - }, - - getWifiList: function(event, page, order, cmd) { - wx.onGetWifiList(function(res) { - console.log(res) - }) - - wx.getWifiList(function(res) { - console.log(res) - }) - }, - openLocation: function(event, page, order, cmd) { - var list = page.data.list[order].msg.Table() - var data = list[event.currentTarget.dataset.index]||list[0] - wx.openLocation({name: data.name, address: data.text, latitude: parseInt(data.latitude)/100000.0, longitude: parseInt(data.longitude)/100000.0}) - }, - }, - - onReady: function () {}, - onLoad: function (options) { - console.log("page", this.name, options) - this.data.river = options.river - this.data.storm = options.storm - this.data.title = options.title - app.title(options.title) - - var data = app.data[[options.river, options.storm].join(".")] - data? this.setData({list: this.data.list = data}): this.onaction({}, {name: "刷新"}) - }, - onShow: function () {}, - onHide: function () {}, - onUnload: function () {}, - onReachBottom: function () {}, - onPullDownRefresh: function () { this.onaction({}, {name: "刷新"}) }, - onShareAppMessage: function (res) { - return {title: this.data.title, path: kit.Args("pages/action/action", { - river: this.data.river, storm: this.data.storm, title: this.data.title, - })} - }, +const {shy, Volcanos} = require("../../utils/proto.js") +const {html} = require("../../utils/const.js") +Volcanos._page = {} +Volcanos("onimport", { + _init: function(can, msg) { can.db.list = [] + msg.Table(function(value, index) { can.db.list.push(value) + value.feature = can.base.Obj(value.meta, {}) + value.inputs = can.base.Obj(value.list, []) + value.name = can.core.Split(value.name)[0] + if (!value.inputs || value.inputs.length === 0) { + value.inputs = [{type: html.TEXT}, {type: html.BUTTON, value: "执行"}] + } + can.core.List(value.inputs, function(input) { + input.action = input.action || input.value + input.value = can.core.Value(value, "feature._trans."+input.name) || input.value + input.value == "auto" && (input.value = "") + if (input.value && input.value.indexOf("@") == 0) { + input.action = input.value.slice(1), input.value = "" + } + if (input.type == "select") { + input.values = input.values || can.core.Split(input.value) + } + input.type == "button" && input.action == "auto" && can.core.Timer(100, function() { + can.run({}, [can.db.river, can.db.storm, value.id||value.index], function(msg) { + value.msg = msg, can.page.setData(can, can.db.list) + }) + }) + }) + }), can.page.setData(can, can.db.list) + }, }) +Volcanos("onaction", {list: ["刷新", "扫码", "清屏"], + "刷新": function(event, can) { can.onaction.refresh(event, can) }, + "扫码": function(event, can) { can.user.agent.scanQRCode(can) }, + "清屏": function(event, can) { + can.core.List(can.db.list, function(item) { delete(item.msg) }) + can.page.setData(can, can.db.list) + }, + refresh: function(event, can) { + can.run(event, [can.db.river, can.db.storm], function(msg) { + can.onimport._init(can, msg) + }) + }, + onaction: function(event, can, msg) { var name = msg.Option("name") + (can.onaction[name]||function(event) { can.run(event, [ctx.ACTION, name]) })(event, can) + }, + onInputs: function(event, can, msg) { var order = msg.Option("order")||0, index = msg.Option("index")||0 + var input = can.ui.data.list[order||0].inputs[index||0] + input.value = event.detail.value + }, + onChange: function(event, can, msg) { var order = msg.Option("order")||0, index = msg.Option("index")||0 + var input = can.ui.data.list[order||0].inputs[index||0] + input.value = input.values[parseInt(event.detail.value)] + }, + onAction: function(event, can, msg) { var order = msg.Option("order")||0, name = msg.Option("name") + var field = can.ui.data.list[order||0] + if (field.feature[name]) { + can.data.insert = {field: field, name: name, list: field.feature[name], cb: function(res) { + can.run(event, can.base.Simple([can.db.river, can.db.storm, field.id||field.index, ctx.ACTION, name], res), function(msg) { + can.onaction.onAction(event, can, order) + }) + }} + can.user.jumps("/pages/insert/insert", {river: can.db.river, storm: can.db.storm, index: field.id||field.index, title: field.name}) + return + } + field._history = field._history||[] + switch (name) { + case "back": + var ls = field._history.pop() + var ls = field._history.pop()||[] + var i = 0 + can.core.List(field.inputs, function(input, index) { + if (input.type != html.BUTTON) { + input.value = ls[i++]||"" + } + }) + can.page.setData(can) + can.onaction.onAction(event, can, order, "list") + break + case "run": + case "list": + case "refresh": + break + default: + return + } + var cmds = [can.db.river, can.db.storm, field.id||field.index] + var cmd = can.core.List(field.inputs, function(input) { if (input.type != html.BUTTON) { return input.value } }) + function eq(to, from) { if (!to) { return false } + if (to.length != from.length) { return false } + for (var i = 0; i < to.length; i++) { + if (to[i] != from[i]) { return false } + } return true + } eq(field._history[field._history.length-1], cmd) || field._history.push(cmd) + cmds = cmds.concat(cmd) + for (var i = cmds.length-1; i > 0; i--) { if (cmds[i] === "") { cmds.pop() } else { break } } + can.run(event, cmds, function(msg) { field.msg = msg, can.page.setData(can) }) + }, + onDetail: function(event, can, msg) { var order = msg.Option("order")||0, name = msg.Option("name"), value = msg.Option("value") + var field = can.ui.data.list[order||0] + can.core.List(field.inputs, function(input) { + if (input.name == name) { + input.value = value, can.page.setData(can) + can.onaction.onAction(event, can, order, "list") + } + }) + }, +}) +Volcanos._init() diff --git a/publish/client/mp/pages/action/action.json b/publish/client/mp/pages/action/action.json deleted file mode 100644 index 5ed4543e..00000000 --- a/publish/client/mp/pages/action/action.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "usingComponents": {} -} diff --git a/publish/client/mp/pages/action/action.wxss b/publish/client/mp/pages/action/action.wxss deleted file mode 100644 index e69de29b..00000000 diff --git a/publish/client/mp/pages/insert/insert.js b/publish/client/mp/pages/insert/insert.js index aff7739e..b8ed86b4 100644 --- a/publish/client/mp/pages/insert/insert.js +++ b/publish/client/mp/pages/insert/insert.js @@ -1,5 +1,5 @@ -const kit = require("../../utils/kit.js") const app = getApp() +var kit = {} Page({ name: "insert", diff --git a/publish/client/mp/pages/insert/insert.json b/publish/client/mp/pages/insert/insert.json deleted file mode 100644 index 8835af06..00000000 --- a/publish/client/mp/pages/insert/insert.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "usingComponents": {} -} \ No newline at end of file diff --git a/publish/client/mp/pages/insert/insert.wxss b/publish/client/mp/pages/insert/insert.wxss deleted file mode 100644 index b96c7b27..00000000 --- a/publish/client/mp/pages/insert/insert.wxss +++ /dev/null @@ -1 +0,0 @@ -/* pages/insert/insert.wxss */ \ No newline at end of file diff --git a/publish/client/mp/pages/river/river.js b/publish/client/mp/pages/river/river.js index c75ee87a..3694be08 100644 --- a/publish/client/mp/pages/river/river.js +++ b/publish/client/mp/pages/river/river.js @@ -1,55 +1,31 @@ -const kit = require("../../utils/kit.js") -const app = getApp() - -Page({ - name: "river", - data: { - action: ["刷新", "扫码", "登录"], - list: [], - }, - action: { - "刷新": function(event, page) { - app.requests(page.name, {}, function(msg) { - page.setData({list: msg.Table()}) - }) - }, - "扫码": function(event, page) { - app.scans(function(res) { - switch (res.type) { - case "button": res.name && page.onaction(event, res); break - default: return false - } return true - }) - }, - "登录": function(event, page) { app.conf.sessid = "" - app.userinfo(function(res) { page.onaction(event, {name: "刷新"}) }) - }, - }, - onaction: function(event, data) { data = data || event.target.dataset - console.log("action", this.name, data.name) - this.action[data.name](event, this) - }, - ondetail: function(event, data) { data = data || event.target.dataset - var page = this, item = page.data.list[data.index] - item._show = !item._show; if (item.list) { - return page.setData({list: page.data.list}) - } - - app.requests(page.name, {cmds: [item.hash, "storm"]}, function(msg) { - item.list = msg.Table(), page.setData({list: page.data.list}) - }) - }, - onchange: function(event, data) { data = data || event.target.dataset - var item = this.data.list[data.index]; var storm = item.list[data.i] - app.jumps("action/action", {river: item.hash, storm: storm.hash, title: item.name+"."+storm.name}) - }, - - onReady: function () {}, - onLoad: function (options) { this.onaction({}, {name: "刷新"}) }, - onShow: function () {}, - onHide: function () {}, - onUnload: function () {}, - onReachBottom: function () {}, - onPullDownRefresh: function () { this.onaction({}, {name: "刷新"}) }, - onShareAppMessage: function () {} +const {shy, Volcanos} = require("../../utils/proto.js") +const {ice, chat, html} = require("../../utils/const.js") +Volcanos._page = {} +Volcanos("onimport", { + _init: function(can, msg) { msg.Dump(can) }, }) +Volcanos("onaction", {list: ["刷新", "扫码", "登录"], + "刷新": function(event, can) { can.onaction.refresh(event, can) }, + "扫码": function(event, can) { can.user.agent.scanQRCode(can) }, + "登录": function(event, can) { + can.user.info = {}, can.misc.localStorage(can, ice.MSG_SESSID, can.conf.sessid = "") + can.user.userinfo(can, function() { can.onaction.refresh(event, can) }) + }, + refresh: function(event, can) { can.run(event, [], function(msg) { can.onimport._init(can, msg) }) }, + onaction: function(event, can, msg) { var name = msg.Option("name") + (can.onaction[name]||function(event) { can.run(event, [ctx.ACTION, name]) })(event, can) + }, + ondetail: function(event, can, msg) { var index = msg.Option("index")||"0" + var item = can.ui.data.list[index]; item._show = !item._show + if (item.list) { return can.page.setData(can) } + can.run(event, [item.hash, chat.STORM], function(msg) { + item.list = msg.Table(), can.page.setData(can) + }) + }, + onchange: function(event, can, msg) { var index = msg.Option("index")||0, i = msg.Option("i")||0 + var river = can.ui.data.list[index], storm = river.list[i] + can.user.jumps(can.base.MergeURL("/pages/action/action", {river: river.hash, storm: storm.hash, title: river.name+"."+storm.name})) + }, + _name: "river/", +}) +Volcanos._init() diff --git a/publish/client/mp/pages/river/river.json b/publish/client/mp/pages/river/river.json deleted file mode 100644 index 5ed4543e..00000000 --- a/publish/client/mp/pages/river/river.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "usingComponents": {} -} diff --git a/publish/client/mp/pages/river/river.wxml b/publish/client/mp/pages/river/river.wxml index 1c4803cf..62e9b440 100644 --- a/publish/client/mp/pages/river/river.wxml +++ b/publish/client/mp/pages/river/river.wxml @@ -1,4 +1,3 @@ - diff --git a/publish/client/mp/pages/river/river.wxss b/publish/client/mp/pages/river/river.wxss deleted file mode 100644 index e69de29b..00000000 diff --git a/publish/client/mp/project.config.json b/publish/client/mp/project.config.json index 662959b5..fe0feb3e 100644 --- a/publish/client/mp/project.config.json +++ b/publish/client/mp/project.config.json @@ -1,7 +1,8 @@ { "description": "项目配置文件", "packOptions": { - "ignore": [] + "ignore": [], + "include": [] }, "setting": { "urlCheck": true, @@ -45,33 +46,12 @@ "libVersion": "2.15.0", "appid": "wxf4e5104d83476ed6", "projectname": "%E7%BB%88%E7%AB%AF%E5%B7%A5%E5%85%B7%E9%93%BE", - "debugOptions": { - "hidedInDevtools": [] - }, - "isGameTourist": false, "simulatorType": "wechat", "simulatorPluginLibVersion": {}, "condition": { - "search": { - "list": [] - }, - "conversation": { - "list": [] - }, - "plugin": { - "list": [] - }, - "game": { - "currentL": -1, - "list": [] - }, - "gamePlugin": { - "list": [] - }, "miniprogram": { "list": [ { - "id": 0, "name": "pages/action/action", "pathName": "pages/action/action", "query": "river= e0a1eb&storm=c23ae3&title=hi.scan", @@ -79,5 +59,9 @@ } ] } + }, + "editorSetting": { + "tabIndent": "insertSpaces", + "tabSize": 2 } } \ No newline at end of file diff --git a/publish/client/mp/project.private.config.json b/publish/client/mp/project.private.config.json new file mode 100644 index 00000000..05f1ccf4 --- /dev/null +++ b/publish/client/mp/project.private.config.json @@ -0,0 +1,6 @@ +{ + "projectname": "%E7%BB%88%E7%AB%AF%E5%B7%A5%E5%85%B7%E9%93%BE", + "setting": { + "compileHotReLoad": true + } +} \ No newline at end of file diff --git a/publish/client/mp/sitemap.json b/publish/client/mp/sitemap.json index ca02add2..55d1d29e 100644 --- a/publish/client/mp/sitemap.json +++ b/publish/client/mp/sitemap.json @@ -1,7 +1,7 @@ { "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", "rules": [{ - "action": "allow", - "page": "*" + "action": "allow", + "page": "*" }] -} \ No newline at end of file +} diff --git a/publish/client/mp/utils/const.js b/publish/client/mp/utils/const.js new file mode 100644 index 00000000..b271df7e --- /dev/null +++ b/publish/client/mp/utils/const.js @@ -0,0 +1,53 @@ +var kit = {proto: function(sub, sup) { return sub.__proto__ = sup, sub }, + Dict: function() { var res = {}, arg = arguments; for (var i = 0; i < arg.length; i += 2) { var key = arg[i] + if (typeof key == "object") { i-- + if (key.length == undefined) { + for (var k in key) { res[k] = key[k] } + } else { + for (var j = 0; j < key.length; j += 2) { res[key[j]] = key[j+1] } + } + } else if (typeof key == "string" && key) { res[key] = arg[i+1] } + } return res }, +} +var ice = { + TB: "\t", SP: " ", DF: ":", EQ: "=", AT: "@", QS: "?", PS: "/", PT: ".", FS: ",", NL: "\n", LT: "<", GT: ">", + + MSG_FIELDS: "fields", MSG_SESSID: "sessid", + MSG_DETAIL: "detail", MSG_OPTION: "option", MSG_APPEND: "append", MSG_RESULT: "result", +} +var ctx = { + CONTEXT: "context", COMMAND: "command", CONFIG: "config", INPUTS: "inputs", FEATURE: "feature", + CMDS: "cmds", INDEX: "index", ARGS: "args", STYLE: "style", DISPLAY: "display", ACTION: "action", RUN: "run", + EXTRA_INDEX: "extra.index", EXTRA_ARGS: "extra.args", +} +var mdb = { + EQ: ice.EQ, FS: ice.FS, + KEY: "key", VALUE: "value", STATUS: "status", EXPIRE: "expire", EXTRA: "extra", +} +var nfs = { + DF: ice.DF, PS: ice.PS, PT: ice.PT, +} +var code = { + COMMENT: "comment", KEYWORD: "keyword", + PACKAGE: "package", DATATYPE: "datatype", FUNCTION: "function", CONSTANT: "constant", + STRING: "string", NUMBER: "number", BOOLEAN: "boolean", OBJECT: "object", ARRAY: "array", UNDEFINED: "undefined", + META: "Meta", ALT: "Alt", CONTROL: "Control", SHIFT: "Shift", TAB: "Tab", ESCAPE: "Escape", ENTER: "Enter", + CMD: "Cmd", CTRL: "Ctrl", SPACE: "Space", BACKSPACE: "Backspace", ESC: "Esc", PS: "/", +} +var chat = { + SHARE: "share", RIVER: "river", STORM: "storm", FIELD: "field", TOOL: "tool", +} +var http = { + GET: "GET", PUT: "PUT", POST: "POST", DELETE: "DELETE", + Accept: "Accept", ContentType: "Content-Type", ApplicationJSON: "application/json", ApplicationFORM: "application/x-www-form-urlencoded", +} +var html = { + SELECT: "select", INPUT: "input", TEXT: "text", FILE: "file", TEXTAREA: "textarea", BUTTON: "button", +} +module.exports = { + kit, ice, + ctx, mdb, + nfs, + code, chat, + http, html, +} diff --git a/publish/client/mp/utils/kit.js b/publish/client/mp/utils/kit.js deleted file mode 100644 index f3db505a..00000000 --- a/publish/client/mp/utils/kit.js +++ /dev/null @@ -1,191 +0,0 @@ -const lang = { - STRING: "string", OBJECT: "object", FUNCTION: "function", - ENTER: "Enter", -} -function shy(help, meta, list, cb) { - var index = 0, args = arguments; function next(type) { - if (index < args.length && (!type || type == typeof args[index])) { - return args[index++] - } - } - - cb = args[args.length-1]||function() {} - cb.help = next(code.STRING)||"" - cb.meta = next(code.OBJECT)|| {} - cb.list = next(code.OBJECT)||[] - return cb -} -module.exports = { - EQ: function(obj, other) { - if (typeof obj != typeof other) { return false } - - if (typeof obj == "object") { - if (obj.length != other.length) { return false } - for (var i = 0; i < obj.length; i++) { - if (!this.EQ(obj[i], other[i])) { return false } - } - - for (var k in obj) { - if (!this.EQ(obj[k], other[k])) { return false } - } - return true - } - return obj === other - }, - Number: function(d, n) {var res = []; - while (d > 0) {res.push(d % 10); d = parseInt(d / 10); n--} - while (n > 0) {res.push("0"); n--} - return res.reverse(), res.join(""); - }, - Time: function(t, fmt) {var now = t? new Date(t): new Date(); - fmt = fmt || "%y-%m-%d %H:%M:%S"; - fmt = fmt.replace("%y", now.getFullYear()) - fmt = fmt.replace("%m", Number(now.getMonth()+1, 2)) - fmt = fmt.replace("%d", Number(now.getDate(), 2)) - fmt = fmt.replace("%H", Number(now.getHours(), 2)) - fmt = fmt.replace("%M", Number(now.getMinutes(), 2)) - fmt = fmt.replace("%S", Number(now.getSeconds(), 2)) - return fmt - }, - Args: function(url, args) { var list = [] - for (var k in args) { - list.push(encodeURIComponent(k)+"="+encodeURIComponent(args[k])) - } - return url+"?"+list.join("&") - }, - List: function(list, cb, cbs) {var res = [], val; - for (var i = 0; i < list.length; i++) { - typeof cb == "function"? (val = cb(list[i], i, list)) != undefined && res.push(val): res.push(list[i]) - } - return typeof cbs == "function" && cbs(res), res - }, - Item: function(list, cb, cbs) { - for (var k in list) { cb(k, list[k]) } - }, - Value: function(data, key, value) { - if (data == undefined) { return } - if (key == undefined) { return data } - if (typeof key == "object") { for (var k in key) { - arguments.callee.call(this, data, k, key[k]) - }; return data } - - if (value != undefined) { data[key] = value } - if (data[key] != undefined) { return data[key] } - - var p = data, ls = key.split("."); while (p && ls.length > 0) { - if (ls[0] == "-1") { ls[0] = p.length-1 } - p = p[ls[0]], ls = ls.slice(1) - }; return p - }, - Simple: function() { var res = [] - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; switch (typeof arguments[i]) { - case "number": res.push(arg); break - case "string": res.push(arg); break - case "object": - if (arg.length > 0) { - res = res.concat(arg) - } else { - for (var k in arg) { res.push(k, arg[k]) } - } - } - } - return res - }, - - Timer: shy("定时器, value, [1,2,3,4], {value, length}", function(interval, cb, cbs) { - interval = typeof interval == "object"? interval || []: [interval] - var timer = {stop: false}; function loop(timer, i) { - if (timer.stop || i >= interval.length && interval.length >= 0) { - return typeof cbs == "function" && cbs(timer, interval) - } - return typeof cb == "function" && cb(timer, interval.interval||interval[i], i, interval)? - typeof cbs == "function" && cbs(timer, interval): setTimeout(function() { loop(timer, i+1) }, interval.interval||interval[i+1]) - } - setTimeout(function() { loop(timer, 0) }, interval.interval||interval[0]) - return timer - }), - Split: shy("分词器", function(str) { if (!str || !str.length) { return [] } - var opt = {detail: false}, arg = []; for (var i = 1; i < arguments.length; i++) { - typeof arguments[i] == "object"? opt = arguments[i]: arg.push(arguments[i]) - } - - function _list(str) { var res = {}; for (var i = 0; i < str.length; i++) { res[str[i]] = true }; return res } - // 空白符 - var seps = _list(arg[0]||"\t ,\n") - // 分隔符 - var sups = _list(arg[1]||"{[(.:)]}") - // 引用符 - var subs = _list(arg[2]||"'\"`") - - // 开始分词 - var res = [], list = str - var left = "", space = true, begin = 0 - for (var i = 0; i < list.length; i++) { - if (seps[list[i]]) { - // 空白符 - if (left == "") { - if (!space) { - res.push(list.slice(begin, i)) - } - opt.detail && res.push({text: list.slice(i, i+1), type: "space", left: left}) - space = true, begin = i+1 - } - } else if (subs[list[i]]) { - // 引用符 - if (left == "") { - left = list[i], space = false, begin = i+1 - } else if (left == list[i]) { - opt.detail? res.push({text: list.slice(begin, i), type: "string", left: left, right: left}): res.push(list.slice(begin, i)) - left = "", space = true, begin = i+1 - } - } else if (sups[list[i]]) { - // 分隔符 - if (left == "") { - if (!space) { - res.push(list.slice(begin, i)) - } - res.push(list.slice(i, i+1)) - space = true, begin = i+1 - } - } else if (list[0] == '\\') { - // 转义符 - for (var i = i; i < list.length-1; i++) { - list[i] = list[i+1] - } - list = list.slice(0, list.length-1) - space = false - } else { - space = false - } - } - - // 末尾字符 - if (left != "") { - res.push({text: list.slice(begin), type: "string", left: left, right: ""}) - } else if (begin < list.length) { - res.push(list.slice(begin)) - } - return res - }), - parseJSON: shy("解析器", function(str, def) { var res - if (!str) { return def||{} } - if (typeof str == "object") { return str } - if (str.indexOf("http") == 0) { var ls = str.split("?") - res = {type: "link", name: "", text: str} - res.name = ls[0].split("://").pop().split("/")[0] - ls[1] && ls[1].split("&").forEach(function(item) { var ls = item.split("=") - res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) - }) - return res - } - try { res = JSON.parse(str) - res.text = res.text||str - res.type = res.type||"json" - } catch (e) { - res = {type: "text", text: str} - } - return res - }), -} - diff --git a/publish/client/mp/utils/lib/base.js b/publish/client/mp/utils/lib/base.js new file mode 100644 index 00000000..68b3ca44 --- /dev/null +++ b/publish/client/mp/utils/lib/base.js @@ -0,0 +1,69 @@ +const {ice, mdb, nfs, code, http} = require("../const.js") +const {Volcanos} = require("../proto.js") +module.exports = +Volcanos("base", { + Obj: function(val, def) { + try { + if (typeof val == code.STRING) { if (val == "") { return def } val = JSON.parse(val) } + if (typeof val == code.NUMBER) { return [val] } + if (val.length > 0) { return val } for (var k in val) { return val } return def + } catch (e) { return typeof val == code.STRING && val.split(mdb.FS) || def } + }, + Copy: function(to, from, merge) { if (!from) { return to } + if (arguments.length == 2 || typeof merge == code.BOOLEAN) { for (var k in from) { if (k == undefined) { continue } + if (merge && to.hasOwnProperty(k) && to[k] != undefined && to[k] != "") { continue } + if (from[k] === "") { delete(to[k]) } else { to[k] = from[k] } + } return to } for (var i = 2; i < arguments.length; i++) { var k = arguments[i]; to[k] = from[k] } return to + }, + Eq: function(to, from, skip) { var call = arguments.callee; if (typeof to != typeof from) { return false } + if (typeof to == code.OBJECT) { if (to.length != from.length) { return false } + for (var i = 0; i < to.length; i++) { if (!call(to[i], from[i])) { return false } } + for (var k in to) { if (k != skip && !call(to[k], from[k])) { return false } } return true + } return to === from + }, + Args: function() { var res = [], arg = arguments; function encode(k, v) { k && v != undefined && v != null && res.push(encodeURIComponent(k)+mdb.EQ+encodeURIComponent(v)) } + for (var i = 0; i < arg.length; i += 2) { if (typeof arg[i] == code.OBJECT) { + if (arg[i].length > 0) { for (var j = 0; j < arg[i].length; j += 2) { encode(arg[i][j], arg[i][j+1]) } } else { for (var k in arg[i]) { encode(k, arg[i][k]) } } i-- + } else { encode(arg[i], arg[i+1]) } } return res.join("&") + }, + _parse: function(url, res) { var list = url.split("#")[0].split(ice.QS); res = res||{}, res._origin = list[0] + list[1] && list[1].split("&").forEach(function(item) { var ls = item.split(mdb.EQ); res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) }) + return res + }, + MergeURL: function(url) { var arg = this._parse(url); delete(arg._origin); for (var i = 1; i < arguments.length; i += 2) { delete(arg[arguments[i]]) } + var arg = this.Args.apply(this, [arg].concat(Array.prototype.slice.call(arguments, 1))); return url.split(ice.QS)[0]+(arg? ice.QS+arg: "") + }, + Number: function(d, n) { var res = [] + while (d > 0) { res.push(d%10); d = parseInt(d/10); n-- } while (n > 0) { res.push("0"); n-- } + return res.reverse(), res.join("") + }, + Simple: function() { var res = []; for (var i = 0; i < arguments.length; i++) { var val = arguments[i]; switch (typeof val) { + case code.OBJECT: if (val.length > 0) { res = res.concat(val); break } + for (var k in val) { k && val[k] && res.push(k, val[k]) } break + default: res.push(val) + } } return res }, + AddUniq: function(list, value) { list = list||[], list.indexOf(value) == -1 && list.push(value); return list }, + isIn: function(item) { var arg = arguments; for (var i = 1; i < arg.length; i++) { + if (typeof arg[i] == code.OBJECT && arg[i].length > 0 && arg[i].indexOf(item) > -1) { return true } + if (item == arg[i]) { return true } + } }, + Time: function(t, fmt) {var now = t? new Date(t): new Date(); + fmt = fmt || "%y-%m-%d %H:%M:%S"; + fmt = fmt.replace("%y", now.getFullYear()) + fmt = fmt.replace("%m", Number(now.getMonth()+1, 2)) + fmt = fmt.replace("%d", Number(now.getDate(), 2)) + fmt = fmt.replace("%H", Number(now.getHours(), 2)) + fmt = fmt.replace("%M", Number(now.getMinutes(), 2)) + fmt = fmt.replace("%S", Number(now.getSeconds(), 2)) + return fmt + }, + ParseJSON: function(str) { var res; if (typeof str == code.OBJECT) { return str } + if (str.indexOf(ice.HTTP) == 0) { var res = this._parse(str, {type: web.LINK, name: "", text: str}); return res.name = res._origin.split("://").pop().split(nfs.PS)[0], res } + try { res = JSON.parse(str), res.text = res.text||str, res.type = res.type||nfs.JSON } catch (e) { res = {type: mdb.TEXT, text: str} } return res + }, + isNumber: function(val) { return typeof val == code.NUMBER }, + isString: function(val) { return typeof val == code.STRING }, + isObject: function(val) { return typeof val == code.OBJECT }, + isArray: function(val) { return Array.isArray(val) }, + isFunc: function(val) { return typeof val == code.FUNCTION }, +}) diff --git a/publish/client/mp/utils/lib/core.js b/publish/client/mp/utils/lib/core.js new file mode 100644 index 00000000..eaf02991 --- /dev/null +++ b/publish/client/mp/utils/lib/core.js @@ -0,0 +1,81 @@ +const {ice, mdb, nfs, code, http} = require("../const.js") +const {shy, Volcanos} = require("../proto.js") +module.exports = +Volcanos("core", { + Value: function(data, key, value) { if (data == undefined) { return } if (key == undefined) { return data } + if (typeof key == code.OBJECT) { if (key.length != undefined) { key = key.join(nfs.PT) } else { for (var k in key) { arguments.callee.call(this, data, k, key[k]) } return data } } + if (value != undefined) { var _node = data, keys = key.split(nfs.PT) + for (var i = 0; i < keys.length; i++) { var _next = _node[keys[i]]||{}; _node[keys[i]] = _next + if (i < keys.length - 1) { _node = _next } else { _node[keys[i]] = value } + } + } + var node = data, keys = key.split(nfs.PT); while (node && keys.length > 0) { + if (keys[0] == "-1") { keys[0] = node.length-1 } node = node[keys[0]], keys = keys.slice(1) + } return node == undefined? data[key]: node + }, + Split: function(str) { if (!str || !str.length) { return [] } + var opt = {detail: false}, arg = []; for (var i = 1; i < arguments.length; i++) { var v = arguments[i]; typeof v == code.OBJECT? opt = v: arg.push(v) } + function _list(str) { var res = {}; for (var i = 0; i < str.length; i++) { res[str[i]] = true }; return res } + var space = _list(arg[0]||"\t ,;\n") // 空白符 + var block = _list(arg[1]||"{[()]}") // 分隔符 + var quote = _list(arg[2]||"'\"`") // 引用符 + var trans = _list(arg[3]||"\\") // 转义符 + var res = [], begin = 0; function push(obj) { obj && res.push(typeof obj == code.STRING || opt.detail? obj: obj.text), begin = -1 } + for (var s = "", i = 0; i < str.length; i++) { + if (space[str[i]]) { if (s) { continue } + begin > -1 && push(str.slice(begin, i)), opt.detail && push({type: code.SPACE, text: str.slice(i, i+1)}) + } else if (block[str[i]]) { if (s) { continue } + begin > -1 && push(str.slice(begin, i)), push(str.slice(i, i+1)) + } else if (quote[str[i]]) { + if (s == "") { + begin > -1 && push(str.slice(begin, i)), s = str[i], begin = i+1 + } else if (s == str[i]) { + push({type: code.STRING, text: str.slice(begin, i), left: s, right: str[i]}), s = "", begin = -1 + } + } else if (trans[str[i]]) { begin == -1 && (begin = i), i++ + } else { begin == -1 && (begin = i) } + } return begin > -1 && (s? push({type: code.STRING, text: str.slice(begin), left: s, right: ""}): push(str.slice(begin))), res + }, + CallFunc: function(func, args, mod) { args = args||{}; var can = args["can"]||args[0], msg = args["msg"]||args[1], cb = args["cb"] + if (Array.isArray(args)) { this.List(args, function(arg) { if (!arg) { return } if (arg.request && arg.run) { can = arg } else if (arg.Append && arg.Result) { msg = arg } else if (typeof arg == code.FUNCTION) { cb = arg } }) } + func = typeof func == code.FUNCTION? func: typeof func == code.OBJECT && func.length > 0? this.Value(func[0], this.Keys(func.slice(1))): typeof func == code.STRING? this.Value(mod||can, func): null + if (typeof func != code.FUNCTION) { if (typeof cb == code.FUNCTION) { cb() } return } + var list = [], echo = false; args.length > 0? list = args: this.List(func.toString().split(")")[0].split("(")[1].split(mdb.FS), function(item, index) { item = item.trim(); if (item == "") { return } + list.push(args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) || null); if (item == "cb") { echo = true } + }); var res = func.apply(mod||can, list); if (msg && msg.Defer) { msg.Defer() } + if (!echo && typeof cb == code.FUNCTION) { res && msg&&msg.Echo&&msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) } return res + }, + List: function(list, cb, interval, cbs) { + if (typeof list == code.STRING) { list = [list] } else if (typeof list == code.NUMBER) { // [end cb interval]|[begin end interval] + var begin = 0, end = list, step = typeof interval == code.NUMBER? interval: 1; if (typeof cb == code.NUMBER) { begin = list, end = cb, cb = null } + list = []; for (var i = begin; i < end; i += step) { list.push(i) } + } list = list||[] + if (interval > 0) { + function loop(i) { i >= list.length? typeof cbs == code.FUNCTION && cbs(list): cb(list[i], i, list), setTimeout(function() { loop(i+1) }, interval) } + typeof cb == code.FUNCTION && list.length > 0 && setTimeout(function() { loop(0) }, interval/4) + } else { var res = [] + for (var i = 0; i < list.length; i++) { var _res = typeof cb == code.FUNCTION? cb(list[i], i, list): list[i]; _res != undefined && res.push(_res) } + list = res + } return list + }, + Item: function(obj, cb) { var list = [] + for (var k in obj) { var res = typeof cb == code.FUNCTION? cb(k, obj[k], list): k; res != undefined && list.push(res) } + return list + }, + ItemCB: function(meta, cb, can, item) { var list = [] + for (var k in meta) { if (k.indexOf("on") == 0 && typeof meta[k] == code.FUNCTION) { (function(k) { list.push(k) + if (typeof cb == code.FUNCTION) { + cb(k, meta[k]) + } else { cb[k] = function(event) { can.misc.Event(event, can, function(msg) { + meta[k](event, can, item) + }) } } + })(k) } } return list + }, + Timer: shy("定时器, value, [1,2,3,4], {delay, interval, length}", function(interval, cb, cbs) { var timer = {stop: false} + function loop(i) { timer.stop || i >= interval.length && interval.length >= 0 || cb(timer, interval.interval||interval[i], i, interval)? + typeof cbs == code.FUNCTION && cbs(timer, interval): setTimeout(function() { loop(i+1) }, interval.interval||interval[i+1]) + } interval = typeof interval == code.OBJECT? interval: [interval]; if (interval.interval == 0) { return cb(), timer } + var delay = interval.delay||interval.interval/2||interval[0] + return typeof cb == code.FUNCTION && (timer._timer = setTimeout(function() { loop(0) }, delay)), timer + }), +}) diff --git a/publish/client/mp/utils/lib/misc.js b/publish/client/mp/utils/lib/misc.js new file mode 100644 index 00000000..b365d8c6 --- /dev/null +++ b/publish/client/mp/utils/lib/misc.js @@ -0,0 +1,113 @@ +const {kit, ice, mdb, nfs, code, http} = require("../const.js") +const {Volcanos} = require("../proto.js") +module.exports = +Volcanos("misc", { + Message: function(event, can) { var msg = kit.proto({}, {_event: event, _can: can, _target: can._target, + Display: function(file) { return msg.Option(ice.MSG_DISPLAY, file) }, + DisplayStory: function(file) { return msg.Option(ice.MSG_DISPLAY, chat.PLUGIN_STORY+file) }, + SearchOrOption: function(key) { return can.misc.Search(can, key)||msg.Option(key) }, + OptionProcess: function() { return msg.Option(ice.MSG_PROCESS) }, + OptionStatus: function() { return msg.Option(ice.MSG_STATUS) }, + StatusTimeCount: function(obj) { msg.append && msg.Status(can.base.Copy(kit.Dict(mdb.TIME, can.base.Time(), mdb.COUNT, msg.Length()+"x"+msg.append.length), obj)) }, + Status: function(obj) { return msg.Option(ice.MSG_STATUS, JSON.stringify(can.core.Item(obj, function(key, value) { return {name: key, value: value} }))) }, + OptionDefault(key, val) { var arg = arguments; for (var i = 0; i < arg.length; i += 2) { msg.Option(arg[i]) || msg.Option(arg[i], arg[i+1]) } return msg.Option(key) }, + Option: function(key, val) { if (key == undefined) { return msg.option || [] } + if (can.base.isObject(key)) { return can.core.Item(key, msg.Option) } + if (val == undefined) { return can.base.isIn(key, msg.option) && msg[key] && msg[key][0] || "" } + return msg.option = can.base.AddUniq(msg.option, key), msg[key] = can.core.List(arguments).slice(1), val + }, + Append: function(key, val) { if (key == undefined) { return msg.append || [] } + if (can.base.isObject(key)) { return can.core.Item(key, msg.Append) } + if (val == undefined) { return can.base.isIn(key, msg.append) && msg[key] && msg[key][0] || "" } + return msg.append = can.base.AddUniq(msg.append, key), msg[key] = can.core.List(arguments).slice(1), val + }, + Result: function() { if (!msg.result) { return "" } return msg.result[0] == ice.ErrWarn? msg.result.join(lex.SP): msg.result.join("") }, + Results: function() { return msg.result && msg.result[0] == ice.ErrWarn? "": msg.Result() }, + TableDetail: function() { var item = can.Option(); return msg.Table(function(value) { can.core.Value(item, value.key, value.value) }), item }, + IsDetail: function() { + return msg.Option("fields") == "detail" || msg.append && msg.append.length == 2 && msg.append[0] == "key" && msg.append[1] == "value" + }, + Table: function(cb) { return can.core.List(msg.Length(), function(index) { var item = {} + can.core.List(msg.append, function(k) { item[k] = msg[k]&&msg[k][index]||"" }) + return can.base.isFunc(cb)? cb(item, index): item + }) }, + Length: function() { var max = 0; can.core.List(msg.append, function(k) { if (msg[k] && msg[k].length > max) { max = msg[k].length } }); return max }, + Clear: function(key) { switch (key||ice.MSG_APPEND) { + case ice.MSG_OPTION: + case ice.MSG_APPEND: can.core.List(msg[key], function(key) { delete(msg[key]) }) + default: delete(msg[key]) + } }, + Copy: function(res) { if (!res) { return msg } + res.append && res.append.length > 0 && (msg.append = res.append) && res.append.forEach(function(key) { + var i = msg.option && msg.option.indexOf(key); if (i > -1) { msg.option[i] = "", delete(msg[key]) } + res[key] && (msg[key] = (msg[key]||[]).concat(res[key])) + }), res.result && res.result.length > 0 && (msg.result = (msg.result||[]).concat(res.result)) + res.option && res.option.length > 0 && (msg.option = res.option) && res.option.forEach(function(key) { res[key] && (msg[key] = res[key]) }) + res._option && (msg._option = res._option) && res._option.forEach(function(key) { res[key] && (msg[key] = res[key]) }) + return msg + }, + Push: function(key, value, detail) { + if (can.base.isObject(key)) { can.core.List(value||msg.append||can.base.Obj(msg.Option(ice.MSG_FIELDS))||can.core.Item(key), function(item) { + detail? msg.Push(mdb.KEY, item).Push(mdb.VALUE, key[item]||""): msg.Push(item, key[item]||"") + }); return msg } + var i = msg.option && msg.option.indexOf(key); if (i > -1) { msg.option[i] = "", msg[key] = [] } + msg.append = can.base.AddUniq(msg.append, key), msg[key] = msg[key]||[] + msg[key].push(can.base.isString(value)||can.base.isFunc(value)? value: JSON.stringify(value)); return msg + }, + PushAction: function(button) { can.core.List(msg.Length(), function() { + msg.Push(ctx.ACTION, can.page.Format(html.INPUT, "", mdb.TYPE, html.BUTTON, mdb.NAME, button, mdb.VALUE, can.user.trans(can, button))) + }); return msg }, + Echo: function(res) { msg.result = (msg.result||[]).concat(can.core.List(arguments)); return msg._hand = true, msg }, + Dump: function(can) { can = can||msg._can; if (can.user.isNodejs) { return } + can.onmotion.clear(can), can.onappend.table(can, msg), can.onappend.board(can, msg), can.onmotion.story.auto(can) + }, + Defer: function(cb) { msg._defer = msg._defer||[] + if (arguments.length == 0) { msg._defer = can.core.List(msg._defer.reverse(), function(cb) { can.base.isFunc(cb) && cb() }) } else { msg._defer.push(cb) } + }, + IsErr: function() { + return msg.result && msg.result[0] == "warn: " + }, + _caller: function(skip) { msg.Option("log.caller") || msg.Option("log.caller", can.misc.fileLine((skip||2)+3).link); return msg }, + isDebug: function() { return msg.Option(log.DEBUG) == ice.TRUE }, + }); return msg }, + requests: function(can, msg, cmd, data, cb) { + wx.showLoading(), can.misc.request(can, msg, cmd, data, function(msg) { wx.hideLoading(), cb && cb(msg) }) + }, + request: function(can, msg, cmd, data, cb) { data.sessid = can.conf.sessid + wx.request({method: http.POST, url: can.conf.serve+nfs.PS+cmd, data: data, success: function(res) { + if (res.statusCode == 401) { return can.user.login(can, function() { can.misc.request(can, msg, cmd, data, cb) }) } + msg.Copy(res.data), console.log("request", cmd, data.cmds||data, msg) + msg.Data = function(item, index) { + var text = msg[item]&&msg[item][index]||"" + var data = {_type: "text", _text: text} + if (text.indexOf("<") != 0) { return [data] } + var res = [], list = can.core.Split(text, " ", "<=/>") + for (var i = 0; i < list.length; i++) { + if (list[i] == "<") { data = {} + if (list[i] == "/") { i++ } else { res.push(data) } + data._type = list[i+1], data._text = text, i++ + continue + } else if (list[i] == ">") { + continue + } else if (list[i+1] == "=") { + data[list[i]] = list[i+2], i += 2 + } else { + data[list[i]] = list[i] + } + } + return res.length == 0? [data]: res + } + msg._index = []; for (var i = 0; i < msg.Length(); i++) { msg._index.push(i) } + msg._view = {}, msg[ice.MSG_APPEND] && can.core.List(msg[ice.MSG_APPEND], function(k) { msg._view[k] = {} + for (var i in msg[k]) { msg._view[k][i] = msg.Data(k, i) } + }), cb && cb(msg) + }}) + }, + download: function(can, msg, cmd, data, cb) { data.sessid = can.conf.sessid + wx.downloadFile({url: can.conf.serve+nfs.PS+cmd, data: data, success: cb}) + }, + localStorage: function(can, key, value) { + value != undefined && wx.setStorageSync(key, value) + return wx.getStorageSync(key) + }, +}) diff --git a/publish/client/mp/utils/lib/page.js b/publish/client/mp/utils/lib/page.js new file mode 100644 index 00000000..0b0fe167 --- /dev/null +++ b/publish/client/mp/utils/lib/page.js @@ -0,0 +1,8 @@ +const {ice, mdb, nfs, code, http} = require("../const.js") +const {Volcanos} = require("../proto.js") +module.exports = +Volcanos("page", { + setData: function(can, list) { + can.ui.setData({list: list||can.ui.data.list}) + } +}) diff --git a/publish/client/mp/utils/lib/user.js b/publish/client/mp/utils/lib/user.js new file mode 100644 index 00000000..56d5effd --- /dev/null +++ b/publish/client/mp/utils/lib/user.js @@ -0,0 +1,68 @@ +const {ice, mdb, nfs, code, http} = require("../const.js") +const {Volcanos} = require("../proto.js") +module.exports = +Volcanos("user", { + agent: { + getLocation: function(can, cb) { + wx.chooseLocation({success: function(res) { + cb && cb({ + latitude: parseInt(res.latitude * 100000), + longitude: parseInt(res.longitude * 100000), + type: "gcj02", name: res.name, text: res.address, + }) + }}) + }, + getClipboard: function(can, cb) { + wx.getClipboardData({success: function(res) { + cb && cb(can.base.ParseJSON(res.data)) + }}) + }, + scanQRCode: function(can, cb) { + wx.scanCode({success: function(res) { var data = can.base.ParseJSON(res.result) + if (cb && cb(data)) { return } + switch (data.type) { + case "auth": + can.user.userinfo(can, function() { + can.user.modal(can, "授权登录", data.name, function(res) { + res.confirm && can.misc.request(can, can.request(), "mp/login/action/scan", data, function(msg) { + can.user.toast(can, "授权成功") + }) + }) + }) + break + default: can.misc.request(can, can.request(), "mp/login/action/scan", data) + } + }}) + }, + }, info: {}, + jumps: function(url, cb) { + wx.navigateTo({url: url, success: cb}) + }, + title: function(text, cb) { + text && wx.setNavigationBarTitle({title: text, success: cb}) + }, + toast: function(can, content, title) { + wx.showToast({title: title, content: content||""}) + }, + modal: function(can, content, title, cb) { + wx.showModal({title: title||"", content: content||"", success: cb}) + }, + login: function(can, cb) { + can.conf.sessid = can.conf.sessid||can.misc.localStorage(can, ice.MSG_SESSID) + if (can.conf.sessid) { return cb && cb() } + wx.login({success: function(res) { can.misc.request(can, can.request(), "mp/login/action/sess", {code: res.code}, function(msg) { + wx.setStorage({key: ice.MSG_SESSID, data: can.conf.sessid = msg.Result()}), cb && cb() + }) }}) + }, + userinfo: function(can, cb) { + can.user.info.userNick? can.misc.request(can, can.request(), "mp/login/action/user", {}, function(msg) { + cb && cb(can.user.info) + }): can.user.login(can, function() { wx.getSetting({success: function(res) { + res.authSetting['scope.userInfo'] && wx.getUserInfo({success: function(res) { + can.misc.request(can, can.request(), "mp/login/action/user", can.user.info = res.userInfo, function(msg) { + cb && cb(can.user.info) + }) + }}) + }}) }) + }, +}) diff --git a/publish/client/mp/utils/proto.js b/publish/client/mp/utils/proto.js new file mode 100644 index 00000000..8ab93458 --- /dev/null +++ b/publish/client/mp/utils/proto.js @@ -0,0 +1,59 @@ +const {ctx, code, chat} = require("const.js") + +function shy(help, meta, list, cb) { var arg = arguments, i = 0; function next(type) { + if (type == code.OBJECT) { if (typeof arg[i] == code.OBJECT && arg[i].length == undefined) { return arg[i++] } + } else if (type == code.ARRAY) { if (typeof arg[i] == code.OBJECT && arg[i].length != undefined) { return arg[i++] } + } else if (i < arg.length && (!type || type == typeof arg[i])) { return arg[i++] } +} return cb = typeof arg[arg.length-1] == code.FUNCTION? arg[arg.length-1]: function() {}, cb.help = next(code.STRING)||"", cb.meta = next(code.OBJECT)||{}, cb.list = next(code.ARRAY)||[], cb } + +function Volcanos(name, list) { + if (Volcanos._page) { Volcanos._page[name] = list } + return list +} + +Volcanos._init = function() { + var can = {__proto__: Volcanos._page, + request: function(event) { event = event||{}, event = event._event||event + var msg = event._msg||can.misc.Message(event, can); event._msg = msg + function set(key, value) { if (key == "_method") { return msg._method = value } + value == "" || msg.Option(key) || msg.Option(key, value) + } + can.core.List(arguments, function(item, index) { if (!item || index == 0) { return } + can.base.isFunc(item.Option)? can.core.List(item.Option(), function(key) { + key.indexOf("_") == 0 || key.indexOf("user.") == 0 || set(key, item.Option(key)) + }): can.core.Item(can.base.isFunc(item)? item(): item, set) + }); return msg + }, + run: function(event, cmds, cb) { + can.misc.requests(can, can.request(event), can.onaction._name||"action/", {cmds: cmds}, function(msg) { + msg.Dump = function() { can.ui.setData({list: msg.Table()}) }, cb(msg) + }) + }, + }; Volcanos._page.__proto__ = getApp(), delete(Volcanos._page) + var page = {data: {action: can.onaction.list, list: []}, + onLoad: function(options) { can.ui = this, can.db = options + console.log(can.ui.route, options) + can.user.title(options.title||"") + can.user.login(can, function() { + if (can.onaction.refresh) { + can.onaction.refresh({}, can) + } else { + + } + }) + }, + onShow: function() {}, + onReady: function() {}, + onHide: function() {}, + onUnload: function() {}, + onReachBottom: function() {}, + onPullDownRefresh: function() { this.onLoad(can.db) }, + onShareAppMessage: function() {} + } + can.core.ItemCB(can.onaction, function(key, cb) { page[key] = function(event) { + // can.core.CallFunc(cb, {event: event, can: can, msg: can.request(event, event.target.dataset)}) + can.core.CallFunc(cb, [event, can, can.request(event, event.target.dataset)]) + } }), Page(page) +} + +module.exports = {shy, Volcanos}