JavaWeb_(视频网站)_四、博客模块1

 

 

添加博客

  添加博客流程图

 

  创建博客实体

  blog实体中包含了三个复杂字段catagory、subCatagory、tag

  blog与catagory属于多对一关系

  blog与subCatagory属于多对一关系

  subCatagory与tag属于多对多关系

  catagory与subCatagory属于一对多关系

  blog与tag属于多对多关系

package com.Gary.betobe.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;

//博客
@Entity
public class Blog {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String coverImage;
    
    private String title;
    
    @Lob
    private String content;
    
    private String keyword;
    
    private Long viewNum;
    
    private String createTime;
    
    //该博客属于哪一个分类
    @ManyToOne(targetEntity = Catagory.class)
    @JoinColumn(name="catagory_id")
    private Catagory catagory;
    
    //该博客属于哪一个小分类
    @ManyToOne(targetEntity = SubCatagory.class)
    @JoinColumn(name="sub_catagory_id")
    private SubCatagory subCatagory;
    
    //博客标签,多对多
    @ManyToMany
    @JoinTable(
            name = "blog_tag",
            joinColumns = @JoinColumn(name="blog_id"),
            inverseJoinColumns = @JoinColumn(name = "tag_id")
            )
    private Set<Tag> blogTags = new HashSet<Tag>();

    //该博客是哪一个人发的
    @ManyToOne(targetEntity = User.class)
    @JoinColumn(name="user_id")
    private User user;
    
    protected Blog()
    {
        
    }
    
    
    
    public Blog(Long id, String coverImage, String title, String content, String keyword, Long viewNum,
            String createTime, Catagory catagory, SubCatagory subCatagory, Set<Tag> blogTags) {
        super();
        this.id = id;
        this.coverImage = coverImage;
        this.title = title;
        this.content = content;
        this.keyword = keyword;
        this.viewNum = viewNum;
        this.createTime = createTime;
        this.catagory = catagory;
        this.subCatagory = subCatagory;
        this.blogTags = blogTags;
    }



    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCoverImage() {
        return coverImage;
    }

