关于网站建站设计的烧脑问题请教JellyBool

A.数据库设计问题

  1. 比如一篇帖子下有评论发布与回复功能,每层回复都可以被再评论与覆盖。
    title(title_id int,title_content varchar,pubshier varchar,pubdate)
    answer(title_id,answer_content,answer_account,answer_date)
    还是一般来说就是主题表,留言表,用ID关联一下就可以呢?

  2. 我有个想法,还有一种是将评论回复信息存储一个JSON文件,放在服务器上,每次打开一篇文章调用JSON读取下信息,如果有回复,就继续写入。

  3. 图片或者视频一般情况是放在七牛云这样的存储空间上,比如一篇帖子里有40张图片,一篇里面只有5张图片,我数据库里存的是图片的外链,那这个应该怎么操作。是吧所有的图片链接put到一个字段里还是有别的存储方法。

首先,可以全部放content存储字段你怕不够的话有textlong-text呢。一般情况下不会爆。比如使用七牛存储的情况下,七牛的图片或视频的编辑你都可以调用接口,在你自己的代码实现,你只需要在上传的时候告诉七牛你要怎么处理这些文件,最后文件的保存地址是什么就可以了。你不用自己写图片视频的压缩转换编码 @carpho

JellyBool

第一,帖子的表(discussion)最简单的设计为:

(id,title,content,user_id)

评论,也就是answer:

(id,content,discussion_id,user_id)

恩,就是可以使用id关联。

第二,这个JSON文件的方式我没有试过,理论上是可行的。

第三,如果你使用了编辑器的话,可以直接将连接嵌入到帖子的contentt当中,你只要保证图片的连接是对的就可以了。如果是外挂的图片,也就是可以使用一对多的关系,每张图片的连接地址和帖子id关联就可以了。

carpho

@JellyBool 比如这个Markdown编辑器 这么多得内容全部由content一个字段存起来,如果这个是超长字段对于存储没有问题么。我也不知道哪种方式最好。图片的这个我还有个不太懂,麻烦请教您下,比如我用七牛云,他们有自带的图片或视频压缩转码方式,我只要在编辑器中设置逻辑让图片存在在七牛就OK了么?还是七牛云会给我一个地址供我上传文件,我需要自己写图片视频的压缩转换编码。

JellyBool

首先,可以全部放content存储字段你怕不够的话有textlong-text呢。一般情况下不会爆。比如使用七牛存储的情况下,七牛的图片或视频的编辑你都可以调用接口,在你自己的代码实现,你只需要在上传的时候告诉七牛你要怎么处理这些文件,最后文件的保存地址是什么就可以了。你不用自己写图片视频的压缩转换编码 @carpho

carpho

@JellyBool Bingo!Thankyou so much!

carpho

@JellyBool 对咯 这个编辑器就有回复信息和时间啊 还有赞 有@ 等各个功能 这个编辑器是怎么处理@别人并且记录@的对象和统计次数 还有并且在个人中心还能alert个小圆圈 发表时间功能我自己明白

JellyBool

这些具体的功能是在无法一时说的清楚,技术如下:

@这个功能使用atWho.js

alert使用的是socket。 @carpho

carpho

@JellyBool 我当时还在想自己写逻辑 看这个就明白啦 谢谢大神 今天真的麻烦你了 真心感谢

JellyBool

没事,我晚上整理一下后面的答案给你吧 @carpho 先上课先

carpho

@JellyBool 谢咯 嘿嘿

JellyBool

使用atWho.js,参与@的用户从数据库获取,也就是参与评论的所有用户名。然后使用

var inputer = $('#content');
inputer.on("inserted.atwho", function($li, query) {});

进行回调,将@到的用户名ajax发给服务器,这时候就从后端发站内通知给用户。

个人中心还能alert个小圆圈这个使用的是Vue.js的数据双向绑定,然后结合Websocket实现实时web,也就是目前非常流行的realtime app

carpho
 <script>
    Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('value');
    var MyComponent = Vue.extend({
        template: '#forum-post-like-button-template',

        props:['commentId','currentUser','userLiked'],

        data: function() {
            return {
                replyId:'',
                liked: false,
                current:'',
                likes: 0,
                users: []
            };
        },

        ready: function() {
            this.users = this.userLiked.length > 0 ? this.userLiked.split(',') : [];
            this.likes = this.users.length;
            this.liked  = this.users.indexOf(this.currentUser) > -1;
        },

        methods: {
            doLike: function() {
                if(this.currentUser.length > 0){
                    this.liked = ! this.liked;
                    if ( this.liked) {
                        this.likes++;
                        this.addUserToList();
                    } else {
                        this.likes--;
                        this.removeUserFromList();
                    }
                }else{
                    document.querySelector('#loginButton').click();
                }

            },

            addUserToList: function() {
                this.current = this.currentUser;
                var votes = {'comment_id':this.commentId,'name':this.current};
                this.$http.post('/api/comment/votes', votes,function(response){
                });
                this.users.push(this.current);
            },

            removeUserFromList: function() {
                this.current = this.currentUser;
                var votes = {'comment_id':this.commentId,'name':this.current};
                this.$http.post('/api/comment/cancel', votes,function(response){
                });
                this.users.$remove(this.current);
            }
        }
    });
    Vue.component('forum-post-like-button', MyComponent);
    new Vue({ el: '.replies__vue' });
</script>
            <script>
    new Vue({
        el: '#navbar-notifications',
        data: {
            user_id:**,
            name:'***',
            title: $('title').text(),
            active: false
        },
        ready: function() {
            this.$http.get('/events/count', function (data) {
                this.active = data > 0 ? true : data > 0;
                document.title = data > 0 ?'('+data+')'+this.title: this.title;
                this.$set('count', data);
            });

            var pusher = new Pusher('2fa0ac88454b92ad6455', {
                encrypted: true
            });
            pusher.subscribe('you_have_new_notifications').bind('App\\Events\\YouHaveNewNotifications',this.countNotification)
        },
        methods: {
            countNotification: function (user) {
                if(user.user_id == this.user_id)
                {
                    this.count ++;
                    document.title = '('+this.count+')'+this.title;
                    this.active=true;
                    toastr.options.closeButton = true;
                    toastr.options.positionClass = 'toast-bottom-right';
                    toastr.success('<a href="/user/notifications">你有新的消息通知!</a>',this.name);
                }
            }

        }
    });
</script> 

这个是那个vue.js么 是不是和socket.io是一样的东西呢 我不太懂 这部分功能麻烦能详细说明下么 ?@JellyBool

carpho

dropzone.js 拖拽上传文件的js脚本

carpho
<script>
    Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('value');
    new Vue({
        el: '#container',
        data: {
            messages: [

            ],
            newMessage: {
                name: 'carpho',
                avatar: '<img src="/images/default-avatar.png" class="img-circle">',
                content: ''
            },

            newComment: {
                conversation_id: '47',
                type: 'discuss',
                user_id: '53',
                discuss_user_id: '53',
                content: ''
            }

        },
        methods: {
            onSubmitForm: function(e) {
                e.preventDefault();
                var message = this.newMessage;
                var comment = this.newComment;
                comment.content = message.content;
                this.$http.post('/discuss/47/replies', comment,function(response){
                    message.content = response.html;
                    this.messages.push(message);
                });
                this.newMessage = {
                    name: 'carpho',
                    avatar: '<img src="/images/default-avatar.png" class="img-circle">',
                    content: ''
                };

            }
        }
    });
</script>

这是那个通知消息么 我看到上面写着img-circle @JellyBool

JellyBool

这个是实现评论的时候的js @carpho