「小程序JAVA实战」小程序首页视频(49)

原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!
原文链接地址:「小程序JAVA实战」小程序首页视频(49)

视频显示的内容是视频的截图,用户的头像,用户的昵称,都需要一个结合。所以涉及到关联查询.源码:https://github.com/limingios/wxProgram.git 中wx-springboot 和 No.15

获取系统信息

  • 官网介绍

https://developers.weixin.qq.com/miniprogram/dev/dev/api/system/system-info/wx.getSystemInfo.html

  • 获取系统信息

因为现在手机的屏幕大小不一致,显示适配是个很大的问题,如何适配首选要拿到对应手机的像素值,通过像素值获取响应的信息,动态的控制适配。

后台程序

自定义关联查询,通过分页组件查询出来对应的组合数据,controller提供分页接口。

  • java分页工具
package com.idig8.utils;

import java.util.List;

/**
 * @Description: 封装分页后的数据格式
 */
public class PagedResult {
    
    private int page;           // 当前页数
    private int total;          // 总页数  
    private long records;       // 总记录数
    private List<?> rows;       // 每行显示的内容
    
    public int getPage() {
        return page;
    }
    public void setPage(int page) {
        this.page = page;
    }
    public int getTotal() {
        return total;
    }
    public void setTotal(int total) {
        this.total = total;
    }
    public long getRecords() {
        return records;
    }
    public void setRecords(long records) {
        this.records = records;
    }
    public List<?> getRows() {
        return rows;
    }
    public void setRows(List<?> rows) {
        this.rows = rows;
    }

}

  • java组件原理

通过拦截的方式,当在执行某条sql语句的时候在根据不同数据库的方言,在sql语句查询的时候添加查询limit。PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件,其实我并不想加上好用两个字,但是为了表扬插件作者开源免费的崇高精神,我毫不犹豫的加上了好用一词作为赞美。原本以为分页插件,应该是很简单的,然而PageHelper比我想象的要复杂许多,它做的很强大,也很彻底,强大到使用者可能并不需要这么多功能,彻底到一参可以两用。但是,我认为,作为分页插件,完成物理分页任务是根本,其它的很多智能并不是必要的,保持它够傻够憨,专业术语叫stupid,简单就是美。

  • 增加Vo返回参数实体
package com.idig8.pojo.vo;

import java.util.Date;
import javax.persistence.*;

public class VideosVO {
    private String id;
    private String userId;
    private String audioId;
    private String videoDesc;
    private String videoPath;
    private Float videoSeconds;
    private Integer videoWidth;
    private Integer videoHeight;
    private String coverPath;
    private Long likeCounts;
    private Integer status;
    private Date createTime;
    private String username;
    private String faceImage;
    private String nickname;
    
    public String getId() {
        return id;
    }

    /**
     * @param id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * 获取发布者id
     *
     * @return user_id - 发布者id
     */
    public String getUserId() {
        return userId;
    }

    /**
     * 设置发布者id
     *
     * @param userId 发布者id
     */
    public void setUserId(String userId) {
        this.userId = userId;
    }

    /**
     * 获取用户使用音频的信息
     *
     * @return audio_id - 用户使用音频的信息
     */
    public String getAudioId() {
        return audioId;
    }

    /**
     * 设置用户使用音频的信息
     *
     * @param audioId 用户使用音频的信息
     */
    public void setAudioId(String audioId) {
        this.audioId = audioId;
    }

    /**
     * 获取视频描述
     *
     * @return video_desc - 视频描述
     */
    public String getVideoDesc() {
        return videoDesc;
    }

    /**
     * 设置视频描述
     *
     * @param videoDesc 视频描述
     */
    public void setVideoDesc(String videoDesc) {
        this.videoDesc = videoDesc;
    }

    /**
     * 获取视频存放的路径
     *
     * @return video_path - 视频存放的路径
     */
    public String getVideoPath() {
        return videoPath;
    }

    /**
     * 设置视频存放的路径
     *
     * @param videoPath 视频存放的路径
     */
    public void setVideoPath(String videoPath) {
        this.videoPath = videoPath;
    }

    /**
     * 获取视频秒数
     *
     * @return video_seconds - 视频秒数
     */
    public Float getVideoSeconds() {
        return videoSeconds;
    }

    /**
     * 设置视频秒数
     *
     * @param videoSeconds 视频秒数
     */
    public void setVideoSeconds(Float videoSeconds) {
        this.videoSeconds = videoSeconds;
    }

    /**
     * 获取视频宽度
     *
     * @return video_width - 视频宽度
     */
    public Integer getVideoWidth() {
        return videoWidth;
    }

    /**
     * 设置视频宽度
     *
     * @param videoWidth 视频宽度
     */
    public void setVideoWidth(Integer videoWidth) {
        this.videoWidth = videoWidth;
    }

