更新公告功能;去除小组可见公告;增加后端测试;修改后台对应的 js 和界面
This commit is contained in:
@@ -1,43 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
from functools import wraps
|
|
||||||
|
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
|
||||||
from django.shortcuts import render
|
|
||||||
|
|
||||||
from utils.shortcuts import error_response, error_page
|
|
||||||
|
|
||||||
from account.models import SUPER_ADMIN
|
|
||||||
from .models import Announcement
|
|
||||||
|
|
||||||
|
|
||||||
def check_user_announcement_permission(func):
|
|
||||||
@wraps(func)
|
|
||||||
def _check_user_announcement_permission(*args, **kwargs):
|
|
||||||
"""
|
|
||||||
这个函数检测当前用户能否查看这个公告
|
|
||||||
"""
|
|
||||||
# CBV 的情况,第一个参数是self,第二个参数是request
|
|
||||||
if len(args) == 2:
|
|
||||||
request = args[-1]
|
|
||||||
else:
|
|
||||||
request = args[0]
|
|
||||||
|
|
||||||
if "announcement_id" not in kwargs:
|
|
||||||
return error_page(request, u"参数错误")
|
|
||||||
announcement_id = kwargs["announcement_id"]
|
|
||||||
|
|
||||||
try:
|
|
||||||
announcement = Announcement.objects.get(id=announcement_id, visible=True)
|
|
||||||
except Announcement.DoesNotExist:
|
|
||||||
return error_page(request, u"公告不存在")
|
|
||||||
|
|
||||||
# 如果公告是只有部分小组可见的
|
|
||||||
if not announcement.is_global:
|
|
||||||
# 用户必须是登录状态的
|
|
||||||
if not request.user.is_authenticated():
|
|
||||||
return HttpResponseRedirect("/login/")
|
|
||||||
if not announcement.groups.filter(id__in=request.user.group_set.all()).exists():
|
|
||||||
return error_page(request, u"公告不存在")
|
|
||||||
return func(*args, **kwargs)
|
|
||||||
|
|
||||||
return _check_user_announcement_permission
|
|
||||||
@@ -19,9 +19,6 @@ class Announcement(models.Model):
|
|||||||
last_update_time = models.DateTimeField(auto_now=True)
|
last_update_time = models.DateTimeField(auto_now=True)
|
||||||
# 是否可见 false的话相当于删除
|
# 是否可见 false的话相当于删除
|
||||||
visible = models.BooleanField(default=True)
|
visible = models.BooleanField(default=True)
|
||||||
# 公告可见范围 True 是全局可见 False 是部分小组可见,需要在下面的字段中存储可见的小组
|
|
||||||
is_global = models.BooleanField()
|
|
||||||
groups = models.ManyToManyField(Group)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "announcement"
|
db_table = "announcement"
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ from .models import Announcement
|
|||||||
class CreateAnnouncementSerializer(serializers.Serializer):
|
class CreateAnnouncementSerializer(serializers.Serializer):
|
||||||
title = serializers.CharField(max_length=50)
|
title = serializers.CharField(max_length=50)
|
||||||
content = serializers.CharField(max_length=10000)
|
content = serializers.CharField(max_length=10000)
|
||||||
is_global = serializers.BooleanField()
|
|
||||||
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])
|
|
||||||
|
|
||||||
|
|
||||||
class AnnouncementSerializer(serializers.ModelSerializer):
|
class AnnouncementSerializer(serializers.ModelSerializer):
|
||||||
@@ -30,5 +28,3 @@ class EditAnnouncementSerializer(serializers.Serializer):
|
|||||||
title = serializers.CharField(max_length=50)
|
title = serializers.CharField(max_length=50)
|
||||||
content = serializers.CharField(max_length=10000)
|
content = serializers.CharField(max_length=10000)
|
||||||
visible = serializers.BooleanField()
|
visible = serializers.BooleanField()
|
||||||
is_global = serializers.BooleanField()
|
|
||||||
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])
|
|
||||||
|
|||||||
@@ -1,171 +1,64 @@
|
|||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.test import TestCase
|
from django.test import TestCase, Client
|
||||||
|
|
||||||
from rest_framework.test import APITestCase, APIClient
|
from rest_framework.test import APITestCase, APIClient
|
||||||
|
|
||||||
from account.models import User
|
from account.models import User
|
||||||
|
from account.tests import create_user
|
||||||
from group.models import Group
|
from group.models import Group
|
||||||
from announcement.models import Announcement
|
from announcement.models import Announcement
|
||||||
from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN
|
from account.models import ADMIN, SUPER_ADMIN
|
||||||
|
|
||||||
|
|
||||||
class AnnouncementAdminAPITest(APITestCase):
|
class AnnouncementAdminAPITest(APITestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.client = APIClient()
|
self.client = APIClient()
|
||||||
self.url = reverse("announcement_admin_api")
|
self.url = reverse("announcement_admin_api")
|
||||||
user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
|
self.user1 = create_user(admin_type=SUPER_ADMIN)
|
||||||
user1.set_password("testaa")
|
|
||||||
user1.save()
|
|
||||||
user2 = User.objects.create(username="test2", admin_type=ADMIN)
|
|
||||||
user2.set_password("testbb")
|
|
||||||
user2.save()
|
|
||||||
self.group = Group.objects.create(name="group1", description="des0",
|
|
||||||
join_group_setting=0, visible=True,
|
|
||||||
admin=user2)
|
|
||||||
self.announcement = Announcement.objects.create(title="bb",
|
|
||||||
content="BB",
|
|
||||||
created_by=User.objects.get(username="test2"),
|
|
||||||
is_global=False)
|
|
||||||
|
|
||||||
# 以下是发布公告的测试
|
self.user2 = create_user(username="test1", email="test1@qq.com", admin_type=SUPER_ADMIN)
|
||||||
def test_invalid_format(self):
|
|
||||||
self.client.login(username="test1", password="testaa")
|
|
||||||
data = {"title": "test1"}
|
|
||||||
response = self.client.post(self.url, data=data)
|
|
||||||
self.assertEqual(response.data["code"], 1)
|
|
||||||
|
|
||||||
def test_group_at_least_one(self):
|
self.announcement = Announcement.objects.create(title="bb",
|
||||||
self.client.login(username="test1", password="testaa")
|
content="BB",
|
||||||
data = {"title": "title0", "content": "content0", "is_global": False}
|
created_by=self.user1)
|
||||||
response = self.client.post(self.url, data=data)
|
|
||||||
self.assertEqual(response.data, {"code": 1, "data": u"至少选择一个小组"})
|
|
||||||
|
|
||||||
def test_global_announcement_successfully(self):
|
def test_create_announcement_successfully(self):
|
||||||
self.client.login(username="test1", password="testaa")
|
self.client.login(username="test", password="111111")
|
||||||
data = {"title": "title0", "content": "content0", "is_global": True}
|
data = {"title": "title0", "content": "content0"}
|
||||||
response = self.client.post(self.url, data=data)
|
response = self.client.post(self.url, data=data)
|
||||||
self.assertEqual(response.data, {"code": 0, "data": u"公告发布成功!"})
|
self.assertEqual(response.data, {"code": 0, "data": u"公告发布成功!"})
|
||||||
|
|
||||||
def test_group_announcement_successfully(self):
|
def test_edit_announcement_successfully(self):
|
||||||
self.client.login(username="test2", password="testbb")
|
self.client.login(username="test", password="111111")
|
||||||
data = {"title": "title0", "content": "content0", "is_global": False, "groups": [self.group.id]}
|
data = {"id": self.announcement.id, "title": "11", "content": "22", "visible": True}
|
||||||
response = self.client.post(self.url, data=data)
|
response = self.client.put(self.url, data=data)
|
||||||
self.assertEqual(response.data, {"code": 0, "data": u"公告发布成功!"})
|
self.assertEqual(response.data["code"], 0)
|
||||||
|
|
||||||
def test_global_announcement_does_not_has_privileges(self):
|
|
||||||
self.client.login(username="test2", password="testbb")
|
|
||||||
data = {"title": "title0", "content": "content0", "is_global": True}
|
|
||||||
response = self.client.post(self.url, data=data)
|
|
||||||
self.assertEqual(response.data, {"code": 1, "data": u"只有超级管理员可以创建全局公告"})
|
|
||||||
|
|
||||||
# 以下是编辑公告的测试
|
|
||||||
def test_put_invalid_data(self):
|
|
||||||
self.client.login(username="test1", password="testaa")
|
|
||||||
data = {"title": "test0", "content": "test0", "visible": "True"}
|
|
||||||
response = self.client.put(self.url, data=data)
|
|
||||||
self.assertEqual(response.data["code"], 1)
|
|
||||||
|
|
||||||
def test_announcement_does_not_exist(self):
|
|
||||||
self.client.login(username="test1", password="testaa")
|
|
||||||
announcement = Announcement.objects.create(title="aa",
|
|
||||||
content="AA",
|
|
||||||
created_by=User.objects.get(username="test1"),
|
|
||||||
is_global=True)
|
|
||||||
data = {"id": announcement.id + 1, "title": "11", "content": "22",
|
|
||||||
"visible": True, "is_global": True}
|
|
||||||
response = self.client.put(self.url, data=data)
|
|
||||||
self.assertEqual(response.data, {"code": 1, "data": u"公告不存在"})
|
|
||||||
|
|
||||||
def test_edit_global_announcement_successfully(self):
|
|
||||||
self.client.login(username="test1", password="testaa")
|
|
||||||
data = {"id": self.announcement.id, "title": "11", "content": "22",
|
|
||||||
"visible": True, "is_global": True}
|
|
||||||
response = self.client.put(self.url, data=data)
|
|
||||||
self.assertEqual(response.data["code"], 0)
|
|
||||||
|
|
||||||
def test_edit_group_announcement_successfully(self):
|
|
||||||
self.client.login(username="test2", password="testbb")
|
|
||||||
data = {"id": self.announcement.id, "title": "11", "content": "22",
|
|
||||||
"visible": True, "is_global": False, "groups": [self.group.id]}
|
|
||||||
response = self.client.put(self.url, data=data)
|
|
||||||
self.assertEqual(response.data["code"], 0)
|
|
||||||
self.assertEqual(response.data["data"]["title"], "11")
|
|
||||||
self.assertEqual(response.data["data"]["content"], "22")
|
|
||||||
|
|
||||||
def test_edit_group_at_least_one(self):
|
|
||||||
self.client.login(username="test1", password="testaa")
|
|
||||||
data = {"id": self.announcement.id, "title": "title0", "content": "content0",
|
|
||||||
"visible": True, "is_global": False}
|
|
||||||
response = self.client.put(self.url, data=data)
|
|
||||||
self.assertEqual(response.data, {"code": 1, "data": u"至少选择一个小组"})
|
|
||||||
|
|
||||||
# 以下是公告分页的测试
|
|
||||||
def test_get_data_successfully(self):
|
|
||||||
self.client.login(username="test1", password="testaa")
|
|
||||||
self.assertEqual(self.client.get(self.url).data["code"], 0)
|
|
||||||
|
|
||||||
def test_keyword_global_announcement(self):
|
|
||||||
self.client.login(username="test1", password="testaa")
|
|
||||||
Announcement.objects.create(title="aa",
|
|
||||||
content="AA",
|
|
||||||
created_by=User.objects.get(username="test1"),
|
|
||||||
visible=True,
|
|
||||||
is_global=True)
|
|
||||||
|
|
||||||
Announcement.objects.create(title="bb",
|
|
||||||
content="BB",
|
|
||||||
created_by=User.objects.get(username="test1"),
|
|
||||||
visible=False,
|
|
||||||
is_global=True)
|
|
||||||
|
|
||||||
response = self.client.get(self.url + "?visible=true")
|
|
||||||
self.assertEqual(response.data["code"], 0)
|
|
||||||
for item in response.data["data"]:
|
|
||||||
self.assertEqual(item["visible"], True)
|
|
||||||
|
|
||||||
def test_keyword_group_announcement(self):
|
|
||||||
self.client.login(username="test2", password="testbb")
|
|
||||||
Announcement.objects.create(title="aa",
|
|
||||||
content="AA",
|
|
||||||
created_by=User.objects.get(username="test2"),
|
|
||||||
visible=True,
|
|
||||||
is_global=False)
|
|
||||||
|
|
||||||
Announcement.objects.create(title="cc",
|
|
||||||
content="CC",
|
|
||||||
created_by=User.objects.get(username="test2"),
|
|
||||||
visible=False,
|
|
||||||
is_global=False)
|
|
||||||
|
|
||||||
response = self.client.get(self.url + "?visible=true")
|
|
||||||
self.assertEqual(response.data["code"], 0)
|
|
||||||
for item in response.data["data"]:
|
|
||||||
self.assertEqual(item["visible"], True)
|
|
||||||
|
|
||||||
|
|
||||||
class AnnouncementPageTest(TestCase):
|
class AnnouncementPageTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
user = User.objects.create(username="test")
|
self.client = Client()
|
||||||
user.set_password("testaa")
|
user = create_user()
|
||||||
user.save()
|
self.a1 = Announcement.objects.create(title="aa",
|
||||||
Announcement.objects.create(title="aa",
|
content="AA",
|
||||||
content="AA",
|
created_by=user,
|
||||||
created_by=User.objects.get(username="test"),
|
visible=True,
|
||||||
visible=True,
|
)
|
||||||
is_global=True)
|
|
||||||
|
|
||||||
Announcement.objects.create(title="bb",
|
self.a2 = Announcement.objects.create(title="bb",
|
||||||
content="BB",
|
content="BB",
|
||||||
created_by=User.objects.get(username="test"),
|
created_by=User.objects.get(username="test"),
|
||||||
visible=False,
|
visible=False
|
||||||
is_global=True)
|
)
|
||||||
|
|
||||||
def test_visit_announcement_successfully(self):
|
def test_visit_announcement_successfully(self):
|
||||||
response = self.client.get('/announcement/1/')
|
response = self.client.get('/announcement/' + str(self.a1.id) + "/")
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertTemplateUsed(response, "oj/announcement/announcement.html")
|
||||||
|
|
||||||
def test_announcement_does_not_exist(self):
|
def test_announcement_does_not_exist(self):
|
||||||
response = self.client.get('/announcement/3/')
|
response = self.client.get('/announcement/10086/')
|
||||||
self.assertTemplateUsed(response, "utils/error.html")
|
self.assertTemplateUsed(response, "utils/error.html")
|
||||||
|
|
||||||
|
def test_visit_hidden_announcement(self):
|
||||||
|
response = self.client.get('/announcement/' + str(self.a2.id) + "/")
|
||||||
|
self.assertTemplateUsed(response, "utils/error.html")
|
||||||
|
|||||||
@@ -6,20 +6,26 @@ from utils.shortcuts import serializer_invalid_response, error_response, success
|
|||||||
|
|
||||||
from utils.shortcuts import paginate, error_page
|
from utils.shortcuts import paginate, error_page
|
||||||
from account.models import SUPER_ADMIN, ADMIN
|
from account.models import SUPER_ADMIN, ADMIN
|
||||||
|
from account.decorators import super_admin_required
|
||||||
from group.models import Group
|
from group.models import Group
|
||||||
from .models import Announcement
|
from .models import Announcement
|
||||||
from .serializers import (CreateAnnouncementSerializer, AnnouncementSerializer,
|
from .serializers import (CreateAnnouncementSerializer, AnnouncementSerializer,
|
||||||
EditAnnouncementSerializer)
|
EditAnnouncementSerializer)
|
||||||
from .decorators import check_user_announcement_permission
|
|
||||||
|
|
||||||
|
|
||||||
@check_user_announcement_permission
|
|
||||||
def announcement_page(request, announcement_id):
|
def announcement_page(request, announcement_id):
|
||||||
announcement = Announcement.objects.get(id=announcement_id, visible=True)
|
"""
|
||||||
|
公告的详情页面
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
announcement = Announcement.objects.get(id=announcement_id, visible=True)
|
||||||
|
except Announcement.DoesNotExist:
|
||||||
|
return error_page(request, u"公告不存在")
|
||||||
return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
|
return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
|
||||||
|
|
||||||
|
|
||||||
class AnnouncementAdminAPIView(APIView):
|
class AnnouncementAdminAPIView(APIView):
|
||||||
|
@super_admin_required
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
"""
|
"""
|
||||||
公告发布json api接口
|
公告发布json api接口
|
||||||
@@ -29,29 +35,12 @@ class AnnouncementAdminAPIView(APIView):
|
|||||||
serializer = CreateAnnouncementSerializer(data=request.data)
|
serializer = CreateAnnouncementSerializer(data=request.data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
data = serializer.data
|
data = serializer.data
|
||||||
groups = []
|
Announcement.objects.create(title=data["title"], content=data["content"], created_by=request.user)
|
||||||
# 如果不是全局公告,就去查询一下小组的id 列表中的内容,注意用户身份
|
|
||||||
if not data["is_global"]:
|
|
||||||
if request.user.admin_type == SUPER_ADMIN:
|
|
||||||
groups = Group.objects.filter(id__in=data["groups"])
|
|
||||||
else:
|
|
||||||
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
|
|
||||||
if not groups.count():
|
|
||||||
return error_response(u"至少选择一个小组")
|
|
||||||
else:
|
|
||||||
if request.user.admin_type != SUPER_ADMIN:
|
|
||||||
return error_response(u"只有超级管理员可以创建全局公告")
|
|
||||||
|
|
||||||
announcement = Announcement.objects.create(title=data["title"],
|
|
||||||
content=data["content"],
|
|
||||||
created_by=request.user,
|
|
||||||
is_global=data["is_global"])
|
|
||||||
|
|
||||||
announcement.groups.add(*groups)
|
|
||||||
return success_response(u"公告发布成功!")
|
return success_response(u"公告发布成功!")
|
||||||
else:
|
else:
|
||||||
return serializer_invalid_response(serializer)
|
return serializer_invalid_response(serializer)
|
||||||
|
|
||||||
|
@super_admin_required
|
||||||
def put(self, request):
|
def put(self, request):
|
||||||
"""
|
"""
|
||||||
公告编辑json api接口
|
公告编辑json api接口
|
||||||
@@ -63,43 +52,27 @@ class AnnouncementAdminAPIView(APIView):
|
|||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
data = serializer.data
|
data = serializer.data
|
||||||
try:
|
try:
|
||||||
if request.user.admin_type == SUPER_ADMIN:
|
announcement = Announcement.objects.get(id=data["id"])
|
||||||
announcement = Announcement.objects.get(id=data["id"])
|
|
||||||
else:
|
|
||||||
announcement = Announcement.objects.get(id=data["id"], created_by=request.user)
|
|
||||||
except Announcement.DoesNotExist:
|
except Announcement.DoesNotExist:
|
||||||
return error_response(u"公告不存在")
|
return error_response(u"公告不存在")
|
||||||
groups = []
|
|
||||||
if not data["is_global"]:
|
|
||||||
if request.user.admin_type == SUPER_ADMIN:
|
|
||||||
groups = Group.objects.filter(id__in=data["groups"])
|
|
||||||
else:
|
|
||||||
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
|
|
||||||
if not groups.count():
|
|
||||||
return error_response(u"至少选择一个小组")
|
|
||||||
announcement.title = data["title"]
|
announcement.title = data["title"]
|
||||||
announcement.content = data["content"]
|
announcement.content = data["content"]
|
||||||
announcement.visible = data["visible"]
|
announcement.visible = data["visible"]
|
||||||
announcement.is_global = data["is_global"]
|
|
||||||
announcement.save()
|
announcement.save()
|
||||||
|
|
||||||
# 重建小组和公告的对应关系
|
|
||||||
announcement.groups.clear()
|
|
||||||
announcement.groups.add(*groups)
|
|
||||||
return success_response(AnnouncementSerializer(announcement).data)
|
return success_response(AnnouncementSerializer(announcement).data)
|
||||||
else:
|
else:
|
||||||
return serializer_invalid_response(serializer)
|
return serializer_invalid_response(serializer)
|
||||||
|
|
||||||
|
@super_admin_required
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
"""
|
"""
|
||||||
公告分页json api接口
|
公告分页json api接口
|
||||||
---
|
---
|
||||||
response_serializer: AnnouncementSerializer
|
response_serializer: AnnouncementSerializer
|
||||||
"""
|
"""
|
||||||
if request.user.admin_type == SUPER_ADMIN:
|
announcement = Announcement.objects.all().order_by("-create_time")
|
||||||
announcement = Announcement.objects.all().order_by("-last_update_time")
|
|
||||||
else:
|
|
||||||
announcement = Announcement.objects.filter(created_by=request.user)
|
|
||||||
visible = request.GET.get("visible", None)
|
visible = request.GET.get("visible", None)
|
||||||
if visible:
|
if visible:
|
||||||
announcement = announcement.filter(visible=(visible == "true"))
|
announcement = announcement.filter(visible=(visible == "true"))
|
||||||
|
|||||||
@@ -1,69 +1,38 @@
|
|||||||
require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"],
|
require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator", "pager"],
|
||||||
function ($, avalon, csrfTokenHeader, bsAlert, editor) {
|
function ($, avalon, csrfTokenHeader, bsAlert, editor) {
|
||||||
avalon.ready(function () {
|
avalon.ready(function () {
|
||||||
|
|
||||||
var createAnnouncementEditor = editor("#create-announcement-editor");
|
var createAnnouncementEditor = editor("#create-announcement-editor");
|
||||||
var editAnnouncementEditor = editor("#edit-announcement-editor");
|
var editAnnouncementEditor = editor("#edit-announcement-editor");
|
||||||
|
|
||||||
if (avalon.vmodels.announcement){
|
if (avalon.vmodels.announcement){
|
||||||
var vm = avalon.vmodels.announcement;
|
var vm = avalon.vmodels.announcement;
|
||||||
announcementList = [];
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
var vm = avalon.define({
|
var vm = avalon.define({
|
||||||
$id: "announcement",
|
$id: "announcement",
|
||||||
//通用变量
|
announcementList: [],
|
||||||
announcementList: [], // 公告列表数据项
|
pager: {
|
||||||
previousPage: 0, // 之前的页数
|
getPage: function(page){
|
||||||
nextPage: 0, // 之后的页数
|
getPage(page);
|
||||||
page: 1, // 当前页数
|
}
|
||||||
editingAnnouncementId: 0, // 正在编辑的公告的ID, 为零说明未在编辑
|
},
|
||||||
totalPage: 1, // 总页数
|
isEditing: false,
|
||||||
showVisibleOnly: false, //仅显示可见公告
|
announcementId: -1,
|
||||||
// 编辑
|
showVisibleOnly: false,
|
||||||
newTitle: "",
|
newTitle: "",
|
||||||
announcementVisible: 0,
|
announcementVisible: 0,
|
||||||
showGlobalViewRadio: true,
|
|
||||||
isGlobal: true,
|
|
||||||
allGroups: [],
|
|
||||||
getNext: function () {
|
|
||||||
if (!vm.nextPage)
|
|
||||||
return;
|
|
||||||
getPageData(vm.page + 1);
|
|
||||||
},
|
|
||||||
getPrevious: function () {
|
|
||||||
if (!vm.previousPage)
|
|
||||||
return;
|
|
||||||
getPageData(vm.page - 1);
|
|
||||||
},
|
|
||||||
getBtnClass: function (btnType) {
|
|
||||||
if (btnType == "next") {
|
|
||||||
return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
editAnnouncement: function (announcement) {
|
editAnnouncement: function (announcement) {
|
||||||
vm.newTitle = announcement.title;
|
vm.newTitle = announcement.title;
|
||||||
|
vm.announcementId = announcement.id;
|
||||||
editAnnouncementEditor.setValue(announcement.content);
|
editAnnouncementEditor.setValue(announcement.content);
|
||||||
vm.announcementVisible = announcement.visible;
|
vm.announcementVisible = announcement.visible;
|
||||||
if (vm.editingAnnouncementId == announcement.id)
|
vm.isEditing = !vm.isEditing;
|
||||||
vm.editingAnnouncementId = 0;
|
|
||||||
else
|
|
||||||
vm.editingAnnouncementId = announcement.id;
|
|
||||||
vm.isGlobal = announcement.is_global;
|
|
||||||
for (var i = 0; i < announcement.groups.length; i++) {
|
|
||||||
for (var j = 0; j < vm.allGroups.length; j++) {
|
|
||||||
if (announcement.groups[i] == vm.allGroups[j].id) {
|
|
||||||
vm.allGroups[j].isSelected = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
editAnnouncementEditor.focus();
|
editAnnouncementEditor.focus();
|
||||||
},
|
},
|
||||||
cancelEdit: function () {
|
cancelEdit: function () {
|
||||||
vm.editingAnnouncementId = 0;
|
vm.isEditing = false;
|
||||||
},
|
},
|
||||||
submitChange: function () {
|
submitChange: function () {
|
||||||
var title = vm.newTitle;
|
var title = vm.newTitle;
|
||||||
@@ -74,39 +43,22 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"],
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedGroups = [];
|
|
||||||
if (!vm.isGlobal) {
|
|
||||||
for (var i = 0; i < vm.allGroups.length; i++) {
|
|
||||||
if (vm.allGroups[i].isSelected) {
|
|
||||||
selectedGroups.push(vm.allGroups[i].id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vm.isGlobal && !selectedGroups.length) {
|
|
||||||
bsAlert("请至少选择一个小组");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
beforeSend: csrfTokenHeader,
|
|
||||||
url: "/api/admin/announcement/",
|
url: "/api/admin/announcement/",
|
||||||
contentType: "application/json;charset=UTF-8",
|
contentType: "application/json;charset=UTF-8",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
method: "put",
|
method: "put",
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
id: vm.editingAnnouncementId,
|
id: vm.announcementId,
|
||||||
title: title,
|
title: title,
|
||||||
content: content,
|
content: content,
|
||||||
visible: vm.announcementVisible,
|
visible: vm.announcementVisible
|
||||||
is_global: vm.isGlobal,
|
|
||||||
groups: selectedGroups
|
|
||||||
}),
|
}),
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (!data.code) {
|
if (!data.code) {
|
||||||
bsAlert("修改成功");
|
bsAlert("修改成功");
|
||||||
vm.editingAnnouncementId = 0;
|
vm.isEditing = false;
|
||||||
getPageData(1);
|
getPage(1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bsAlert(data.data);
|
bsAlert(data.data);
|
||||||
@@ -116,69 +68,27 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"],
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
vm.$watch("showVisibleOnly", function () {
|
vm.$watch("showVisibleOnly", function () {
|
||||||
getPageData(1);
|
getPage(1);
|
||||||
|
avalon.vmodels.announcementPager.currentPage = 1;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getPageData(1);
|
function getPage(page) {
|
||||||
|
var url = "/api/admin/announcement/?paging=true&page=" + page + "&page_size=2";
|
||||||
$.ajax({
|
|
||||||
url: "/api/user/",
|
|
||||||
method: "get",
|
|
||||||
dataType: "json",
|
|
||||||
success: function (data) {
|
|
||||||
if (!data.code) {
|
|
||||||
var admin_type = data.data.admin_type;
|
|
||||||
if (data.data.admin_type == 1) {
|
|
||||||
vm.isGlobal = false;
|
|
||||||
vm.showGlobalViewRadio = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$.ajax({
|
|
||||||
url: "/api/admin/group/",
|
|
||||||
method: "get",
|
|
||||||
dataType: "json",
|
|
||||||
success: function (data) {
|
|
||||||
if (!data.code) {
|
|
||||||
if (!data.data.length) {
|
|
||||||
if (admin_type != 2)
|
|
||||||
bsAlert("您的用户权限只能创建组内公告,但是您还没有创建过小组");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < data.data.length; i++) {
|
|
||||||
var item = data.data[i];
|
|
||||||
item["isSelected"] = false;
|
|
||||||
vm.allGroups.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bsAlert(data.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function getPageData(page) {
|
|
||||||
var url = "/api/admin/announcement/?paging=true&page=" + page + "&page_size=10";
|
|
||||||
if (vm.showVisibleOnly)
|
if (vm.showVisibleOnly)
|
||||||
url += "&visible=true";
|
url += "&visible=true";
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
dataType: "json",
|
|
||||||
method: "get",
|
method: "get",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (!data.code) {
|
if (!data.code) {
|
||||||
vm.announcementList = data.data.results;
|
vm.announcementList = data.data.results;
|
||||||
vm.totalPage = data.data.total_page;
|
avalon.vmodels.announcementPager.totalPage = data.data.total_page;
|
||||||
vm.previousPage = data.data.previous_page;
|
|
||||||
vm.nextPage = data.data.next_page;
|
|
||||||
vm.page = page;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bs_alert(data.data);
|
bsAlert(data.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -193,28 +103,12 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"],
|
|||||||
bsAlert("请填写公告内容");
|
bsAlert("请填写公告内容");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var selectedGroups = [];
|
|
||||||
if (!vm.isGlobal) {
|
|
||||||
for (var i = 0; i < vm.allGroups.length; i++) {
|
|
||||||
if (vm.allGroups[i].isSelected) {
|
|
||||||
selectedGroups.push(vm.allGroups[i].id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vm.isGlobal && !selectedGroups.length) {
|
|
||||||
bsAlert("请至少选择一个小组");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
beforeSend: csrfTokenHeader,
|
|
||||||
url: "/api/admin/announcement/",
|
url: "/api/admin/announcement/",
|
||||||
contentType: "application/json;charset=UTF-8",
|
contentType: "application/json",
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
title: title,
|
title: title,
|
||||||
content: content,
|
content: content
|
||||||
is_global: vm.isGlobal,
|
|
||||||
groups: selectedGroups
|
|
||||||
}),
|
}),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
method: "post",
|
method: "post",
|
||||||
@@ -223,7 +117,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"],
|
|||||||
bsAlert("提交成功!");
|
bsAlert("提交成功!");
|
||||||
$("#title").val("");
|
$("#title").val("");
|
||||||
createAnnouncementEditor.setValue("");
|
createAnnouncementEditor.setValue("");
|
||||||
getPageData(1);
|
getPage(1);
|
||||||
} else {
|
} else {
|
||||||
bsAlert(data.data);
|
bsAlert(data.data);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,6 @@
|
|||||||
<th>创建时间</th>
|
<th>创建时间</th>
|
||||||
<th>更新时间</th>
|
<th>更新时间</th>
|
||||||
<th>创建者</th>
|
<th>创建者</th>
|
||||||
<th>类型</th>
|
|
||||||
<th>可见</th>
|
<th>可见</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -17,7 +16,6 @@
|
|||||||
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
|
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
|
||||||
<td>{{ el.last_update_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
|
<td>{{ el.last_update_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
|
||||||
<td>{{ el.created_by.username }}</td>
|
<td>{{ el.created_by.username }}</td>
|
||||||
<td ms-text="el.is_global?'全局可见':'组内可见'"></td>
|
|
||||||
<td ms-text="el.visible?'可见':'不可见'"></td>
|
<td ms-text="el.visible?'可见':'不可见'"></td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn-sm btn-info" ms-click="editAnnouncement(el)">编辑</button>
|
<button class="btn-sm btn-info" ms-click="editAnnouncement(el)">编辑</button>
|
||||||
@@ -28,12 +26,10 @@
|
|||||||
<label>仅显示可见 <input ms-duplex-checked="showVisibleOnly" type="checkbox"/></label>
|
<label>仅显示可见 <input ms-duplex-checked="showVisibleOnly" type="checkbox"/></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
页数:{{ page }}/{{ totalPage }}
|
<ms:pager $id="announcementPager" config="pager"></ms:pager>
|
||||||
<button ms-attr-class="getBtnClass('pre')" ms-click="getPrevious">上一页</button>
|
|
||||||
<button ms-attr-class="getBtnClass('next')" ms-click="getNext">下一页</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ms-visible="editingAnnouncementId">
|
<div ms-visible="isEditing">
|
||||||
<h3>编辑公告</h3>
|
<h3>编辑公告</h3>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -47,32 +43,14 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>可见 <input ms-duplex-checked="announcementVisible" type="checkbox"/></label>
|
<label>可见 <input ms-duplex-checked="announcementVisible" type="checkbox"/></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label>可见范围</label>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<span ms-if="showGlobalViewRadio">
|
|
||||||
<input type="radio" value="true" name="isGlobal" ms-duplex-boolean="isGlobal">全局可见
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<input type="radio" value="false" name="isGlobal" ms-duplex-boolean="isGlobal">小组内可见
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-12" ms-if="!isGlobal">
|
|
||||||
<!-- radio 的value 没有用 但是没有的话,表单验证会出错-->
|
|
||||||
<div ms-repeat="allGroups" class="col-md-4">
|
|
||||||
<input type="checkbox" value="group_id" ms-duplex-checked="el.isSelected"> {{ el.name }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button ms-click="submitChange()" class="btn btn-success">保存修改</button>
|
<button ms-click="submitChange()" class="btn btn-success">保存修改</button>
|
||||||
|
|
||||||
<button ms-click="cancelEdit()" class="btn btn-danger">取消</button>
|
<button ms-click="cancelEdit()" class="btn btn-danger">取消</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3>添加公告</h3>
|
<h3>发布公告</h3>
|
||||||
|
|
||||||
<form id="announcement-form">
|
<form id="announcement-form">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -89,31 +67,7 @@
|
|||||||
|
|
||||||
<div class="help-block with-errors"></div>
|
<div class="help-block with-errors"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label>可见范围</label>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<span ms-if="showGlobalViewRadio">
|
|
||||||
<label>
|
|
||||||
<small><input type="radio" value="true" name="isGlobal" ms-duplex-boolean="isGlobal">全局可见
|
|
||||||
</small>
|
|
||||||
</label>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<label>
|
|
||||||
<small><input type="radio" value="false" name="isGlobal" ms-duplex-boolean="isGlobal">小组内可见
|
|
||||||
</small>
|
|
||||||
</label>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-12" ms-if="!isGlobal">
|
|
||||||
<!-- radio 的value 没有用 但是没有的话,表单验证会出错-->
|
|
||||||
<div ms-repeat="allGroups" class="col-md-4">
|
|
||||||
<input type="checkbox" value="group_id" ms-duplex-checked="el.isSelected"> {{ el.name }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button type="submit" class="btn btn-success">发布公告</button>
|
<button type="submit" class="btn btn-success">发布公告</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from announcement.models import Announcement
|
|||||||
|
|
||||||
|
|
||||||
def public_announcement_list():
|
def public_announcement_list():
|
||||||
return Announcement.objects.filter(is_global=True, visible=True).order_by("-create_time")
|
return Announcement.objects.filter(visible=True).order_by("-create_time")
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
register.assignment_tag(public_announcement_list, name="public_announcement_list")
|
register.assignment_tag(public_announcement_list, name="public_announcement_list")
|
||||||
Reference in New Issue
Block a user