Commit 0c966f57 authored by wanli's avatar wanli

新增一个小工具

parent b990dac6
...@@ -6,10 +6,9 @@ from fullstack.event import PySignal ...@@ -6,10 +6,9 @@ from fullstack.event import PySignal
class SignalManager(object): class SignalManager(object):
# 接口模块 # 接口模块
actionUpdatePassword = PySignal() actionUpdatePassword = PySignal()
# 上传文件
actionBackupDatabase = PySignal() actionBackupDatabase = PySignal()
actionApplicationBuild = PySignal() actionApplicationBuild = PySignal()
actionGetConvertString = PySignal()
# 登录模块 # 登录模块
actionLogin = PySignal() actionLogin = PySignal()
......
...@@ -21,4 +21,4 @@ backup_dir = backup ...@@ -21,4 +21,4 @@ backup_dir = backup
evueapps_dir = evueapps evueapps_dir = evueapps
launcher_dir = launcher launcher_dir = launcher
host = 127.0.0.1 host = 127.0.0.1
port = 5001 port = 5000
\ No newline at end of file \ No newline at end of file
...@@ -21,8 +21,9 @@ logger = logging.getLogger(__name__) ...@@ -21,8 +21,9 @@ logger = logging.getLogger(__name__)
def initConnect(): def initConnect():
# 系统模块 # 系统模块
signalManager.actionUpdatePassword.connect(apiManager.update_user_password)
signalManager.actionApplicationBuild.connect(appsManager.build) signalManager.actionApplicationBuild.connect(appsManager.build)
signalManager.actionGetConvertString.connect(apiManager.get_escape_text)
signalManager.actionUpdatePassword.connect(apiManager.update_user_password)
# 登录模块 # 登录模块
signalManager.actionLogin.connect(loginManager.login) signalManager.actionLogin.connect(loginManager.login)
......
...@@ -9,10 +9,10 @@ import uuid ...@@ -9,10 +9,10 @@ import uuid
from datetime import datetime from datetime import datetime
from pony.orm import * from pony.orm import *
from flask import request
from model import fullStackDB from model import fullStackDB
from model.user import User from model.user import User
from utils import md5_salt from utils import md5_salt
from utils.ccode import convert_string
logger = logging.getLogger("ApiManager") logger = logging.getLogger("ApiManager")
...@@ -20,9 +20,9 @@ class ApiManager(object): ...@@ -20,9 +20,9 @@ class ApiManager(object):
def __init__(self): def __init__(self):
super(ApiManager, self).__init__() super(ApiManager, self).__init__()
def update_user_password(self, data): def update_user_password(self, user, data):
with db_session: with db_session:
editor = User.get(id=request.current_user.get("id")) editor = User.get(id=user)
if not editor: if not editor:
return False, "current user is not exists" return False, "current user is not exists"
...@@ -46,4 +46,7 @@ class ApiManager(object): ...@@ -46,4 +46,7 @@ class ApiManager(object):
return True, "success" return True, "success"
def get_escape_text(self, data):
return convert_string(data['string'])
apiManager = ApiManager() apiManager = ApiManager()
...@@ -55,6 +55,12 @@ class GetRoleUser(BaseSchema): ...@@ -55,6 +55,12 @@ class GetRoleUser(BaseSchema):
class Meta: class Meta:
unknown = EXCLUDE unknown = EXCLUDE
class ConvertString(BaseSchema):
string = fields.String(required=True)
class Meta:
unknown = EXCLUDE
class ExportProject(BaseSchema): class ExportProject(BaseSchema):
project = fields.List(fields.String, required=True) project = fields.List(fields.String, required=True)
production = fields.List(fields.String, required=True) production = fields.List(fields.String, required=True)
......
# -*- coding: utf-8 -*-
import sys
header = \
u'''
/****************************************************************************
**
** Copyright (C) 2021 @scriptiot
**
** EVM是一款通用化设计的虚拟机引擎,拥有语法解析前端接口、编译器、虚拟机和虚拟机扩展接口框架。
** 支持js、python、qml、lua等多种脚本语言,纯C开发,零依赖,支持主流 ROM > 50KB, RAM > 2KB的MCU;
** 自带垃圾回收(GC)先进的内存管理,采用最复杂的压缩算法,无内存碎片(大部分解释器都存在内存碎片)
** Version : 3.0
** Email : scriptiot@aliyun.com
** Website : https://github.com/scriptiot
** Licence: MIT Licence
****************************************************************************/
'''
def cstr_encode(text, splitLines=True, escapePercent=False):
output = "\""
count = len(text)
for i in range(count):
if text[i] == '\f':
output += "\\f"
elif text[i] == '\n':
if splitLines:
output += "\\n\"\n\""
else:
output += "\\n";
elif text[i] == '\r':
output += "\\r"
elif text[i] == '\t':
output += "\\t"
elif text[i] == '\"':
output += "\\\""
elif text[i] == '\\':
output += "\\\\"
elif text[i] == '%':
if escapePercent:
output += "%%"
else:
output += "%"
else:
output += text[i]
output += "\""
return output
def convert(fpath):
with open(fpath, "r") as f:
content = f.read()
ret = cstr_encode(content)
ccode = "%s\nconst char * appjs_content=\\\n%s;" % (header, ret)
with open("appjs.c", "w", encoding="utf-8") as f:
f.write(ccode)
return ccode
def convert_string(string):
return "%s\nconst char * appjs_content=\\\n%s;" % (header, cstr_encode(string))
if __name__ == '__main__':
ret = convert(sys.argv[1])
print(ret)
...@@ -14,7 +14,7 @@ from app import config, signalManager ...@@ -14,7 +14,7 @@ from app import config, signalManager
from fullstack.login import Auth from fullstack.login import Auth
from fullstack.response import ResponseCode, response_result from fullstack.response import ResponseCode, response_result
from fullstack.validation import validate_schema from fullstack.validation import validate_schema
from schema.api import UpdatePasswordSchema, ApplicationBuildSchema from schema.api import UpdatePasswordSchema, ApplicationBuildSchema, ConvertString
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -38,7 +38,7 @@ def actionShowReport(): ...@@ -38,7 +38,7 @@ def actionShowReport():
@validate_schema(UpdatePasswordSchema) @validate_schema(UpdatePasswordSchema)
@Auth.auth_required @Auth.auth_required
def update_password(): def update_password():
result, message = signalManager.actionUpdatePassword.emit(request.schema_data) result, message = signalManager.actionUpdatePassword.emit(request.current_user.get("id"), request.schema_data)
if result: if result:
return response_result(ResponseCode.OK, data=result, msg=message) return response_result(ResponseCode.OK, data=result, msg=message)
else: else:
...@@ -100,6 +100,12 @@ def update_db(): ...@@ -100,6 +100,12 @@ def update_db():
return response_result(ResponseCode.OK, data=result) return response_result(ResponseCode.OK, data=result)
@api.route("/system/convertString", methods=['POST'])
@validate_schema(ConvertString)
def convert_string():
result = signalManager.actionGetConvertString.emit(request.schema_data)
return response_result(ResponseCode.OK, data=result)
@api.route("/application/build", methods=["post"]) @api.route("/application/build", methods=["post"])
@validate_schema(ApplicationBuildSchema) @validate_schema(ApplicationBuildSchema)
def application_build(): def application_build():
......
...@@ -231,6 +231,14 @@ export function updateAppLogs(params) { ...@@ -231,6 +231,14 @@ export function updateAppLogs(params) {
}); });
} }
export function getConvertString(params) {
return request({
url: "/api/v1/evm_store/system/convertString",
method: "post",
data: params,
});
}
export function getTopicList(params) { export function getTopicList(params) {
return request({ return request({
url: "/uowap/index", url: "/uowap/index",
......
...@@ -175,6 +175,17 @@ export const constantRoutes = [ ...@@ -175,6 +175,17 @@ export const constantRoutes = [
meta: { title: '应用管理', icon: 'home' } meta: { title: '应用管理', icon: 'home' }
}] }]
}, },
{
path: '/',
redirect: '/tool',
component: Layout,
children: [{
path: 'tool',
name: 'AppTool',
component: () => import('@/views/system/tool'),
meta: { title: '工具', icon: 'home' }
}]
},
{ {
path: '/', path: '/',
redirect: '/build', redirect: '/build',
......
...@@ -63,5 +63,12 @@ export default { ...@@ -63,5 +63,12 @@ export default {
icon: "gongzuotai", icon: "gongzuotai",
path: "docs", path: "docs",
}, },
{
vue: "system/tool.vue",
title: "工具",
name: "AppTool",
icon: "gongzuotai",
path: "tool",
},
], ],
}; };
<template>
<div class="app-container">
<el-form :inline="true" :model="form" size="mini">
<el-form-item label="部门名称">
<el-select v-model="form.uuid" filterable placeholder="请输入部门名称">
<el-option v-for="(item, index) in depots" :key="index" :label="item.name" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item><el-button type="primary" @click="onSubmit">查询</el-button></el-form-item>
<el-form-item><el-button @click="onReset">重置</el-button></el-form-item>
<el-form-item><el-button type="warning" @click="onAdd">添加</el-button></el-form-item>
</el-form>
<el-table v-loading="isLoading" element-loading-text="Loading" :data="list" size="mini" border stripe fit highlight-current-row>
<el-table-column prop="name" label="部名称" align="center" min-width="100"></el-table-column>
<el-table-column prop="create_at" label="创建时间" width="150"></el-table-column>
<el-table-column prop="create_by.username" label="创建者" width="150"></el-table-column>
<el-table-column prop="update_at" label="更新时间" width="150" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="update_by.username" label="更新者" width="150"></el-table-column>
<el-table-column label="操作" align="center" width="180" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="success" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="form.pagenum" background small :page-size="form.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
</div>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%">
<el-form :model="post" status-icon :rules="rules" :inline="true" ref="post" size="mini" label-width="80px">
<el-form-item label="部门名称" prop="name">
<el-input type="text" v-model="post.name" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" plain @click="submitForm('post')">提交</el-button>
<el-button type="success" size="mini" plain @click="onReset('post')">重置</el-button>
<el-button size="mini" @click="dialogVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getDepotList, deleteDepot, addDepot, updateDepot } from '@/api/index'
import { mapTrim, compareObjectDiff } from '@/utils/index'
import { formatUTCDateTime } from '@/utils/utils'
export default {
data() {
return {
total: 0,
list: [],
depots: [],
form: {
uuid: null,
name: null,
pagesize: 15,
pagenum: 1
},
isLoading: false,
dialogTitle: "",
dialogVisible: false,
currentValue: null,
currentIndex: null,
post: {
name: null,
},
rules: {
permission: [{ type: 'string', required: true, message: '权限名称不能为空', trigger: 'blur' }],
name: [
{ type: 'string', required: true, message: '用户名不能为空', trigger: 'blur' },
{ min: 1, max: 20, message: '字符串长度在 1 到 20 之间', trigger: 'blur' }
]
}
}
},
methods: {
fetchData(params) {
this.isLoading = true
getDepotList(Object.assign({
pagenum: this.form.pagenum,
pagesize: this.form.pagesize,
}, params)).then(res => {
if (res.code == 200) {
this.total = res.count
this.list = res.data.map(item => {
item.create_at = formatUTCDateTime(item.create_at)
item.update_at = formatUTCDateTime(item.update_at)
return item
})
}
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
}).finally(() => {
this.isLoading = false
})
},
fetchSelectData() {
getDepotList({ "scope_type": "list" }).then(res => {
if (res.code == 200) this.roles = res.data
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
})
},
handleSizeChange(e) {
this.form.pagesize = e
this.fetchData(mapTrim(this.form))
},
handleCurrentChange(e) {
this.form.pagenum = e
this.fetchData(mapTrim(this.form))
},
handleEdit(index, row) {
this.post.name = row.name
this.currentValue = row
this.currentIndex = index
this.dialogTitle = "编辑"
this.dialogVisible = true
},
handleDelete(index, row) {
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') deleteDepot(row.uuid).then(res => {
console.log(res)
// this.total -= 1
// this.$delete(this.list, index)
this.fetchData(mapTrim(this.form))
this.$message({ type: 'success', message: `成功删除第${ index }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
let result = true
if (valid) {
if (this.dialogTitle === '添加') addDepot(this.post).then(res => {
console.log(res)
// this.$message({ type: 'success', message: '添加成功' })
this.fetchData(mapTrim(this.form))
}).catch(err => {
this.$message.error(err.message)
})
else if (this.dialogTitle === '编辑') updateDepot(this.currentValue.uuid, compareObjectDiff(this.post, this.currentValue)).then(res => {
console.log(res)
// this.$set(this.list, this.currentIndex, Object.assign(this.currentValue, tmp))
// this.$message({ type: 'success', message: '更新成功' })
this.fetchData(mapTrim(this.form))
}).catch(err => {
this.$message.error(err.message)
})
} else {
result = false
}
this.dialogVisible = false
return result
})
},
onAdd() {
this.dialogTitle = "添加"
this.dialogVisible = true
},
onSubmit() {
this.form.pagenum = 1
this.form.pagesize = 15
this.fetchData(mapTrim(this.form))
},
onReset(formName) {
this.form.name = null
this.form.pagesize = 15,
this.form.pagenum = 1
this.$refs[formName].resetFields()
this.fetchData()
}
},
mounted() {
},
created() {
this.fetchData()
this.fetchSelectData()
const user = JSON.parse(sessionStorage.getItem("user"))
if (!user || user.role.permission.depots == "无权限") this.$router.push("/403")
}
}
</script>
<style lang="scss" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
<template>
<div class="app-container">
<el-alert
title="将文本转换为类似C的文字,转义换行符,制表符,双引号和反斜杠。"
type="success"
></el-alert>
<el-row :gutter="20">
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
<h5>请输入要转换的文本:</h5>
<el-input
type="textarea"
:autosize="{ minRows: 30, maxRows: 50 }"
resize="none"
placeholder="请输入内容"
v-model="inputString"
></el-input>
</el-col>
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
<h5>转换结果:</h5>
<el-input
type="textarea"
:autosize="{ minRows: 30, maxRows: 50 }"
resize="none"
placeholder="转换结果"
v-model="outputString"
></el-input>
</el-col>
</el-row>
<div style="margin: 10px 0px">
<el-form>
<el-form-item>
<el-button type="primary" @click="getConvertString">转换</el-button>
<el-button type="success" @click="downloadFile">下载</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import { getConvertString } from "@/api/app-store";
export default {
name: "AppTool",
data() {
return {
inputString: null,
outputString: null,
filename: "app.js",
};
},
methods: {
createFile(content, filename) {
const a = document.createElement("a");
const blob = new Blob([content]);
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
},
downloadFile() {
if (!this.inputString) return this.$message.error("输入内容不能为空");
this.filename = "app.js.c";
this.$prompt("请输入文件名", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputValue: this.filename,
inputErrorMessage: "文件名格式不正确",
})
.then(({ value }) => {
if (value) this.filename = `${value}.c`;
else this.filename = "app.js.c";
this.createFile(this.outputString, this.filename);
})
.catch(() => {
this.$message({
type: "info",
message: "取消输入",
});
});
},
getConvertString() {
getConvertString({ string: this.inputString })
.then((res) => {
this.outputString = res.data;
this.$message.success(res.message);
})
.catch((err) => {
this.$message.error(err.message);
});
},
},
mounted() {},
created() {},
};
</script>
<style lang="scss" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
\ No newline at end of file
class Klass:
def __init__(self):
pass
klass = Klass()
def dict2obj(dictionary):
klass.__dict__.update(dictionary)
return klass
if __name__ == "__main__":
d = { 'a': 1, 'b': 2 }
print(dict2obj(d))
\ No newline at end of file
...@@ -7,13 +7,13 @@ class {{ contronller['className'] }}(object): ...@@ -7,13 +7,13 @@ class {{ contronller['className'] }}(object):
def get(self, params): def get(self, params):
# handle business # handle business
result = {{ model['className'] }}.query.filter(*filters).order_by({{ model['className'] }}.areaId).paginate(args.currentPage, args.pageSize, error_out=False) result = {{ model['className'] }}.query.filter(*filters).order_by({{ model['className'] }}.areaId).paginate(params['pageNum'], params['pageSize'], error_out=False)
return result return result
def post(self, params): def post(self, params):
# handle business # handle business
result = {{ model['className'] }}.query.filter({{ model['className'] }}.areaName == args.areaName).first() result = {{ model['className'] }}.query.filter({{ model['className'] }}.areaName == params['areaName']).first()
if result and result.del_flag: if result and result.del_flag:
result.del_flag = False result.del_flag = False
result.update_by = jwt['id'] result.update_by = jwt['id']
...@@ -23,17 +23,17 @@ class {{ contronller['className'] }}(object): ...@@ -23,17 +23,17 @@ class {{ contronller['className'] }}(object):
elif result and result.del_flag == False: elif result and result.del_flag == False:
return pretty_result(code.EXISTS_ERROR) return pretty_result(code.EXISTS_ERROR)
result = {{ model['className'] }}(areaCode=args.areaCode, areaName=args.areaName, level=args.level, cityCode=args.cityCode, center=args.center, parentId=args.parentId, hasChildren=args.hasChildren, create_by=jwt['id'], create_date=datetime.now(), update_by=jwt['id'], update_date=datetime.now()) result = {{ model['className'] }}(**params)
db.session.add(result) db.session.add(result)
db.session.commit() db.session.commit()
return pretty_result(code.OK) return pretty_result(code.OK)
def put(self, params): def put(self, id, params):
# handle business # handle business
result = {{ model['className'] }}.query.get(id) result = {{ model['className'] }}.query.get(id)
if not result: return pretty_result(code.NO_DATA) if not result: return pretty_result(code.NO_DATA)
if args: if params:
for key, value in args.items(): for key, value in params.items():
if value != None: setattr(result, key, value) if value != None: setattr(result, key, value)
result.update_by = jwt['id'] result.update_by = jwt['id']
result.update_date = datetime.now() result.update_date = datetime.now()
...@@ -41,7 +41,7 @@ class {{ contronller['className'] }}(object): ...@@ -41,7 +41,7 @@ class {{ contronller['className'] }}(object):
else: else:
return pretty_result(code.PARAM_NULL) return pretty_result(code.PARAM_NULL)
def delete(self, params): def delete(self, id):
# handle business # handle business
result = {{ model['className'] }}.query.get(id) result = {{ model['className'] }}.query.get(id)
if not result: return pretty_result(code.NO_DATA_FOUND) if not result: return pretty_result(code.NO_DATA_FOUND)
...@@ -49,5 +49,5 @@ class {{ contronller['className'] }}(object): ...@@ -49,5 +49,5 @@ class {{ contronller['className'] }}(object):
result.update_by = jwt['id'] result.update_by = jwt['id']
result.update_date = datetime.now() result.update_date = datetime.now()
result.del_flag = True result.del_flag = True
# db.session.delete(pump) db.session.delete(result)
db.session.commit() db.session.commit()
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment