From d9574b3225015ada33339f7ab37b4b066b829cd0 Mon Sep 17 00:00:00 2001 From: shy Date: Thu, 7 Dec 2023 22:47:42 +0800 Subject: [PATCH] add usr/program/ --- base/web/share.go | 6 +-- conf.go | 1 + misc/wx/access.go | 1 + misc/wx/ide.go | 58 +++++++++++++++++---- misc/wx/pages.go | 2 +- misc/wx/scan.go | 1 + misc/wx/scan.js | 127 ++++++++++++++++++++++++++++++++++++++++++++++ misc/wx/scan.wxml | 45 ++++++++++++++++ misc/wx/wxml.go | 4 +- misc/wx/wxss.go | 4 +- 10 files changed, 233 insertions(+), 16 deletions(-) create mode 100644 misc/wx/scan.js create mode 100644 misc/wx/scan.wxml diff --git a/base/web/share.go b/base/web/share.go index 6ac01c00..fb4d7785 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -82,12 +82,12 @@ func init() { m.EchoQRCode(m.Cmd(SHARE, mdb.CREATE, mdb.TYPE, LOGIN).Option(mdb.LINK)).ProcessInner() }}, ctx.COMMAND: {Hand: func(m *ice.Message, arg ...string) { - if msg := mdb.HashSelect(m.Spawn(), m.Option(SHARE)); !IsNotValidFieldShare(m, msg) { - m.Cmdy(ctx.COMMAND, msg.Append(mdb.NAME)) + if msg := mdb.HashSelects(m.Spawn(), m.Option(SHARE)); !IsNotValidFieldShare(m, msg) { + m.Cmdy(Space(m, msg.Append(SPACE)), ctx.COMMAND, msg.Append(mdb.NAME)) } }}, ctx.RUN: {Hand: func(m *ice.Message, arg ...string) { - if msg := mdb.HashSelect(m.Spawn(), m.Option(SHARE)); !IsNotValidFieldShare(m, msg) { + if msg := mdb.HashSelects(m.Spawn(), m.Option(SHARE)); !IsNotValidFieldShare(m, msg) { aaa.SessAuth(m, kit.Dict(msg.AppendSimple(aaa.USERNICK, aaa.USERNAME, aaa.USERROLE))) m.Cmdy(Space(m, msg.Append(SPACE)), msg.Append(mdb.NAME), arg[1:]) } diff --git a/conf.go b/conf.go index 4e4fbc72..ed700944 100644 --- a/conf.go +++ b/conf.go @@ -131,6 +131,7 @@ const ( // DIR USR_INSTALL = "usr/install/" USR_REQUIRE = "usr/require/" USR_PUBLISH = "usr/publish/" + USR_PROGRAM = "usr/program/" USR_PORTAL = "usr/portal/" USR_LOCAL = "usr/local/" USR_ICONS = "usr/icons/" diff --git a/misc/wx/access.go b/misc/wx/access.go index 41505ee3..62565357 100644 --- a/misc/wx/access.go +++ b/misc/wx/access.go @@ -137,6 +137,7 @@ func Meta() ice.Map { SEX, "性别", TAGS, "标签", REMARK, "备注", "subscribe", "订阅", "subscribe_time", "时间", "nickname", "昵称", "headimgurl", "头像", + "projectname", "项目", ENV, "环境", PAGES, "页面", ))) } diff --git a/misc/wx/ide.go b/misc/wx/ide.go index 8d125769..07a05eb3 100644 --- a/misc/wx/ide.go +++ b/misc/wx/ide.go @@ -4,6 +4,7 @@ import ( "net/url" "path" "runtime" + "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" @@ -15,17 +16,18 @@ import ( "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/core/code" kit "shylinux.com/x/toolkits" ) func _ide_args(m *ice.Message) (args []string) { - args = append(kit.Split(m.Option(ctx.ARGS), "=&"), kit.Simple(kit.Dict(m.OptionSimple(web.SPACE, ctx.INDEX, log.DEBUG)))...) + args = append(kit.SplitQuery(m.Option(ctx.ARGS)), kit.Simple(kit.Dict(m.OptionSimple(web.SPACE, ctx.INDEX, log.DEBUG)))...) kit.If(m.Option(tcp.WIFI), func(p string) { args = append(args, m.Cmd(tcp.WIFI, p).AppendSimple(tcp.SSID, aaa.PASSWORD)...) }) return } func _ide_args_cli(m *ice.Message) []string { return []string{"--project", kit.Path(mdb.Config(m, PROJECT)), "--compile-condition", kit.Format(kit.Dict( - "pathName", m.Option(PAGES), "query", kit.JoinKV("=", "&", kit.Simple(kit.Dict(web.SERVE, url.QueryEscape(web.UserHost(m)), _ide_args(m)))...), + "pathName", m.Option(PAGES), "query", kit.JoinQuery(kit.Simple(kit.Dict(web.SERVE, url.QueryEscape(web.UserHost(m)), _ide_args(m)))...), ))} } func _ide_args_qrcode(m *ice.Message, p string) []string { @@ -33,7 +35,10 @@ func _ide_args_qrcode(m *ice.Message, p string) []string { } const ( - PAGES_ACTION = "pages/action/action" + PAGES_RIVER = "pages/river/river" + PAGES_ACTION = "pages/action/action" + PAGES_INSERT = "pages/insert/insert" + PUBLISH_CLIENT_MP = "publish/client/mp" ) const ( PROJECT = "project" @@ -55,12 +60,43 @@ func init() { ) Index.MergeCommands(ice.Commands{ IDE: {Name: "ide hash auto", Help: "集成开发环境", Meta: Meta(), Actions: ice.MergeActions(ice.Actions{ - ice.APP: {Help: "应用", Hand: func(m *ice.Message, arg ...string) { - IdeCli(m, cli.OPEN, "--project", kit.Path(mdb.Config(m, PROJECT))) + code.AUTOGEN: {Name: "autogen projectname*=demo appid*='wxf4e5104d83476ed6' serve*='https://2021.shylinux.com'", Help: "生成", Hand: func(m *ice.Message, arg ...string) { + const ( + CONF_JS = "conf.js" + APP_JSON = "app.json" + PROJECT_CONFIG_JSON = "project.config.json" + PROJECT_PRIVATE_CONFIG_JSON = "project.private.config.json" + ) + p, mp := ice.USR_PROGRAM, ice.USR_VOLCANOS+PUBLISH_CLIENT_MP + nfs.DirDeepAll(m, mp, "", func(value ice.Maps) { + if !kit.IsIn(value[nfs.PATH], PROJECT_CONFIG_JSON, PROJECT_PRIVATE_CONFIG_JSON) { + m.Cmd(nfs.COPY, p+value[nfs.PATH], path.Join(mp, value[nfs.PATH]), ice.Maps{nfs.DIR_ROOT: ""}) + } + }) + m.Cmd(nfs.SAVE, p+CONF_JS, `module.exports = `+kit.Formats(kit.Dict( + m.OptionSimple(APPID, web.SERVE), nfs.MODULE, ice.Info.Make.Module, nfs.VERSION, ice.Info.Make.Versions(), + ))) + m.Cmd(nfs.DEFS, p+PROJECT_CONFIG_JSON, kit.Formats(kit.Dict(m.OptionSimple(APPID, "projectname")))) + list := []string{} + m.Travel(func(_ *ice.Context, s *ice.Context, key string, cmd *ice.Command) { + if h, ok := cmd.Actions[PAGES]; ok { + prefix := strings.ReplaceAll(s.Prefix(), nfs.PT, "-") + file := strings.TrimPrefix(m.Resource(kit.Select(key+".js", h.Name)), nfs.REQUIRE) + list = append(list, path.Join(PAGES, prefix, kit.TrimExt(path.Base(file), nfs.JS))) + kit.For([]string{WXML, WXSS, nfs.JS}, func(ext string) { + file = kit.ExtChange(file, ext) + m.Cmd(nfs.COPY, path.Join(p, PAGES, prefix, path.Base(file)), file) + }) + } + }) + app := kit.UnMarshal(m.Cmdx(nfs.CAT, p+APP_JSON)) + kit.Value(app, PAGES, kit.AddUniq(kit.Simple(kit.Value(app, PAGES)), list...)) + m.Cmd(nfs.SAVE, p+APP_JSON, kit.Formats(app)) + IdeCli(m.Sleep3s(), cli.OPEN, "--project", kit.Path(mdb.Config(m, PROJECT, p))) }}, aaa.LOGIN: {Help: "登录", Hand: func(m *ice.Message, arg ...string) { p := nfs.TempName(m) - m.GoSleep("1s", func() { web.PushNoticeGrow(m, ice.Render(m, ice.RENDER_IMAGES, web.SHARE_LOCAL+p)) }) + m.GoSleep3s(func() { web.PushNoticeGrow(m, ice.Render(m, ice.RENDER_IMAGES, web.SHARE_LOCAL+p)) }) IdeCli(m, "", _ide_args_cli(m), _ide_args_qrcode(m, p)).ProcessRefresh() }}, web.ADMIN: {Help: "后台", Hand: func(m *ice.Message, arg ...string) { @@ -109,14 +145,15 @@ func init() { }, mdb.ExportHashAction( mdb.FIELD, "time,hash,name,pages,space,index,args,wifi", cli.DARWIN, "/Applications/wechatwebdevtools.app/Contents/MacOS/cli", - PROJECT, "usr/volcanos/publish/client/mp/", )), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 && tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) && kit.Value(kit.UnMarshal(IdeCli(m.Spawn(), ISLOGIN).Append(cli.CMD_OUT)), aaa.LOGIN) != true { m.EchoInfoButton("请登录: ", aaa.LOGIN) return - } - if mdb.HashSelect(m, arg...); tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) { - m.PushAction(AUTO_PREVIEW, PREVIEW, PUSH, mdb.REMOVE).Action(mdb.CREATE, ice.APP, aaa.LOGIN, web.ADMIN, DOC) + } else if !nfs.Exists(m, ice.USR_PROGRAM) { + m.EchoInfoButton("请生成项目: ", code.AUTOGEN) + return + } else if mdb.HashSelect(m, arg...); tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) { + m.PushAction(AUTO_PREVIEW, PREVIEW, PUSH, mdb.REMOVE).Action(aaa.LOGIN, code.AUTOGEN, mdb.CREATE, web.ADMIN, DOC) } else { m.PushAction(PUSH, mdb.REMOVE).Action(mdb.CREATE, web.ADMIN, DOC) } @@ -127,6 +164,7 @@ func init() { } p := mdb.Config(m, CURRENT) m.Table(func(value ice.Maps) { m.Push(mdb.STATUS, kit.Select("", CURRENT, value[mdb.HASH] == p)) }) + m.StatusTimeCount(mdb.ConfigSimple(m, PROJECT)) }}, }) } diff --git a/misc/wx/pages.go b/misc/wx/pages.go index 24af1c7b..bff58dd4 100644 --- a/misc/wx/pages.go +++ b/misc/wx/pages.go @@ -11,7 +11,7 @@ import ( func init() { web.Index.MergeCommands(ice.Commands{ - "/pages/": {Actions: aaa.WhiteAction(ctx.ACTION), Hand: func(m *ice.Message, arg ...string) { + web.PP(PAGES): {Actions: aaa.WhiteAction(ctx.ACTION), Hand: func(m *ice.Message, arg ...string) { if len(arg[0]) == 0 || arg[0] == "" || arg[0] == chat.RIVER { web.RenderMain(m) } else { diff --git a/misc/wx/scan.go b/misc/wx/scan.go index 50de7f5d..84526009 100644 --- a/misc/wx/scan.go +++ b/misc/wx/scan.go @@ -71,6 +71,7 @@ func init() { m.Echo(msg.Result()) } }}, + PAGES: {Name: "scan.js"}, }, mdb.ExportHashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,name,text,icons,space,index,args,type,image,link")), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { m.Cmdy(ACCESS).PushAction("").Option(ice.MSG_ACTION, "") diff --git a/misc/wx/scan.js b/misc/wx/scan.js new file mode 100644 index 00000000..fbe773e4 --- /dev/null +++ b/misc/wx/scan.js @@ -0,0 +1,127 @@ +const {ice, ctx, mdb, web, code, chat, http, html} = require("../../utils/const.js") +const {shy, Volcanos} = require("../../utils/proto.js") +Volcanos._page = {} +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { can.ui.data.list = [] + msg.Table(function(field, order) { can.ui.data.list.push(field) + field.feature = can.base.Obj(field.meta, {}) + field.inputs = can.base.Obj(field.list, []) + field.name = can.core.Split(field.name)[0] + if (!field.inputs || field.inputs.length === 0) { + return can.core.Timer(30, function() { + can.onaction._refresh({}, can, order) + }) + } + can.core.List(field.inputs, function(input) { + input.action = input.action || input.value + input.value == ice.AUTO && (input.value = "") + if (input.value && input.value.indexOf("@") == 0) { + input.action = input.value.slice(1), input.value = "" + } + if (input.type == html.SELECT) { + input.values = input.values || can.core.Split(input.value) + } + if (can.base.isIn(input.type, html.TEXT, html.TEXTAREA)) { + input.placeholder = can.user.trans(can, input.placeholder||input.name, field, html.INPUT) + } + if (input.type == html.BUTTON) { + input.value = can.user.trans(can, input.value||input.name, field) + } else { + if (can.db.cmd||can.db.index) { input.value = input.value||can.db[input.name] } + } + input.type == html.BUTTON && input.action == ice.AUTO && can.core.Timer(30, function() { + can.onaction._refresh({}, can, order) + }) + }) + }), can.page.setData(can), can.user.toast(can, "加载成功") + }, +}) +Volcanos(chat.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.ui.data.list, function(item) { delete(item.msg) }), can.page.setData(can) }, + _refresh: function(event, can, order) { can.page.setData(can) + can.onaction.onAction({}, can, ice.LIST, {order: order, name: ice.LIST}) + }, + refresh: function(event, can) { can.onaction._apis = "", can.onaction._cmds = [] + if (can.db.share) { can.onaction._apis = "/share/"+can.db.share + can.run(event, [ctx.ACTION, ctx.COMMAND], function(msg) { + can.onaction._cmds = [ctx.ACTION, ctx.RUN], can.onimport._init(can, msg) + }) + } else if (can.db.river && can.db.storm) { + can.onaction._cmds = [can.db.river, can.db.storm] + can.run(event, [], function(msg) { can.onimport._init(can, msg) }) + } else { + can.run(event, [ctx.ACTION, ctx.COMMAND, can.db.cmd||can.db.index||"cli.qrcode"], function(msg) { + can.onaction._cmds = [ctx.ACTION, ctx.RUN], can.onimport._init(can, msg) + }) + } + }, + onaction: function(event, can, button, data) { var name = data.name; + (can.onaction[name]||function(event) { can.run(event, [ctx.ACTION, name]) })(event, can) + }, + onInputs: function(event, can, button, data) { var order = data.order, index = data.index + var input = can.ui.data.list[order||0].inputs[index||0] + input.value = event.detail.value + }, + onChange: function(event, can, button, data) { var order = data.order, index = data.index + var input = can.ui.data.list[order||0].inputs[index||0] + input.value = input.values[parseInt(event.detail.value)] + can.onaction._refresh(event, can, order) + }, + onAction: function(event, can, button, data) { var order = data.order, name = data.name + var field = can.ui.data.list[order||0], msg = can.request(event) + if (field.feature[name]) { if (can.base.isIn(name, mdb.CREATE, mdb.INSERT)) { msg._method = http.PUT } + return can.data.insert = {field: field, name: name, list: field.feature[name], cb: function(res) { + can.run(event, can.base.Simple([field.id||field.index, ctx.ACTION, name], res), function(msg) { + can.onaction._refresh(event, can, order) + }) + }}, can.user.jumps(chat.PAGES_INSERT) + } field._history = field._history||[] + switch (name) { + case ice.BACK: field._history.pop(); var ls = field._history.pop()||[], i = 0 + can.core.List(field.inputs, function(input) { if (input.type != html.BUTTON) { input.value = ls[i++]||"" } }) + can.onaction._refresh(event, can, order); break + case ctx.RUN: break + case ice.LIST: + case web.REFRESH: msg._method = http.GET; break + default: msg.Option(ctx.ACTION, name) + } + var cmd = can.core.List(field.inputs, function(input) { if (input.type != html.BUTTON) { return input.value } }) + for (var i = cmd.length-1; i > 0; i--) { if (cmd[i] === "") { cmd.pop() } else { break } } + 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) + can.run(event, [field.id||field.index].concat(cmd), function(msg) { + msg._head = can.core.List(msg.append, function(item) { return can.user.trans(can, item, field, html.INPUT) }) + can.core.Item(msg._view, function(key, value) { can.core.List(value, function(value) { can.core.List(value, function(input, i) { + if (input.type == html.BUTTON) { input.value = can.user.trans(can, input.value||input.name, field) } + if (input._type == html.TEXT) { input._text = can.user.trans(can, input._text, field, html.VALUE) } + }) }) }) + msg._status = can.core.List(can.base.Obj(msg.Option(ice.MSG_STATUS)), function(item) { return item }) + msg._action = can.core.List(can.base.Obj(msg.Option(ice.MSG_ACTION)), function(item) { + if (typeof item == code.STRING) { return {type: html.BUTTON, name: item, value: can.user.trans(can, item)} } + return item.value = can.user.trans(can, item.value||item.name), item + }), field.msg = msg, can.page.setData(can) + }) + }, + onDetail: function(event, can, button, data) { var order = data.order, name = data.name, value = data.value, input = data.input + var field = can.ui.data.list[order||0] + if (input && input.type == html.BUTTON) { var msg = can.request(event, field.msg.Table()[data.index]) + if (can.base.isIn(name, mdb.REMOVE, mdb.DELETE)) { msg._method = http.DELETE } + var _input = {}; can.core.List(field.inputs, function(input) { if (input.type != html.BUTTON) { _input[input.name] = input.value } }), can.request(event, _input) + if (field.feature[input.name]) { + can.onAction(event, can, input.name, {order: order, name: input.name}) + } else { + can.run(event, [field.id||field.index, ctx.ACTION, input.name], function(msg) { + can.onaction._refresh(event, can, order) + }) + } return + } + can.core.List(field.inputs, function(input) { + if (input.name == name) { input.value = value, can.onaction._refresh(event, can, order) } + }) + }, +}) +Volcanos._init() + diff --git a/misc/wx/scan.wxml b/misc/wx/scan.wxml new file mode 100644 index 00000000..408f7210 --- /dev/null +++ b/misc/wx/scan.wxml @@ -0,0 +1,45 @@ + + + + + + + {{field.name}}({{field.help}}) + + + + + + + + {{item.value||item.values[item.index||0]}} + + + + + + + + + + + + + + + + + + + {{item.name}}: {{item.value}} + + + + + + diff --git a/misc/wx/wxml.go b/misc/wx/wxml.go index 6fc9bd5e..9d0a2e63 100644 --- a/misc/wx/wxml.go +++ b/misc/wx/wxml.go @@ -6,9 +6,11 @@ import ( kit "shylinux.com/x/toolkits" ) +const WXML = "wxml" + func init() { Index.MergeCommands(ice.Commands{ - "wxml": {Actions: code.PlugAction(code.PLUG, kit.Dict( + WXML: {Actions: code.PlugAction(code.PLUG, kit.Dict( code.INCLUDE, code.HTML, code.KEYWORD, kit.Dict( "page", code.KEYWORD, diff --git a/misc/wx/wxss.go b/misc/wx/wxss.go index 9068c75e..acc918a0 100644 --- a/misc/wx/wxss.go +++ b/misc/wx/wxss.go @@ -6,9 +6,11 @@ import ( kit "shylinux.com/x/toolkits" ) +const WXSS = "wxss" + func init() { Index.MergeCommands(ice.Commands{ - "wxss": {Actions: code.PlugAction(code.PLUG, kit.Dict( + WXSS: {Actions: code.PlugAction(code.PLUG, kit.Dict( code.INCLUDE, code.CSS, code.KEYWORD, kit.Dict( "page", code.KEYWORD,