    /**
     * 获取视频高度
     *
     * @return video_height - 视频高度
     */
    public Integer getVideoHeight() {
        return videoHeight;
    }

    /**
     * 设置视频高度
     *
     * @param videoHeight 视频高度
     */
    public void setVideoHeight(Integer videoHeight) {
        this.videoHeight = videoHeight;
    }

    /**
     * 获取视频封面图
     *
     * @return cover_path - 视频封面图
     */
    public String getCoverPath() {
        return coverPath;
    }

    /**
     * 设置视频封面图
     *
     * @param coverPath 视频封面图
     */
    public void setCoverPath(String coverPath) {
        this.coverPath = coverPath;
    }

    /**
     * 获取喜欢/赞美的数量
     *
     * @return like_counts - 喜欢/赞美的数量
     */
    public Long getLikeCounts() {
        return likeCounts;
    }

    /**
     * 设置喜欢/赞美的数量
     *
     * @param likeCounts 喜欢/赞美的数量
     */
    public void setLikeCounts(Long likeCounts) {
        this.likeCounts = likeCounts;
    }

    /**
     * 获取视频状态:
1、发布成功
2、禁止播放,管理员操作
     *
     * @return status - 视频状态:
1、发布成功
2、禁止播放,管理员操作
     */
    public Integer getStatus() {
        return status;
    }

    /**
     * 设置视频状态:
1、发布成功
2、禁止播放,管理员操作
     *
     * @param status 视频状态:
1、发布成功
2、禁止播放,管理员操作
     */
    public void setStatus(Integer status) {
        this.status = status;
    }

    /**
     * 获取创建时间
     *
     * @return create_time - 创建时间
     */
    public Date getCreateTime() {
        return createTime;
    }

    /**
     * 设置创建时间
     *
     * @param createTime 创建时间
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getFaceImage() {
        return faceImage;
    }

    public void setFaceImage(String faceImage) {
        this.faceImage = faceImage;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    
    
}
  • 数据库查询java的mapper
package com.idig8.mapper;

import java.util.List;

import com.idig8.pojo.Videos;
import com.idig8.pojo.vo.VideosVO;
import com.idig8.utils.MyMapper;

public interface VideosUsersMapper extends MyMapper<VideosVO> {
    
    public List<VideosVO> queryAllVideos();
}
  • 数据库Mybatis的xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.idig8.mapper.VideosUsersMapper" >
  <resultMap id="BaseResultMap" type="com.idig8.pojo.vo.VideosVO" >
    <!--
      WARNING - @mbg.generated
    -->
    <id column="id" property="id" jdbcType="VARCHAR" />
    <result column="user_id" property="userId" jdbcType="VARCHAR" />
    <result column="audio_id" property="audioId" jdbcType="VARCHAR" />
    <result column="video_desc" property="videoDesc" jdbcType="VARCHAR" />
    <result column="video_path" property="videoPath" jdbcType="VARCHAR" />
    <result column="video_seconds" property="videoSeconds" jdbcType="REAL" />
    <result column="video_width" property="videoWidth" jdbcType="INTEGER" />
    <result column="video_height" property="videoHeight" jdbcType="INTEGER" />
    <result column="cover_path" property="coverPath" jdbcType="VARCHAR" />
    <result column="like_counts" property="likeCounts" jdbcType="BIGINT" />
    <result column="status" property="status" jdbcType="INTEGER" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="face_image" property="faceImage" jdbcType="VARCHAR" />
    <result column="nickname" property="nickname" jdbcType="VARCHAR" />
  </resultMap>
  
  <select id="queryAllVideos" resultMap="BaseResultMap">
    select v.*,u.face_image,u.username,u.nickname from videos v
    left join users u on v.user_id = u.id
    where 
        1 = 1
        and v.status = 1
    order by v.create_time
    
  </select>
  
</mapper>

  • service的接口和实现
package com.idig8.service;

import com.idig8.pojo.Videos;
import com.idig8.utils.PagedResult;

public interface VideoService {

    
    /**
     * 保存视频信息
     * @param Id
     * @return
     */
    public String saveVideo(Videos video);
    
    /**
     * 分析查询视频列表
     * @param page
     * @param pageSize
     * @return
     */
    public PagedResult getAllVideos(Integer page,Integer pageSize);
}
    
    

package com.idig8.service.Impl;

import java.util.List;

import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;
import com.idig8.mapper.VideosMapper;
import com.idig8.mapper.VideosUsersMapper;
import com.idig8.pojo.Videos;
import com.idig8.pojo.vo.VideosVO;
import com.idig8.service.VideoService;
import com.idig8.utils.PagedResult;

@Service
public class VideoServiceImpl implements  VideoService {

    @Autowired
    private VideosMapper videosMapper;
    
    @Autowired
    private VideosUsersMapper videosUsersMapper;
    
