Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion backend/system/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
from django.contrib import admin
from system.models import Notice

# Register your models here.
@admin.register(Notice)
class NoticeAdmin(admin.ModelAdmin):
list_display = ['title', 'notice_type', 'is_read', 'user', 'create_datetime']
list_filter = ['notice_type', 'is_read', 'create_datetime']
search_fields = ['title', 'content']
ordering = ['-create_datetime']
readonly_fields = ['create_datetime', 'update_datetime']

fieldsets = (
(None, {
'fields': ('title', 'content', 'notice_type', 'is_read', 'user')
}),
('额外信息', {
'fields': ('extra', 'color', 'remark'),
'classes': ('collapse',)
}),
('时间信息', {
'fields': ('create_datetime', 'update_datetime'),
'classes': ('collapse',)
}),
)
123 changes: 123 additions & 0 deletions backend/system/apis/notice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
from typing import List

from django.shortcuts import get_object_or_404
from ninja import Field, ModelSchema, Query, Router, Schema
from ninja.pagination import paginate
from system.models import Notice
from utils.fu_crud import create, delete, retrieve, update
from utils.fu_ninja import FuFilters, MyPagination
from utils.fu_response import FuResponse
from utils.usual import get_user_info_from_token

router = Router()


class Filters(FuFilters):
title: str = Field(None, alias="title")
notice_type: int = Field(None, alias="notice_type")
is_read: bool = Field(None, alias="is_read")
user_id: int = Field(None, alias="user_id")


class SchemaIn(ModelSchema):
user_id: int = Field(None, alias="user")

class Config:
model = Notice
model_exclude = ['id', 'user', 'create_datetime', 'update_datetime']


class SchemaOut(ModelSchema):
class Config:
model = Notice
model_fields = '__all__'


class MarkReadSchema(Schema):
notice_ids: List[int] = Field(..., alias="notice_ids")


@router.post("/notice", response=SchemaOut)
def create_notice(request, data: SchemaIn):
notice = create(request, data.dict(), Notice)
return notice


@router.delete("/notice/{notice_id}")
def delete_notice(request, notice_id: int):
delete(notice_id, Notice)
return {"success": True}


@router.put("/notice/{notice_id}", response=SchemaOut)
def update_notice(request, notice_id: int, payload: SchemaIn):
notice = update(request, notice_id, payload, Notice)
return notice


@router.get("/notice", response=List[SchemaOut])
@paginate(MyPagination)
def list_notice(request, filters: Filters = Query(...)):
qs = retrieve(request, Notice, filters)
return qs


@router.get("/notice/all/list", response=List[SchemaOut])
def all_list_notice(request):
qs = retrieve(request, Notice)
return qs


@router.get("/notice/{notice_id}", response=SchemaOut)
def get_notice(request, notice_id: int):
notice = get_object_or_404(Notice, id=notice_id)
return notice


@router.get("/notice/my/list", response=List[SchemaOut])
def list_my_notice(request, notice_type: int = None, is_read: bool = None):
user_info = get_user_info_from_token(request)
user_id = user_info['id']
filters = Filters(user_id=user_id)
if notice_type is not None:
filters.notice_type = notice_type
if is_read is not None:
filters.is_read = is_read
qs = retrieve(request, Notice, filters)
return qs


@router.get("/notice/my/unread/count")
def get_my_unread_count(request):
user_info = get_user_info_from_token(request)
user_id = user_info['id']
count = Notice.objects.filter(user_id=user_id, is_read=False).count()
return {"count": count}


@router.put("/notice/mark/read/{notice_id}")
def mark_read(request, notice_id: int):
notice = get_object_or_404(Notice, id=notice_id)
notice.is_read = True
notice.save()
return {"success": True}


@router.put("/notice/mark/read/all")
def mark_all_read(request):
user_info = get_user_info_from_token(request)
user_id = user_info['id']
Notice.objects.filter(user_id=user_id, is_read=False).update(is_read=True)
return {"success": True}


@router.put("/notice/mark/read/batch")
def mark_batch_read(request, data: MarkReadSchema):
user_info = get_user_info_from_token(request)
user_id = user_info['id']
Notice.objects.filter(
user_id=user_id,
id__in=data.notice_ids,
is_read=False
).update(is_read=True)
return {"success": True}
25 changes: 25 additions & 0 deletions backend/system/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import hashlib
import os

from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.db import models
from utils.models import CoreModel
Expand Down Expand Up @@ -410,3 +411,27 @@ class Meta:
verbose_name = '代码生成器模板'
verbose_name_plural = verbose_name
ordering = ('-create_datetime',)


