forked from Open-CT/OpenPBL
fix: bug modify (#12)
* fix: get server url * refactor: fix ui * feat: message list * refactor: rename to web * feat: support redis endpoint * fix: redis session * docs: update README * fix: skip preflight check * docs: update README
This commit is contained in:
parent
8e3c8a7d78
commit
fb330b43f8
|
@ -8,11 +8,11 @@ RUN go env -w CGO_ENABLED=0 GOPROXY=https://goproxy.io,direct GOOS=linux GOARCH=
|
|||
ENV PATH=$PATH:/openpbl/node-v12.22.0-linux-x64/bin
|
||||
RUN npm install -g yarn
|
||||
|
||||
COPY openpbl-landing/package.json /openpbl/openpbl-landing/package.json
|
||||
RUN cd openpbl-landing && yarn install
|
||||
COPY web/package.json /openpbl/web/package.json
|
||||
RUN cd web && yarn install
|
||||
|
||||
COPY openpbl-landing /openpbl/openpbl-landing
|
||||
RUN cd openpbl-landing && yarn build && rm -rf node_modules
|
||||
COPY web /openpbl/web
|
||||
RUN cd web && yarn build && rm -rf node_modules
|
||||
|
||||
COPY ./ /openpbl
|
||||
RUN cd /openpbl && go build main.go
|
||||
|
|
|
@ -9,8 +9,6 @@ System of PBL.
|
|||
`web/.env`
|
||||
|
||||
```dotenv
|
||||
REACT_APP_BASE_URL='http://localhost:5000/api'
|
||||
|
||||
REACT_APP_OSS_REGION='oss-cn-hangzhou'
|
||||
REACT_APP_OSS_ACCESSKEYID=
|
||||
REACT_APP_OSS_ACCESSKEYSECRET=
|
||||
|
@ -23,6 +21,7 @@ REACT_APP_APP_NAME=
|
|||
REACT_APP_CASDOOR_ORGANIZATION='openct'
|
||||
|
||||
GENERATE_SOURCEMAP=false
|
||||
SKIP_PREFLIGHT_CHECK=true
|
||||
```
|
||||
|
||||
```bash
|
||||
|
@ -56,6 +55,7 @@ driverName = mysql
|
|||
dataSourceName = root:123@tcp(localhost:3306)/
|
||||
dbName = openpbl_db
|
||||
|
||||
redisEndpoint =
|
||||
jwtSecret = CasdoorSecret
|
||||
|
||||
casdoorEndpoint =
|
||||
|
|
|
@ -11,6 +11,7 @@ driverName = mysql
|
|||
dataSourceName = root:123@tcp(localhost:3306)/
|
||||
dbName = openpbl_db
|
||||
|
||||
redisEndpoint =
|
||||
jwtSecret = CasdoorSecret
|
||||
|
||||
casdoorEndpoint =
|
||||
|
|
|
@ -3,6 +3,7 @@ package controllers
|
|||
import (
|
||||
"OpenPBL/models"
|
||||
"OpenPBL/util"
|
||||
"fmt"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor-go-sdk/auth"
|
||||
)
|
||||
|
@ -36,12 +37,14 @@ type MessagesResponse struct {
|
|||
// GetUserMessages
|
||||
// @Title
|
||||
// @Description
|
||||
// @Param type path string true "received sent"
|
||||
// @Param readType params string true "read unread all"
|
||||
// @Param messageType params string true "info warn error all"
|
||||
// @Param from params int false ""
|
||||
// @Param size params int false ""
|
||||
// @Param orderType params string false "desc asc"
|
||||
// @Success 200 {object} MessagesResponse
|
||||
// @Failure 400
|
||||
// @router /:type [get]
|
||||
// @router / [get]
|
||||
func (m *MessageController) GetUserMessages() {
|
||||
user := m.GetSessionUser()
|
||||
var resp ProjectResponse
|
||||
|
@ -62,16 +65,17 @@ func (m *MessageController) GetUserMessages() {
|
|||
if err != nil {
|
||||
size = 10
|
||||
}
|
||||
t := m.GetString(":type")
|
||||
orderType := m.GetString("orderType")
|
||||
r := m.GetString("readType")
|
||||
t := m.GetString("messageType")
|
||||
uid := util.GetUserId(user)
|
||||
|
||||
var messages []models.Message
|
||||
var rows int64
|
||||
if t == "received" {
|
||||
messages, rows, err = models.GetReceivedMessages(uid, "desc", from, size)
|
||||
} else if t == "sent" {
|
||||
messages, rows, err = models.GetSentMessages(uid, "desc", from, size)
|
||||
}
|
||||
messages, rows, err = models.GetMessages(uid, orderType, t, r, from, size)
|
||||
|
||||
fmt.Println(err)
|
||||
|
||||
if err != nil {
|
||||
m.Data["json"] = MessagesResponse{
|
||||
Code: 400,
|
||||
|
@ -85,3 +89,121 @@ func (m *MessageController) GetUserMessages() {
|
|||
}
|
||||
m.ServeJSON()
|
||||
}
|
||||
|
||||
// ReadUserMessage
|
||||
// @Title
|
||||
// @Description
|
||||
// @Param messageId path string true ""
|
||||
// @Success 200 {object} Response
|
||||
// @Failure 400
|
||||
// @router /:messageId/read [post]
|
||||
func (m *MessageController) ReadUserMessage() {
|
||||
user := m.GetSessionUser()
|
||||
var resp ProjectResponse
|
||||
if user == nil {
|
||||
resp = ProjectResponse{
|
||||
Code: 401,
|
||||
Msg: "请先登录",
|
||||
}
|
||||
m.Data["json"] = resp
|
||||
m.ServeJSON()
|
||||
return
|
||||
}
|
||||
uid := util.GetUserId(user)
|
||||
mid, err := m.GetInt64(":messageId")
|
||||
err = models.ReadMessage(mid, uid)
|
||||
if err != nil {
|
||||
m.Data["json"] = Response{
|
||||
Code: 400,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
} else {
|
||||
m.Data["json"] = Response{
|
||||
Code: 200,
|
||||
}
|
||||
}
|
||||
m.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteUserMessage
|
||||
// @Title
|
||||
// @Description
|
||||
// @Param messageId path string true ""
|
||||
// @Success 200 {object} Response
|
||||
// @Failure 400
|
||||
// @router /:messageId/delete [post]
|
||||
func (m *MessageController) DeleteUserMessage() {
|
||||
user := m.GetSessionUser()
|
||||
var resp ProjectResponse
|
||||
if user == nil {
|
||||
resp = ProjectResponse{
|
||||
Code: 401,
|
||||
Msg: "请先登录",
|
||||
}
|
||||
m.Data["json"] = resp
|
||||
m.ServeJSON()
|
||||
return
|
||||
}
|
||||
uid := util.GetUserId(user)
|
||||
mid, err := m.GetInt64(":messageId")
|
||||
msg := models.Message{
|
||||
Id: mid,
|
||||
ReceiverId: uid,
|
||||
}
|
||||
err = msg.Delete()
|
||||
if err != nil {
|
||||
m.Data["json"] = Response{
|
||||
Code: 400,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
} else {
|
||||
m.Data["json"] = Response{
|
||||
Code: 200,
|
||||
}
|
||||
}
|
||||
m.ServeJSON()
|
||||
}
|
||||
|
||||
// ReadAllUserMessage
|
||||
// @Title
|
||||
// @Description
|
||||
// @Success 200 {object} Response
|
||||
// @Failure 400
|
||||
// @router /read-all [post]
|
||||
func (m *MessageController) ReadAllUserMessage() {
|
||||
user := m.GetSessionUser()
|
||||
var resp ProjectResponse
|
||||
if user == nil {
|
||||
resp = ProjectResponse{
|
||||
Code: 401,
|
||||
Msg: "请先登录",
|
||||
}
|
||||
m.Data["json"] = resp
|
||||
m.ServeJSON()
|
||||
return
|
||||
}
|
||||
uid := util.GetUserId(user)
|
||||
err := models.ReadAllMessage(uid)
|
||||
if err != nil {
|
||||
m.Data["json"] = Response{
|
||||
Code: 400,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
} else {
|
||||
m.Data["json"] = Response{
|
||||
Code: 200,
|
||||
}
|
||||
}
|
||||
m.ServeJSON()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func CreateMessage(msg *models.Message) bool {
|
||||
err := msg.Create()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -16,4 +16,4 @@ services:
|
|||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
volumes:
|
||||
- /usr/local/docker/openpbl-mysql:/var/lib/mysql
|
||||
- /usr/local/docker/mysql:/var/lib/mysql
|
1
go.sum
1
go.sum
|
@ -126,6 +126,7 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
|||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
|
|
14
main.go
14
main.go
|
@ -9,6 +9,7 @@ import (
|
|||
"flag"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/plugins/cors"
|
||||
_ "github.com/astaxie/beego/session/redis"
|
||||
"log"
|
||||
)
|
||||
|
||||
|
@ -20,11 +21,11 @@ func main() {
|
|||
var err error
|
||||
configPath := util.GetConfigFile(mode)
|
||||
err = beego.LoadAppConfig("ini", configPath)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Println("App start with runmode: " + mode)
|
||||
log.Println("Load config file: " + configPath)
|
||||
models.InitAdapter()
|
||||
controllers.InitCasdoor()
|
||||
|
||||
|
@ -39,15 +40,20 @@ func main() {
|
|||
beego.BConfig.WebConfig.DirectoryIndex = true
|
||||
beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
|
||||
}
|
||||
beego.SetStaticPath("/static", "openpbl-landing/build/static")
|
||||
beego.SetStaticPath("/static", "web/build/static")
|
||||
beego.BConfig.WebConfig.DirectoryIndex = true
|
||||
beego.InsertFilter("/", beego.BeforeRouter, routers.TransparentStatic)
|
||||
beego.InsertFilter("/*", beego.BeforeRouter, routers.TransparentStatic)
|
||||
|
||||
beego.BConfig.WebConfig.Session.SessionName = "openct_session_id"
|
||||
beego.BConfig.WebConfig.Session.SessionName = "openpbl_session_id"
|
||||
if beego.AppConfig.String("redisEndpoint") == "" {
|
||||
beego.BConfig.WebConfig.Session.SessionProvider = "file"
|
||||
beego.BConfig.WebConfig.Session.SessionProviderConfig = "./tmp"
|
||||
beego.BConfig.WebConfig.Session.SessionGCMaxLifetime = 3600 * 24 * 365
|
||||
} else {
|
||||
beego.BConfig.WebConfig.Session.SessionProvider = "redis"
|
||||
beego.BConfig.WebConfig.Session.SessionProviderConfig = beego.AppConfig.String("redisEndpoint")
|
||||
}
|
||||
beego.BConfig.WebConfig.Session.SessionGCMaxLifetime = 3600 * 24 * 30
|
||||
|
||||
beego.Run()
|
||||
}
|
||||
|
|
|
@ -100,6 +100,8 @@ func (a *Adapter) createTable() {
|
|||
|
||||
new(ProjectSkill),
|
||||
new(ProjectSubject),
|
||||
|
||||
new(Message),
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
|
|
@ -6,21 +6,17 @@ import (
|
|||
)
|
||||
|
||||
type Message struct {
|
||||
Id int64 `json:"id" xorm:"not null pk"`
|
||||
ReceiverId string `json:"receiverId" xorm:"not null index"`
|
||||
Id int64 `json:"id" xorm:"not null pk autoincr"`
|
||||
ReceiverId string `json:"receiverId" xorm:"index"`
|
||||
|
||||
SenderId string `json:"senderId" xorm:"index"`
|
||||
SenderName string `json:"senderName"`
|
||||
MessageType string `json:"messageType" xorm:"not null index"` // warn error info
|
||||
|
||||
ProjectId int64 `json:"projectId" xorm:"index"`
|
||||
ProjectTitle string `json:"projectTitle"`
|
||||
|
||||
MessageType string `json:"messageType" xorm:"not null index"` // remind message
|
||||
Content string `json:"content" xorm:"text"`
|
||||
MessageTitle string `json:"messageTitle" xorm:"text"`
|
||||
Content string `json:"content" xorm:"longtext"`
|
||||
|
||||
Read bool `json:"read" xorm:"default false index"`
|
||||
|
||||
CreateAt time.Time `json:"CreateAt" xorm:"created"`
|
||||
CreateAt time.Time `json:"createAt" xorm:"created"`
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,34 +33,50 @@ func (m *Message) Delete() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func ReadMessage(messageId int64) (err error) {
|
||||
func ReadMessage(messageId int64, uid string) (err error) {
|
||||
_, err = (&Message{}).GetEngine().
|
||||
ID(messageId).
|
||||
Update(&Message{
|
||||
Id: messageId,
|
||||
ReceiverId: uid,
|
||||
Read: true,
|
||||
})
|
||||
return
|
||||
}
|
||||
func ReadAllMessage(uid string) (err error) {
|
||||
_, err = (&Message{}).GetEngine().
|
||||
Update(&Message{
|
||||
ReceiverId: uid,
|
||||
Read: true,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func GetReceivedMessages(uid string, orderType string, from int, size int) (m []Message, rows int64, err error) {
|
||||
err = (&Message{}).GetEngine().
|
||||
Where("receiver_id = ?", uid).
|
||||
Desc("create_at").
|
||||
Limit(size, from).
|
||||
Find(&m)
|
||||
rows, err = (&Message{}).GetEngine().
|
||||
Count(&Message{ReceiverId: uid})
|
||||
return
|
||||
func GetMessages(uid string, orderType string, messageType string, read string, from int, size int) (m []Message, rows int64, err error) {
|
||||
s := (&Message{}).GetEngine().
|
||||
Where("receiver_id = ?", uid)
|
||||
s2 := (&Message{}).GetEngine().
|
||||
Where("receiver_id = ?", uid)
|
||||
if read == "read" {
|
||||
s = s.Where("read = true")
|
||||
s2 = s2.Where("read = true")
|
||||
} else if read == "unread" {
|
||||
s = s.Where("read = false")
|
||||
s2 = s2.Where("read = false")
|
||||
}
|
||||
if messageType == "error" || messageType == "info" || messageType == "warn" {
|
||||
s = s.Where("message_type = ?", messageType)
|
||||
s2 = s2.Where("message_type = ?", messageType)
|
||||
}
|
||||
|
||||
func GetSentMessages(uid string, orderType string, from int, size int) (m []Message, rows int64, err error) {
|
||||
err = (&Message{}).GetEngine().
|
||||
Where("sender_id = ?", uid).
|
||||
Desc("create_at").
|
||||
Limit(size, from).
|
||||
Find(&m)
|
||||
rows, err = (&Message{}).GetEngine().
|
||||
Count(&Message{SenderId: uid})
|
||||
rows, err = s2.Count()
|
||||
|
||||
if orderType == "asc" {
|
||||
s = s.Asc("create_at")
|
||||
} else {
|
||||
s = s.Desc("create_at")
|
||||
}
|
||||
|
||||
err = s.Limit(size, from).Find(&m)
|
||||
return
|
||||
}
|
|
@ -37,7 +37,7 @@ func init() {
|
|||
beego.GlobalControllerRouter["OpenPBL/controllers:MessageController"] = append(beego.GlobalControllerRouter["OpenPBL/controllers:MessageController"],
|
||||
beego.ControllerComments{
|
||||
Method: "GetUserMessages",
|
||||
Router: "/:type",
|
||||
Router: "/",
|
||||
AllowHTTPMethods: []string{"get"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
|
|
|
@ -13,7 +13,7 @@ func TransparentStatic(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
path := "openpbl-landing/build"
|
||||
path := "web/build"
|
||||
if urlPath == "/" {
|
||||
path += "/index.html"
|
||||
} else {
|
||||
|
@ -21,7 +21,7 @@ func TransparentStatic(ctx *context.Context) {
|
|||
}
|
||||
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
http.ServeFile(ctx.ResponseWriter, ctx.Request, "openpbl-landing/build/index.html")
|
||||
http.ServeFile(ctx.ResponseWriter, ctx.Request, "web/build/index.html")
|
||||
} else {
|
||||
http.ServeFile(ctx.ResponseWriter, ctx.Request, path)
|
||||
}
|
||||
|
|
|
@ -35,6 +35,10 @@ func init() {
|
|||
beego.NSInclude(
|
||||
&controllers.StudentController{})),
|
||||
|
||||
beego.NSNamespace("/message",
|
||||
beego.NSInclude(
|
||||
&controllers.MessageController{})),
|
||||
|
||||
)
|
||||
beego.AddNamespace(ns)
|
||||
}
|
||||
|
|
3
web/.env
3
web/.env
|
@ -1,5 +1,3 @@
|
|||
REACT_APP_BASE_URL='http://localhost:5000/api'
|
||||
|
||||
REACT_APP_OSS_REGION='oss-cn-hangzhou'
|
||||
REACT_APP_OSS_ACCESSKEYID=
|
||||
REACT_APP_OSS_ACCESSKEYSECRET=
|
||||
|
@ -12,3 +10,4 @@ REACT_APP_APP_NAME=
|
|||
REACT_APP_CASDOOR_ORGANIZATION='openct'
|
||||
|
||||
GENERATE_SOURCEMAP=false
|
||||
SKIP_PREFLIGHT_CHECK=true
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "openpbl-landing",
|
||||
"name": "web",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import request from "./request";
|
||||
import qs from 'qs'
|
||||
|
||||
const MessageApi = {
|
||||
getUserMessages(query) {
|
||||
return request({
|
||||
url: `/message`,
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
},
|
||||
readMessage(m) {
|
||||
return request({
|
||||
url: `/message/${m.id}/read`,
|
||||
method: 'post',
|
||||
data: qs.stringify(m)
|
||||
})
|
||||
},
|
||||
readAllMessage() {
|
||||
return request({
|
||||
url: `/message/read-all`,
|
||||
method: 'post',
|
||||
})
|
||||
},
|
||||
deleteMessage(m) {
|
||||
return request({
|
||||
url: `/message/${m.id}/delete`,
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default MessageApi
|
|
@ -1,8 +1,16 @@
|
|||
import axios from 'axios'
|
||||
import {message} from 'antd'
|
||||
|
||||
function getServerUrl() {
|
||||
const hostname = window.location.hostname
|
||||
if (hostname === 'localhost') {
|
||||
return `http://${hostname}:5000/api`
|
||||
}
|
||||
return '/api'
|
||||
}
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: process.env.REACT_APP_BASE_URL,
|
||||
baseURL: getServerUrl(),
|
||||
timeout: 10000,
|
||||
withCredentials: true
|
||||
})
|
||||
|
|
|
@ -1,9 +1,41 @@
|
|||
import React from "react";
|
||||
import React, {useState} from "react";
|
||||
|
||||
|
||||
import MessageList from "../component/MessageList";
|
||||
import MessageApi from "../../../api/MessageApi"
|
||||
|
||||
function AllMessage() {
|
||||
const [messages, setMessages] = useState([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [total, setTotal] = useState(0)
|
||||
|
||||
const updateMessageList = (from, size) => {
|
||||
setLoading(true)
|
||||
const query = {
|
||||
readType: 'all',
|
||||
messageType: 'all',
|
||||
from: from,
|
||||
size: size,
|
||||
orderType: 'desc'
|
||||
}
|
||||
MessageApi.getUserMessages(query)
|
||||
.then(res=>{
|
||||
setLoading(false)
|
||||
if (res.data.code === 200) {
|
||||
setMessages(res.data.messages)
|
||||
setTotal(res.data.count)
|
||||
}
|
||||
})
|
||||
.catch(e=>{console.log(e)})
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
all message
|
||||
<MessageList
|
||||
loading={loading}
|
||||
total={total}
|
||||
updateMessageList={updateMessageList}
|
||||
messages={messages}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import React from "react";
|
||||
import MessageList from "../component/MessageList";
|
||||
|
||||
function Communication() {
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default Communication
|
|
@ -0,0 +1,77 @@
|
|||
import React, {useEffect, useState} from "react";
|
||||
import {Button, Pagination, Table} from "antd";
|
||||
|
||||
import util from "../../component/Util"
|
||||
|
||||
function MessageList(obj) {
|
||||
const [page, setPage] = useState(1)
|
||||
const [pageSize, setPageSize] = useState(10)
|
||||
|
||||
useEffect(()=>{
|
||||
obj.updateMessageList(page - 1, pageSize);
|
||||
}, [])
|
||||
|
||||
const changePage = p => {
|
||||
setPage(p)
|
||||
obj.updateMessageList((p-1)*pageSize, pageSize)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table
|
||||
loading={obj.loading}
|
||||
dataSource={obj.messages}
|
||||
columns={[
|
||||
{
|
||||
title: '标题',
|
||||
dataIndex: 'messageTitle',
|
||||
key: 'messageTitle'
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'createAt',
|
||||
key: 'createAt',
|
||||
render: (text, item, index) => (
|
||||
<>
|
||||
{util.FilterMoment(text)}
|
||||
</>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
dataIndex: 'messageType',
|
||||
key: 'messageType',
|
||||
render: (text, item, index) => (
|
||||
<>
|
||||
{text === 'warning' ? '警告': null}
|
||||
{text === 'info' ? '信息': null}
|
||||
{text === 'error' ? '错误': null}
|
||||
</>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
render: (text, item, index) => (
|
||||
<>
|
||||
<Button>未读</Button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
]}
|
||||
pagination={false}
|
||||
/>
|
||||
<Pagination
|
||||
total={obj.total}
|
||||
showTotal={t => `共${obj.total}条消息`}
|
||||
current={page}
|
||||
onChange={changePage}
|
||||
onShowSizeChange={()=>obj.updateMessageList(page-1, pageSize)}
|
||||
style={{margin: '20px', textAlign: 'right'}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MessageList
|
|
@ -1,12 +1,12 @@
|
|||
import React from "react";
|
||||
import DocumentTitle from "react-document-title";
|
||||
import {Affix, Layout, Menu} from "antd";
|
||||
|
||||
import {Link, Redirect, Route, Switch} from "react-router-dom";
|
||||
|
||||
import AllMessage from "./AllMessage";
|
||||
import UnreadMessage from "./UnreadMessage";
|
||||
import ReadMessage from "./ReadMessage";
|
||||
import Communication from "./Communication";
|
||||
|
||||
class Message extends React.Component {
|
||||
state = {
|
||||
|
@ -32,12 +32,20 @@ class Message extends React.Component {
|
|||
未读消息
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="read-message">已读消息</Menu.Item>
|
||||
<Menu.Item key="remind">留言沟通</Menu.Item>
|
||||
<Menu.Item key="read-message">
|
||||
<Link to="/message/read">
|
||||
已读消息
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="remind">
|
||||
<Link to="/message/communication">
|
||||
留言沟通
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
</Layout.Sider>
|
||||
</Affix>
|
||||
<Layout.Content style={{backgroundColor: 'white'}}>
|
||||
<Layout.Content style={{backgroundColor: 'white', marginLeft: '10px'}}>
|
||||
<Switch>
|
||||
<Route exact path="/message" render={() => (
|
||||
<Redirect to="/message/all"/>
|
||||
|
@ -45,6 +53,7 @@ class Message extends React.Component {
|
|||
<Route exact path="/message/all" component={AllMessage}/>
|
||||
<Route exact path="/message/unread" component={UnreadMessage}/>
|
||||
<Route exact path="/message/read" component={ReadMessage}/>
|
||||
<Route exact path="/message/communication" component={Communication}/>
|
||||
</Switch>
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
|
|
|
@ -6,7 +6,7 @@ import {Link} from 'react-router-dom'
|
|||
import ChapterApi from "../../../../../api/ChapterApi"
|
||||
import SectionApi from "../../../../../api/SectionApi"
|
||||
|
||||
import util from "../../../component/Util"
|
||||
import util from "../../../../component/Util"
|
||||
|
||||
const {SubMenu} = Menu;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import {Button, Collapse, Divider, InputNumber, List, message, Progress, Tooltip
|
|||
import TaskApi from "../../../../api/TaskApi";
|
||||
import ChapterApi from "../../../../api/ChapterApi";
|
||||
import TaskCard from "../../PreviewProject/component/TaskCard";
|
||||
import util from "../../component/Util"
|
||||
import util from "../../../component/Util"
|
||||
import SubmitApi from "../../../../api/SubmitApi";
|
||||
|
||||
function StudentEvidence(obj) {
|
||||
|
|
|
@ -31,7 +31,7 @@ class MyProject extends React.PureComponent {
|
|||
const {type} = this.state
|
||||
return (
|
||||
<DocumentTitle title="My Project">
|
||||
<Layout>
|
||||
<Layout style={{margin: '20px'}}>
|
||||
<Affix offsetTop={0}>
|
||||
<Layout.Sider
|
||||
breakpoint="lg"
|
||||
|
@ -95,7 +95,7 @@ class MyProject extends React.PureComponent {
|
|||
}
|
||||
</Layout.Sider>
|
||||
</Affix>
|
||||
<Layout.Content>
|
||||
<Layout.Content style={{marginLeft: '10px'}}>
|
||||
{type === 'teacher' ?
|
||||
<Switch>
|
||||
<Route exact path="/my-project" render={() => (
|
||||
|
|
|
@ -6,7 +6,7 @@ import SectionApi from "../../../api/SectionApi";
|
|||
import "../CreateProject/Section/component/section-edit.less"
|
||||
import "./preview.less"
|
||||
import TaskApi from "../../../api/TaskApi";
|
||||
import util from "../component/Util"
|
||||
import util from "../../component/Util"
|
||||
import StudentApi from "../../../api/StudentApi";
|
||||
import TaskCard from "./component/TaskCard";
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import TaskApi from "../../../../api/TaskApi";
|
|||
import ProjectApi from "../../../../api/ProjectApi";
|
||||
import ChapterApi from "../../../../api/ChapterApi";
|
||||
import SectionApi from "../../../../api/SectionApi";
|
||||
import util from "../../component/Util"
|
||||
import util from "../../../component/Util"
|
||||
import "./index.less"
|
||||
|
||||
const {SubMenu} = Menu
|
||||
|
|
|
@ -3,7 +3,7 @@ import {Menu, message, Progress} from 'antd'
|
|||
import QueueAnim from 'rc-queue-anim';
|
||||
|
||||
import ChapterApi from "../../../../api/ChapterApi";
|
||||
import util from "../../component/Util"
|
||||
import util from "../../../component/Util"
|
||||
|
||||
const {SubMenu} = Menu;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import {Avatar, Button, message, Pagination, Popconfirm, Table} from "antd";
|
|||
import {DeleteOutlined} from "@ant-design/icons"
|
||||
|
||||
import ProjectApi from "../../../../api/ProjectApi";
|
||||
import util from "../../component/Util"
|
||||
import util from "../../../component/Util"
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
function StudentAdmin(obj) {
|
||||
|
|
|
@ -14,7 +14,7 @@ import StudentApi from "../../../api/StudentApi";
|
|||
import StudentAdmin from "./component/StudentAdmin";
|
||||
import {getUser} from "../../User/Auth/Auth";
|
||||
import {DeleteOutlined} from "@ant-design/icons";
|
||||
import util from "../component/Util"
|
||||
import util from "../../component/Util"
|
||||
import StudentEvidence from "../Evidence/component/StudentEvidence";
|
||||
|
||||
class ProjectInfo extends React.PureComponent {
|
||||
|
|
|
@ -6,7 +6,7 @@ import {Link} from 'react-router-dom';
|
|||
|
||||
import './project-list.less';
|
||||
import ProjectListApi from '../../../api/ProjectListApi'
|
||||
import util from './Util'
|
||||
import util from '../../component/Util'
|
||||
|
||||
const {Meta} = Card;
|
||||
const {Search} = Input;
|
||||
|
|
Loading…
Reference in New Issue