浏览代码

merge uic done

laiwei 8 年之前
父节点
当前提交
0ce61c24f7

+ 12 - 0
rrd/model/team.py

@@ -0,0 +1,12 @@
+#-*- coding:utf-8 -*-
+class Team(object):
+    def __init__(self, id, name, resume, creator, users=[]):
+        self.id = id
+        self.name = name
+        self.resume = resume
+        self.creator = creator
+        self.users = users
+
+    def __repr__(self):
+        return "<Team id=%s, name=%s>" % (self.id, self.name)
+    __str__ = __repr__

+ 2 - 2
rrd/model/user.py

@@ -5,7 +5,7 @@ class UserToken(object):
         self.sig = sig
     
     def __repr__(self):
-        return "<User name=%s, sig=%s>"  % (self.name, self.sig)
+        return "<UserToken name=%s, sig=%s>"  % (self.name, self.sig)
     __str__ = __repr__
 
 class User(object):
@@ -20,7 +20,7 @@ class User(object):
         self.role = role
 
     def __repr__(self):
-        return "<UserProfile id=%s, name=%s, cnname=%s>" \
+        return "<User id=%s, name=%s, cnname=%s>" \
                 % (self.id, self.name, self.cnname)
     __str__ = __repr__
 

+ 6 - 21
rrd/static/js/g.js

