diff --git a/templates/admin.html b/templates/admin.html
index 6887714..ec28f56 100644
--- a/templates/admin.html
+++ b/templates/admin.html
@@ -10,36 +10,114 @@
{% block content %}
-
-
-
-
-
-
-
- | 邮箱 |
- 用户名 |
- 上次登录时间 |
-
-
-
-
- |
- |
- |
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ | 邮箱 |
+ 用户名 |
+ 上次登录时间 |
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+
+ 新建
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% end %}
{% block script %}
@@ -49,9 +127,20 @@
new Vue({
el: "#app",
data: Object.assign({
+ locationOperTitle: '',
+ locationOperAction : '',
+ dialogTableVisible: false,
+ tabActiveName: "admin",
formEmail: "",
users: [],
token: "",
+ form:{
+ "location": "",
+ "providerIP":"",
+ "id":""
+ },
+ eqtLocationDatas:[
+ ]
}, ret),
methods: {
addAdmin() {
@@ -65,7 +154,87 @@
console.log(ret)
this.$message("添加成功")
})
- }
+ },
+ tableHeaderColor ({row, column, rowIndex, columnIndex}) {
+ if (rowIndex === 0) {
+ return 'background-color: #D2E9FF;'
+ }
+ },
+ openNewLocationDialog(){
+ let that = this
+ that.locationOperAction = 'new'
+ that.locationOperTitle = '新建'
+ that.dialogTableVisible = true
+ },
+ openEditLocationDialog(index, row){
+ let that = this
+ that.locationOperAction = 'edit'
+ that.locationOperTitle = '编辑'
+ that.form.location = row.location
+ that.form.providerIP = row.providerIP
+ that.form.id = row.id
+ that.dialogTableVisible = true
+ },
+ handleNewLocation(){
+ let that = this
+ $.ajax({
+ url: "/api/v1/location",
+ method: "post",
+ data: JSON.stringify({
+ location: that.form.location,
+ providerIP: that.form.providerIP
+ })
+ }).then(ret => {
+ console.log(ret)
+ this.$message("添加成功")
+ that.dialogTableVisible = false
+ that.handleGetLocation({'name':'dept'})
+ })
+
+ },
+ handleGetLocation(value){
+ let that = this
+ if(value.name === 'dept'){
+ $.ajax({
+ url: "/api/v1/location",
+ method: "get"
+ }).then(ret => {
+ that.eqtLocationDatas = ret.location
+ console.log(ret)
+ })
+ }
+ },
+ handleEditLocation(){
+ let that = this
+ $.ajax({
+ url: "/api/v1/location/" + that.form.providerIP,
+ method: "put",
+ data: JSON.stringify({
+ location: that.form.location,
+ providerIP: that.form.providerIP
+ })
+ }).then(ret => {
+ console.log(ret)
+ this.$message("编辑成功")
+ that.dialogTableVisible = false
+ that.handleGetLocation({'name':'dept'})
+ })
+
+
+ },
+ handleDeleteLocation(index, row){
+ let that = this
+ $.ajax({
+ url: "/api/v1/location/" + row.providerIP,
+ method: "delete",
+ }).then(ret => {
+ console.log(ret)
+ this.$message("删除成功")
+ that.handleGetLocation({'name':'dept'})
+ })
+
+ },
+
}
})
})
diff --git a/templates/index.html b/templates/index.html
index 8792a54..cb614ee 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -64,7 +64,7 @@
设备离线
- 释放中
+ 释放中
-
-
-
-
-
-
-
+
+
+
+
@@ -165,6 +161,7 @@
new Vue({
el: "#app",
data: Object.assign({
+ locationOptions: [],
websocketDisconnected: false,
user: {
name: currentUserName,
@@ -186,6 +183,7 @@
}, { "devices": ret.devices }),
computed: {
tableData() {
+ let that = this
let devices = this.orderedDevices.map(v => {
for (const key in v.properties) {
if (v.properties.hasOwnProperty(key)) {
@@ -196,10 +194,21 @@
v['display_size'] = display.width + "x" + display.height;
return v;
})
+
const fp = this.filters.platform
if (Object.values(fp).some(b => b)) {
devices = devices.filter(v => fp[v.platform])
}
+
+ // 将手机中的location字段,和实际维护的location表做匹配并转换
+ devices.forEach(device=>{
+ for(let j=0; j < that.locationOptions.length; j++){
+ if(device['locationProperties']['providerIP'] === that.locationOptions[j]['providerIP']){
+ device['locationProperties']['location'] = that.locationOptions[j]['location']
+ }
+ }
+ });
+ console.log(devices);
return devices;
},
orderedDevices() {
@@ -340,22 +349,6 @@
}
})
},
- updateDeviceDepartment(udid, text) { // admin required
- $.ajax({
- url: "/api/v1/devices/" + udid,
- method: "put",
- contentType: "application/json",
- data: JSON.stringify({
- "department": text,
- })
- }).fail(ret => {
- if (ret.status == 400) {
- this.$message.error(ret.responseJSON.description)
- } else {
- this.$message.error(ret.responseText)
- }
- })
- },
formatTimeUsed() {
// let duration = moment(this.finishedAt) - moment(this.createdAt);
// return moment.utc(duration).format('HH:mm:ss')
@@ -422,6 +415,17 @@
event.preventDefault()
}
console.log(device.udid)
+ },
+ getLocationOptions(){
+ let that = this
+ $.ajax({
+ url: "/api/v1/location",
+ method: "get"
+ }).then(ret => {
+ that.locationOptions = ret.location
+ console.log(ret)
+ {#this.$message("获取成功")#}
+ })
}
},
components: {
@@ -470,6 +474,8 @@
let wsURL = scheme + "://" + location.host + "/websocket/devicechanges";
let ws = new WebSocket(wsURL);
let refreshKey = null;
+ this.getLocationOptions()
+
ws.onopen = (evt) => {
console.log("Websocket Connected")
refreshKey = setInterval(() => {
diff --git a/web/database.py b/web/database.py
index 8304904..bd09d9b 100644
--- a/web/database.py
+++ b/web/database.py
@@ -28,6 +28,10 @@ class DB(object):
"groups": {
"name": "groups",
},
+ "location": {
+ "name": "location",
+ "primary_key": "providerIP",
+ }
}
def __init__(self, db='demo', **kwargs):
@@ -211,13 +215,18 @@ async def all(self):
results.append(await cursor.next())
return results
- async def save(self, data: dict, id=None) -> dict:
+ async def save(self, data: dict, id=None, excludes=None) -> dict:
"""Update when exists or insert it
Returns:
dict which will contains "id"
"""
data = data.copy()
+
+ if excludes:
+ for item in excludes:
+ data.pop(item, None)
+
if id:
data[self.primary_key] = id
@@ -231,7 +240,6 @@ async def save(self, data: dict, id=None) -> dict:
# add some data
data['createdAt'] = time_now()
-
ret = await self.insert(data)
assert ret['errors'] == 0
diff --git a/web/urls.py b/web/urls.py
index 2502384..7cfa842 100644
--- a/web/urls.py
+++ b/web/urls.py
@@ -16,7 +16,7 @@
from .views.upload import UploadItemHandler, UploadListHandler
from .views.user import (
AdminListHandler, APIAdminListHandler, APIUserHandler,
- APIUserSettingsHandler, UserHandler)
+ APIUserSettingsHandler, UserHandler, APILocationListHandler)
urlpatterns = [
(r"/", MainHandler),
@@ -47,6 +47,8 @@
(r"/api/v1/user/devices/([^/]+)/active", APIUserDeviceActiveHandler), # GET
(r"/api/v1/user/settings", APIUserSettingsHandler), # GET, PUT
(r"/api/v1/admins", APIAdminListHandler), # GET, POST
+ (r"/api/v1/location/([^/]+)", APILocationListHandler), # GET, POST, PUT, DELETE
+ (r"/api/v1/location", APILocationListHandler), # GET, POST, PUT, DELETE
## Group API
# (r"/api/v1/user/groups/([^/]+)", APIUserGroupHandler), # GET, POST, DELETE TODO(ssx)
(r"/api/v1/user/groups", APIUserGroupListHandler), # GET, POST
diff --git a/web/views/device.py b/web/views/device.py
index d73f4b6..c0c6032 100644
--- a/web/views/device.py
+++ b/web/views/device.py
@@ -128,17 +128,6 @@ async def get(self, udid):
"device": data,
})
- @catch_error_wraps(rdb.errors.ReqlNonExistenceError)
- async def put(self, udid):
- if not self.current_user.admin:
- raise RuntimeError("Update requires admin")
-
- props = self.get_payload()
- await db.table("devices").get(udid).update({
- "department": props['department'],
- })
- self.write_json({"success": True, "description": "updated"})
-
class APIDevicePropertiesHandler(CorsMixin, BaseRequestHandler):
@catch_error_wraps(rdb.errors.ReqlNonExistenceError)
diff --git a/web/views/provider.py b/web/views/provider.py
index 7f76e48..00a8313 100644
--- a/web/views/provider.py
+++ b/web/views/provider.py
@@ -115,8 +115,11 @@ async def _on_update(self, req):
updates['sources'] = {
self._id: source,
}
+ provider_ip = source['remoteConnectAddressNetwork']
+ updates['locationProperties'] = dict(location=provider_ip, providerIP=provider_ip)
updates['updatedAt'] = time_now()
await db.table("devices").save(updates, udid)
+ await db.table("location").save(updates['locationProperties'], provider_ip, excludes=['location']) # yapf: disable
async def on_message(self, message):
req = json.loads(message)
diff --git a/web/views/user.py b/web/views/user.py
index 67af27d..3d6e4fa 100644
--- a/web/views/user.py
+++ b/web/views/user.py
@@ -45,6 +45,52 @@ async def post(self):
"data": ret,
})
+class APILocationListHandler(AdminRequestHandler):
+ async def get(self):
+ """
+ Response example:
+ {
+ "success": true,
+ "location": [{
+ "location": "",
+ "providerIP" : ""
+ ...
+ }]
+ }
+ """
+ ret = await db.table("location").all()
+ self.write_json({
+ "success": True,
+ "location": ret,
+ })
+
+ async def put(self, provider_ip):
+ """
+ """
+ payload = self.get_payload()
+ ret = await db.table("location") .get(provider_ip).update(payload) # yapf: disable
+ self.write_json({
+ "success": True,
+ "location": ret,
+ })
+
+ async def post(self):
+ payload = self.get_payload()
+ ret = await db.table("location").save(payload) # yapf: disable
+ # ret = await db.table("location").get(payload["location"]).update({"admin": True}) # yapf: disable
+ self.write_json({
+ "success": True,
+ "data": ret,
+ })
+
+ async def delete(self, providerIP):
+ """
+ """
+ ret = await db.table("location").get(providerIP).delete() # yapf: disable
+ self.write_json({
+ "success": True,
+ "location": ret,
+ })
class APIUserHandler(AuthRequestHandler):
async def get(self):