    @Autowired
    private Sid sid;
    
    @Transactional(propagation =Propagation.REQUIRED)
    public String  saveVideo(Videos video){
        String id = sid.nextShort();
        video.setId(id);
                
        videosMapper.insertSelective(video);
        return id;
        
        
    }

    @Override
    @Transactional(propagation =Propagation.SUPPORTS)
    public PagedResult getAllVideos(Integer page, Integer pageSize) {
        
        PageHelper.startPage(page,pageSize);
        
        List<VideosVO> list = videosUsersMapper.queryAllVideos();
        PageInfo<VideosVO> pageList =new PageInfo<>(list);
        
        PagedResult result = new PagedResult();
        result.setPage(page);
        result.setTotal(pageList.getPages());
        result.setRows(list);
        result.setRecords(pageList.getTotal());
        
        return result;
    }
}

  • controller的开发
package com.idig8.controller;

import java.io.File;
import java.util.Date;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.idig8.pojo.Bgm;
import com.idig8.pojo.Videos;
import com.idig8.service.BgmService;
import com.idig8.service.VideoService;
import com.idig8.utils.FetchVideoCover;
import com.idig8.utils.JSONResult;
import com.idig8.utils.MergeVideoMp3;
import com.idig8.utils.PagedResult;
import com.idig8.utils.enums.VideoStatusEnum;
import com.idig8.utils.file.FileUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;


@RestController
@Api(value="视频相关业务的接口", tags= {"视频相关业务的controller"})
@RequestMapping("/video")
public class VideoController extends BasicController {
    
    @Autowired
    private BgmService bgmService;
    
    @Autowired
    private VideoService videosService;
    
    @Value("${server.file.path}")
    private String fileSpace;
    
    @Value("${server.ffmpeg.path}")
    private String ffmpegexe;
    
    
    @ApiOperation(value="上传视频", notes="上传视频的接口")
    @ApiImplicitParams({
        @ApiImplicitParam(name="userId", value="用户id", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="bgmId", value="背景音乐id", required=false, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="videoSeconds", value="背景音乐播放长度", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="videoWidth", value="视频宽度", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="videoHeight", value="视频高度", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="desc", value="视频描述", required=false, 
                dataType="String", paramType="form")
    })
    @PostMapping(value="/upload", headers="content-type=multipart/form-data")
    public JSONResult upload(String userId, 
                String bgmId, double videoSeconds, 
                int videoWidth, int videoHeight,
                String desc,
                @ApiParam(value="短视频", required=true)
                MultipartFile file) throws Exception {
        
        if (StringUtils.isBlank(userId)) {
            return JSONResult.errorMsg("用户id不能为空...");
        }
        // 文件保存的命名空间
        String fileName = file.getOriginalFilename();
        // 保存到数据库中的相对路径
        String path = "";
        String videOutPath = "";
        String ImagePath = "";
        try {
             path = FileUtil.uploadFile(file.getBytes(), fileSpace, fileName);
            } catch (Exception e) {
                e.getStackTrace();
                   return JSONResult.errorMsg(e.getMessage());
            }                
         
    
        if(StringUtils.isNotBlank(bgmId)){
            Bgm bgm = bgmService.queryBgmById(bgmId);
            String mp3BgmPath = fileSpace + bgm.getPath();
            MergeVideoMp3 mergeVideoMp3 = new MergeVideoMp3(ffmpegexe);
            String videOutPathName = UUID.randomUUID().toString()+".mp4";
            File targetFile = new File(fileSpace + userId);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            videOutPath = "/"+userId+"/"+videOutPathName;
            String videoInput = fileSpace +path;
            mergeVideoMp3.convertor(videoInput, mp3BgmPath, videoSeconds, fileSpace +videOutPath);
            
        }else{
            videOutPath = path;
            
        }
        
        ImagePath =  "/"+userId+"/"+UUID.randomUUID().toString()+".jpg";;
        FetchVideoCover fetchVideoCover = new FetchVideoCover(ffmpegexe);
        fetchVideoCover.getCover(fileSpace +videOutPath, fileSpace +ImagePath);
        
        
        Videos videos = new Videos();
        videos.setAudioId(bgmId);
        videos.setCreateTime(new Date());
        videos.setVideoDesc(desc);
        videos.setId(UUID.randomUUID().toString());
        videos.setUserId(userId);
        videos.setVideoHeight(videoHeight);
        videos.setVideoWidth(videoWidth);
        videos.setVideoPath(videOutPath);
        videos.setCoverPath(ImagePath);
        videos.setStatus(VideoStatusEnum.SUCCESS.value);
        videosService.saveVideo(videos);
                 
        return JSONResult.ok(path);
        
    }
    
