Commit 51356508 authored by wanli's avatar wanli

feat(设备管理模块): 增加设备管理模块增删查改功能

parent 57b2d28e
<!--
* @Author: your name
* @Date: 2021-04-22 18:04:01
* @LastEditTime: 2021-06-30 11:24:58
* @LastEditors: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-19 17:04:37
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\README.md
-->
......@@ -21,6 +21,7 @@
- https://docs.pyfilesystem.org/en/latest/index.html
- https://jinja.palletsprojects.com/en/3.0.x/
- https://www.jb51.net/article/205786.htm
- https://blog.csdn.net/weixin_39352048/article/details/80363326
# 问题
......
'''
Author: your name
Date: 2021-07-15 09:33:39
LastEditTime: 2021-07-19 18:21:58
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\controllers\device.py
'''
#!/usr/bin/env python
# -*- coding: utf_8 -*-
from datetime import datetime
from application.app import db
from models.user import UserModel
from models.device import DeviceModel
from webcreator.log import logger
from webcreator.response import ResponseCode
......@@ -23,6 +32,9 @@ class DeviceResource(object):
# handle business
logger.warn(params)
filters = [DeviceModel.is_delete==False]
if params.get("type"): filters.append(DeviceModel.type==params.get("type"))
if params.get("name"): filters.append(DeviceModel.name==params.get("name"))
if params.get("imei"): filters.append(DeviceModel.imei==params.get("imei"))
result = DeviceModel.query.filter(*filters).order_by(DeviceModel.create_at).paginate(params.get('page', 1), params.get('pageSize', 10), error_out=False)
if result:
......@@ -39,8 +51,18 @@ class DeviceResource(object):
db.session.commit()
return True, ResponseCode.HTTP_SUCCESS
elif result and result.is_delete == False:
return False, ResponseCode.HTTP_INVAILD_REQUEST
return False, ResponseCode.IMEI_EXISTS
user = UserModel.query.filter(UserModel.uuid==jwt.get("uuid")).one_or_none()
if not user:
return False, ResponseCode.USER_NOT_EXISTS
params.update({
'create_at': datetime.now(),
'create_by': user.id,
'update_at': datetime.now(),
'update_by': user.id
})
result = DeviceModel(**params)
db.session.add(result)
db.session.commit()
......
......@@ -17,17 +17,23 @@ class DeviceModel(PrimaryModel):
# db.Index('idx_xxx', 'xxx', mysql_using='btree'),
# )
def __init__(self, imei, name='', type='', desc=''):
def __init__(self, imei, name='', type='', desc='', create_by=None, create_at=None, update_by=None, update_at=None, remarks=""):
self.imei = imei
self.name = name
self.type = type
self.desc = desc
self.create_by = create_by
self.create_at = create_at
self.update_by = update_by
self.update_at = update_at
self.remarks = remarks
def __repr__(self):
return '<DeviceModel %r>' % (self.imei)
def to_dict(self):
return {
'uuid': self.uuid,
'imei': self.imei,
'name': self.name,
'type': self.type,
......@@ -69,8 +75,13 @@ class GetListDeviceSchema(ma.SQLAlchemySchema):
page = fields.Integer(required=False)
pageSize = fields.Integer(required=False)
uuid = ma.auto_field()
imei = ma.auto_field()
name = ma.auto_field()
type = ma.auto_field()
desc = ma.auto_field()
create_at = ma.auto_field()
update_at = ma.auto_field()
getListDeviceSchema = GetListDeviceSchema()
getListDevicesSchema = GetListDeviceSchema(many=True)
......
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import traceback
from flask import current_app, jsonify, request
from flask_restful import Resource
from flask_restful.reqparse import RequestParser
......@@ -18,6 +19,8 @@ class DeviceResourceList(Resource):
@jwt_required(locations=["headers"])
def get(self):
# 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
self.parser.add_argument("name", type=str, location="args", required=False)
self.parser.add_argument("imei", type=str, location="args", required=False)
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()
......@@ -35,7 +38,6 @@ class DeviceResourceList(Resource):
json_dumps = getListDeviceSchema.dump(result)
if result:
json_dumps = getListDevicesSchema.dump(result.items)
logger.warn(json_dumps)
return response_result(message, data=json_dumps, total=result.total, pageSize=args.pageSize)
return response_result(message)
except Exception as e:
......@@ -45,13 +47,15 @@ class DeviceResourceList(Resource):
@jwt_required(locations=["headers"])
def post(self):
try:
jwt = get_jwt_identity()
json_payload = request.json
data = postDeviceSchema.load(json_payload)
result, message = signalManager.actionPostDevice.emit(data)
result, message = signalManager.actionPostDevice.emit(data, jwt)
logger.info(result)
logger.warn(message)
return response_result(message)
except Exception as e:
traceback.print_exc()
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-17 22:41:29
LastEditTime: 2021-07-19 17:40:36
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\webcreator\response.py
......@@ -97,6 +97,12 @@ class ResponseCode(object):
DIRECTORY_NOT_EXISTS = (3010003, 'directory not exists')
DIRECTORY_EXISTS = (3010004, 'directory already exists')
# 设备管理模块
DEVICE_NOT_EXISTS = (3010001, 'device not exists')
DEVICE_EXISTS = (3010002, 'device already exists')
IMEI_NOT_EXISTS = (3010001, 'device imei not exists')
IMEI_EXISTS = (3010002, 'device imei already exists')
def response_result(response, msg=None, data=None, **kwargs):
c, m = response
......
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-19 16:08:16
* @LastEditTime: 2021-07-19 18:13:07
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\api\openapi.js
*/
import request from '@/utils/request'
import request from "@/utils/request";
export function users(params) {
return request({
url: 'https://randomuser.me/api',
method: 'get',
params
})
return request({
url: "https://randomuser.me/api",
method: "get",
params,
});
}
export function postLogin(params) {
return request({
url: '/api/v1/login',
method: 'post',
data: params
})
return request({
url: "/api/v1/login",
method: "post",
data: params,
});
}
export function postApplication(params) {
return request({
url: "/api/v1/app",
method: "post",
data: params
})
return request({
url: "/api/v1/app",
method: "post",
data: params,
});
}
export function getApplicationList(params) {
return request({
url: "/api/v1/app",
method: "get",
params
})
return request({
url: "/api/v1/app",
method: "get",
params,
});
}
export function rebuildApplication(uuid) {
return request({
url: `/api/v1/app/${uuid}`,
method: "get"
})
return request({
url: `/api/v1/app/${uuid}`,
method: "get",
});
}
export function deleteApplication(uuid) {
return request({
url: `/api/v1/app/${uuid}`,
method: "delete"
})
return request({
url: `/api/v1/app/${uuid}`,
method: "delete",
});
}
export function getPackageList(params) {
return request({
url: "/api/v1/package",
method: "get",
params
})
return request({
url: "/api/v1/package",
method: "get",
params,
});
}
export function updateReview(params) {
return request({
url: "/api/v1/api/app-review",
method: "post",
data: params
})
return request({
url: "/api/v1/api/app-review",
method: "post",
data: params,
});
}
export function getDeviceList(params) {
return request({
url: "/api/v1/device",
method: "get",
params
})
return request({
url: "/api/v1/device",
method: "get",
params,
});
}
export function postDevice(params) {
return request({
url: "/api/v1/device",
method: "post",
data: params,
});
}
export function deleteDevice(uuid) {
return request({
url: `/api/v1/device/${uuid}`,
method: "delete",
});
}
export function updateDevice(uuid, params) {
return request({
url: `/api/v1/device/${uuid}`,
method: "put",
data: params,
});
}
......@@ -53,6 +53,9 @@ export default {
'menu.application.manager': '应用打包',
'menu.device': '设备管理',
'menu.device.index': '设备列表',
'menu.tools': '工具集',
'menu.tools.index': 'Convert To C String',
'menu.tools.monitor': '资源监视器',
//---
'app.home.introduce': 'introduce',
'app.analysis.test': 'Gongzhuan No.{no} shop',
......
......@@ -55,6 +55,9 @@ export default {
'menu.application.manager': '应用打包',
'menu.device': '设备管理',
'menu.device.index': '设备列表',
'menu.tools': '工具集',
'menu.tools.index': 'Convert To C String',
'menu.tools.monitor': '资源监视器',
//---
'app.home.introduce': '介绍',
'app.analysis.test': '工专路 {no} 号店',
......
......@@ -169,7 +169,7 @@ const router = new Router({
},
{
path: "/application",
icon: "table",
icon: "shop",
name: "application",
// redirect: '/application/index',
component: BasicLayout,
......@@ -196,7 +196,7 @@ const router = new Router({
},
{
path: "/device",
icon: "table",
icon: "usb",
name: "device",
// redirect: '/application/index',
component: BasicLayout,
......@@ -213,6 +213,25 @@ const router = new Router({
},
],
},
{
path: "/tools",
icon: "tool",
name: "tools",
// redirect: '/application/index',
component: BasicLayout,
children: [
{ path: "/tools", redirect: "/tools/monitor" },
{
path: "/tools/monitor",
name: "Monitor",
component: () => import("@/views/Application/Monitor"),
},
{
path: "/tools/index",
component: () => import("@/views/Application/Tool"),
},
],
},
],
});
......
......@@ -87,7 +87,7 @@ const mock = [
},
{
id: "1044886626813353984",
icon: 'table',
icon: 'shop',
parentId: "0",
name: "application",
path: "/application",
......@@ -113,7 +113,7 @@ const mock = [
},
{
id: "1044886626813353984",
icon: 'table',
icon: 'usb',
parentId: "0",
name: "device",
path: "/device",
......@@ -129,6 +129,32 @@ const mock = [
},
],
},
{
id: "1044886626813353984",
icon: 'tool',
parentId: "0",
name: "tools",
path: "/tools",
leaf: false,
children: [
{
id: "1044886629921333248",
parentId: "1044886626813353984",
name: "monitor",
path: "/tools/monitor",
leaf: true,
children: [],
},
{
id: "1044886629921333248",
parentId: "1044886626813353984",
name: "index",
path: "/tools/index",
leaf: true,
children: [],
},
],
},
];
const state = {
......
......@@ -3,83 +3,39 @@
<a-card :bordered="false">
<div class="tableList">
<div class="tableListForm">
<a-form v-show="!expandForm" layout="inline">
<a-form layout="inline">
<a-row :gutter="{ md: 8, lg: 24, xl: 48 }">
<a-col :md="8" :sm="24">
<a-form-item label="设备名" v-decorator="['name']">
<a-input placeholder="请输入" />
<a-input v-model="query.name" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="性别" v-decorator="['gender']">
<a-select placeholder="请选择" style="width: 100%">
<a-option value="male">male</a-option>
<a-option value="female">female</a-option>
</a-select>
<a-form-item label="IMEI" v-decorator="['imei']">
<a-input v-model="query.imei" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<span class="submitButtons">
<a-button type="primary" htmlType="submit"> 查询 </a-button>
<a-button :style="{ marginLeft: '8px' }"> 重置 </a-button>
<a :style="{ marginLeft: '8px' }" @click="toggleForm">
展开 <a-icon type="down" />
</a>
<a-button
type="primary"
htmlType="submit"
@click="getDataList"
>
查询
</a-button>
<a-button :style="{ marginLeft: '8px' }" @click="resetForm">
重置
</a-button>
</span>
</a-col>
</a-row>
</a-form>
<a-form v-show="expandForm" layout="inline">
<a-row :gutter="{ md: 8, lg: 24, xl: 48 }">
<a-col :md="8" :sm="24">
<a-form-item label="设备名" v-decorator="['name']">
<a-input placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="IMEI" v-decorator="['imei']">
<a-input placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="设备类型" v-decorator="['type']">
<a-select placeholder="请选择" style="width: 100%">
<a-option value="male">male</a-option>
<a-option value="female">female</a-option>
</a-select>
</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="时间" v-decorator="['registered']">
<a-range-picker style="width: 100%" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="邮箱" v-decorator="['email']">
<a-input placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-form-item label="国籍" v-decorator="['nat']">
<a-input placeholder="请输入" />
</a-form-item>
</a-col>
</a-row>
<div style="overflow: hidden">
<div :style="{ float: 'right', marginBottom: '24px' }">
<a-button type="primary" htmlType="submit"> 查询 </a-button>
<a-button :style="{ marginLeft: '8px' }"> 重置 </a-button>
<a :style="{ marginLeft: '8px' }" @click="toggleForm">
收起 <a-icon type="up" />
</a>
</div>
</div>
</a-form>
</div>
<div class="tableListOperator">
<a-button icon="plus" type="primary" @click="onAdd"> 新建 </a-button>
<a-button icon="plus" type="primary" @click="handleAdd">
新建
</a-button>
<span v-show="selectedRowKeys.length > 0">
<a-button>批量操作</a-button>
<!-- <a-dropdown overlay={menu}>
......@@ -106,9 +62,9 @@
@change="handleTableChange"
>
<template slot="action" slot-scope="text, record">
<a href="javascript:;">查看</a>
<a href="javascript:void(0);" @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a href="javascript:;">编辑</a>
<a href="javascript:void(0);" @click="handleDelete(record)">删除</a>
</template>
</a-table>
</div>
......@@ -162,12 +118,11 @@ const columns = [
];
import { mapTrim } from "@/utils/index";
import { getDeviceList } from "@/api/openapi";
import { getDeviceList, deleteDevice } from "@/api/openapi";
export default {
name: "DeviceIndex",
data: () => ({
expandForm: false,
selectedRowKeys: [],
columns,
sya: {
......@@ -221,11 +176,32 @@ export default {
ARangePicker: DatePicker.RangePicker,
},
methods: {
onAdd() {
this.$router.push({ name: "DeviceForm", params: {} });
resetForm() {
this.query = {
imei: null,
name: null,
type: null,
};
this.getDataList();
},
handleAdd() {
this.$router.push({ name: "DeviceForm", params: { title: "添加" } });
},
handleEdit(record) {
this.$router.push({
name: "DeviceForm",
params: { title: "编辑", record },
});
},
toggleForm() {
this.expandForm = !this.expandForm;
handleDelete(record) {
deleteDevice(record.uuid)
.then((res) => {
message.success(res.msg);
this.getDataList();
})
.catch((err) => {
message.error(err.msg);
});
},
onSelectChange(selectedRowKeys) {
window.console.log("selectedRowKeys changed: ", selectedRowKeys);
......
......@@ -3,82 +3,53 @@
<a-card :body-style="{ padding: '24px 32px' }" :bordered="false">
<a-form>
<a-form-item
label="标题"
label="设备名"
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
:required="true"
>
<a-input placeholder="给目标起个名字" />
<a-input v-model="post.name" placeholder="给设备起个名字" />
</a-form-item>
<a-form-item
label="起止日期"
label="IMEI"
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
:required="true"
>
<a-range-picker style="width: 100%" />
<a-input v-model="post.imei" placeholder="请描述设备IMEI" />
</a-form-item>
<a-form-item
label="目标描述"
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
>
<a-textarea rows="4" placeholder="请输入你阶段性工作目标" />
</a-form-item>
<a-form-item
label="衡量标准"
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
>
<a-textarea rows="4" placeholder="请输入衡量标准" />
</a-form-item>
<a-form-item
label="客户"
label="设备描述"
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
:required="false"
>
<a-input placeholder="请描述你服务的客户,内部客户直接 @姓名/工号" />
<a-textarea v-model="post.desc" rows="4" placeholder="请输入设备描述信息" />
</a-form-item>
<a-form-item
label="邀评人"
label="设备类型"
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
:required="false"
:required="true"
>
<a-input placeholder="请直接 @姓名/工号,最多可邀请 5 人" />
</a-form-item>
<a-form-item
label="权重"
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
:required="false"
>
<a-input-number :min="0" :max="100" />
<span>%</span>
</a-form-item>
<a-form-item
label="目标公开"
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
:required="false"
help="客户、邀评人默认被分享"
>
<a-radio-group v-model="value">
<a-radio :value="1">公开</a-radio>
<a-radio :value="2">部分公开</a-radio>
<a-radio :value="3">不公开</a-radio>
</a-radio-group>
<a-select mode="multiple" v-if="value === 2">
<a-select-option value="4">同事甲</a-select-option>
<a-select-option value="5">同事乙</a-select-option>
<a-select-option value="6">同事丙</a-select-option>
<a-select
v-model="post.type"
mode="default"
style="width: 100%"
placeholder="请选择设备类型"
:allowClear="true"
>
<a-select-option v-for="item in categoryList" :key="item.value">
{{ item.label }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
style="margin-top: 24px"
:wrapperCol="{ span: 10, offset: 7 }"
>
<a-button type="primary">提交</a-button>
<a-button style="margin-left: 8px">保存</a-button>
<a-button type="primary" v-if="title == '添加'" @click="postDevice">提交</a-button>
<a-button style="margin-left: 8px" v-else @click="updateDevice">保存</a-button>
</a-form-item>
</a-form>
</a-card>
......@@ -110,6 +81,9 @@ import {
import PageHeaderWrapper from "@/components/PageHeaderWrapper";
import DescriptionItem from "@/components/DescriptionItem";
import { mapTrim } from "@/utils/index";
import { postDevice, updateDevice } from "@/api/openapi";
export default {
name: "DeviceForm",
components: {
......@@ -145,18 +119,46 @@ export default {
},
data() {
return {
value: 1,
uuid: null,
title: "添加",
categoryList: [
{ label: "手表", value: "watch" }
],
post: {
name: null,
imei: null,
desc: null,
type: null,
}
};
},
computed: {
desc() {
return "表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。";
},
},
created() {
message.success("success");
const params = this.$route.params
console.log(params)
if (params.title) {
this.title = params.title
}
if(params.record) {
this.uuid = params.record.uuid
this.post = params.record
}
},
methods: {
postDevice() {
postDevice(this.post).then(res => {
message.success(res.msg)
}).catch(err => {
message.error(err.msg)
})
},
updateDevice() {
updateDevice(this.uuid, mapTrim(this.post)).then(res => {
message.success(res.msg)
}).catch(err => {
message.error(err.msg)
})
}
}
};
</script>
......
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