class Notice(CoreModel):
NOTICE_TYPE_CHOICES = (
(0, "通知"),
(1, "消息"),
(2, "待办"),
)
title = models.CharField(max_length=255, verbose_name="标题", help_text="标题")
content = models.TextField(verbose_name="内容", help_text="内容", null=True, blank=True)
notice_type = models.IntegerField(choices=NOTICE_TYPE_CHOICES, default=0, verbose_name="消息类型", help_text="消息类型(0:通知 1:消息 2:待办)")
is_read = models.BooleanField(default=False, verbose_name="是否已读", help_text="是否已读")
user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="接收用户", help_text="接收用户", on_delete=models.CASCADE, db_constraint=False, related_name='notices')
extra = models.CharField(max_length=64, verbose_name="额外信息", help_text="额外信息(如状态标签)", null=True, blank=True)
color = models.CharField(max_length=32, verbose_name="标签颜色", help_text="标签颜色", null=True, blank=True)

class Meta:
db_table = "system_notice"
verbose_name = '消息通知'
verbose_name_plural = verbose_name
ordering = ('-create_datetime',)

def __str__(self):
return self.title
2 changes: 2 additions & 0 deletions backend/system/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from system.apis.monitor import router as monitor_router
from system.apis.menu_column import router as menu_column_field_router
from system.apis.code_generator import router as generator_template_router
from system.apis.notice import router as notice_router

system_router = Router()
system_router.add_router('/', dept_router, tags=["Dept"])
Expand All @@ -49,3 +50,4 @@
system_router.add_router('/', monitor_router, tags=["Monitor"])
system_router.add_router('/', menu_column_field_router, tags=["MenuColumnField"])
system_router.add_router('/', generator_template_router, tags=["GeneratorTemplate"])
system_router.add_router('/', notice_router, tags=["Notice"])
46 changes: 46 additions & 0 deletions web/src/api/sys/model/noticeModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
export interface NoticeModel {
id: number;
title: string;
content: string;
notice_type: number;
is_read: boolean;
user: number;
extra: string;
color: string;
remark: string;
create_datetime: string;
update_datetime: string;
creator: number;
modifier: string;
belong_dept: number;
sort: number;
}

export interface NoticeListItem {
id: string;
avatar: string;
title: string;
titleDelete?: boolean;
datetime: string;
type: string;
read?: boolean;
description: string;
clickClose?: boolean;
extra?: string;
color?: string;
}

export interface NoticeTabItem {
key: string;
name: string;
list: NoticeListItem[];
unreadlist?: NoticeListItem[];
}

export interface UnreadCountModel {
count: number;
}

export interface MarkReadParams {
notice_ids: number[];
}
70 changes: 70 additions & 0 deletions web/src/api/sys/notice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { defHttp } from '/@/utils/http/axios';
import { NoticeModel, UnreadCountModel, MarkReadParams } from './model/noticeModel';

enum Api {
NoticeList = '/api/system/notice',
NoticeMyList = '/api/system/notice/my/list',
NoticeUnreadCount = '/api/system/notice/my/unread/count',
NoticeMarkRead = '/api/system/notice/mark/read',
NoticeMarkAllRead = '/api/system/notice/mark/read/all',
NoticeMarkBatchRead = '/api/system/notice/mark/read/batch',
}

export function getNoticeList(params?: Recordable) {
return defHttp.get<NoticeModel[]>({
url: Api.NoticeList,
params,
});
}

export function getMyNoticeList(params?: { notice_type?: number; is_read?: boolean }) {
return defHttp.get<NoticeModel[]>({
url: Api.NoticeMyList,
params,
});
}

export function getUnreadCount() {
return defHttp.get<UnreadCountModel>({
url: Api.NoticeUnreadCount,
});
}

export function markNoticeRead(noticeId: number) {
return defHttp.put<{ success: boolean }>({
url: `${Api.NoticeMarkRead}/${noticeId}`,
});
}

export function markAllNoticeRead() {
return defHttp.put<{ success: boolean }>({
url: Api.NoticeMarkAllRead,
});
}

export function markBatchNoticeRead(params: MarkReadParams) {
return defHttp.put<{ success: boolean }>({
url: Api.NoticeMarkBatchRead,
params,
});
}

export function createNotice(data: Partial<NoticeModel>) {
return defHttp.post<NoticeModel>({
url: Api.NoticeList,
params: data,
});
}

export function updateNotice(noticeId: number, data: Partial<NoticeModel>) {
return defHttp.put<NoticeModel>({
url: `${Api.NoticeList}/${noticeId}`,
params: data,
});
}

export function deleteNotice(noticeId: number) {
return defHttp.delete<{ success: boolean }>({
url: `${Api.NoticeList}/${noticeId}`,
});
}
Loading