    @PostMapping(value="/showAll")
    @ApiOperation(value="视频列表", notes="分页的视频列表")
    @ApiImplicitParam(name="page", value="页码", 
    dataType="String", paramType="query")
    public JSONResult upload(
                Integer page) throws Exception {
        if(page == null){
            page = 1;
        }
        
        PagedResult result = videosService.getAllVideos(page, PAGE_SIZE);
                 
        return JSONResult.ok(result);
        
    }
}

小程序的页面开发

  <view wx:for="{{videoList}}" class="item-container">  



     <view style='width:{{screenWidth}}px;height:210px;' class='back-img'> 
        <image src="{{serverUrl}}{{item.coverPath}}" style='width:{{screenWidth}}px;height:210px;' mode="aspectFit" bindtap='showVideoInfo' data-arrindex='{{index}}'></image>
     </view> 


    <view class="desc">
        <view class="faceName">
            <image class='myface' src="{{serverUrl}}{{item.faceImage}}"></image>
            <view class="nickname">{{item.nickname}}</view>
        </view>
    </view>


  </view>  
.item-container {
    position: relative;
}

.cover {
    width: 100%;
    height: 400rpx;
    display: block; 
}

.back-img{
    display: block; 
    background-color: black;
}

.desc {
    margin-top: -40rpx;
    margin-bottom: 10rpx;
    display: flex;
    align-items: center;
}

.desc .right {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.desc .faceName {
    display: flex;
    flex-direction: column;
    align-items: center;
    
    margin-left: 10px;
}

.title {
    font-size: 30rpx;
    margin-top: 10rpx;
    margin-left: 20rpx;
    width: 600rpx;
}

.myface {
    display: block;
    width: 60rpx;
    height: 60rpx;
    border-radius: 30rpx;
    margin-top: 10rpx;
    margin-right: 20rpx;
}

.nickname {
    font-size: 20rpx;
    margin-top: 6rpx;
    margin-right: 20rpx;
    color: darkgray;
}

const app = getApp()

Page({
  data: {
    // 用于分页的属性
    totalPage: 1,
    page: 1,
    videoList: [],
    screenWidth: 350,
    serverUrl: "",
    searchContent: ""
  },

  onLoad: function (params) {
    var me = this;
    var screenWidth = wx.getSystemInfoSync().screenWidth;
    me.setData({
      screenWidth: screenWidth,
    });

    var searchContent = params.search;
    var isSaveRecord = params.isSaveRecord;
    if (isSaveRecord == null || isSaveRecord == '' || isSaveRecord == undefined) {
      isSaveRecord = 0;
    }

    me.setData({
      searchContent: searchContent
    });

    // 获取当前的分页数
    var page = me.data.page;
    var me = this;
    var serverUrl = app.serverUrl;
    wx.showLoading({
      title: '请等待,加载中...',
    });

    var searchContent = me.data.searchContent;

    wx.request({
      url: serverUrl + '/video/showAll?page=' + page + "&isSaveRecord=" + isSaveRecord,
      method: "POST",
      data: {
        videoDesc: searchContent
      },
      success: function (res) {
        wx.hideLoading();
        wx.hideNavigationBarLoading();
        wx.stopPullDownRefresh();

        console.log(res.data);

        // 判断当前页page是否是第一页,如果是第一页,那么设置videoList为空
        if (page === 1) {
          me.setData({
            videoList: []
          });
        }

        var videoList = res.data.data.rows;
        var newVideoList = me.data.videoList;

        me.setData({
          videoList: newVideoList.concat(videoList),
          page: page,
          totalPage: res.data.data.total,
          serverUrl: serverUrl
        });

      }
    })
  }


})

PS:主要说了关联查询的步骤,首选建立一个VO类,然后mapper关联VO类,增加对应xml文件返回VO类,service内添加分页插件,查询VO类,通过分页插件设置。
页面通过微信组件获取手机的宽度,通过宽度动态的进行适配,调用接口返回内容通过block方法迭代循环展示数据。下次说下上拉和下拉刷新。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,916评论 2 89
  • 在一个方法内部定义的变量都存储在栈中,当这个函数运行结束后,其对应的栈就会被回收,此时,在其方法体中定义的变量将不...
    Y了个J阅读 4,415评论 1 14
  • 正儿八经想写写自己的话语 总觉得有些话应该说一说 试一试 自己的体会 自己的感悟 从心灵转换到改...
    莫名的雨天阅读 151评论 0 0
  • 早上吃了一大勺黑芝麻酱,大半个苹果,一碗半的醪糟枸杞(加冰糖)两个核桃,一个水煮蛋 中午韭菜猪肉饺子白菜猪肉饺子吃...
    艾小柒阅读 290评论 0 0
  • 江火连年,一倾波涛难觅主; 蓑笠鱼钩,钓起风无数。 岸上高歌,曲意江南暮; 抱琴抚,船头鸣鼓; 牵马江头驻。
    古来古来阅读 218评论 0 16