Commit b8947a5e authored by wanli's avatar wanli

feat(应用管理模块): 增加上架、下架按钮,源码编辑

应用管理增加上架下架功能,同时提供在线源码编辑
parent a61e7b5f
'''
Author: your name
Date: 2021-06-30 18:03:41
LastEditTime: 2021-07-17 21:24:19
LastEditTime: 2021-07-19 14:28:10
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\application\signal_manager.py
......@@ -63,6 +63,8 @@ class SignalManager(object):
actionPostFileCreate = PySignal()
actionPostFileCreateDir = PySignal()
actionPostFilePaste = PySignal()
# api
actionPostAppReview = PySignal()
def __init__(self):
super().__init__()
......
'''
Author: your name
Date: 2021-06-30 17:43:46
LastEditTime: 2021-07-17 21:25:21
LastEditTime: 2021-07-19 14:29:10
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\controllers\__init__.py
......@@ -11,6 +11,7 @@ FilePath: \evm-store\tools\build_out\controllers\__init__.py
from application.signal_manager import signalManager
from .area import areaManager
from .api import appReview
from .app import appManager
from .package import packageManager
from .user import userManager
......@@ -76,3 +77,5 @@ def initConnect():
signalManager.actionPostFileCreate.connect(fileManager.create_file)
signalManager.actionPostFileCreateDir.connect(fileManager.create_dir)
signalManager.actionPostFilePaste.connect(fileManager.paste)
# api
signalManager.actionPostAppReview.connect(appReview.post)
'''
Author: your name
Date: 2021-07-12 11:14:48
LastEditTime: 2021-07-15 17:43:48
LastEditTime: 2021-07-19 15:19:26
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\controllers\appi.py
......@@ -98,4 +98,23 @@ class BuildAppResource(object):
buildAppResource = BuildAppResource()
class AppReview(object):
def __init__(self):
super().__init__()
def post(self, app, review, jwt={}):
user = UserModel.query.filter(UserModel.uuid==jwt.get("uuid")).one_or_none()
if not user:
return None, ResponseCode.USER_NOT_EXISTS
app = AppModel.query.filter(AppModel.uuid==app).one_or_none()
if not app:
return None, ResponseCode.APPLICATION_NOT_EXISTS
app.app_review = review
app.update_at = datetime.now()
app.update_by = user.id
db.session.commit()
return True, ResponseCode.HTTP_SUCCESS
appReview = AppReview()
\ No newline at end of file
......@@ -122,7 +122,7 @@ class AppResource(object):
else:
filters.append(AppModel.create_by==user.id)
temp.update({ "create_by": user.id, "is_delete": False })
logger.info(params)
if "scope" in params and params.get("scope") == "list":
result = AppModel.query.filter_by(**temp).order_by(AppModel.create_at.desc())
temp = []
......@@ -148,7 +148,6 @@ class AppResource(object):
if result.total and len(result.items):
return result, ResponseCode.HTTP_SUCCESS
return None, ResponseCode.HTTP_NOT_FOUND
def post(self, params, jwt={}):
......
{"directories": [{"basename": "\u6d4b\u8bd59-1.0.9-6-20210717135613", "dirname": ".", "path": "\u6d4b\u8bd59-1.0.9-6-20210717135613", "timestamp": 1626501373, "type": "dir"}], "files": []}
\ No newline at end of file
{"directories": [{"basename": "src", "dirname": "\u6d4b\u8bd58-1.0.8-6-20210717140706", "path": "\u6d4b\u8bd58-1.0.8-6-20210717140706/src", "timestamp": 1626502026, "type": "dir"}], "files": [{"basename": "epk.json", "dirname": "\u6d4b\u8bd58-1.0.8-6-20210717140706", "extension": "json", "filename": "epk", "path": "\u6d4b\u8bd58-1.0.8-6-20210717140706/epk.json", "size": 437, "timestamp": 1626502026, "type": "file"}, {"basename": "\u6d4b\u8bd58.epk", "dirname": "\u6d4b\u8bd58-1.0.8-6-20210717140706", "extension": "epk", "filename": "\u6d4b\u8bd58", "path": "\u6d4b\u8bd58-1.0.8-6-20210717140706/\u6d4b\u8bd58.epk", "size": 2848, "timestamp": 1626502026, "type": "file"}]}
\ No newline at end of file
'''
Author: your name
Date: 2021-07-15 03:22:19
LastEditTime: 2021-07-17 21:49:04
LastEditTime: 2021-07-19 14:39:33
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\views\__init__.py
......@@ -12,6 +12,7 @@ FilePath: \evm-store\tools\build_out\views\__init__.py
from flask import Blueprint
from flask_restful import Api
from . import area
from . import openapi
from . import app
from . import package
from . import user
......@@ -36,6 +37,8 @@ api.add_resource(area.AreaResourceList, '/area')
api.add_resource(app.AppResource, '/app/<string:uuid>')
api.add_resource(app.AppResourceList, '/app')
api.add_resource(openapi.AppReviewResource, '/api/app-review')
api.add_resource(package.PackageResource, '/package/<string:uuid>')
api.add_resource(package.PackageResourceList, '/package')
......
......@@ -49,6 +49,8 @@ class AppResourceList(Resource):
return response_result(ResponseCode.HTTP_SUCCESS, data=json_dumps)
else:
json_dumps = getListAppsSchema.dump(result.items)
for item in json_dumps:
item['file_dir'] = os.path.dirname(item['download_url'])
return response_result(ResponseCode.HTTP_SUCCESS, data=json_dumps, total=result.total, pageSize=args.pageSize)
return response_result(message)
except Exception as e:
......
'''
Author: your name
Date: 2021-07-19 14:29:33
LastEditTime: 2021-07-19 15:31:33
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\views\api.py
'''
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import os
from flask import current_app, jsonify, request
from flask_restful import Resource
from flask_restful.reqparse import RequestParser
from flask_jwt_extended import ( jwt_required, get_jwt_identity )
from marshmallow.exceptions import ValidationError
from application.signal_manager import signalManager
from models.login import postLoginSchema, getListLoginSchema, getListLoginsSchema, getLoginSchema
from webcreator.log import logger
from webcreator.response import ResponseCode, response_result
class AppReviewResource(Resource):
def __init__(self):
# 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
self.parser = RequestParser()
def get(self):
# 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
# self.parser.add_argument("page", type=int, location="args", default=1)
# self.parser.add_argument("pageSize", type=int, location="args", default=15)
# args = self.parser.parse_args()
try:
json_payload = request.json
logger.warn(json_payload)
data = getListLoginSchema.load(json_payload)
result, message = signalManager.actionGetListLogin.emit(data)
json_dumps = getListLoginSchema.dump(result)
if result:
json_dumps = getListLoginsSchema.dump(result.items)
return response_result(message, data=json_dumps, count=result.total)
return response_result(message)
except ValidationError as e:
return response_result(ResponseCode.HTTP_INVAILD_REQUEST, data=e.messages)
except Exception as e:
data = None
if hasattr(e, 'args'):
data = e.args
current_app.logger.error(e)
return response_result(ResponseCode.HTTP_SERVER_ERROR, data=data)
@jwt_required(locations=["headers"])
def post(self):
self.parser.add_argument("review", type=int, location="json", default=0, required=True)
self.parser.add_argument("app", type=str, location="json", required=False)
args = self.parser.parse_args()
try:
jwt = get_jwt_identity()
result, message = signalManager.actionPostAppReview.emit(args.app, args.review, jwt)
if result:
return response_result(message, data=result)
return response_result(message)
except ValidationError as e:
return response_result(ResponseCode.HTTP_INVAILD_REQUEST, data=e.messages)
except Exception as e:
data = None
if hasattr(e, 'args'):
data = e.args
current_app.logger.error(e)
return response_result(ResponseCode.HTTP_SERVER_ERROR, data=data)
class BuildAppResource(Resource):
def __init__(self):
pass
# 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
# self.parser = RequestParser()
@jwt_required(locations=["headers"])
def get(self, uuid):
# 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
# self.parser.add_argument("page", type=int, location="args", default=1)
# self.parser.add_argument("pageSize", type=int, location="args", default=15)
# args = self.parser.parse_args()
try:
json_payload = request.json
print("========>", uuid, json_payload)
data = getLoginSchema.load(json_payload)
result, message = signalManager.actionGetLogin.emit(uuid, data)
if result:
json_dumps = getLoginSchema.dump(result)
return response_result(message, data=json_dumps)
return response_result(message)
except Exception as e:
current_app.logger.error(e)
return response_result(ResponseCode.HTTP_SERVER_ERROR)
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-16 20:19:01
* @LastEditTime: 2021-07-19 14:58:18
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\api\openapi.js
......@@ -61,3 +61,12 @@ export function getPackageList(params) {
params
})
}
export function updateReview(params) {
return request({
url: "/api/v1/api/app-review",
method: "post",
data: params
})
}
......@@ -3,15 +3,28 @@
<a-card :bordered="false">
<div class="tableList">
<div class="tableListForm">
<a-form v-show="!expandForm" layout="inline" :model="query" :form="form">
<a-form
v-show="!expandForm"
layout="inline"
:model="query"
:form="form"
>
<a-row :gutter="{ md: 8, lg: 24, xl: 48 }">
<a-col :md="8" :sm="24">
<a-form-item label="应用名称" prop="app_name" v-decorator="['app_name']">
<a-form-item
label="应用名称"
prop="app_name"
v-decorator="['app_name']"
>
<a-input v-model="query.app_name" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="应用类别" prop="category" v-decorator="['category']">
<a-form-item
label="应用类别"
prop="category"
v-decorator="['category']"
>
<a-select
v-model="query.category"
placeholder="请选择"
......@@ -28,10 +41,16 @@
</a-col>
<a-col :md="8" :sm="24">
<span class="submitButtons">
<a-button type="primary" htmlType="submit" @click="getApplicationList">
<a-button
type="primary"
htmlType="submit"
@click="getApplicationList"
>
查询
</a-button>
<a-button :style="{ marginLeft: '8px' }" @click="resetForm"> 重置 </a-button>
<a-button :style="{ marginLeft: '8px' }" @click="resetForm">
重置
</a-button>
<a :style="{ marginLeft: '8px' }" @click="toggleForm">
展开 <a-icon type="down" />
</a>
......@@ -39,15 +58,28 @@
</a-col>
</a-row>
</a-form>
<a-form v-show="expandForm" layout="inline" :model="query" :form="form">
<a-form
v-show="expandForm"
layout="inline"
:model="query"
:form="form"
>
<a-row :gutter="{ md: 8, lg: 24, xl: 48 }">
<a-col :md="8" :sm="24">
<a-form-item label="应用名称" prop="app_name" v-decorator="['app_name']">
<a-form-item
label="应用名称"
prop="app_name"
v-decorator="['app_name']"
>
<a-input v-model="query.app_name" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="应用类别" prop="category" v-decorator="['category']">
<a-form-item
label="应用类别"
prop="category"
v-decorator="['category']"
>
<a-select
v-model="query.category"
placeholder="请选择"
......@@ -63,14 +95,22 @@
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="应用版本号" prop="app_version" v-decorator="['app_version']">
<a-form-item
label="应用版本号"
prop="app_version"
v-decorator="['app_version']"
>
<a-input v-model="query.app_version" placeholder="请输入" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="{ md: 8, lg: 24, xl: 48 }">
<a-col :md="8" :sm="24">
<a-form-item label="创建时间" prop="create_at" v-decorator="['create_at']">
<a-form-item
label="创建时间"
prop="create_at"
v-decorator="['create_at']"
>
<a-range-picker
v-model="query.create_at"
style="width: 100%"
......@@ -78,7 +118,11 @@
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="应用尺寸" prop="app_screen_size" v-decorator="['app_screen_size']">
<a-form-item
label="应用尺寸"
prop="app_screen_size"
v-decorator="['app_screen_size']"
>
<a-select v-model="query.app_screen_size">
<a-select-option
v-for="item in sizeList"
......@@ -91,7 +135,11 @@
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="适配平台" prop="app_arch" v-decorator="['app_arch']">
<a-form-item
label="适配平台"
prop="app_arch"
v-decorator="['app_arch']"
>
<a-select v-model="query.app_arch">
<a-select-option
v-for="item in portList"
......@@ -106,10 +154,16 @@
</a-row>
<div style="overflow: hidden">
<div :style="{ float: 'right', marginBottom: '24px' }">
<a-button type="primary" htmlType="submit" @click="getApplicationList">
<a-button
type="primary"
htmlType="submit"
@click="getApplicationList"
>
查询
</a-button>
<a-button :style="{ marginLeft: '8px' }" @click="resetForm"> 重置 </a-button>
<a-button :style="{ marginLeft: '8px' }" @click="resetForm">
重置
</a-button>
<a :style="{ marginLeft: '8px' }" @click="toggleForm">
收起 <a-icon type="up" />
</a>
......@@ -151,8 +205,10 @@
<template slot="name" slot-scope="name">
{{ name.first }} {{ name.last }}
</template>
<template slot="registered" slot-scope="registered">
{{ registered.date }} ({{ registered.age }})
<template slot="review" slot-scope="record">
<a-tag :color="record == '上架' ? 'green' : 'red'">
{{ record }}
</a-tag>
</template>
<template
slot="expandedRowRender"
......@@ -243,6 +299,14 @@
>重新打包</a
>
<a-divider type="vertical" />
<a href="javascript:;" @click="handleEditSource(record)"
>编辑源码</a
>
<a-divider type="vertical" />
<a href="javascript:;" @click="updateReview(record, 1)">上架</a>
<a-divider type="vertical" />
<a href="javascript:;" @click="updateReview(record, 0)">下架</a>
<a-divider type="vertical" />
<a href="javascript:;" @click="deleteApplication(record)">删除</a>
</template>
</a-table>
......@@ -265,6 +329,7 @@ import {
Divider,
Dropdown,
Input,
Tag,
Select,
DatePicker,
message,
......@@ -283,7 +348,12 @@ const columns = [
},
{
title: "应用类别",
dataIndex: "category",
dataIndex: "category_text",
},
{
title: "应用状态",
dataIndex: "app_review_text",
scopedSlots: { customRender: "review" },
},
{
title: "文件大小",
......@@ -308,6 +378,7 @@ import {
getApplicationList,
rebuildApplication,
deleteApplication,
updateReview
} from "@/api/openapi";
import { mapTrim } from "@/utils/index";
......@@ -366,12 +437,6 @@ export default {
},
},
}),
async asyncData({ store, route }, config = { results: 15 }) {
await store.dispatch("frontend/openapi/getUsers", {
...config,
path: route.path,
});
},
components: {
Icon,
APageHeaderWrapper: PageHeaderWrapper,
......@@ -379,6 +444,7 @@ export default {
ARow: Row,
ACol: Col,
ACard: Card,
ATag: Tag,
ACardGrid: Card.Grid,
ACardMeta: Card.Meta,
AList: List,
......@@ -400,10 +466,23 @@ export default {
this.form = this.$form.createForm(this, {});
},
methods: {
handleEditSource(record) {
console.log(record)
this.$router.push({ name: "FileManager", params: { directory: record.file_dir, disk: "epks" } })
},
updateReview(record, value) {
// 上架1 下架0
updateReview({ app: record.uuid, review: value }).then(res => {
message.success(res.msg)
this.getApplicationList()
}).catch(err => {
message.error(err.msg)
})
},
resetForm() {
this.$nextTick(() => {
this.form.resetFields();
})
});
},
toggleForm() {
this.expandForm = !this.expandForm;
......@@ -420,38 +499,34 @@ export default {
this.post.page = pagination.current;
this.post.pageSize = pagination.pageSize;
this.getApplicationList();
// const pager = { ...this.users.pagination };
// pager.current = pagination.current;
// this.users.pagination = pager;
// this.$options.asyncData(
// { store: this.$store, route: this.$route },
// {
// results: pagination.pageSize,
// page: pagination.current,
// sortField: sorter.field,
// sortOrder: sorter.order,
// ...filters,
// }
// );
},
getApplicationList() {
this.loading = true
this.loading = true;
let opts = mapTrim(this.query);
opts = Object.assign(opts, this.post);
getApplicationList(opts)
.then((res) => {
if (res.code == 200) {
this.tableData.list = res.data;
this.tableData.list = res.data.map((item) => {
const cat = this.categoryList.find(
(i) => item.category == i.value
);
if (cat) item.category_text = cat.label;
item.app_review_text = item.app_review ? "上架" : "下架";
return item;
});
this.tableData.pagination.pageSize = res.pageSize;
this.tableData.pagination.total = res.total;
}
message.success(res.msg);
})
.catch((err) => {
console.log(err);
message.error(err.msg);
}).finally(() => {
this.loading = false
})
.finally(() => {
this.loading = false;
});
},
rebuildApplication(record) {
......@@ -466,8 +541,8 @@ export default {
deleteApplication(record) {
deleteApplication(record.uuid)
.then((res) => {
message.success(res.msg);
this.getApplicationList();
message.success(res.msg)
this.getApplicationList()
})
.catch((err) => {
message.error(err.msg);
......
......@@ -103,9 +103,9 @@
</a-row>
</template>
<template slot="action" slot-scope="text, record">
<a href="javascript:;" @click="edit(record)">编辑源文件</a>
<a href="javascript:;" @click="hadnleEdit(record)">编辑源文件</a>
<a-divider type="vertical" />
<a href="javascript:;" @click="download(record)">下载EPK</a>
<a href="javascript:;" @click="handleDownload(record)">下载EPK</a>
</template>
</a-table>
</div>
......@@ -230,8 +230,7 @@ export default {
ARangePicker: DatePicker.RangePicker,
},
methods: {
download(record) {
console.log(record);
handleDownload(record) {
download(`${record.app_name}_${record.app_version}.epk`, record.file_path)
.then((res) => {
message.success(res.msg);
......@@ -240,8 +239,8 @@ export default {
message.error(err.msg);
});
},
edit(record) {
this.$router.push({ name: "FileManager", params: { directory: record.file_dir, disk: "uploads" } })
hadnleEdit(record) {
this.$router.push({ name: "FileManager", params: { directory: record.file_dir, disk: "epks" } })
},
resetForm() {
this.query = {
......
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