Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
user event & send claim request
Browse files Browse the repository at this point in the history
  • Loading branch information
staugur committed May 30, 2021
1 parent 0ccdb25 commit 3ace96e
Show file tree
Hide file tree
Showing 12 changed files with 384 additions and 48 deletions.
119 changes: 104 additions & 15 deletions client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,116 @@ import Footer from './views/public/Footer.vue'
export default {
name: 'App',
components: { Navbar, Footer },
data() {
return {
event: {}
}
},
created() {
this.$store.actions.fetchConfig()
this.$store.actions.fetchConfig(this.getEvent())
window.addEventListener('beforeunload', (e) => {
this.$store.actions.saveConfig2Local()
})
},
mounted() {
let url = '/api/user/event'
let es = new EventSource(url)
es.addEventListener('message', (event) => {
console.log(event.data)
})
es.addEventListener('error', (event) => {
if (event.readyState == EventSource.CLOSED) {
console.log('event was closed')
methods: {
sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
},
getEvent() {
if (!this.$store.state.isLogin) {
return false
}
})
es.addEventListener('close', (event) => {
console.log(event.type)
es.close()
})
let url = '/api/user/event?jwt=' + this.$store.state.token
let es = new EventSource(url)
es.addEventListener('message', (event) => {
try {
let data = JSON.parse(event.data)
this.handleEvent(data)
//es.close()
} catch (e) {
console.error(e)
}
})
es.addEventListener('error', (event) => {
if (event.readyState == EventSource.CLOSED) {
console.log('event was closed')
}
})
es.addEventListener('close', (event) => {
console.log(event.type)
es.close()
})
},
handleEvent(data) {
if (!Array.isArray(data) || data.length === 0) {
return false
}
data.forEach(async (d) => {
let opt = d.opt
if (!opt.msg || this.event[d.id]) {
return false
}
this.event[d.id] = true
await this.sleep(1000)
let mnOpt = {
message: opt.msg,
type: opt.theme || 'info',
dangerouslyUseHTMLString: opt.is_html,
duration: 0,
showClose: true,
onClose: () => {
this.deleteEvent(d.id)
}
}
if (opt.classify === 'message') {
this.$message(
Object.assign(
{ customClass: 'el-message--slim' },
mnOpt
)
)
} else if (opt.classify === 'notify') {
let ni = this.$notify(
Object.assign(
{
title: opt.title,
position: 'bottom-right',
onClick: () => {
let jump = opt.notify_jump
if (jump) {
this.$router.push(jump)
ni.close()
}
}
},
mnOpt
)
)
} else if (opt.classify === 'alert') {
this.$alert(opt.msg, opt.title || '提示', {
confirmButtonText: '确定',
type: opt.theme,
dangerouslyUseHTMLString: opt.is_html,
buttonSize: 'mini',
callback: (action) => {
console.log(action)
if (action === 'confirm') {
this.deleteEvent(d.id)
}
}
})
}
})
},
deleteEvent(id) {
console.log('delete', id)
this.$http.delete(`/user/event/${id}`).then(() => {
this.$message.success({
message: '事件已读,已经删除!',
customClass: 'el-message--slim'
})
})
}
}
}
</script>
Expand Down
3 changes: 2 additions & 1 deletion client/src/libs/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ export const mutations = {
}

export const actions = {
fetchConfig() {
fetchConfig(cb) {
//get public config
http.get('/config').then(function (res) {
for (let k in res.data) {
mutations.commit(k, res.data[k])
}
actions.saveConfig2Local()
typeof cb === 'function' && cb()
})
},
saveConfig2Local() {
Expand Down
4 changes: 2 additions & 2 deletions client/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,5 @@ app.config.globalProperties.$http = http
app.config.globalProperties.$store = store
app.config.globalProperties.$ELEMENT = { size: 'mini' }
let vm = app.mount('#app')
//window.app = app
//window.vm = vm
window.app = app
window.vm = vm
22 changes: 15 additions & 7 deletions client/src/views/album/AlbumFairy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,26 @@ export default {
}
}
// Add function buttons
let taBtns = [
/*
{
let taBtns = []
if (this.isLogin && this.user !== owner) {
taBtns.push({
name: '认领',
plain: true,
type: 'success',
click: () => {
console.log('click ta')
this.$http
.post('/user/claim', { owner: owner, album: name })
.then((res) => {
this.$message.success({
message: '已申请,等待批准',
customClass: 'el-message--slim'
})
this.btns[0].name = '待确认'
this.btns[0].disabled = true
})
}
}
*/
]
})
}
let claimBtns = []
let homeBtns = [
{
Expand Down
7 changes: 5 additions & 2 deletions server/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ func StartApi(config *sys.Setting) {
auth.POST("/signin", signInView)

user := api.Group("/user", loginRequired) // 用户接口,需登录
user.GET("/event", eventView)
user.POST("/upload", uploadView)

user.POST("/album", createAlbumView)
Expand All @@ -72,8 +71,12 @@ func StartApi(config *sys.Setting) {
user.POST("/fairy", createFairyView)
user.DELETE("/fairy/:id", dropFairyView)

user.GET("/claim", listClaimView)
user.POST("/claim", createClaimView)
user.GET("/claim", listClaimView)

user.POST("/event", createEventView)
user.GET("/event", listEventView)
user.DELETE("/event/:id", dropEventView)

e.Logger.Fatal(e.Start(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)))
}
12 changes: 6 additions & 6 deletions server/api/tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ func getUser(c echo.Context) string {
}

// 从 name/id 中解析专辑ID
func getAlbumID(user, name string) string {
if name == "" {
return name
func getAlbumID(user, nameOrID string) string {
if nameOrID == "" {
return nameOrID
}
if strings.HasPrefix(name, vars.AlbumPre) {
if strings.HasPrefix(nameOrID, vars.AlbumPre) {
// name is id
return name
return nameOrID
} else {
return album.AlbumName2ID(user, name)
return album.AlbumName2ID(user, nameOrID)
}
}

Expand Down
85 changes: 74 additions & 11 deletions server/api/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (

"fairyla/internal/album"
"fairyla/internal/user/auth"
"fairyla/internal/user/event"
"fairyla/vars"

"github.com/labstack/echo/v4"
Expand Down Expand Up @@ -191,16 +192,6 @@ func uploadView(c echo.Context) error {
}
}

// 用户消息
func eventView(c echo.Context) error {
c.Response().Header().Set("Content-Type", "text/event-stream")
c.Response().Header().Set("Cache-Control", "no-cache")
c.Response().Header().Set("Connection", "keep-alive")
ret, _ := json.Marshal(vars.ResOK())
res := fmt.Sprintf("data: %s\n\n", string(ret))
return c.String(200, res)
}

/*
* AlbumView 专辑视图
*
Expand Down Expand Up @@ -531,5 +522,77 @@ func listClaimView(c echo.Context) error {

// 认领其他用户专辑(需由所属者确认方可领取成功)
func createClaimView(c echo.Context) error {
return nil
user := getUser(c)
owner := c.FormValue("owner")
id := c.FormValue("album")
if owner == "" || id == "" {
return errors.New("invalid param")
}
if user == owner {
return errors.New("already belong ta")
}
w := album.New(rc)
err := w.CreateClaim(user, owner, getAlbumID(owner, id))
if err != nil {
return err
}
return c.JSON(200, vars.ResOK())
}

/*
* EventView 用户事件视图
*
* 状态:已登录
*/

// 创建事件
func createEventView(c echo.Context) error {
user := getUser(c)
action := getParam(c, "action")
if action == "message" {
msg := c.FormValue("message")
class := c.FormValue("classify")
m, err := event.NewMessage(user, msg, class)
if err != nil {
return err
}
err = m.Write(rc)
if err != nil {
return err
}
return c.JSON(200, vars.ResOK())
}
return errors.New("invalid action param")
}

// 查询事件
func listEventView(c echo.Context) error {
w := event.New(rc)
ms, err := w.ListMessages(getUser(c), c.FormValue("classify"))
if err != nil {
return err
}
Accept := c.Request().Header.Get("Accept")
if strings.Contains(Accept, "application/json") {
return c.JSON(200, vars.NewResData(ms))
}
ret, err := json.Marshal(ms)
if err != nil {
return err
}
c.Response().Header().Set("Content-Type", "text/event-stream")
c.Response().Header().Set("Cache-Control", "no-cache")
c.Response().Header().Set("Connection", "keep-alive")
res := fmt.Sprintf("retry: 30000\ndata: %s\n\n", string(ret))
return c.String(200, res)
}

// 删除事件
func dropEventView(c echo.Context) error {
w := event.New(rc)
err := w.DropMessages(getUser(c), c.Param("id"))
if err != nil {
return err
}
return c.JSON(200, vars.ResOK())
}
34 changes: 34 additions & 0 deletions server/internal/album/album.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"sort"
"strings"

"fairyla/internal/user/event"
"fairyla/pkg/db"
"fairyla/pkg/util"
"fairyla/vars"
Expand Down Expand Up @@ -387,3 +388,36 @@ func (w wrap) ListClaimAlbums(owner string) (data []Album, err error) {
}
return
}

func (w wrap) CreateClaim(by, to, albumID string) error {
has, err := w.HasUser(to)
if err != nil {
return err
}
if !has {
return errors.New("not found username")
}
a, err := w.GetAlbum(to, albumID)
if err != nil {
return err
}
exist, err := a.Exist(w.Conn)
if err != nil {
return err
}
if !exist {
return errors.New("invalid album param")
}
_, err = w.HSet(vars.GenClaimedKey(to), albumID, by)
if err != nil {
return err
}
tpl := fmt.Sprintf(
"您好,用户【%s】认领了您的专辑【%s】,希望共同维护,请及时处理。", by, a.Name,
)
m, _ := event.NewMessage(to, tpl, "notify")
m.Opt.Title = "专辑认领通知"
m.Opt.Theme = "info"
m.Opt.NotifyJump = "/album/" + a.Name
return m.Write(w.Conn)
}
Loading

0 comments on commit 3ace96e

Please # to comment.