<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          App開(kāi)發(fā)之帖子系統(tǒng)(實(shí)戰(zhàn)篇)

          共 52316字,需瀏覽 105分鐘

           ·

          2020-11-23 03:05

          帖子系統(tǒng)數(shù)據(jù)庫(kù)設(shè)計(jì)

          帖子表

          評(píng)論表

          收藏表

          點(diǎn)贊表

          點(diǎn)贊評(píng)論表(點(diǎn)贊帖子和點(diǎn)贊評(píng)論我用了2個(gè)表,也可以用一個(gè)表用類(lèi)型字段區(qū)分)


          發(fā)帖

          客戶端add_post_page.dart

          import 'dart:convert';
          import 'package:common_utils/common_utils.dart';import 'package:flutter/material.dart';import 'package:flutter/services.dart';import 'package:flutter_songbei/custom/common_bottom_sheet.dart';import 'package:flutter_songbei/custom/griditem/add_post_images_grid_item.dart';import 'package:flutter_songbei/custom/network_loading.dart';import 'package:flutter_songbei/models/image_model.dart';import 'package:flutter_songbei/models/post_model.dart';import 'package:flutter_songbei/network/chttp.dart';import 'package:flutter_songbei/network/params.dart';import 'package:flutter_songbei/provider/app.dart';import 'package:flutter_songbei/qiniu/qiniu_file.dart';import 'package:flutter_songbei/qiniu/qiniu_scuess.dart';import 'package:flutter_songbei/utils/qiniu.dart';import 'package:flutter_songbei/utils/toast_util.dart';import 'package:image_picker/image_picker.dart';import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';import 'package:provider/provider.dart';import 'package:sy_flutter_qiniu_storage/sy_flutter_qiniu_storage.dart';
          class AddPostPage extends StatefulWidget { @override State createState() { return _PageState(); }}
          class _PageState extends State<AddPostPage> { TextEditingController _titleController = TextEditingController(); TextEditingController _controller = TextEditingController();
          String specification = ""; int per_add = 0; int image_max = 9;
          String token = ''; Map qiniuFlies = Map();
          List images = List();
          final ImagePicker _picker = ImagePicker();
          @override void initState() { var image = ImageModel(); image.type = 1; images.add(image); _reqQiniuToken();
          rootBundle.loadString('assets/data/specification.txt').then((value) => { this.specification = value, print('-----specification:${specification}') });
          WidgetsBinding.instance.addPostFrameCallback((_) { _reqPrivileges(); }); super.initState(); }
          @override void dispose() { _controller.dispose(); super.dispose(); }
          @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( '想法', ), centerTitle: true, actions: [ FlatButton.icon( onPressed: () { _submit(); }, icon: Icon( Icons.near_me, size: 14, color: Colors.white, ), label: Text( '發(fā)布', style: TextStyle(color: Colors.white), ), ) ], ), body: Container( color: Colors.white, padding: EdgeInsets.all(10), child: Column( children: [ // TextField( // controller: _titleController, // minLines: 1, // maxLines: 20, // decoration: InputDecoration( // contentPadding: EdgeInsets.all(5.0), // hintText: '編輯想法標(biāo)題', // filled: true, // fillColor: Colors.white, // border: InputBorder.none, // ), // ), // Divider( // height: 1, // ), TextField( controller: _controller, minLines: 5, maxLines: 20, decoration: InputDecoration( contentPadding: EdgeInsets.all(5.0), hintText: '寫(xiě)下你的想法', filled: true, fillColor: Colors.white, border: InputBorder.none, ), ), Flexible( child: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, //橫軸三個(gè)子widget childAspectRatio: 1.0 //寬高比為1時(shí),子widget ), itemCount: images.length, itemBuilder: (content, index) { return AddPostGridItem( images[index], onAdd: (item) { showPhotos(); }, onDel: (item) { print('-----item:$item'); images.removeAt(index); for (var i = images.length - 1; i >= 0; i--) { if (images[i].id == item.id) { images.removeAt(i); } } if (images.length < image_max) { if (images[images.length - 1].type != 1) { var image = ImageModel(); image.type = 1; images.add(image); } } setState(() {}); }, ); }), ), ], ), )); }
          showPhotos() { var cur_images = 0; for (var i = 0; i < images.length; i++) { if (images[i].type == 0) { cur_images++; } } if (cur_images < image_max) { } else { ToastUtil.showToast(context, '最多可上傳$image_max張圖片'); } showDialog( barrierDismissible: true, //是否點(diǎn)擊空白區(qū)域關(guān)閉對(duì)話框,默認(rèn)為true,可以關(guān)閉 context: context, builder: (BuildContext context) { var list = List(); list.add('相冊(cè)'); list.add('相機(jī)'); return CommonBottomSheet( list: list, onItemClickListener: (index) async { print('-----index:$index'); if (index == 0 || index == 2) { var source = ImageSource.gallery; if (index == 2) source = ImageSource.camera; PickedFile file = await _picker.getImage(source: source); if (file == null) { ToastUtil.showToast(context, '選擇文件失敗'); return; } var insert_index = 0; images.forEach((element) { if (element.type == 0) { insert_index += 1; } }); var image = ImageModel(); image.path = image.url = file.path; image.type = 0; image.state = 0; images.insert(insert_index, image); if (images.length > image_max) { for (var i = images.length - 1; i >= 0; i--) { if (images[i].type == 1) { images.removeAt(i); } } } setState(() {});// _onUpload(file); Future future = this._onUpload(file); future.then((qiniuScuess) { for (var i = 0; i < images.length; i++) { if (images[i].type == 0 && images[i].path == qiniuScuess.file_path) { images[i].state = 1; images[i].url = Qiniu.getUpUrl(qiniuScuess.qiniu_key); print('------上傳成功'); } } setState(() {}); }); } Navigator.pop(context); }, ); }); }
          _submit() { print("=============================="); // if (_titleController.text.isEmpty) { // ToastUtil.showToast(context, '編輯想法標(biāo)題'); // return; // } if (_controller.text.isEmpty) { ToastUtil.showToast(context, '寫(xiě)下你的想法'); return; } List upImages = List(); for (var i = 0; i < images.length; i++) { if (images[i].type == 0 && images[i].state == 1) { upImages.add(images[i]); } }// if (upImages.length == 0) {// ToastUtil.showToast(context, '請(qǐng)選擇圖片');// return;// }
          var to_json = {}; if (upImages.length > 0) { List photos = List(); for (var i = 0; i < upImages.length; i++) { photos.add(upImages[i].toServerJson(i)); }// print(photos); to_json = {'photos': photos}; } _reqAddDiscuss( _titleController.text, _controller.text, json.encode(to_json)); }
          /** * 用戶規(guī)范 */ showSpecification() { showDialog( context: context, builder: (context) { return AlertDialog( title: Text('用戶發(fā)布內(nèi)容規(guī)范'), content: Container( height: MediaQuery.of(context).size.height / 2, child: SingleChildScrollView( child: Container( padding: EdgeInsets.all(10.0), child: Text( specification, style: TextStyle(fontSize: 18.0), ), ), ), ), actions: [ FlatButton( child: Text("同意"), onPressed: () => {_reqSetPri(), Navigator.of(context).pop()}), FlatButton( child: Text("拒絕"), onPressed: () => { Navigator.of(context).pop(), Navigator.of(context).pop() }), ]); }); }
          void _reqAddDiscuss(title, content, extend) { print('-----userid:${Provider.of(context, listen: false).userid}'); showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return NetworkLoading(); }); CHttp.post( CHttp.DISCUSS_ADD, (data) { Navigator.pop(context); ToastUtil.showToast(context, '發(fā)布成功'); Navigator.pop(context, PostModel(data)); }, params: PAddPost(Provider.of(context, listen: false).userid, title, content, 1,extend) .toJson(), errorCallback: (err) { Navigator.pop(context); ToastUtil.showToast(context, err); }, completeCallback: () {// Navigator.pop(context); }); }
          Future _onUpload(PickedFile file) async { if (token == null || (token != null && token.length == 0)) { ToastUtil.showToast(context, 'token 無(wú)效!'); return null; } print('---_onUpload:${token}'); QiniuScuess qiniuScuess = null; if (token == null || (token != null && token.length == 0)) { ToastUtil.showToast(context, 'token 無(wú)效!'); return qiniuScuess; } if (file == null) { return qiniuScuess; } qiniuFlies[file.path] = QinuFile(file.path); final syStorage = SyFlutterQiniuStorage(); //監(jiān)聽(tīng)上傳進(jìn)度 syStorage.onChanged().listen((dynamic percent) { double p = percent;// setState(() { if (qiniuFlies[file.path] != null) qiniuFlies[file.path].process = p;// });// print(percent); LogUtil.e('---percent:${percent}');// if (qiniuFlies[file.path] != null&&p >= 1.0) {//// LogUtil.e('---qiuniu_link:${qiniu_link}');// Qiniu.httpGetImageInfo(Qiniu.getUpUrl(qiniuFlies[file.path].qiniu_key), (data) {// Map info_map = jsonDecode(jsonEncode(data));//// this.myFileStorage.onUpScuess(file.path,qiniuFlies[file.path].qiniu_key,info_map);// qiniuScuess = QiniuScuess(file.path,qiniuFlies[file.path].qiniu_key,info_map);// this.myFileStorage.onUpScuess(qiniuScuess);// print('-----tag qiniuScuess:${qiniuScuess}');// setState(() {// _controller.text = _controller.text;// });// }, errorCallback: (err) {//// });// } });
          String key = Qiniu.getUpPath(file.path);// LogUtil.e('---key:${key}');// setState(() {// qiniu_key = key;// }); qiniuFlies[file.path].qiniu_key = key; //上傳文件 UploadResult result = await syStorage.upload(file.path, token, key); if (result.success) { qiniuScuess = QiniuScuess(file.path, qiniuFlies[file.path].qiniu_key); } print('-----result:${result} qiniuScuess:${qiniuScuess}'); return qiniuScuess; }
          void _reqQiniuToken() { CHttp.post(CHttp.QINIU_UPTOKEN, (data) { LogUtil.e('-----data:${data}'); setState(() { token = data; }); }, errorCallback: (err) { LogUtil.e('-----err:${err}'); }); }
          void _reqPrivileges() { CHttp.post( CHttp.USER_PRIVILEGES, (data) { LogUtil.e('-----data:${data}'); var temp_per_add = data['per_add']; setState(() { per_add = temp_per_add; }); if (temp_per_add == 0) { this.showSpecification(); } }, params: PUserid(Provider.of(context, listen: false).userid).toJson(), errorCallback: (err) { LogUtil.e('-----err:${err}'); }); }
          void _reqSetPri() { CHttp.post( CHttp.USER_SETPRI, (data) { LogUtil.e('-----data:${data}'); var temp_per_add = data['per_add']; setState(() { per_add = temp_per_add; }); if (temp_per_add == 0) { showSpecification(); } }, params: PSetPri(Provider.of(context, listen: false).userid, 'per_add', true) .toJson(), errorCallback: (err) { LogUtil.e('-----err:${err}'); }); }}


          服務(wù)器?discuss.js

          router.post('/add', function(req, res, next) {    try {        ru.logReq(req);        var userid = req.body.userid;        var title = req.body.title;        var content = req.body.content;        var extend = req.body.extend;        var type = req.body.type;        var os = req.body.os;        if (!content || !userid ||!type) {            ru.resError(res, '參數(shù)錯(cuò)誤');        } else {            discussDao.addDiscuss(userid, type, title, content, extend, function(err, result) {                if (err) {                    ru.resError(res, err);                } else {                    var poem = {};                    if (result.length > 0) {                        poem = result[0];                    }                    ru.resSuccess(res, poem);                    // console.log(poem)                    userDao.queryFollowMe(userid, function(err, result) {                        if (err) {                            logger.error(err);                        } else {                            if (result.length > 0) {                                let messages = [];                                console.log('--------------')                                console.log(result);                                for (var i = 0; i < result.length; i++) {                                    var title = poem.nickname + '發(fā)布了新討論';                                    var content = poem.nickname + '發(fā)布了[' + poem.title + ']';                                    var addDiscussExtend = new AddDiscussExtend(poem.id, poem.userid, poem.head, poem.nickname, poem.title);                                    var message = new Notice(NoticeType.DADD, result[i].fansid, title, content, addDiscussExtend);                                    messages.push(message)                                }                                if (messages.length > 0) {                                    httputil.requstLocalPost('/psbook/message/actionmsgs', { messages: messages }, function(err, result) {                                        logger.debug(err);                                        logger.debug(result);                                    });                                }
          var app_name = appconfig.APP_NAME; var webhook_body = "####" + app_name + "\n用戶:" + userid + "發(fā)布了新的討論[" + poem.title + "]" +"\n系統(tǒng):["+os+"]"; webhook.sendMarkdownMsg(webhook_body, function(err, result) { if (err) { logger.error(err); } }); } } }) } }) } } catch (err) { ru.resError(res, err.message); }});

          帖子列表

          客戶端發(fā)現(xiàn)頁(yè)

          import 'package:flutter/material.dart';import 'package:flutter_songbei/custom/listitem/post_list_item.dart';import 'package:flutter_songbei/models/post_model.dart';import 'package:flutter_songbei/network/chttp.dart';import 'package:flutter_songbei/network/params.dart';import 'package:flutter_songbei/pages/post/post_page.dart';import 'package:flutter_songbei/pages/user/login_page.dart';import 'package:flutter_songbei/provider/app.dart';import 'package:flutter_songbei/utils/app_util.dart';import 'package:flutter_songbei/utils/toast_util.dart';import 'package:provider/provider.dart';import 'package:pull_to_refresh/pull_to_refresh.dart';
          import '../../app_theme.dart';
          class FoundTab extends StatefulWidget { @override State createState() { return _PageState(); }}
          class _PageState extends State<FoundTab> { List posts = List();
          /** * 0 下拉刷新 1 上拉刷新 */ int pull_type = 0;
          int count = 0;
          RefreshController _refreshController = RefreshController(initialRefresh: false);
          @override void initState() { super.initState(); pull_type = 0; _requestNDiscuss(); }
          @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('發(fā)現(xiàn)'), backgroundColor: AppTheme.mainColor, ), body: Container( child: SmartRefresher( enablePullDown: true, enablePullUp: true, controller: _refreshController, onRefresh: _onRefresh, onLoading: _onLoading, child: ListView.separated( itemBuilder: (content, index) { return PostListItem( posts[index], index, this.onItem, onStar: (item) { if (AppUtil.isLogin(context) == false) { Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage())); return; } _reqPostStar(item); }, onLove: (item) { if (AppUtil.isLogin(context) == false) { Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage())); return; } _reqPostLove(item); }, ); }, itemCount: posts.length, separatorBuilder: (context, index) { return Divider( height: 0.5, indent: 0, color: Color(0xFFDDDDDD), ); }, ), ), ), ); }
          void _onRefresh() { pull_type = 0; _requestNDiscuss(); }
          void _onLoading() { pull_type = 1; if (posts.length < count) { _requestHDiscuss(); } else { _refreshController.loadComplete(); } }
          void onItem(item) { Navigator.push( context, MaterialPageRoute(builder: (context) => PostPage(item.id))) .then((res) { if (res != null) { print('-----res'); print(res); if (res['action'] == 'del') { var id = res['id']; var temp_discuss = posts; for (var i = temp_discuss.length - 1; i >= 0; i--) { if (temp_discuss[i].id == id) { temp_discuss.removeAt(i); } } this.setState(() { posts = temp_discuss; }); } } }); }
          void _requestNDiscuss() { var fromid = 0; var forms = posts; if (forms.length > 0) { fromid = forms[0].id; } CHttp.post( CHttp.DISCUSS_NDISCUSS, (data) { if (!mounted) { return; } count = data['count']; var temp_discuss = List(); var res_discuss = data['discuss']; for (var i = 0; i < res_discuss.length; i++) { temp_discuss.add(PostModel(res_discuss[i])); } posts.insertAll(0, temp_discuss); setState(() { }); print(posts); }, params: PDiscuss(Provider.of(context, listen: false).userid, fromid) .toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }, completeCallback: () { if (pull_type == 0) { _refreshController.refreshCompleted(); } else { _refreshController.loadComplete(); } }); }
          void _requestHDiscuss() { var fromid = 0; var forms = posts; if (forms.length > 0) { fromid = forms[forms.length - 1].id; } CHttp.post( CHttp.DISCUSS_HDISCUSS, (data) { if (!mounted) { return; } count = data['count']; var temp_discuss = List(); var res_discuss = data['discuss']; for (var i = 0; i < res_discuss.length; i++) { temp_discuss.add(PostModel(res_discuss[i])); } posts.addAll(temp_discuss); setState(() { }); print(posts); }, params: PDiscuss(Provider.of(context).userid, fromid).toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }, completeCallback: () { if (pull_type == 0) { _refreshController.refreshCompleted(); } else { _refreshController.loadComplete(); } }); }
          void _reqPostStar(PostModel post) { print(post); var star = post.mystar != null&&post.mystar == 1 ? 0 : 1; CHttp.post( CHttp.STATR, (data) { if (!mounted) { return; } post.mystar = star; var starnum = post.starnum != null?post.starnum :0; if (star == 1) { starnum += 1; } else { if (starnum > 0) { starnum -= 1; } } post.starnum = starnum; setState(() {}); ToastUtil.showToast(context, star == 1 ? '收藏成功' : '取消收藏'); print(data); }, params: PStar(Provider.of(context, listen: false).userid, 3, post.id, star) .toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }); }
          void _reqPostLove(PostModel post) { CHttp.post( CHttp.LOVE_LOVE, (data) { if (!mounted) { return; } print(data); var love = data['love']; var lovenum = post.lovenum; if (love == 1) { lovenum += 1; } else { if (lovenum > 0) { lovenum -= 1; } } post.lovenum = lovenum; post.mylove = love; setState(() {}); }, params: PPostLove(Provider.of(context, listen: false).userid,3, post.id, post.mylove == 0 ? 1 : 0) .toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }, completeCallback: () {
          }); }
          }


          服務(wù)器帖子列表

          /** * 最新帖子 */router.post('/ndiscuss', function(req, res, next) {    try {        ru.logReq(req);        var id = req.body.id;        var userid = req.body.userid;        discussDao.queryNDiscuss(id, userid, function(err, poems) {            if (err) {                ru.resError(res, err);            } else {                ru.resSuccess(res, poems);            }        })    } catch (err) {        ru.resError(res, err.message);    }});/** * 歷史帖子 */router.post('/hdiscuss', function(req, res, next) {    try {        ru.logReq(req);        var id = req.body.id;        var userid = req.body.userid;        discussDao.queryHDiscuss(id, userid, function(err, poems) {            if (err) {                ru.resError(res, err);            } else {                ru.resSuccess(res, poems);            }        });    } catch (err) {        ru.resError(res, err.message);    }});


          帖子詳情

          客戶端post_page.dart

          import 'package:cached_network_image/cached_network_image.dart';import 'package:flutter/material.dart';import 'package:flutter_songbei/custom/follow_user.dart';import 'package:flutter_songbei/custom/listitem/comment_list_item.dart';import 'package:flutter_songbei/custom/listitem/post_love_lits_item.dart';import 'package:flutter_songbei/custom/loading.dart';import 'package:flutter_songbei/manager/ui_manager.dart';import 'package:flutter_songbei/models/comment_model.dart';import 'package:flutter_songbei/models/follow_model.dart';import 'package:flutter_songbei/models/love_model.dart';import 'package:flutter_songbei/models/photo_gallery_model.dart';import 'package:flutter_songbei/models/post_model.dart';import 'package:flutter_songbei/network/chttp.dart';import 'package:flutter_songbei/network/params.dart';import 'package:flutter_songbei/pages/my/report_page.dart';import 'package:flutter_songbei/pages/user/login_page.dart';import 'package:flutter_songbei/pages/user/loves_page.dart';import 'package:flutter_songbei/provider/app.dart';import 'package:flutter_songbei/utils/app_util.dart';import 'package:flutter_songbei/utils/toast_util.dart';import 'package:provider/provider.dart';
          import '../../app_theme.dart';import '../photos_gallery_page.dart';
          class PostPage extends StatefulWidget { int id;
          PostPage(this.id);
          @override State createState() { return _PageState(id); }}
          class _PageState extends State<PostPage> { int id; PostModel post; FollowModel follow; List comments = List(); List loves = List();
          TextEditingController _textController = TextEditingController(); FocusNode _focusNode = FocusNode(); bool _isComposing = false;
          String placeholder = '發(fā)表評(píng)論...'; String ctips = ''; int cid = 0; String cnickname = ''; String ccomment = ''; String comment = '';
          _PageState(this.id);
          @override void initState() { super.initState(); _requestDiscuss(); _requestNewestComment(); _requestLoves(); }
          @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('想法'), centerTitle: true, ), body: _buildBody(), ); }
          Widget _buildBody() { print('_buildBody'); print(post); if (post != null) { return Column( children: [ Flexible( child: Container( padding: EdgeInsets.all(10), decoration: BoxDecoration(color: Colors.white), child: ListView( children: [ _buildFollow(), _buildPost(context), _buildLoves(), _buildMenus(), Row( children: [Text('全部回復(fù):${post.commentnum}')], ), ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: comments.length, itemBuilder: (BuildContext context, int positon) { return CommentLstItem(comments[positon], onComment:(item) {// print('----item:${item}'); if (AppUtil.isLogin(context) == false) { Navigator.push( context, MaterialPageRoute( builder: (context) => LoginPage())); return; } _renderTips(item.id, item.nickname, item.comment); }, onLove:(item) { _onLoveComment(item); }, onDel:(item) { showDialog( context: context, builder: (context) { return AlertDialog( title: Text('刪除評(píng)論'), content: Container( child: Text('是否確認(rèn)刪除評(píng)論?'), ), actions: [ FlatButton( child: const Text('取消'), onPressed: () { Navigator.of(context).pop(); }, ), FlatButton( child: const Text('確認(rèn)'), onPressed: () { _onDelComment(item); Navigator.of(context).pop(); }), ], ); }); }); }, separatorBuilder: (context, index) { return Divider( height: 0.5, indent: 0, color: Color(0xFFDDDDDD), ); }, ) ], ), ), ), Divider(height: 1.0), Container( decoration: new BoxDecoration(color: Theme.of(context).cardColor), child: _buildTextComposer(), //頁(yè)面下方的文本輸入控件 ) ], ); } else { return Loading(); } }
          Widget _buildFollow() { print('------_buildFollow'); print(follow); if (follow != null) { return Container( child: FollowUser(1, follow, (item) {}), ); } else { return Container(); } }
          Widget _buildPost(BuildContext context) { print('post.time:${post.time}'); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.fromLTRB(0, 10, 0, 0), child: Text( post.title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ), Padding( padding: EdgeInsets.fromLTRB(0, 10, 0, 10), child: Text( post.content, style: TextStyle(fontSize: 16), ), ), _buildPhotos(context), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Text( UIManager.getTime(post.time), style: TextStyle(fontSize: 14,color: AppTheme.grayColor), ) ], ) ], ); }
          Widget _buildPhotos(BuildContext context) { if (post.postExtend != null && post.postExtend.photos.length > 0) { var photos = post.postExtend.photos; return Container( padding: EdgeInsets.fromLTRB(0, 10, 0, 0), child: ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemBuilder: (BuildContext content, int index) { return InkWell( child: Container( constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.width), child: CachedNetworkImage( imageUrl: UIManager.getHeadurl(photos[index].photo), fit: BoxFit.cover, width: double.infinity, ), ), onTap: (){ List gallery_photos = List(); photos.forEach((element) { gallery_photos.add(PhotoGalleryModel(element.photo)); }); Navigator.push( context, MaterialPageRoute(builder: (context) => PhotosGalleryPage(gallery_photos,index))); }, ); }, itemCount: photos.length, ), ); } else { return Container(); } }
          Widget _buildLoves() { if (post.lovenum > 0) { return GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => LovesPage(id))); }, child: Container( padding: EdgeInsets.all(10), child: Column( children: [ Container( height: 40, width: MediaQuery.of(context).size.width/2, child: ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), scrollDirection: Axis.horizontal, itemCount: loves.length, itemBuilder: (BuildContext context, int positon) { return PostLoveListItem(loves[positon]); }, separatorBuilder: (context, index) { return Divider( height: 0.5, indent: 0, color: Color(0xFFDDDDDD), ); }, ), ), Divider( height: 5, color: Colors.white, ), Text( '${post.lovenum}人贊過(guò) >', style: TextStyle(color: Colors.black45), ) ], ), ), ); } else { return Container(); } }
          Widget _buildMenus() { print('-----_buildMenus'); print(post); return Padding( padding: EdgeInsets.fromLTRB(0, 10, 0, 10), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( child: Column( children: [ Container( width: 40, height: 40, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20.0)), border: Border.all(color: AppTheme.grayColor)), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image( image: AssetImage( UIManager.getLoveAssetImage(post.mylove)), width: 20, height: 20, color: UIManager.getLoveColor(post.mylove), ) ], ), ), Padding( padding: EdgeInsets.fromLTRB(0, 5, 0, 0), child: Text( UIManager.getNumStr(post.lovenum), style: TextStyle(color: AppTheme.grayColor), ), ) ], ), onTap: () { _onLove(); }, ), SizedBox( width: 40, height: 40, ), InkWell( child: Column( children: [ Container( width: 40, height: 40, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20.0)), border: Border.all(color: AppTheme.grayColor)), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image( image: AssetImage( UIManager.getStarAssetImage(post.mystar)), width: 20, height: 20, color: UIManager.getStarColor(post.mystar), ) ], ), ), Padding( padding: EdgeInsets.fromLTRB(0, 5, 0, 0), child: Text( UIManager.getNumStr(post.starnum), style: TextStyle(color: AppTheme.grayColor), ), ) ], ), onTap: () { _onStar(); }, ), SizedBox( width: 40, height: 40, ), InkWell( child: Container( width: 40, height: 40, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20.0)), border: Border.all(color: AppTheme.grayColor)), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image( image: AssetImage('assets/post/jubao.png'), width: 20, height: 20, color: AppTheme.grayColor, ) ], ), ), onTap: () { _onReport(); }, ), _buildDelete(), ], ), ); }
          Widget _buildDelete() { if (post.userid == Provider.of(context).userid) { return Row( children: [ SizedBox( width: 40, height: 40, ), InkWell( child: Container( width: 40, height: 40, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20.0)), border: Border.all(color: AppTheme.grayColor)), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image( image: AssetImage('assets/post/shanchu.png'), width: 20, height: 20, color: AppTheme.grayColor, ) ], ), ), onTap: () { showDialog( context: context, builder: (context) { return AlertDialog( title: Text('刪除想法'), content: Container( child: Text('是否確認(rèn)刪除想法?'), ), actions: [ FlatButton( child: const Text('取消'), onPressed: () { Navigator.of(context).pop(); }, ), FlatButton( child: const Text('確認(rèn)'), onPressed: () { _onDelDiscuss(); Navigator.of(context).pop(); }), ], ); }); }, ) ], ); } else { return Container(); } }
          Widget _buildTextComposer() { return IconTheme( data: IconThemeData(color: Theme.of(context).accentColor), child: Container( margin: const EdgeInsets.symmetric(horizontal: 8.0), child: Column( children: [ cid > 0 ? Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: MediaQuery.of(context).size.width / 3 * 2,// child: Text(ctips,// style: TextStyle(color: Colors.black45),// maxLines: 1,// textAlign: TextAlign.left,// overflow: TextOverflow.ellipsis,// softWrap: true,// ), child: RichText( text: TextSpan( text: '正在回復(fù)', style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black87), children: [ TextSpan( text: cnickname, style: TextStyle( fontWeight: FontWeight.bold, color: Colors.lightBlueAccent)), TextSpan( text: '的', style: TextStyle(color: Colors.black87)), TextSpan( text: ccomment, style: TextStyle( color: Colors.lightBlueAccent)), ]), textAlign: TextAlign.left, maxLines: 1, overflow: TextOverflow.ellipsis, softWrap: true, ), ), FlatButton( child: Text('取消回復(fù)'), onPressed: () { _renderTips(0, '', ''); _onHideKey(); }, ) ], ) : Container(), Row( children: [ Flexible( child: TextField( controller: _textController, focusNode: _focusNode, onChanged: (String text) { //new 通過(guò)onChanged事件更新_isComposing 標(biāo)志位的值 setState(() { //new 調(diào)用setState函數(shù)重新渲染受到_isComposing變量影響的IconButton控件 _isComposing = text.length > 0; //new 如果文本輸入框中的字符串長(zhǎng)度大于0則允許發(fā)送消息 }); //new }, //new onSubmitted: _handleSubmitted, decoration: InputDecoration.collapsed(hintText: placeholder), ), ), Container( margin: EdgeInsets.symmetric(horizontal: 4.0), child: IconButton( icon: Icon(Icons.send), onPressed: _isComposing ? () => _handleSubmitted(_textController.text) //modified : null, //modified 當(dāng)沒(méi)有為onPressed綁定處理函數(shù)時(shí),IconButton默認(rèn)為禁用狀態(tài) ), ), ], ) ], ), ), ); }
          void _renderTips(cid, cnickname, comment) {// print('----cnickname:${cnickname}'); var placeholder = '發(fā)表評(píng)論...'; var ctips = ''; if (cid > 0) { placeholder = '回復(fù)...'; ctips = '正在回復(fù)[${cnickname}]的[${comment}]'; print('----${ctips}');// this.refs.cinput.focus(); FocusScope.of(context).requestFocus(_focusNode); } else { this._onHideKey(); } setState(() { this.cid = cid; this.cnickname = cnickname; this.ccomment = comment; this.placeholder = placeholder; this.ctips = ctips; this.comment = ''; }); }
          void _onHideKey() { if (_focusNode.hasFocus == true) {// FocusScope.of(context).requestFocus(_focusNode); FocusScope.of(context).requestFocus(FocusNode()); } }
          //定義發(fā)送文本事件的處理函數(shù) void _handleSubmitted(String text) { comment = _textController.text; if (AppUtil.isLogin(context)) { _onRelease(); } else { Navigator.push( context, MaterialPageRoute(builder: (context) => LoginPage())) .then((perfect) { if (perfect != null) { _onRelease(); } }); } }
          void _onRelease() { if (comment.length == 0) { ToastUtil.showToast(context, '請(qǐng)輸入內(nèi)容'); return; } var params = PCommentAdd(3, Provider.of(context, listen: false).userid, id, cid, comment) .toJson(); CHttp.post( CHttp.COMMENT_ADD, (data) { if (!mounted) { return; } var temp_comment = CommentModel(data); comments.insert(0, temp_comment); setState(() {}); _requestLoveComment(); ToastUtil.showToast(context, '評(píng)論成功'); _renderTips(0, '', ''); _textController.clear(); //清空輸入框 }, params: params, errorCallback: (err) { ToastUtil.showToast(context, err); }); }
          void _onLoveComment(CommentModel comment) { if (!AppUtil.isLogin(context)) { Navigator.push( context, MaterialPageRoute(builder: (context) => LoginPage())) .then((perfect) { if (perfect != null) {} }); return; } var onlove = comment.love == 1 ? 0 : 1; print('---comment.love:${comment.love}'); print('---onlove:${onlove}'); var params = PLoveComment( 2, Provider.of(context, listen: false).userid, id, comment.id, onlove) .toJson(); CHttp.post( CHttp.LOVE_LOVECOMMENT, (data) { var id = data['id']; var love = data['love']; for (var i = 0; i < comments.length; i++) { if (comments[i].id == id) { var lovenum = comments[i].lovenum; if (love == 1) { lovenum += 1; } else { if (lovenum > 0) lovenum -= 1; } comments[i].lovenum = lovenum; comments[i].love = love; } } setState(() {}); }, params: params, errorCallback: (err) { ToastUtil.showToast(context, err); }); }
          void _onDelComment(CommentModel comment) { if (!AppUtil.isLogin(context)) { Navigator.push( context, MaterialPageRoute(builder: (context) => LoginPage())) .then((perfect) { if (perfect != null) {} }); return; } var params = PDelComment( 2, Provider.of(context, listen: false).userid, comment.id,id,) .toJson(); CHttp.post( CHttp.COMMENT_DEL, (data) { for (var i = comments.length - 1; i >= 0; i--) { if (comments[i].id == comment.id) { comments.removeAt(i); } } setState(() {}); }, params: params, errorCallback: (err) { ToastUtil.showToast(context, err); }); }
          _onDelDiscuss() { CHttp.post( CHttp.DISCUSS_DEL, (data) { ToastUtil.showToast(context, '想法刪除成功'); Navigator.of(context).pop({'action': 'del', 'id': post.id}); }, params: PDiscuss(Provider.of(context, listen: false).userid, id) .toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }); }
          void _onLove() { if (AppUtil.isLogin(context) == false) { Navigator.push( context, MaterialPageRoute(builder: (context) => LoginPage())); return; } _reqPostLove(post); }
          void _onStar() { if (AppUtil.isLogin(context) == false) { Navigator.push( context, MaterialPageRoute(builder: (context) => LoginPage())); return; } _reqPostStar(post); }
          void _onReport() { Navigator.push( context, MaterialPageRoute( builder: (context) => ReportPage('舉報(bào)想法', post.userid,post.id, 3))); }
          void _requestDiscuss() { CHttp.post( CHttp.DISCUSS_INFO, (data) { if (!mounted) { return; } post = PostModel(data); setState(() {}); _requestFloow(post.userid); }, params: PPost(Provider.of(context, listen: false).userid, id).toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }); }
          void _requestFloow(String fansid){ CHttp.post( CHttp.USER_FOLLOWINFO, (data) { if (!mounted) { return; } follow = FollowModel(data); setState(() {}); }, params: PFollowUser(Provider.of(context, listen: false).userid, fansid).toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }); } /** * 請(qǐng)求點(diǎn)單數(shù)和評(píng)論數(shù) */ void _requestLoveComment() { CHttp.post( CHttp.LOVE_LCNUM, (data) { if (!mounted) { return; } print(data); }, params: PCommentNum(3, id).toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }); }
          /** * 請(qǐng)求評(píng)論列表 */ void _requestNewestComment() { var fromid = 0; if (comments.length > 0) { fromid = comments[0].id; } CHttp.post( CHttp.COMMENT_LATEST, (data) { if (!mounted) { return; } List temp_comments = List(); for (var i = 0; i < data.length; i++) { temp_comments.add(CommentModel(data[i])); } comments.insertAll(0, temp_comments); setState(() {});// print(data); }, params: PComment(3, fromid, id).toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }); }
          void _reqPostStar(PostModel post) { print(post); var star = post.mystar != null&&post.mystar == 1 ? 0 : 1; CHttp.post( CHttp.STATR, (data) { if (!mounted) { return; } post.mystar = star; var starnum = post.starnum != null?post.starnum :0; if (star == 1) { starnum += 1; } else { if (starnum > 0) { starnum -= 1; } } post.starnum = starnum; setState(() {}); ToastUtil.showToast(context, star == 1 ? '收藏成功' : '取消收藏'); print(data); }, params: PStar(Provider.of(context, listen: false).userid, 3, post.id, star) .toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }); }
          void _reqPostLove(PostModel post) { CHttp.post( CHttp.LOVE_LOVE, (data) { if (!mounted) { return; } print(data); var love = data['love']; var lovenum = post.lovenum; if (love == 1) { lovenum += 1; } else { if (lovenum > 0) { lovenum -= 1; } } post.lovenum = lovenum; post.mylove = love; setState(() {}); }, params: PPostLove(Provider.of(context, listen: false).userid,3, post.id, post.mylove == 0 ? 1 : 0) .toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }, completeCallback: () {
          }); }
          _requestLoves() { CHttp.post( CHttp.LOVE_LOVES, (data) { if (!mounted) { return; } List temp_loves = List(); for (var i = 0; i < data.length; i++) { temp_loves.add(LoveModel(data[i])); } setState(() { loves = temp_loves; }); }, params: PLoves(3, id).toJson(), errorCallback: (err) { ToastUtil.showToast(context, err); }); }}


          服務(wù)器帖子詳情

          router.post('/info', function(req, res, next) {    ru.logReq(req);    var id = req.body.id;    var userid = req.body.userid;    if (!id) {        ru.resError(res, '參數(shù)錯(cuò)誤')    } else {        discussDao.queryDiscussInfo(id, userid, function(err, result) {            if (err) {                ru.resError(res, err)            } else {                if (result.del == 1) {                    ru.resError(res, '作品已刪除')                } else {                    ru.resSuccess(res, result);                }            }        });    }});


          項(xiàng)目整體功能還在開(kāi)發(fā)中,待基礎(chǔ)功能完成后,我會(huì)放在Github上,方便大家交流討論。

          瀏覽 27
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    人人操人人摸人人色 | 日本一级做a爱片 | 日韩精品一区二区三区av | 伊人久久久 | 国产精品久久久久久久久久青青 |