    public void setCoverImage(String coverImage) {
        this.coverImage = coverImage;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    public Long getViewNum() {
        return viewNum;
    }

    public void setViewNum(Long viewNum) {
        this.viewNum = viewNum;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public Catagory getCatagory() {
        return catagory;
    }

    public void setCatagory(Catagory catagory) {
        this.catagory = catagory;
    }

    public SubCatagory getSubCatagory() {
        return subCatagory;
    }

    public void setSubCatagory(SubCatagory subCatagory) {
        this.subCatagory = subCatagory;
    }

    public Set<Tag> getBlogTags() {
        return blogTags;
    }

    public void setBlogTags(Set<Tag> blogTags) {
        this.blogTags = blogTags;
    }

    
    
}
Blog.java

 

package com.Gary.betobe.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

//大分类
@Entity
public class Catagory {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String catagory;
    
    //大分类下的所有博客
    @OneToMany(targetEntity = Blog.class)
    @JoinColumn(name="catagory_id")
    private Set<Blog> blogs = new HashSet<Blog>();
    
    //该大分类下的所有小分类
    @OneToMany(targetEntity = SubCatagory.class)
    @JoinColumn(name="catagory_id")
    private Set<SubCatagory> subCatagorys = new HashSet<SubCatagory>();
    
    
    protected Catagory()
    {
        
    }
    
    

    public Catagory(Long id, String catagory, Set<Blog> blogs, Set<SubCatagory> subCatagorys) {
        super();
        this.id = id;
        this.catagory = catagory;
        this.blogs = blogs;
        this.subCatagorys = subCatagorys;
    }



    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCatagory() {
        return catagory;
    }

    public void setCatagory(String catagory) {
        this.catagory = catagory;
    }

    public Set<Blog> getBlogs() {
        return blogs;
    }

    public void setBlogs(Set<Blog> blogs) {
        this.blogs = blogs;
    }

    public Set<SubCatagory> getSubCatagorys() {
        return subCatagorys;
    }

    public void setSubCatagorys(Set<SubCatagory> subCatagorys) {
        this.subCatagorys = subCatagorys;
    }
    
    
    
    
}
Catagory.java

 

package com.Gary.betobe.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

//小分类
@Entity
public class SubCatagory {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String subCatagory;
    
    //该小分类下的所有博客
    @OneToMany(targetEntity = Blog.class)
    @JoinColumn(name="sub_catagory_id")
    private Set<Blog> blogs = new HashSet<Blog>();
    
    //这个小分类属于哪一个大分类
    @ManyToOne(targetEntity = Catagory.class)
    @JoinColumn(name="catagory_id")
    private Catagory catagory;
    
    //小分类与标签,多对多
    @ManyToMany
    @JoinTable(
            name="sub_catagory_tag",
            joinColumns = @JoinColumn(name = "sub_catagory_id"),
            inverseJoinColumns = @JoinColumn(name="tag_id")
            )
    private Set<Tag> tags = new HashSet<Tag>();
    
    
    protected SubCatagory()
    {
        
    }
    
    

    public SubCatagory(Long id, String subCatagory, Set<Blog> blogs, Catagory catagory, Set<Tag> tags) {
        super();
        this.id = id;
        this.subCatagory = subCatagory;
        this.blogs = blogs;
        this.catagory = catagory;
        this.tags = tags;
    }



    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getSubCatagory() {
        return subCatagory;
    }

    public void setSubCatagory(String subCatagory) {
        this.subCatagory = subCatagory;
    }

    public Set<Blog> getBlogs() {
        return blogs;
    }

    public void setBlogs(Set<Blog> blogs) {
        this.blogs = blogs;
    }

    public Catagory getCatagory() {
        return catagory;
    }

    public void setCatagory(Catagory catagory) {
        this.catagory = catagory;
    }

    public Set<Tag> getTags() {
        return tags;
    }

    public void setTags(Set<Tag> tags) {
        this.tags = tags;
    }
    

}
SubCatagory.java

 

package com.Gary.betobe.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

//标签
@Entity
public class Tag {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String tag;
    
    //该标签下的所有博客
    @ManyToMany(mappedBy = "blogTags")
    private Set<Blog> tagBlogs = new HashSet<Blog>();
    
    //该标签下的所有小分类
    @ManyToMany(mappedBy = "tags")
    private Set<SubCatagory> subCatagoryTage = new HashSet<SubCatagory>();

    
    protected Tag()
    {
        
    }
    
    
    
    public Tag(Long id, String tag, Set<Blog> tagBlogs, Set<SubCatagory> subCatagoryTage) {
        super();
        this.id = id;
        this.tag = tag;
        this.tagBlogs = tagBlogs;
        this.subCatagoryTage = subCatagoryTage;
    }



    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public Set<Blog> getTagBlogs() {
        return tagBlogs;
    }

    public void setTagBlogs(Set<Blog> tagBlogs) {
        this.tagBlogs = tagBlogs;
    }

    public Set<SubCatagory> getSubCatagoryTage() {
        return subCatagoryTage;
    }

    public void setSubCatagoryTage(Set<SubCatagory> subCatagoryTage) {
        this.subCatagoryTage = subCatagoryTage;
    }
    
    
    
    
}
Tag.java

 

  数据库多生成了六张表(六个关系)

  

 

   给catagory大分类添加一些假数据

  

 

 

  给sub_catagory大分类下增加小分类

  

 

 

  动态将catagory大分类标签显示在subit-post-blog.html上

  <div class="post-category submit-post">
    <label>Choose Blog Category:
      <select>
        <option th:each="catagory:${catagoryList}" th:text="${catagory.catagory}" th:value="${catagory.catagory}">one</option>
    </select>
    </label>
  </div>

 

  上传Bolg标签的Controller层

  @RequestMapping("/submitPostBlog")
    public String submitPostBlog(Model model)
    {
        User user = (User) session.getAttribute("user");
        baseDataUtils.getData(model,user.getId().toString());
        
        List<Catagory> catagoryList = catagoryService.findAllCatagory();
        
        System.out.println(catagoryList);
        model.addAttribute("catagoryList",catagoryList);
        return "submit-post-blog.html";
    }

 

package com.Gary.betobe.repository;

import org.springframework.data.repository.CrudRepository;

import com.Gary.betobe.domain.Catagory;

public interface CatagoryRepository extends CrudRepository<Catagory,Long>{

    
    
}
CatagoryRepository.java

 

package com.Gary.betobe.service;

import java.util.List;

import org.springframework.stereotype.Service;

import com.Gary.betobe.domain.Catagory;

@Service
public interface CatagoryService {

    List<Catagory> findAllCatagory();

}
CatagoryService.java

 

 

  接下来制作当改变了Choose Blog Category大标题后,下边的Choose Blog SubCategory下标题也会跟着改变

  给大标题和小标题添加一个隐藏button

  <!-- 大标题 -->
  <div class="post-category submit-post">
    <label>Choose Blog Category:
      <select>
        <option th:each="catagory:${catagoryList}" th:onclick="catagoryClick([[${#setUtils.getSubCatagorys(catagory.subCatagorys)}]],[[${catagory.id}]])" th:value="${catagory.catagory}" th:text="${catagory.catagory}">one</option>
      </select>
    </label>
    <input required="required" id="catagoryIdInput" type="text" style="display:none;">
  </div>
  <!-- 小标题 -->
  <div class="post-category submit-post">
    <label>Choose Blog SubCategory:
      <select id="subCatagoryId">
        <option value="">one</option>
        <option value="">two</option>
        <option value="">three</option>
      </select>
    </label>
    <input required="required" id="subcatagoryInInput" type="text" style="display:none">
  </div>

 

<script type="text/javascript">
    function catagoryClick(str,id)
    {
        //清空select
            //获得父元素
        var subCatagoryId = document.getElementById("subCatagoryId");
            //获得父元素下的所有子元素
        var childs = subCatagoryId.childNodes;
            //遍历删除
        for(var i = childs.length - 1;i>=0;i--)
        {
            subCatagoryId.removeChild(childs[i]);
        }
        //切割str
        var subCatagory = new Array();
        subCatagory = str.split("|");
        //1,MAD
        //2,MMD
        for(var i=0;i<subCatagory.length;i++)
        {
            //alert(subCatagory[i]);
            //2,MMD
            var idList = new Array();
            idList = subCatagory[i].split(",");
            //alert(idList[1]);
            
            //添加option
            var option = document.createElement("option");
            option.innerHTML = idList[1];
            //二级下拉点击事件
            option.setAttribute("onclick","subCatagoryClick("+idList[0]+")")
            subCatagoryId.appendChild(option);
        }
        //
        $("#catagoryIdInput").val(id);
        //alert(str);
    }
    
    function subCatagoryClick(id)
    {
        //给subcatagoryinput赋值
        $("#subcatagoryInInput").val(id);
    }

</script>

 

 

 

通过Cropper插件更换图片

  图片的替换流程图

  

 

  通过表单提交图片

  <form id="uploadBlogCoverImageForm" method="post" enctype="multipart/form-data">
    <input type="file" name="file" id="videoUpload" onchange="uploadBlogCover(this)" class="show-for-sr">
  </form>

 

  当点击Upload File上传图片按钮后,文件将保存到classpath:static\upload\blog\temp下

  

 

 

 

  上传文件的javascript代码

    //上传封面
    function uploadBlogCover(e)
    {
        //alert(e.files[0].name);
        var forData = new FormData($("#uploadBlogCoverImageForm")[0]);
        
        $.ajax({
            
            type:"POST",
            cache:false,
            url:"/uploadImageAJAX",
            data:forData,
            processData:false,
            contentType:false,
            dataType:"json",
            success:function(result)
            {
                alert("success")
            },
            error:function()
            {
                alert("dis success")
            }
        })    
    }

 

   后端处理图片上传请求

@RequestMapping("/uploadImageAJAX")
    @ResponseBody
    public String uploadImageAJAX(@RequestParam("file")MultipartFile file) throws Exception
    {
        //保存图片
        //创建文件
        String path = ResourceUtils.getURL("classpath:").getPath()+"static/upload/blog/temp";
        String name = file.getOriginalFilename();
        File dest = new File(path + "/" +name);
        //如果路径不存在,创建路径
        if(!dest.getParentFile().exists())
        {
            dest.getParentFile().mkdir();
        }
        //保存文件
        file.transferTo(dest);
        String json = "{\"success\":"+true+"}";
        return json;
        
    }

 

 

   当图片成功上传到classpath:static\upload\blog\temp后,在ajax中使用cropperMy.replace()将读取图片上传到本地文件夹的位置

cropperMy.replace("http://www.pinzhi365.com/upload/blog/temp/"+fileName,false);

 

    //上传封面
    function uploadBlogCover(e)
    {
        //alert(e.files[0].name);
        var fileName = e.files[0].name;
        var forData = new FormData($("#uploadBlogCoverImageForm")[0]);
        
        $.ajax({
            
            type:"POST",
            cache:false,
            url:"/uploadImageAJAX",
            data:forData,
            processData:false,
            contentType:false,
            dataType:"json",
            success:function(result)
            {
                cropperMy.replace("http://www.pinzhi365.com/upload/blog/temp/"+fileName,false);
            },
            error:function()
            {
                alert("dis success")
            }
        })    
    }

 

 

 

如何将前端切割好的图片保存分析

 

 

   Ajax上传Base64格式文件前端书写

  <a href="javascript;void(0);" onclick="saveImage()" style="background: #656fc3;border-bottom: 3px solid #424da9" class="button">
    <i class="fa fa-plus"></i>
      Save COVER
  </a>

 

//保存切割之后的图片
    function saveImage()
    {
        //alert("Gary555");
        //拿到Base64格式的文本
        var base64URL = cropperMy.getCroppedCanvas({width:770,height:370}).toDataURL("image/jpeg");
        //ajax保存图片
        $.post(
            [[@{~/uploadCoverAJAX}]],
            {"base64":base64URL},
            function(data)
            {
                if(data.success)
                {
                    $("#coverImageInput").val("blog/cover/"+data.fileName);
                    layer.msg("上传成功!!")
                }
                //alert();
                //文件路径
            },
            "json"
        )
    }

 

  后端处理上传的Base64文件图片

  @RequestMapping("/uploadCoverAJAX")
  @ResponseBody
    public String uploadCoverAJAX(String base64) throws Exception
    {
        //获得classpath在本地的地址
        String path = ResourceUtils.getURL("classpath:").getPath() + "static/upload/blog/cover";
        //保存图片
        File file = new File(path);
        if(!file.exists())
        {
            file.mkdir();
        }
        //替换数据
        if(base64.indexOf("jpeg")!=-1)
        {
            base64 = base64.replaceFirst("jpeg", "jpg");
        }
        //获取文件名
        String upName = UUID.randomUUID().toString()+System.currentTimeMillis()+"."+base64.substring(11,14);
        //将base64中有用的数据保存下来
        String iconBase64 = base64.substring(22);
        //将base64换位字节数据
        byte[] buffer = Base64Coder.decode(iconBase64);
        //用FileOutputStream写文件
        FileOutputStream out = new FileOutputStream(path + "/" + upName);
        out.write(buffer);
        out.close();
        //返回Json
        
        String json = "{\"success\":"+true+",\"fileName\":\""+upName+"\"}";    
        
        return json;
    }

 

  前端封装富文本字段

  <div class="large-12 columns submit-post">
    <button class="button expanded" type="button" onclick="mySubmit()">publish now</button>
  </div>

 

  富文本表单字段的提交

    //自己的表单提交
    function mySubmit()
    {
        var markup = $(".summernote").summernote('code');
        //富文本的内容赋值到textarea中
        $("#contentTextarea").text(markup);
        //表单提交
        $("#submitButton").click();
    }

 

<form th:action="@{~/saveBlog}" method="post" data-abide novalidate>
                                            <div data-abide-error class="alert callout submit-post" style="display: none;">
                                                <p><i class="fa fa-exclamation-triangle"></i>
                                                    There are some errors in your form.</p>
                                            </div>
                                            <div class="row">

                                                <div class="large-12 columns submit-post">

                                                    <div class="upload-video">
                                                        <label for="videoUpload" class="button">Upload File</label>
                                                        
                                                        <span>No file chosen</span>
                                                    </div>
                                                    <p class="extraMargin">Please upload the appropriate blog cover recommendation 770 * 370.</p>
                                                    
                                                    <!-- 图片切割 -->
                                                    <div style="width:400px;heigh:280px;">
                                                        <img id="image" src="../upload/user/head/1.jpg">        
                                                    </div>
                                                    <div>&nbsp;</div>
                                                    <h6>Perview Cover</h6>
                                                    <div class="blogCover" style="overflow:hidden;height:770px;width:370px;position:relative;"></div>
                                                    <div>&nbsp;</div>
                                                    <a href="javascript:void(0);" onclick="saveImage()" style="background: #656fc3;border-bottom: 3px solid #424da9" class="button">
                                                        <i class="fa fa-plus"></i>
                                                        Save COVER
                                                    </a>
                                                </div>
                                                
                                                <div class="large-12 columns">
                                                    <div class="post-meta submit-post">
                                                        <label>Meta Title:
                                                            <textarea name="title" required="required" placeholder="enter meta title"></textarea>
                                                        </label>
                                                        <p>IF you want to put your custom meta Title then put here otherwise your post title will be the default meta Title</p>
                                                    </div>
                                                    <div class="post-meta">
                                                        <label>Meta Description:
                                                            
                                                        </label>
                                                        
                                                        <!-- 富文本 -->
                                                        <div class="summernote"></div>
                                                        <textarea id="contentTextarea" name="content" style="display:none;"></textarea>
                                                        
                                                        <div class="submit-post">
                                                        <p>IF you want to put your custom meta description then put here otherwise your post description will be the default meta description</p>
                                                         </div>
                                                    
                                                    </div>
                                                    <div class="post-meta submit-post">
                                                        <label>Meta keywords:
                                                            <textarea name="keyword" required="required" placeholder="enter meta keywords"></textarea>
                                                        </label>
                                                        <p>IF you want to put your custom meta Keywords then put here otherwise your post Keywords will be the default meta Keywords</p>
                                                    </div>
                                                    
                                                    <!-- 大标题 -->
                                                    <div class="post-category submit-post">
                                                        <label>Choose Blog Category:
                                                            <select>
                                                                <option th:each="catagory:${catagoryList}" th:onclick="catagoryClick([[${#setUtils.getSubCatagorys(catagory.subCatagorys)}]],[[${catagory.id}]])" th:value="${catagory.catagory}" th:text="${catagory.catagory}">one</option>
                                                                 
                                                            </select>
                                                        </label>
                                                        <input required="required" name="catagoryId" id="catagoryIdInput" type="text" style="display:none;">
                                                    </div>
                                                    <!-- 小标题 -->
                                                    <div class="post-category submit-post">
                                                        <label>Choose Blog SubCategory:
                                                            <select id="subCatagoryId">
                                                              <option value="">one</option>
                                                              <option value="">two</option>
                                                              <option value="">three</option>
                                                            </select>
                                                        </label>
                                                        <input required="required" name="subCatagoryId" id="subcatagoryInInput" type="text" style="display:none">
                                                    </div>

                                                </div>
          
                                                <div class="large-12 columns submit-post">
                                                    <label>Tags:
                                                            <!-- 英文逗号隔开 -->
                                                               <input name="tagsinput" id="tagsinputval" class="tagsinput" data-role="tagsinput" value="faltui,这是一个标签" placeholder="输入后回车"/>
                                                            
                                                    </label>
                                                </div>
                                                <input id="coverImageInput" name="coverImage" type="text" style="display:none;">
                                                <div class="large-12 columns submit-post">
                                                    <button id="submitButton" type="submit" style="display:none;"></button>
                                                    <button class="button expanded" type="button" onclick="mySubmit()">publish now</button>
                                                </div>
                                            </div>
                                       </form>
Blog博客表单.html

 

  小分类与标签绑定关系 

  更新更新SubCatagory小标签

  

 

 

   展示上传图片(期间出了一个bug,栈溢出问题  解决:传送门)

 

   BlogController.java下的saveBlog请求

@RequestMapping("/saveBlog")
    public String saveBlog(Blog blog,String tagsinput,String catagoryId,String subCatagoryId)
    {
        System.err.println("blog = "+blog);
        //ViewNum
        //createTime
        
        //catagory    
        System.err.println("catagoryId = "+catagoryId);
        //subCatagory
        System.err.println("subCatagoryId = "+subCatagoryId);
        //user  session
        //blogTags
        System.err.println("tagsinput = "+tagsinput);
        
        //封装分类
        Catagory catagory = catagoryService.findCatagoryById(catagoryId);
        blog.setCatagory(catagory);
        //封装小分类
        SubCatagory subCatagory = subCatagoryService.findSubCatagoryById(subCatagoryId);
        //blog.setSubCatagory(subCatagory);
        
        //封装创建时间
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        String createTime = format.format(date);
        blog.setCreateTime(createTime);
        
        //封装标签
        //tagsinput = tagsinput.toUpperCase();
        String[] tags = tagsinput.split(",");
        Set<Tag> blogTags = new HashSet<>();
        for(int i=0;i<tags.length;i++)
        {
            Tag tag = null;
            //如果标签不存在,数据库里没有重复的标签
            if(tagService.findTagByTag(tags[i]) ==null )
            {
                //如果没有重复的,可以添加
                tag = new Tag(null,tags[i],new HashSet<>(),new HashSet<>());
                tag = tagService.saveTag(tag);
            }
            //如果标签存在
            else 
            {
                //不可添加
                tag = tagService.findTagByTag(tags[i]);
            }
            
            blogTags.add(tag);
            //维护subCatagory与tag之间多对多关系
            subCatagory.getTags().add(tag);
            System.out.println("111");
            tag.getSubCatagoryTage().add(subCatagory);
        }
        
        //维护blog与tag关系
        blog.setBlogTags(blogTags);
        blog.setSubCatagory(subCatagory);
        //封装发布博客的用户
        User user = (User) session.getAttribute("user");
        blog.setUser(user);
        //封装浏览数目
        blog.setViewNum(0L);
        //保存
        blogService.saveBlog(blog);
        
        return "redirect:/index";
    }
saveBlog

 

 

 

 

 

 

 

 

 

 

 

  

posted @ 2019-12-22 21:32  Cynical丶Gary  阅读(154)  评论(0编辑  收藏  举报