@@ -124,7 +124,7 @@ function query_team() {
 }
 
 function create_user() {
-	$.post('/admin/user/create', {
+	$.post('/user/create', {
 		'name' : $("#name").val(),
 		'cnname' : $("#cnname").val(),
 		'email' : $("#email").val(),
@@ -171,7 +171,7 @@ function reset_password(id) {
 }
 
 function create_team() {
-	$.post('/admin/team/create', {
+	$.post('/team/create', {
 		'name' : $("#name").val(),
 		'resume' : $("#resume").val(),
 		'users' : $("#users").val()
@@ -185,7 +185,7 @@ function create_team() {
 }
 
 function edit_team(tid) {
-	$.post('/admin/team/'+tid+'/edit', {
+	$.post('/team/'+tid+'/edit', {
 		'resume' : $("#resume").val(),
 		'users' : $("#users").val(),
 		'id': tid
@@ -216,7 +216,7 @@ function delete_user(uid) {
 
 function delete_team(id) {
 	my_confirm("真的真的要删除么?", [ '确定', '取消' ], function() {
-		$.get('/admin/team/'+id+'/delete', {}, function(json) {
+		$.post('/team/'+id+'/delete', {}, function(json) {
 			if (json.msg.length > 0) {
 				err_message_quietly(json.msg);
 			} else {
@@ -224,9 +224,9 @@ function delete_team(id) {
 					location.reload();
 				});
 			}
-		});
+		}, "json");
 	}, function() {
-	}, "json");
+	});
 }
 
 function set_role(uid, obj) {
@@ -247,18 +247,3 @@ function set_role(uid, obj) {
 	}, "json");
 }
 
-function user_detail(uid) {
-	$("#user_detail_div").load("/user/detail?id=" + uid);
-	$.layer({
-		type : 1,
-		shade : [ 0.5, '#000' ],
-		shadeClose : true,
-		closeBtn : [ 0, true ],
-		area : [ '450px', '240px' ],
-		title : false,
-		border : [ 0 ],
-		page : {
-			dom : '#user_detail_div'
-		}
-	}, "json");
-}

+ 10 - 0
rrd/templates/team/base.html

@@ -0,0 +1,10 @@
+{% extends "base.html" %}
+
+{%block head_js%}
+    {{super()}}
+    <script src="{{url_for('static', filename='js/g.js')}}"></script>
+{%endblock%}
+
+{%block navbar%}
+  {%include "navbar.html"%}
+{%endblock%}

+ 81 - 0
rrd/templates/team/create.html

@@ -0,0 +1,81 @@
+{% extends "team/base.html" %}
+
+{% block container_outer %}
+<div id="container" class="container-fluid">
+
+	<div class="row">
+		<div class="col-md-12">
+			<div style="margin: 0 auto; max-width: 400px;">
+
+				<ol class="breadcrumb">
+					<li><a href="/">首页</a></li>
+					<li><a href="/team/list">用户组列表</a></li>
+					<li class="active">创建用户组</li>
+				</ol>
+
+				<div class="panel panel-default">
+					<div class="panel-heading">
+						<h3 class="panel-title">Create Team</h3>
+					</div>
+					<div class="panel-body">
+						<div class="form-group">
+							<label for="name">名称(a-zA-Z0-9_-.):</label> <input type="text"
+							id="name" class="form-control" />
+						</div>
+						<div class="form-group">
+							<label for="resume">简介(方便以后能想起这个组的作用,选填):</label> <input
+							type="text" id="resume" class="form-control" />
+						</div>
+						<div class="form-group">
+							<label for="users">成员:</label> <input
+							type="text" id="users" class="form-control" />
+						</div>
+						<button type="button" class="btn btn-default" onclick="create_team();">
+							<span class="glyphicon glyphicon-floppy-disk"></span>
+							创建
+						</button>
+						<a href="/team/list" class="btn btn-default">
+							<span class="glyphicon glyphicon-arrow-left"></span>
+							返回
+						</a>
+					</div>
+				</div>
+
+			</div>
+		</div>
+	</div>
+
+</div>
+{%endblock%}
+
+{% block more_js%}
+
+{{super()}}
+<script type="text/javascript">
+$(function() {
+	$("#users").select2({
+        placeholder: "输入要添加组员的name",
+        allowClear: true,
+        multiple: true,
+        quietMillis: 100,
+        minimumInputLength: 1,
+        id: function(obj){return obj.id;},
+        ajax: {
+            url: "/user/query",
+            dataType: 'json',
+            data: function(term, page) {
+                return {
+                    query: term,
+                    limit: 20
+                };
+            },
+            results: function(json, page) {
+                return {results: json.users};
+            }
+        },
+        formatResult: function(obj) {return obj.name + "["+obj.cnname+"]" + "["+obj.email+"]"},
+        formatSelection: function(obj) {return obj.name},
+    });
+});
+</script>
+{%endblock%}

+ 83 - 0
rrd/templates/team/edit.html

@@ -0,0 +1,83 @@
+{% extends "team/base.html" %}
+
+{% block container_outer %}
+<div id="container" class="container-fluid">
+
+	<div class="row">
+		<div class="col-md-12">
+			<div style="margin: 0 auto; max-width: 400px;">
+
+				<ol class="breadcrumb">
+					<li><a href="/">首页</a></li>
+					<li><a href="/team/list">用户组列表</a></li>
+					<li class="active">修改用户组</li>
+				</ol>
+
+				<div class="panel panel-default">
+					<div class="panel-heading">
+						<h3 class="panel-title">Edit Team: {{team.name}}</h3>
+					</div>
+					<div class="panel-body">
+						<div class="form-group">
+							<label for="resume">简介(方便以后能想起这个组的作用,选填):</label> <input
+							type="text" id="resume" class="form-control" value="{{team.resume}}"/>
+						</div>
+						<div class="form-group">
+							<label for="users">成员:</label> <input
+							type="text" id="users" class="form-control" value="{{team_user_ids}}"/>
+						</div>
+						<button type="button" class="btn btn-default" onclick="edit_team('{{team.id}}');">
+							<span class="glyphicon glyphicon-floppy-disk"></span>
+							更新
+						</button>
+						<a href="/team/list" class="btn btn-default">
+							<span class="glyphicon glyphicon-arrow-left"></span>
+							返回
+						</a>
+					</div>
+				</div>
+
+			</div>
+		</div>
+	</div>
+
+</div>
+{%endblock%}
+
+
+{% block more_js%}
+
+{{super()}}
+<script type="text/javascript">
+$(function() {
+	$("#users").select2({
+        placeholder: "输入要添加组员的name",
+        allowClear: true,
+        multiple: true,
+        quietMillis: 100,
+        minimumInputLength: 1,
+        id: function(obj){return obj.id;},
+        initSelection: function(element, callback) {
+            $.getJSON("/team/{{team.id}}/users", function(json) {
+        		callback(json.users);
+        	});
+        },
+        ajax: {
+            url: "/user/query",
+            dataType: 'json',
+            data: function(term, page) {
+                return {
+                    query: term,
+                    limit: 20
+                };
+            },
+            results: function(json, page) {
+                return {results: json.users};
+            }
+        },
+        formatResult: function(obj) {return obj.name + "["+obj.cnname+"]" + "["+obj.email+"]"},
+        formatSelection: function(obj) {return obj.name},
+    });
+});
+</script>
+{%endblock%}

+ 80 - 0
rrd/templates/team/list.html

@@ -0,0 +1,80 @@
+{% extends "team/base.html" %}
+
+{%block head_js%}
+    {{super()}}
+
+    <script>
+    $(function() {
+        $("#query").keypress(function(e) {
+            var key = e.which;
+            if (key == 13) {
+                query_team();
+            }
+        });
+    });
+    </script>
+
+{%endblock%}
+
+{% block container_outer %}
+<div id="container" class="container-fluid">
+
+	<div class="row">
+		<div class="col-md-12">
+
+			<div style="margin: 0 auto; max-width: 500px;">
+
+				<ol class="breadcrumb">
+					<li><a href="/">首页</a></li>
+					<li class="active">用户组管理</li>
+				</ol>
+
+				<div class="form-inline mb20" role="form">
+					<div class="form-group">
+						<input type="text" value="{{query_term}}" class="form-control" id="query"
+						placeholder="query name">
+					</div>
+					<button type="button" onclick="query_team();" class="btn btn-default">
+						<span class="glyphicon glyphicon-search"></span>
+						Search
+					</button>
+					
+					<a href="/team/create" class="btn btn-default pull-right">
+						<span class="glyphicon glyphicon-plus"></span>
+						Add
+					</a>
+				</div>
+
+				<div class="ts">
+                    {%for team in teams%}
+					<div class="t">
+						<div>
+							<span class="glyphicon glyphicon-align-justify" style="font-size:9px;"></span>
+							{{team.name}}
+							<span class="gray" style="margin-right:10px;">{{team.resume}}</span>
+                            <a href="/team/{{team.id}}/edit" class="orange" style="text-decoration:none;">
+								<span class="glyphicon glyphicon-edit"></span>
+							</a>
+							<span class="cut-line">¦</span>
+							<a href="javascript:delete_team('{{team.id}}');" class="orange" style="text-decoration:none;">
+								<span class="glyphicon glyphicon-trash"></span>
+							</a>
+						</div>
+						<div class="mt10">
+                            {%for u in team.users%}
+								<code class="users">{{u.name}}</code>
+							{%endfor%}
+						</div>
+						<hr>
+					</div>
+					{%endfor%}
+				</div>
+
+
+			</div>
+
+		</div>
+	</div>
+
+</div>
+{%endblock%}

+ 1 - 1
rrd/templates/user/list.html

@@ -39,7 +39,7 @@
 					</button>
 
                     {%if g.user.is_admin() or g.user.is_root()%}
-                    <a href="/admin/user/create" class="btn btn-default pull-right">
+                    <a href="/user/create" class="btn btn-default pull-right">
                             <span class="glyphicon glyphicon-plus"></span>
                             Add
                     </a>

+ 132 - 3
rrd/view/team.py

@@ -1,12 +1,141 @@
 #-*- coding:utf-8 -*-
+import json
 from flask import request, g, abort, render_template
 from rrd import app
+from rrd import config, corelib
+from rrd.view.utils import require_login
+from rrd.model.team import Team
+from rrd.model.user import User
 
-@app.route("/team", methods=["GET", "POST"])
-def account_team():
+@app.route("/team/<int:team_id>/users", methods=["GET",])
+@require_login()
+def team_users(team_id):
     if request.method == "GET":
+        ret = {"msg":""}
+
+        h = {"Content-type": "application/json"}
+        r = corelib.auth_requests(g.user_token, "GET", "%s/team/%s" \
+                %(config.API_ADDR, team_id), headers=h)
+        if r.status_code != 200:
+            ret["msg"] = r.text
+            return json.dumps([])
+        else:
+            j = r.json()
+            return json.dumps(j)
+
+
+@app.route("/team/list", methods=["GET",])
+@require_login()
+def team_list():
+    if request.method == "GET":
+        teams = []
+        query_term = request.args.get("query", "")
+        if query_term:
+            d = {
+                    "q": query_term,
+                    "limit": g.limit or 50,
+                    "page": g.page or 1,
+            }
+        else:
+            d = {
+                    "q": ".",
+                    "limit": g.limit or 50,
+                    "page": g.page or 1,
+            }
+
+        h = {"Content-type": "application/json"}
+        r = corelib.auth_requests(g.user_token, "GET", "%s/team" \
+                %(config.API_ADDR,), params=d, headers=h)
+        if r.status_code != 200:
+            abort(400, "request to api fail: %s" %(r.text,))
+
+        for j in r.json():
+            users = [User(x["id"], x["name"], x["cnname"], x["email"], x["phone"], x["im"], x["qq"], x["role"]) for x in j['users']]
+            t = Team(j["team"]["id"], j["team"]["name"], j["team"]["resume"], j['creator_name'], users)
+            teams.append(t)
+
         return render_template("team/list.html", **locals())
 
+
+@app.route("/team/create", methods=["GET", "POST"])
+@require_login()
+def team_create():
+    if request.method == "GET":
+        return render_template("team/create.html", **locals())
+    
+    if request.method == "POST":
+        ret = {"msg":""}
+
+        name = request.form.get("name", "")
+        resume = request.form.get("resume", "")
+        users = request.form.get("users", "")
+
+        user_ids = users and users.split(",") or []
+        user_ids = [int(x) for x in user_ids]
+
+        if not name:
+            ret["msg"] = "empty name"
+            return json.dumps(ret)
+        
+        h = {"Content-type": "application/json"}
+        d = {
+                "team_name": name, "resume": resume, "users": user_ids,
+        }
+        r = corelib.auth_requests(g.user_token ,"POST", "%s/team" %(config.API_ADDR,), \
+                data=json.dumps(d), headers=h)
+        if r.status_code != 200:
+            ret["msg"] = r.text
+
+        return json.dumps(ret)
+
+@app.route("/team/<int:team_id>/edit", methods=["GET", "POST"])
+@require_login()
+def team_edit(team_id):
+    if request.method == "GET":
+
+        h = {"Content-type": "application/json"}
+        r = corelib.auth_requests(g.user_token, "GET", "%s/team/%s" \
+                %(config.API_ADDR, team_id), headers=h)
+        if r.status_code != 200:
+            abort(r.status_code, r.text)
+
+        j = r.json()
+        team = Team(j['id'], j['name'], j['resume'], j['creator'], [])
+        team_user_ids = ",".join([str(x['id']) for x in j['users']])
+
+        return render_template("team/edit.html", **locals())
+    
     if request.method == "POST":
-        pass
+        ret = {"msg":""}
+
+        resume = request.form.get("resume", "")
+        users = request.form.get("users", "")
+
+        user_ids = users and users.split(",") or []
+        user_ids = [int(x) for x in user_ids]
+
+        h = {"Content-type": "application/json"}
+        d = {
+                "team_id": team_id, "resume": resume, "users": user_ids,
+        }
+        r = corelib.auth_requests(g.user_token ,"PUT", "%s/team" %(config.API_ADDR,), \
+                data=json.dumps(d), headers=h)
+        if r.status_code != 200:
+            ret["msg"] = r.text
+
+        return json.dumps(ret)
+
+@app.route("/team/<int:team_id>/delete", methods=["POST"])
+@require_login(json_msg = "login first")
+def team_delete(team_id):
+    if request.method == "POST":
+        ret = {"msg": ""}
+        
+        h = {"Content-type": "application/json"}
+        r = corelib.auth_requests(g.user_token, "DELETE", "%s/team/%s" \
+                %(config.API_ADDR, team_id), headers=h)
+        if r.status_code != 200:
+            ret['msg'] = "%s:%s" %(r.status_code, r.text)
+
+        return json.dumps(ret)
 

+ 26 - 13
rrd/view/user.py

@@ -82,7 +82,6 @@ def user_change_passwd():
 
         return json.dumps(ret)
         
-##admin
 @app.route("/user/list", methods=["GET",])
 @require_login()
 def user_list():
@@ -95,8 +94,9 @@ def user_list():
                     "limit": g.limit or 50,
                     "page": g.page or 1,
             }
+            h = {"Content-type":"application/json"}
             r = corelib.auth_requests(g.user_token, "GET", "%s/user/users" \
-                    %(config.API_ADDR,), params=d)
+                    %(config.API_ADDR,), params=d, headers=h)
             if r.status_code != 200:
                 abort(400, "request to api fail: %s" %(r.text,))
             j = r.json() or []
@@ -106,21 +106,36 @@ def user_list():
 
         return render_template("user/list.html", **locals())
 
-@app.route("/admin/user/create", methods=["GET", "POST"])
+@app.route("/user/query", methods=["GET",])
+@require_login(json_msg="login first")
+def user_query():
+    if request.method == "GET":
+        query_term = request.args.get("query", "")
+        if query_term:
+            d = {
+                    "q": query_term,
+                    "limit": g.limit or 50,
+                    "page": g.page or 1,
+            }
+            h = {"Content-type":"application/json"}
+            r = corelib.auth_requests(g.user_token, "GET", "%s/user/users" \
+                    %(config.API_ADDR,), params=d, headers=h)
+            if r.status_code != 200:
+                ret['msg'] = t.text
+                return json.dumps(ret)
+
+            j = r.json() or []
+            return json.dumps({"users": j})
+
+@app.route("/user/create", methods=["GET", "POST"])
 @require_login()
-def admin_user_create():
+def user_create():
     if request.method == "GET":
-        if not (g.user.is_admin() or g.user.is_root()):
-            abort(403, "no such privilege")
         return render_template("user/create.html", **locals())
     
     if request.method == "POST":
         ret = {"msg":""}
 
-        if not (g.user.is_admin() or g.user.is_root()):
-            ret["msg"] = "no such privilege"
-            return json.dumps(ret)
-
         name = request.form.get("name", "")
         cnname = request.form.get("cnname", "")
         password = request.form.get("password", "")
@@ -144,8 +159,7 @@ def admin_user_create():
 
         return json.dumps(ret)
 
-
-
+##admin
 @app.route("/admin/user/<int:user_id>/edit", methods=["GET", "POST"])
 @require_login()
 def admin_user_edit(user_id):
@@ -216,7 +230,6 @@ def admin_user_change_password(user_id):
 
         return json.dumps(ret)
 
-
 @app.route("/admin/user/<int:user_id>/role", methods=["POST", ])
 @require_login(json_msg="login first")
 def admin_user_change_role(user_id):