mirror of
https://github.com/balzack/databag.git
synced 2025-02-11 19:19:16 +00:00
adding channel summary method
This commit is contained in:
parent
0416389be0
commit
8e14f51d58
39
doc/api.oa3
39
doc/api.oa3
@ -2144,6 +2144,37 @@ paths:
|
||||
'500':
|
||||
description: internal server error
|
||||
|
||||
/content/channels/{channelId}/summary:
|
||||
get:
|
||||
tags:
|
||||
- content
|
||||
description: Get summary of channel.
|
||||
operationId: get-channel-summary
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: channelId
|
||||
in: path
|
||||
description: specified channel id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ChannelSummary'
|
||||
'401':
|
||||
description: invalid password
|
||||
'404':
|
||||
description: channel not found
|
||||
'410':
|
||||
description: account disabled
|
||||
'500':
|
||||
description: internal server error
|
||||
|
||||
/content/channels/{channelId}:
|
||||
delete:
|
||||
tags:
|
||||
@ -3439,6 +3470,8 @@ components:
|
||||
topicRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
channelSummary:
|
||||
$ref: '#/components/schemas/ChannelSummary'
|
||||
channelDetail:
|
||||
$ref: '#/components/schemas/ChannelDetail'
|
||||
|
||||
@ -3466,6 +3499,12 @@ components:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
ChannelSummary:
|
||||
type: object
|
||||
properties:
|
||||
lastTopic:
|
||||
$ref: '#/components/schemas/TopicDetail'
|
||||
|
||||
ChannelContacts:
|
||||
type: object
|
||||
|
63
net/server/internal/api_getChannelDetail.go
Normal file
63
net/server/internal/api_getChannelDetail.go
Normal file
@ -0,0 +1,63 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetChannelDetail(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// scan parameters
|
||||
params := mux.Vars(r)
|
||||
channelId := params["channelId"]
|
||||
|
||||
var guid string
|
||||
var act *store.Account
|
||||
tokenType := ParamTokenType(r)
|
||||
if tokenType == APP_TOKENAGENT {
|
||||
account, code, err := ParamAgentToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
act = account
|
||||
} else if tokenType == APP_TOKENCONTACT {
|
||||
card, code, err := ParamContactToken(r, true)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
act = &card.Account
|
||||
guid = card.Guid
|
||||
} else {
|
||||
ErrResponse(w, http.StatusBadRequest, errors.New("unknown token type"))
|
||||
return
|
||||
}
|
||||
|
||||
// load channel
|
||||
var slot store.ChannelSlot
|
||||
if err := store.DB.Preload("Channel.Cards.CardSlot").Preload("Channel.Groups.Cards").Preload("Channel.Groups.GroupSlot").Where("account_id = ? AND channel_slot_id = ?", act.ID, channelId).First(&slot).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// return model data
|
||||
if guid != "" {
|
||||
if isChannelShared(guid, slot.Channel) {
|
||||
WriteResponse(w, getChannelDetailModel(&slot, false))
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("channel not shared with requestor"));
|
||||
return
|
||||
}
|
||||
} else {
|
||||
WriteResponse(w, getChannelDetailModel(&slot, true))
|
||||
}
|
||||
}
|
||||
|
65
net/server/internal/api_getChannelSummary.go
Normal file
65
net/server/internal/api_getChannelSummary.go
Normal file
@ -0,0 +1,65 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetChannelSummary(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// scan parameters
|
||||
params := mux.Vars(r)
|
||||
channelId := params["channelId"]
|
||||
|
||||
var guid string
|
||||
var act *store.Account
|
||||
tokenType := ParamTokenType(r)
|
||||
if tokenType == APP_TOKENAGENT {
|
||||
account, code, err := ParamAgentToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
act = account
|
||||
} else if tokenType == APP_TOKENCONTACT {
|
||||
card, code, err := ParamContactToken(r, true)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
act = &card.Account
|
||||
guid = card.Guid
|
||||
} else {
|
||||
ErrResponse(w, http.StatusBadRequest, errors.New("unknown token type"))
|
||||
return
|
||||
}
|
||||
|
||||
// load channel
|
||||
var slot store.ChannelSlot
|
||||
if err := store.DB.Preload("Channel.Topics", func(db *gorm.DB) *gorm.DB {
|
||||
return store.DB.Order("topics.id DESC").Limit(1)
|
||||
}).Preload("Channel.Cards.CardSlot").Preload("Channel.Groups.Cards").Preload("Channel.Groups.GroupSlot").Where("account_id = ? AND channel_slot_id = ?", act.ID, channelId).First(&slot).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// return model data
|
||||
if guid != "" {
|
||||
if isChannelShared(guid, slot.Channel) {
|
||||
WriteResponse(w, getChannelSummaryModel(&slot))
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("channel not shared with requestor"));
|
||||
return
|
||||
}
|
||||
} else {
|
||||
WriteResponse(w, getChannelSummaryModel(&slot))
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,9 @@ func GetChannels(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := store.DB.Preload("Channel.Cards.CardSlot").Preload("Channel.Groups.GroupSlot").Where("account_id = ? AND channel_id != 0", account.ID).Find(&slots).Error; err != nil {
|
||||
if err := store.DB.Preload("Channel.Topics", func(db *gorm.DB) *gorm.DB {
|
||||
return store.DB.Order("topics.id DESC").Limit(1)
|
||||
}).Preload("Channel.Cards.CardSlot").Preload("Channel.Groups.GroupSlot").Where("account_id = ? AND channel_id != 0", account.ID).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
@ -102,14 +104,14 @@ func GetChannels(w http.ResponseWriter, r *http.Request) {
|
||||
account := &card.Account
|
||||
var slots []store.ChannelSlot
|
||||
if channelRevisionSet {
|
||||
if err := store.DB.Preload("Channel.Topics", func(db *gorm.DB) *gorm.DB {
|
||||
return store.DB.Order("topics.id DESC").Limit(1)
|
||||
}).Preload("Channel.Cards").Preload("Channel.Groups.Cards").Where("account_id = ? AND revision > ?", account.ID, channelRevision).Find(&slots).Error; err != nil {
|
||||
if err := store.DB.Preload("Channel.Cards").Preload("Channel.Groups.Cards").Where("account_id = ? AND revision > ?", account.ID, channelRevision).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := store.DB.Preload("Channel.Cards").Preload("Channel.Groups.Cards").Where("account_id = ? AND channel_id != 0", account.ID).Find(&slots).Error; err != nil {
|
||||
if err := store.DB.Preload("Channel.Topics", func(db *gorm.DB) *gorm.DB {
|
||||
return store.DB.Order("topics.id DESC").Limit(1)
|
||||
}).Preload("Channel.Cards").Preload("Channel.Groups.Cards").Where("account_id = ? AND channel_id != 0", account.ID).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
@ -199,6 +199,27 @@ func getChannelDetailModel(slot *store.ChannelSlot, showList bool) *ChannelDetai
|
||||
}
|
||||
}
|
||||
|
||||
func getChannelSummaryModel(slot *store.ChannelSlot) *ChannelSummary {
|
||||
|
||||
if slot.Channel == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
topicDetail := TopicDetail{};
|
||||
if len(slot.Channel.Topics) > 0 {
|
||||
topicDetail.Guid = slot.Channel.Topics[0].Guid;
|
||||
topicDetail.DataType = slot.Channel.Topics[0].DataType;
|
||||
topicDetail.Data = slot.Channel.Topics[0].Data;
|
||||
topicDetail.Created = slot.Channel.Topics[0].Created;
|
||||
topicDetail.Updated = slot.Channel.Topics[0].Updated;
|
||||
topicDetail.Status = slot.Channel.Topics[0].Status;
|
||||
}
|
||||
|
||||
return &ChannelSummary{
|
||||
LastTopic: &topicDetail,
|
||||
}
|
||||
}
|
||||
|
||||
func getChannelModel(slot *store.ChannelSlot, showData bool, showList bool) *Channel {
|
||||
|
||||
if !showData || slot.Channel == nil {
|
||||
@ -215,6 +236,7 @@ func getChannelModel(slot *store.ChannelSlot, showData bool, showList bool) *Cha
|
||||
DetailRevision: slot.Channel.DetailRevision,
|
||||
TopicRevision: slot.Channel.TopicRevision,
|
||||
ChannelDetail: getChannelDetailModel(slot, showList),
|
||||
ChannelSummary: getChannelSummaryModel(slot),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +175,8 @@ type ChannelData struct {
|
||||
|
||||
TopicRevision int64 `json:"topicRevision"`
|
||||
|
||||
ChannelSummary *ChannelSummary `json:"channelSummary,omitempty"`
|
||||
|
||||
ChannelDetail *ChannelDetail `json:"channelDetail,omitempty"`
|
||||
}
|
||||
|
||||
@ -193,6 +195,11 @@ type ChannelDetail struct {
|
||||
Members []string `json:"members"`
|
||||
}
|
||||
|
||||
type ChannelSummary struct {
|
||||
|
||||
LastTopic *TopicDetail `json:"lastTopic,omitempty"`
|
||||
}
|
||||
|
||||
type ChannelParams struct {
|
||||
|
||||
DataType string `json:"dataType"`
|
||||
@ -443,7 +450,7 @@ type TopicDetail struct {
|
||||
|
||||
Status string `json:"status"`
|
||||
|
||||
Transform string `json:"transform"`
|
||||
Transform string `json:"transform,omitempty"`
|
||||
}
|
||||
|
||||
type TopicTags struct {
|
||||
|
@ -545,6 +545,13 @@ var routes = Routes{
|
||||
GetChannelDetail,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelSummary",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/summary",
|
||||
GetChannelSummary,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelSubjectField",
|
||||
strings.ToUpper("Get"),
|
||||
|
8
net/web/src/api/getChannelDetail.js
Normal file
8
net/web/src/api/getChannelDetail.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
|
||||
export async function getChannelDetail(token, channelId) {
|
||||
let detail = await fetchWithTimeout(`/content/channels/${channelId}/detail?agent=${token}`, { method: 'GET' });
|
||||
checkResponse(detail)
|
||||
return await detail.json()
|
||||
}
|
||||
|
8
net/web/src/api/getChannelSummary.js
Normal file
8
net/web/src/api/getChannelSummary.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
|
||||
export async function getChannelSummary(token, channelId) {
|
||||
let summary = await fetchWithTimeout(`/content/channels/${channelId}/summary?agent=${token}`, { method: 'GET' });
|
||||
checkResponse(summary)
|
||||
return await summary.json()
|
||||
}
|
||||
|
8
net/web/src/api/getContactChannelDetail.js
Normal file
8
net/web/src/api/getContactChannelDetail.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
|
||||
export async function getContactChannelDetail(token, channelId) {
|
||||
let detail = await fetchWithTimeout(`/content/channels/${channelId}/detail?contact=${token}`, { method: 'GET' });
|
||||
checkResponse(detail)
|
||||
return await detail.json()
|
||||
}
|
||||
|
8
net/web/src/api/getContactChannelSummary.js
Normal file
8
net/web/src/api/getContactChannelSummary.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
|
||||
export async function getContactChannelSummary(token, channelId) {
|
||||
let summary = await fetchWithTimeout(`/content/channels/${channelId}/summary?contact=${token}`, { method: 'GET' });
|
||||
checkResponse(summary)
|
||||
return await summary.json()
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { getContactChannels } from 'api/getContactChannels';
|
||||
import { getContactChannelDetail } from 'api/getContactChannelDetail';
|
||||
import { getContactChannelSummary } from 'api/getContactChannelSummary';
|
||||
import { getContactProfile } from 'api/getContactProfile';
|
||||
import { setCardProfile } from 'api/setCardProfile';
|
||||
import { getCards } from 'api/getCards';
|
||||
@ -116,15 +117,23 @@ export function useCardContext() {
|
||||
if (cur.data.detailRevision != channel.data.detailRevision) {
|
||||
if (channel.data.channelDetail != null) {
|
||||
cur.data.channelDetail = channel.data.channelDetail;
|
||||
cur.data.detailRevision = channel.data.detailRevision;
|
||||
}
|
||||
else {
|
||||
let detail = await getContactChannelDetail(guid + "." + token, channel.id);
|
||||
cur.data.channelDetail = detail;
|
||||
cur.data.detailRevision = channel.data.detailRevision;
|
||||
}
|
||||
cur.data.detailRevision = channel.data.detailRevision;
|
||||
}
|
||||
if (cur.data.detailRevision != channel.data.detailRevision) {
|
||||
if (channel.data.channelSummary != null) {
|
||||
cur.data.channelSummary = channel.data.channelSummary;
|
||||
}
|
||||
else {
|
||||
let summary = await getContactChannelSummary(guid + "." + token, channel.id);
|
||||
cur.data.channelSummary = summary;
|
||||
}
|
||||
cur.data.topicRevision = channel.data.topicRevision;
|
||||
}
|
||||
cur.data.topicRevision = channel.data.topicRevision;
|
||||
cur.revision = channel.revision;
|
||||
channelMap.set(channel.id, cur);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { getChannels } from 'api/getChannels';
|
||||
import { getChannelDetail } from 'api/getChannelDetail';
|
||||
import { getChannelSummary } from 'api/getChannelSummary';
|
||||
import { addChannel } from 'api/addChannel';
|
||||
import { addChannelTopic } from 'api/addChannelTopic';
|
||||
import { getChannelTopics } from 'api/getChannelTopics';
|
||||
@ -32,15 +33,23 @@ export function useChannelContext() {
|
||||
if (cur.data.detailRevision != channel.data.detailRevision) {
|
||||
if (channel.data.channelDetail != null) {
|
||||
cur.data.channelDetail = channel.data.channelDetail;
|
||||
cur.data.detailRevision = channel.data.detailRevision;
|
||||
}
|
||||
else {
|
||||
let detail = await getChannelDetail(access.current, channel.id);
|
||||
cur.data.channelDetail = detail;
|
||||
cur.data.detailRevision = channel.data.detailRevision;
|
||||
}
|
||||
cur.data.detailRevision = channel.data.detailRevision;
|
||||
}
|
||||
if (cur.data.topicRevision != channel.data.topicRevision) {
|
||||
if (channel.data.channelDetail != null) {
|
||||
cur.data.channelDetail = channel.data.channelDetail;
|
||||
}
|
||||
else {
|
||||
let summary = await getChannelSummary(access.current, channel.id);
|
||||
cur.data.channelSummary = summary;
|
||||
}
|
||||
cur.data.topicRevision = channel.data.topicRevision;
|
||||
}
|
||||
cur.data.topicRevision = channel.data.topicRevision;
|
||||
cur.revision = channel.revision;
|
||||
channels.current.set(channel.id, cur);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user