├── .gitignore ├── README.md ├── cp.sh ├── gulpConfig.js ├── gulpfile.js ├── package.json └── src ├── app.js ├── app.json ├── app.wxss ├── config.js ├── images ├── add.png ├── album.png ├── arrow_left.png ├── awm.jpg ├── card.png ├── collect.png ├── emoji.png ├── group_chat.png ├── home.png ├── my.png ├── new_friend.png ├── photo.png ├── picture.png ├── praise.png └── setting.png ├── modules ├── lib │ ├── formVerify.js │ ├── mathUtil.js │ ├── swipe.js │ └── util.js └── login │ └── index.js ├── pages ├── index │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── item │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── login │ ├── login.js │ ├── login.json │ ├── login.wxml │ └── login.wxss ├── my │ ├── collect.js │ ├── collect.json │ ├── collect.wxml │ ├── collect.wxss │ ├── follow.js │ ├── follow.json │ ├── follow.wxml │ ├── follow.wxss │ ├── index.js │ ├── index.json │ ├── index.wxml │ ├── index.wxss │ ├── list.js │ ├── list.json │ ├── list.wxml │ ├── list.wxss │ ├── setpwd.js │ ├── setpwd.json │ ├── setpwd.wxml │ └── setpwd.wxss ├── register │ ├── register.js │ ├── register.json │ ├── register.wxml │ └── register.wxss └── upload │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── style ├── base │ ├── _animation.scss │ ├── _cartMixin.scss │ ├── _mixin.scss │ ├── _reset.scss │ └── _variables.scss └── widget │ ├── icon.scss │ └── navbar.scss ├── template ├── loadmore │ ├── index.scss │ └── index.wxml ├── toast │ ├── index.js │ ├── index.scss │ └── index.wxml └── tooltip │ ├── index.js │ ├── index.scss │ └── index.wxml └── utils ├── fileCache.js └── util.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | public/script 4 | node_modules 5 | .idea/ 6 | .vscode 7 | .svn 8 | dist/ 9 | tmp/ 10 | config.yaml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 贝比秀秀小程序 2 | 3 | #### src下面文件: 4 | - app.js 小程序启动脚本 5 | - app.json 小程序的全局配置 6 | - app.wxss 小程序的公共样式,所有页面可引用,同名样式会被page对应的样式覆盖 7 | - config.js 主要是一些常量配置,会挂到app.globalData 8 | ###### 文件夹说明 9 | - utils 公用js类库 10 | - template 公共可复用template 11 | - style 公用sass,包括base(sass基础库)和widget(可复用的小部件) 12 | - pages 各相应页面对应文件 13 | - modules 比较独立的一些模块 14 | 15 | ## 项目构建相关: 16 | 17 | setp1: `npm install` 18 | 19 | 开发:`gulp(build&watch)` 20 | 21 | 构建打包: 22 | - `gulp build 或 npm run build` 23 | - 切换环境参数:-e[test\pro\pre] 如:gulp build -e pro 接口用的线上环境,目前默认用的也是线上环境 24 | - 开发时不想压缩JS,可加-dev 参数,如:gulp build -dev 25 | 26 | -------------------------------------------------------------------------------- /cp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #../../weweb/bin/weweb dist 3 | cp -rf ./tmp/dist/* /Library/WebServer/Documents/wxshow/1/bbxx/ -------------------------------------------------------------------------------- /gulpConfig.js: -------------------------------------------------------------------------------- 1 | var srcPath = 'src/'; 2 | var distPath = 'dist/'; 3 | var config = { 4 | srcPath: srcPath, 5 | distPath: distPath, 6 | templateVar:{ 7 | pro:{//请求的域名前缀 8 | domainConf:{ 9 | request : "https://wxshow.vipsinaapp.com",//https://xcx.weidian.com 10 | }, 11 | environment:3 12 | }, 13 | pre:{//请求的域名前缀 14 | domainConf:{ 15 | request : "https://wxshow.vipsinaapp.com",//https://xcx.weidian.com 16 | }, 17 | environment:2 18 | }, 19 | test:{//请求的域名前缀 20 | domainConf:{ 21 | request : "https://wxshow.vipsinaapp.com",//https://xcx.weidian.com 22 | }, 23 | environment:1 24 | } 25 | }, 26 | excludeFolder:['!'+srcPath+'pages/income/**/*.*','!'+srcPath+'pages/notice/**/*.*','!'+srcPath+'pages/member/**/*.*','!'+srcPath+'lib/wxCashierApp/**/*.*'], 27 | js:{ 28 | src:[srcPath + '**/*.js','!' + srcPath + 'lib/**/app.js'] 29 | }, 30 | css:{ 31 | src:[srcPath + '**/*.*ss','!'+srcPath+'style/**/*.*ss','!'+srcPath+'template/**/*.*ss','!'+srcPath+'lib/**/app.wxss','!'+srcPath+'lib/groupon/**/*.wxss'] 32 | }, 33 | image:{ 34 | src:srcPath + 'images/**/*' 35 | }, 36 | other:{ 37 | src:[srcPath + '**/*.wxml',srcPath + '**/*.json',srcPath + 'lib/groupon/**/*.wxss','!'+srcPath+'lib/groupon/**/app.wxss','!' + srcPath + '**/bower.json','!' + srcPath + 'lib/**/app.json'] 38 | } 39 | } 40 | config.js.src = config.js.src.concat(config.excludeFolder); 41 | config.css.src = config.css.src.concat(config.excludeFolder); 42 | config.other.src = config.other.src.concat(config.excludeFolder); 43 | module.exports = config; -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp') 2 | var gutil = require('gulp-util') 3 | var uglify = require('gulp-uglify') 4 | //var uglifyjs = require('uglify-js-harmony'); 5 | //var minifier = require('gulp-uglify/minifier'); 6 | //minifier({}, uglifyjs), 7 | var watchPath = require('gulp-watch-path') 8 | var combiner = require('stream-combiner2') 9 | //var sourcemaps = require('gulp-sourcemaps') 10 | var minifycss = require('gulp-clean-css') 11 | //var autoprefixer = require('gulp-autoprefixer') 12 | var sass = require('gulp-sass') 13 | var automerge = require('gulp-automerge'); 14 | var rename = require('gulp-rename') 15 | var imagemin = require('gulp-imagemin') 16 | var htmlmin = require('gulp-html-minify') 17 | var clean = require('gulp-clean'); 18 | var template = require('gulp-template'); 19 | var autoprefixer = require('gulp-autoprefixer'); 20 | 21 | var config = require('./gulpConfig'); 22 | var srcPath = config.srcPath; 23 | var distPath = config.distPath; 24 | 25 | var options = gutil.env; 26 | var env = options.e || 'pro';//连接环境 27 | var dev = options.dev || false;//连接环境 28 | var tpls = {}, 29 | tplKeys = Object.keys(config.templateVar[env]) || []; 30 | 31 | tplKeys.map(function(key){ 32 | tpls[key] = (typeof config.templateVar[env][key] == 'object')?JSON.stringify(config.templateVar[env][key]):config.templateVar[env][key]; 33 | }) 34 | 35 | var handleError = function (err) { 36 | var colors = gutil.colors; 37 | console.log('\n') 38 | gutil.log(colors.red('Error!')) 39 | gutil.log('fileName: ' + colors.red(err.fileName)) 40 | gutil.log('lineNumber: ' + colors.red(err.lineNumber)) 41 | gutil.log('message: ' + err.message) 42 | gutil.log('plugin: ' + colors.yellow(err.plugin)) 43 | } 44 | 45 | gulp.task("clean", function(){ 46 | return gulp.src(distPath+'/*') 47 | .pipe(clean()); 48 | }) 49 | 50 | gulp.task('template', function() { 51 | gulp.src(config.tplConf.src) 52 | .pipe(template({domainConf: JSON.stringify(config.templateVar[env].domainConf)})) 53 | .pipe(gulp.dest(distPath)) 54 | }); 55 | 56 | gulp.task('watchhtml', function () { 57 | gulp.watch(config.other.src, function (event) { 58 | var paths = watchPath(event, srcPath, distPath) 59 | /* 60 | paths 61 | { srcPath: 'src/js/log.js', 62 | srcDir: 'src/js/', 63 | distPath: 'dist/js/log.js', 64 | distDir: 'dist/js/', 65 | srcFilename: 'log.js', 66 | distFilename: 'log.js' } 67 | */ 68 | gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath) 69 | gutil.log('Dist ' + paths.distPath) 70 | gulp.src(paths.srcPath) 71 | .pipe(htmlmin()) 72 | .pipe(gulp.dest(paths.distDir)); 73 | }) 74 | }) 75 | 76 | gulp.task('htmlmin', function () { 77 | gulp.src(config.other.src,{base:srcPath}) 78 | .pipe(htmlmin()) 79 | .pipe(gulp.dest(distPath)); 80 | }); 81 | 82 | gulp.task('watchjs', function () { 83 | gulp.watch(config.js.src, function (event) { 84 | var paths = watchPath(event, srcPath, distPath) 85 | gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath) 86 | gutil.log('Dist ' + paths.distPath) 87 | 88 | var combined = dev?combiner.obj([ 89 | gulp.src(paths.srcPath), 90 | //sourcemaps.init(), 91 | template(tpls), 92 | //sourcemaps.write('./'), 93 | gulp.dest(paths.distDir) 94 | ]):combiner.obj([ 95 | gulp.src(paths.srcPath), 96 | //sourcemaps.init(), 97 | template({ 98 | domainConf: JSON.stringify(config.templateVar[env].domainConf), 99 | environment:config.templateVar[env].environment 100 | }), 101 | uglify(), 102 | //sourcemaps.write('./'), 103 | gulp.dest(paths.distDir) 104 | ]); 105 | 106 | combined.on('error', handleError); 107 | }) 108 | }) 109 | 110 | gulp.task('uglifyjs', function () { 111 | 112 | 113 | 114 | var combined = dev?combiner.obj([ 115 | gulp.src(config.js.src), 116 | //sourcemaps.init(), 117 | template(tpls), 118 | //sourcemaps.write('./'), 119 | gulp.dest(distPath) 120 | ]):combiner.obj([ 121 | gulp.src(config.js.src), 122 | //sourcemaps.init(), 123 | template({ 124 | domainConf: JSON.stringify(config.templateVar[env].domainConf), 125 | environment:config.templateVar[env].environment 126 | }), 127 | uglify(), 128 | //sourcemaps.write('./'), 129 | gulp.dest(distPath) 130 | ]); 131 | combined.on('error', handleError) 132 | }) 133 | 134 | 135 | gulp.task('watchsass',function () { 136 | gulp.watch(config.css.src, function (event) { 137 | var paths = watchPath(event, srcPath, distPath) 138 | 139 | gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath) 140 | gutil.log('Dist ' + paths.distPath) 141 | gulp.src(paths.srcPath) 142 | .on('error', function (err) { 143 | console.error('Error!', err.message); 144 | }) 145 | //.pipe(sourcemaps.init()) 146 | .pipe(automerge({ 147 | prefixApplyType: 'all', 148 | prefixText: '@import "{relativePrefix}style/base/_variables.scss"; @import "{relativePrefix}style/base/_mixin.scss"; @import "{relativePrefix}style/base/_animation.scss";', 149 | replaceExt: '.wxml', 150 | regexp:/]*src=[\'\"][^\'\"]+?\/template\/([\w-]+)\/\w+\.\w+[\'\"]\s*\/>/g, 151 | appendTpl: '@import "{relativePrefix}template/{name}/index.scss";' 152 | })) 153 | .pipe(sass({outputStyle: 'compressed'})) 154 | .pipe(autoprefixer({ 155 | browsers: ['last 2 versions', 'Android >= 4.0', 'iOS >= 8.0'], 156 | cascade: true, 157 | remove:true //是否去掉不必要的前缀 默认:true 158 | })) 159 | .pipe(rename({ 160 | extname: ".wxss" 161 | })) 162 | //.pipe(minifycss({advanced:false})) 163 | //.pipe(sourcemaps.write('./')) 164 | .pipe(gulp.dest(paths.distDir)) 165 | }) 166 | }) 167 | 168 | gulp.task('sasscss', function () { 169 | gulp.src(config.css.src) 170 | .on('error', function (err) { 171 | console.error('Error!', err.message); 172 | }) 173 | //.pipe(sourcemaps.init()) 174 | .pipe(automerge({ 175 | prefixApplyType: 'all', 176 | prefixText: '@import "{relativePrefix}style/base/_variables.scss"; @import "{relativePrefix}style/base/_mixin.scss"; @import "{relativePrefix}style/base/_animation.scss";', 177 | replaceExt: '.wxml', 178 | regexp:/]*src=[\'\"][^\'\"]+?\/template\/([\w-]+)\/\w+\.\w+[\'\"]\s*\/>/g, 179 | appendTpl: '@import "{relativePrefix}template/{name}/index.scss";' 180 | })) 181 | .pipe(sass({outputStyle: 'compressed'})) 182 | .pipe(autoprefixer({ 183 | browsers: ['last 2 versions', 'Android >= 4.0', 'iOS >= 8.0'], 184 | cascade: true, 185 | remove:true //是否去掉不必要的前缀 默认:true 186 | })) 187 | .pipe(rename({ 188 | extname: ".wxss" 189 | })) 190 | //.pipe(minifycss({advanced:false})) 191 | //.pipe(sourcemaps.write('./')) 192 | .pipe(gulp.dest(distPath)) 193 | }) 194 | 195 | gulp.task('watchimage', function () { 196 | gulp.watch(config.image.src, function (event) { 197 | var paths = watchPath(event, srcPath, distPath) 198 | 199 | gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath) 200 | gutil.log('Dist ' + paths.distPath) 201 | 202 | gulp.src(paths.srcPath) 203 | .pipe(imagemin({ 204 | progressive: true 205 | })) 206 | .pipe(gulp.dest(paths.distDir)) 207 | }) 208 | }) 209 | 210 | gulp.task('image', function () { 211 | gulp.src(config.image.src) 212 | .pipe(imagemin({ 213 | progressive: true 214 | })) 215 | .pipe(gulp.dest(distPath + 'images')) 216 | }) 217 | 218 | gulp.task('default', ['clean'], function(){ 219 | gulp.start( 220 | // build 221 | 'uglifyjs', 'sasscss', 'htmlmin', 222 | // watch 223 | 'watchjs', 'watchsass', 'watchhtml' 224 | ); 225 | }) 226 | 227 | gulp.task('build', ['clean'], function(){ 228 | gulp.start('uglifyjs', 'sasscss', 'htmlmin','image'); 229 | }); 230 | gulp.task('watch', ['watchjs', 'watchsass', 'watchhtml']) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bbxx", 3 | "description": "", 4 | "author": "", 5 | "scripts": { 6 | "dev": "gulp", 7 | "build": "gulp build", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "devDependencies": { 11 | "gulp": "^3.9.1", 12 | "gulp-automerge": "^1.0.6", 13 | "gulp-clean": "^0.3.2", 14 | "gulp-clean-css": "^2.3.2", 15 | "gulp-html-minify": "0.0.14", 16 | "gulp-imagemin": "^3.1.1", 17 | "gulp-rename": "^1.2.2", 18 | "gulp-sass": "^3.0.0", 19 | "gulp-template": "^4.0.0", 20 | "gulp-uglify": "^2.0.0", 21 | "gulp-util": "^3.0.7", 22 | "gulp-watch-path": "^0.1.0", 23 | "gulp-autoprefixer":"^3.1.1", 24 | "stream-combiner2": "^1.1.1" 25 | } 26 | } -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | var scopeNotices = {}, 3 | config = require('./config'), 4 | scopeVersion = '1.0.0'; 5 | var navigateTo = wx.navigateTo; 6 | Object.defineProperty(wx, 'navigateTo', { 7 | get : function () { 8 | return function (params) { 9 | var pageStack = getCurrentPages(); 10 | if(pageStack.length==5){ 11 | console.log('navigateTo to redirectTo....'); 12 | wx.redirectTo(params); 13 | }else{ 14 | navigateTo(params); 15 | } 16 | } 17 | } 18 | }) 19 | 20 | App({ 21 | version: scopeVersion, 22 | 23 | onLaunch : function (e) { 24 | 25 | var _this = this; 26 | wx.getSystemInfo({ 27 | success: function(res) { 28 | _this.systemInfo = res; 29 | if(+res.version.replace('.','')>65){ 30 | _this.downloadInitImg();//缓存常用图片 31 | } 32 | } 33 | }) 34 | }, 35 | 36 | getNotices: function(page, action){//action 规定以__pna(pageNoticeAction)为前缀 37 | if(!page || !scopeNotices[page])return ''; 38 | return action?scopeNotices[page][action]:scopeNotices[page]; 39 | }, 40 | 41 | postPageNotices: function(page, action, payload){ 42 | if(!page || !action)return; 43 | if(!scopeNotices[page])scopeNotices[page] = {}; 44 | scopeNotices[page][action] = payload || ''; 45 | }, 46 | 47 | removeNotices: function(page, action){ 48 | if(page){ 49 | if(action){ 50 | scopeNotices[page][action] = null; 51 | }else{ 52 | scopeNotices[page] = null; 53 | } 54 | } 55 | }, 56 | 57 | dispatchNotices: function(page){//处理消息,一般在页面的onShow事件里调用 58 | //获取页面消息 59 | var pageObj = this.getNotices(page.name); 60 | if(pageObj){ 61 | for(var method in pageObj){ 62 | page['__pna'+method] && page['__pna'+method].call(page,pageObj[method]); 63 | } 64 | this.removeNotices(page.name); 65 | } 66 | }, 67 | 68 | downloadInitImg : function(){ 69 | //下载图片 70 | var _this = this, 71 | fileCache = require("./utils/fileCache"); 72 | var cacheFile = function(name){ 73 | fileCache.cacheFileToLocal({ 74 | name:name, 75 | url:_this.globalData.commonImage[name], 76 | success:function(fileName){ 77 | _this.globalData.commonImage[name] = fileName; 78 | } 79 | }); 80 | } 81 | 82 | var cacheImage = _this.globalData.commonImage; 83 | wx.getStorage({ 84 | key: 'version', 85 | success: function(res) { 86 | var version = res.data; 87 | if(version != scopeVersion){ 88 | fileCache.removeCacheFiles(); 89 | 90 | for(var k in cacheImage){ 91 | (function(k){cacheFile(k);})(k); 92 | } 93 | wx.setStorage({ 94 | key:"version", 95 | data:scopeVersion 96 | }) 97 | }else{ 98 | for(var k in cacheImage){ 99 | cacheImage[k] = fileCache.getCacheFilePath(k) || cacheImage[k]; 100 | } 101 | } 102 | } 103 | }) 104 | }, 105 | 106 | showAlert : function(options){ 107 | if(typeof options!='object' || !options.content){ 108 | return; 109 | } 110 | wx.showModal && wx.showModal({ 111 | title: options.title || '提示', 112 | content: options.content, 113 | showCancel: options.showCancel || false, 114 | confirmText: options.confirmText || '确定', 115 | success: function(res) { 116 | if (res.confirm) { 117 | options.confirmFun && options.confirmFun(); 118 | }else{ 119 | options.cannelFun && options.cannelFun(); 120 | } 121 | } 122 | }) 123 | }, 124 | 125 | globalData : config 126 | }); -------------------------------------------------------------------------------- /src/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages" : [ 3 | "pages/index/index", 4 | "pages/item/index", 5 | "pages/my/index", 6 | "pages/my/list", 7 | "pages/my/follow", 8 | "pages/my/collect", 9 | "pages/my/setpwd", 10 | "pages/login/login", 11 | "pages/upload/index", 12 | "pages/register/register" 13 | ], 14 | 15 | "window" : { 16 | "backgroundTextStyle":"dark", 17 | "navigationBarBackgroundColor": "#ff6699", 18 | "navigationBarTitleText": "贝比秀秀", 19 | "navigationBarTextStyle":"white" 20 | }, 21 | "networkTimeout" : { 22 | "request" : 10000, 23 | "downloadFile" : 20000 24 | }, 25 | "tabBar": { 26 | "color": "#666", 27 | "selectedColor": "#ff6699", 28 | "borderStyle": "black", 29 | "backgroundColor": "#eeeeee", 30 | "list": [{ 31 | "pagePath": "pages/index/index", 32 | "text": "首页", 33 | "selectedIconPath": "images/home.png", 34 | "iconPath": "images/home.png" 35 | }, { 36 | "pagePath": "pages/upload/index", 37 | "text": "上传", 38 | "selectedIconPath": "images/add.png", 39 | "iconPath": "images/add.png" 40 | }, { 41 | "pagePath": "pages/my/index", 42 | "text": "我的", 43 | "selectedIconPath": "images/my.png", 44 | "iconPath": "images/my.png" 45 | }] 46 | }, 47 | "weweb": { 48 | "loginUrl":"pages/login/login" 49 | }, 50 | "debug" : true 51 | } -------------------------------------------------------------------------------- /src/app.wxss: -------------------------------------------------------------------------------- 1 | @import "./style/base/_reset.scss"; 2 | /**app.wxss**/ 3 | page{ 4 | min-height: 100%; 5 | } 6 | .container { 7 | height: 100%; 8 | box-sizing: border-box; 9 | color:#222; 10 | } 11 | .border-bottom{ 12 | border-bottom: 1px solid #efefef; 13 | } 14 | /*底部固定的添加按钮*/ 15 | .tabbar-button{ 16 | position: fixed; 17 | width:100%; 18 | height:112rpx; 19 | line-height:112rpx; 20 | border-top:1rpx solid #9a9a9a; 21 | bottom:0; 22 | left:0; 23 | background-color:rgba(247,247,247,.96); 24 | text-align: center; 25 | } 26 | .tabbar-text-add{ 27 | display: inline-block; 28 | font-size: 32rpx; 29 | color: #000; 30 | margin: 31rpx auto; 31 | height: 50rpx; 32 | line-height: 50rpx; 33 | padding-left: 50rpx; 34 | background:url("https://s.geilicdn.com/weidian_lite/v1.0.0/images/item/add.png") left 5rpx no-repeat; 35 | background-size:40rpx; 36 | text-align: center; 37 | } 38 | 39 | /*列表页面没数据时的错误提示样式*/ 40 | .container-block-err{ 41 | color:#9a9a9a; 42 | font-size: 32rpx; 43 | width: 100%; 44 | height: 300rpx; 45 | line-height: 300rpx; 46 | text-align: center; 47 | } 48 | /*弹出对话框*/ 49 | .win-mask{ 50 | position: fixed; 51 | top:0; 52 | left:0; 53 | width: 100%; 54 | height: 100%; 55 | background: rgba(0,0,0,0.3); 56 | z-index: 100; 57 | } 58 | .win-container{ 59 | position: absolute; 60 | top:0; 61 | left:0; 62 | bottom: 0; 63 | width: 100%; 64 | height: 100%; 65 | z-index: 200; 66 | display: flex; 67 | align-items: center; 68 | align-content: center; 69 | text-align: center; 70 | } 71 | .win-form{ 72 | position: relative; 73 | width: 450rpx; 74 | background: #fff; 75 | padding: 30rpx 25rpx; 76 | margin: 0 auto; 77 | border-radius: 8rpx; 78 | z-index: 111; 79 | } 80 | .win-form-icon{ 81 | position: absolute; 82 | top:-12rpx; 83 | right: -5rpx; 84 | width:40rpx; 85 | height:40rpx; 86 | z-index: 222; 87 | } 88 | .win-form-textarea{ 89 | width: 420rpx; 90 | border: 1rpx solid #989898 !important; 91 | border-radius: 5rpx; 92 | height: 280rpx; 93 | line-height: 24rpx; 94 | text-align: left; 95 | font-size: 28rpx; 96 | padding: 10rpx 15rpx; 97 | margin-bottom: 15rpx; 98 | } 99 | .win-form-tip{ 100 | font-size: 24rpx; 101 | color: #7f7f7f; 102 | line-height: 28rpx; 103 | margin: 10rpx auto; 104 | text-align: left; 105 | } 106 | .win-form-footer{ 107 | width: 100%; 108 | overflow: hidden; 109 | } 110 | .win-form-submit{ 111 | font-size: 30rpx; 112 | width: 50%; 113 | text-align: center; 114 | color: #fff!important; 115 | margin: 25rpx auto 40rpx; 116 | background: #C60A1E!important; 117 | } 118 | 119 | .ellipsis{ 120 | white-space: nowrap; 121 | text-overflow: ellipsis; 122 | overflow: hidden; 123 | } 124 | 125 | .button-disabled{ 126 | color:rgba(255, 255, 255, 0.5)!important; 127 | } 128 | 129 | .navigator-hover { 130 | background:rgba(255, 255, 255, 0); 131 | } 132 | 133 | /*全局动画样式开始*/ 134 | .animated { 135 | -webkit-animation-duration: 1s; 136 | animation-duration: 1s; 137 | -webkit-animation-fill-mode: both; 138 | animation-fill-mode: both; 139 | } 140 | 141 | @-webkit-keyframes fadeIn { 142 | from { 143 | opacity: 0; 144 | } 145 | to { 146 | opacity: 1; 147 | } 148 | } 149 | 150 | @keyframes fadeIn { 151 | from { 152 | opacity: 0; 153 | } 154 | to { 155 | opacity: 1; 156 | } 157 | } 158 | .fadeIn { 159 | -webkit-animation-name: fadeIn; 160 | animation-name: fadeIn; 161 | } 162 | 163 | 164 | @-webkit-keyframes rotate{ 165 | 0%{ 166 | -webkit-transform:rotate(0deg); 167 | } 168 | 100%{ 169 | -webkit-transform:rotate(360deg); 170 | } 171 | } 172 | @keyframes rotate{ 173 | 0%{ 174 | transform:rotate(0deg); 175 | } 176 | 100%{ 177 | transform:rotate(360deg); 178 | } 179 | } 180 | .rotate{ 181 | -webkit-animation:rotate 2s infinite linear; 182 | animation:rotate 2s infinite linear; 183 | } 184 | /*全局动画样式结束*/ 185 | .praise-icon{ 186 | background: url('data:image/png;base64,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') no-repeat; 187 | background-size: 26rpx 28rpx; 188 | background-position: 20rpx center; 189 | } 190 | .bt-share{ 191 | margin: 30rpx auto; 192 | } 193 | .container-list-empty{ 194 | text-align: center; 195 | font-size: 28rpx; 196 | line-height: 80rpx; 197 | margin: 140rpx 20rpx; 198 | } -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | domain : <%= domainConf %>, 3 | userInfo : {} 4 | } -------------------------------------------------------------------------------- /src/images/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/add.png -------------------------------------------------------------------------------- /src/images/album.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/album.png -------------------------------------------------------------------------------- /src/images/arrow_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/arrow_left.png -------------------------------------------------------------------------------- /src/images/awm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/awm.jpg -------------------------------------------------------------------------------- /src/images/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/card.png -------------------------------------------------------------------------------- /src/images/collect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/collect.png -------------------------------------------------------------------------------- /src/images/emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/emoji.png -------------------------------------------------------------------------------- /src/images/group_chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/group_chat.png -------------------------------------------------------------------------------- /src/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/home.png -------------------------------------------------------------------------------- /src/images/my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/my.png -------------------------------------------------------------------------------- /src/images/new_friend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/new_friend.png -------------------------------------------------------------------------------- /src/images/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/photo.png -------------------------------------------------------------------------------- /src/images/picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/picture.png -------------------------------------------------------------------------------- /src/images/praise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/praise.png -------------------------------------------------------------------------------- /src/images/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgfxm/bbxx/269d33af91142e02f4920e5a2a8b1b481d094c92/src/images/setting.png -------------------------------------------------------------------------------- /src/modules/lib/formVerify.js: -------------------------------------------------------------------------------- 1 | var mod = { 2 | checkPrice: function(price){ 3 | if(!/^\d+(\.\d*)?$/.test(price)){ 4 | return false; 5 | } 6 | 7 | return true; 8 | }, 9 | 10 | checkNum: function(num){ 11 | if(!/^\d+$/.test(num)){ 12 | return false; 13 | } 14 | 15 | return true; 16 | }, 17 | 18 | checkMail: function(str) { 19 | return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(str) 20 | }, 21 | 22 | checkPhone: function(str) { 23 | return /^1[34578]\d{9}$/.test('' + str) 24 | } 25 | } 26 | module.exports = mod; -------------------------------------------------------------------------------- /src/modules/lib/mathUtil.js: -------------------------------------------------------------------------------- 1 | var mod = { 2 | //浮点数加法运算 3 | floatAdd:function(arg1,arg2,n){ 4 | var r1,r2,m; 5 | try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 6 | try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 7 | m=Math.pow(10,Math.max(r1,r2)) 8 | //动态控制精度长度 9 | if(n==undefined)n=(r1>=r2)?r1:r2; 10 | return ((arg1*m+arg2*m)/m).toFixed(n); 11 | }, 12 | 13 | //浮点数减法运算 14 | floatSub:function(arg1,arg2,n){ 15 | var r1,r2,m; 16 | try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 17 | try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 18 | m=Math.pow(10,Math.max(r1,r2)); 19 | //动态控制精度长度 20 | if(n==undefined)n=(r1>=r2)?r1:r2; 21 | return ((arg1*m-arg2*m)/m).toFixed(n); 22 | }, 23 | 24 | //浮点数乘法运算 25 | floatMul:function(arg1,arg2) 26 | { 27 | var m=0,s1=arg1.toString(),s2=arg2.toString(); 28 | try{m+=s1.split(".")[1].length}catch(e){} 29 | try{m+=s2.split(".")[1].length}catch(e){} 30 | return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m) 31 | }, 32 | 33 | 34 | //浮点数除法运算 35 | floatDiv:function(arg1,arg2){ 36 | var t1=0,t2=0,r1,r2; 37 | try{t1=arg1.toString().split(".")[1].length}catch(e){} 38 | try{t2=arg2.toString().split(".")[1].length}catch(e){} 39 | r1=Number(arg1.toString().replace(".","")) 40 | r2=Number(arg2.toString().replace(".","")) 41 | return (r1/r2)*Math.pow(10,t2-t1); 42 | } 43 | }; 44 | module.exports = mod; -------------------------------------------------------------------------------- /src/modules/lib/swipe.js: -------------------------------------------------------------------------------- 1 | var mod = { 2 | startPos: [0,0], 3 | startTouch:function(e){ 4 | if(!e)return; 5 | this.startPos = [e.pageX, e.pageY]; 6 | }, 7 | setCurPos:function(e) 8 | { 9 | if(!e)return; 10 | this.curPos = [e.pageX, e.pageY]; 11 | this.calculateGap(); 12 | }, 13 | calculateGap: function(){ 14 | this.gapX = this.curPos[0] - this.startPos[0]; 15 | this.gapY = this.curPos[1] - this.startPos[1]; 16 | } 17 | }; 18 | module.exports = mod; -------------------------------------------------------------------------------- /src/modules/lib/util.js: -------------------------------------------------------------------------------- 1 | var userInfo = {}; 2 | const BASE_DEVICE_WIDTH = 750 3 | const EPS = 0.0001 4 | var width = 0 5 | var dpr = 1 6 | wx.getSystemInfo({ 7 | success: function(res) { 8 | width = res.windowWidth; 9 | dpr = res.pixelRatio; 10 | } 11 | }); 12 | module.exports = { 13 | loginMod: null, 14 | loadModule: function (name) { 15 | return require("../" + name + "/index"); 16 | }, 17 | transformByDPR: function(a) { 18 | a = a / BASE_DEVICE_WIDTH * width 19 | a = Math.floor(a + EPS) 20 | 21 | return a 22 | }, 23 | getUserInfo: function () { 24 | if (this.loginMod && !userInfo.id) { 25 | userInfo = this.loginMod.getUserInfo(); 26 | } 27 | return userInfo; 28 | }, 29 | resetUserInfo: function () { 30 | userInfo = {}; 31 | }, 32 | toType: function (obj) { 33 | return Object.prototype.toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase(); 34 | }, 35 | isString: function (val) { 36 | return this.toType(val) === "string"; 37 | }, 38 | isArray: function (val) { 39 | return Array.isArray(val); // || Object.prototype.toString.call(val) === '[object Array]' 40 | }, 41 | isObject: function (val) { 42 | return val === Object(val); 43 | }, 44 | isPlainObject: function (obj) { 45 | if (this.toType(obj) !== "object" || obj.nodeType) { 46 | return false; 47 | } 48 | 49 | try { 50 | if (obj.constructor && 51 | !{}.hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")) { 52 | return false; 53 | } 54 | } catch (e) { 55 | return false; 56 | } 57 | return true; 58 | }, 59 | isFunction: function (val) { 60 | return Object.prototype.toString.call(val) === '[object Function]'; 61 | }, 62 | isNumeric: function (val) { 63 | return typeof (val) === 'number'; 64 | }, 65 | 66 | extend: function () { 67 | var options, name, src, copy, copyIsArray, clone, 68 | target = arguments[0] || {}, 69 | i = 1, 70 | length = arguments.length, 71 | deep = false; 72 | 73 | // Handle a deep copy situation 74 | if (typeof target === "boolean") { 75 | deep = target; 76 | target = arguments[1] || {}; 77 | // skip the boolean and the target 78 | i = 2; 79 | } 80 | 81 | // Handle case when target is a string or something (possible in deep copy) 82 | if (typeof target !== "object" && !this.isFunction(target)) { 83 | target = {}; 84 | } 85 | 86 | // extend $ itself if only one argument is passed 87 | if (length === i) { 88 | return target; 89 | } 90 | 91 | for (; i < length; i++) { 92 | // Only deal with non-null/undefined values 93 | if ((options = arguments[i]) != null) { 94 | // Extend the base object 95 | for (name in options) { 96 | src = target[name]; 97 | copy = options[name]; 98 | 99 | // Prevent never-ending loop 100 | if (target === copy) { 101 | continue; 102 | } 103 | 104 | // Recurse if we're merging plain objects or arrays 105 | if (deep && copy && (this.isPlainObject(copy) || (copyIsArray = this.isArray(copy)))) { 106 | if (copyIsArray) { 107 | copyIsArray = false; 108 | clone = src && this.isArray(src) ? src : []; 109 | 110 | } else { 111 | clone = src && this.isPlainObject(src) ? src : {}; 112 | } 113 | 114 | // Never move original objects, clone them 115 | target[name] = this.extend(deep, clone, copy); 116 | 117 | // Don't bring in undefined values 118 | } else if (copy !== undefined) { 119 | target[name] = copy; 120 | } 121 | } 122 | } 123 | } 124 | 125 | return target; 126 | }, 127 | 128 | request: function (opt,noCheckUser) { 129 | var _this = this; 130 | if (opt.showLoading !== false) { 131 | wx.showToast({ 132 | mask: opt.showMask || false, 133 | title: '加载中', 134 | icon: 'loading', 135 | duration: 10000 136 | }); 137 | } 138 | var data = opt.data || {}; 139 | /* 140 | this.getUserInfo(); 141 | if (userInfo.id && !noCheckUser) { 142 | data.userId = userInfo.id; 143 | data.token = userInfo.token; 144 | } 145 | */ 146 | //data.debug_port = 'sandbox1'; 147 | function requestFail(res) { 148 | opt.fail && opt.fail(res); 149 | } 150 | 151 | function requestSuccess(rt) { 152 | if(rt.statusCode > 400) { 153 | requestFail(rt) 154 | } else if (opt.succOption) { 155 | opt.succOption.data = rt.data; 156 | _this.checkAjaxResult(opt.succOption, opt); 157 | } else { 158 | opt.success && opt.success(rt); 159 | } 160 | } 161 | 162 | wx.request({ 163 | url: opt.url, 164 | data: data, 165 | method: opt.method || "GET", 166 | complete: function () { 167 | wx.hideToast(); 168 | opt.complete && opt.complete(); 169 | }, 170 | success: requestSuccess, 171 | fail: requestFail 172 | }); 173 | }, 174 | 175 | 176 | 177 | showModal: function (content, success) { 178 | if (typeof content == 'object') { 179 | var opt = content; 180 | } else if (typeof content == 'string') { 181 | var opt = { 182 | title: content, 183 | success: success 184 | } 185 | } else { 186 | return; 187 | } 188 | wx.showModal({ 189 | title: opt.title || '', 190 | content: opt.content || '', 191 | showCancel: opt.showCancel || false, 192 | confirmText: opt.confirmText || '确定', 193 | success: function (res) { 194 | typeof opt.success == 'function' && opt.success(res); 195 | } 196 | }) 197 | }, 198 | 199 | checkAjaxResult: function (obj, opt) { 200 | var _this = this, 201 | data = obj.data, 202 | code = Number(data.status.status_code); 203 | 204 | if (code === 120) { 205 | //console.log("登录已过期,请重新登录"); 206 | if (_this.loginMod) { //登录失效自动静默登录 207 | _this.resetUserInfo(); 208 | _this.loginMod.config.loginCb.success = function () { 209 | _this.request(opt); 210 | _this.loginMod.config.loginCb.success = null; 211 | } 212 | _this.loginMod.doLogin(); 213 | } else { 214 | _this.showModal({ 215 | title: '登录已过期,请重新登录', 216 | success: function (res) { 217 | if (res.confirm) { 218 | _this.loginMod && _this.loginMod.doLogout(); 219 | } 220 | } 221 | }); 222 | } 223 | return; 224 | } 225 | 226 | if (code === 0) { 227 | obj.success && obj.success(data); 228 | } else { 229 | if (obj.error) { 230 | obj.error(data); 231 | } else if (data.status.status_reason) { 232 | _this.showModal(data.status.status_reason); 233 | } 234 | } 235 | }, 236 | 237 | /** 238 | * 对象赋值拷贝 239 | * 240 | * @param {object} target and other objects 241 | * @returns {object} 拷贝后的对象 242 | */ 243 | assign: function (target) { 244 | 245 | if (typeof Object.assign == 'function') { 246 | return Object.assign.apply(null, Array.prototype.slice.call(arguments)); 247 | } 248 | 249 | if (target == null) { 250 | throw new TypeError('Cannot convert undefined or null to object'); 251 | } 252 | target = Object(target); 253 | for (var index = 1; index < arguments.length; index++) { 254 | var source = arguments[index]; 255 | if (source != null) { 256 | for (var key in source) { 257 | if (Object.prototype.hasOwnProperty.call(source, key)) { 258 | target[key] = source[key]; 259 | } 260 | } 261 | } 262 | } 263 | return target; 264 | }, 265 | } 266 | -------------------------------------------------------------------------------- /src/modules/login/index.js: -------------------------------------------------------------------------------- 1 | const storageKey = 'TOKEN_INFO'; 2 | var userLoginInfo = {}, 3 | config = require('../../config'), 4 | util = require('../lib/util'), 5 | domain = config && config.domain.sso || 'https://wxshow.vipsinaapp.com'; 6 | var app = getApp(); 7 | 8 | wx.getStorage({ 9 | key: storageKey, 10 | success: function(res) { 11 | userLoginInfo = res.data || {}; 12 | } 13 | }); 14 | 15 | var login = { 16 | storageKey: storageKey, 17 | config: { 18 | loginApi: domain +"/wx.php?m=weapp&act=login", 19 | loginCb:{ 20 | complete: null, 21 | success: null 22 | }, 23 | }, 24 | 25 | getUserInfo: function(){ 26 | if(userLoginInfo){ 27 | if(!userLoginInfo.id){ 28 | //userLoginInfo = wx.getStorageSync(storageKey); 29 | wx.getStorage({ 30 | key: storageKey, 31 | success: function(res) { 32 | userLoginInfo = res.data || {}; 33 | } 34 | }); 35 | } 36 | }else{ 37 | userLoginInfo = {}; 38 | } 39 | return userLoginInfo; 40 | }, 41 | 42 | setLoginInfo: function(data){//登录后设置globalData和storage里的用户信息 43 | //写入本地缓存信息 44 | wx.setStorage({ 45 | key: storageKey, 46 | data:data 47 | }); 48 | userLoginInfo = data; 49 | this.config.loginCb.success && this.config.loginCb.success(data); 50 | }, 51 | 52 | setConfig: function(config){ 53 | this.getSystemInfo(); 54 | if(config){ 55 | util.extend(true, this.config, config); 56 | } 57 | }, 58 | 59 | getSystemInfo: function(){ 60 | this.systemInfo = app.systemInfo || wx.getSystemInfoSync(); 61 | this.curSystem = this.systemInfo.system && this.systemInfo.system.split(' ')[0].toLowerCase(); 62 | }, 63 | 64 | isLogin: function(){ 65 | this.getUserInfo(); 66 | return !!userLoginInfo.id; 67 | }, 68 | 69 | doLogin: function(){ 70 | var _this = this; 71 | wx.login({ 72 | success: function(res) { 73 | var code = res.code 74 | 75 | if(!code){ 76 | util.showModal("获取登录code失败"); 77 | return; 78 | } 79 | 80 | wx.getUserInfo({ 81 | success: function(res){ 82 | wx.request({ 83 | url : _this.config.loginApi, 84 | data : { 85 | code : code, 86 | rawData : res.rawData, 87 | signature : res.signature, 88 | encryptData : res.encryptedData, 89 | iv : res.iv, 90 | wxid:'bbxx', 91 | clientType: _this.curSystem 92 | }, 93 | method : "GET", 94 | complete : function(rt){ 95 | _this.config.loginCb.complete && _this.config.loginCb.complete(rt); 96 | }, 97 | success : function(data){ 98 | //微信发起的请求成功 99 | var data = data.data, 100 | statusCode = Number(data.status.status_code); 101 | var rt = data.result; 102 | if(statusCode === 0){//console.log('login rt',rt); 103 | rt = util.extend(rt,JSON.parse(res.rawData));//console.log('login userinfo',rt); 104 | app.globalData.userInfo = rt; 105 | //绑定过 直接取信息 走人 106 | _this.setLoginInfo(rt); 107 | 108 | }else{ 109 | util.showModal(data.status.status_reason); 110 | 111 | } 112 | }, 113 | fail : function(e){ 114 | util.showModal("登录失败"); 115 | } 116 | }); 117 | }, 118 | fail : function(rt){ 119 | console.log(rt); 120 | if(rt.errMsg.match(/cancel|deny/) || _this.grantFail === true){ 121 | _this.grantFail = rt.grantFail = true; 122 | util.showModal({content:"由于你拒绝授权,用户信息无法获取,部分功能将不可用,请十分钟后再试"}); 123 | }else{ 124 | util.showModal("获取用户登录信息失败"); 125 | } 126 | _this.config.loginCb.complete && _this.config.loginCb.complete(rt); 127 | } 128 | }); 129 | }, 130 | fail : function(e){ 131 | util.showModal("获取用户登录code失败"); 132 | _this.config.loginCb.complete && _this.config.loginCb.complete(e); 133 | } 134 | }); 135 | 136 | }, 137 | 138 | doLogout: function(isBack,logoutCallback){ 139 | //退出登录 应该清除掉所有缓存信息 140 | wx.clearStorage(); 141 | util.resetUserInfo(); 142 | userLoginInfo = {}; 143 | app.globalData.userInfo = {}; 144 | logoutCallback && logoutCallback(); 145 | if(isBack!==false){ 146 | wx.navigateBack({delta:getCurrentPages().length-1}); 147 | }//到回首页 148 | } 149 | } 150 | module.exports = util.loginMod = login; 151 | -------------------------------------------------------------------------------- /src/pages/index/index.js: -------------------------------------------------------------------------------- 1 | var app = getApp(); 2 | var toast = require('../../template/toast/index.js'); 3 | var util = require("../../utils/util.js"); 4 | 5 | Page({ 6 | scopeData:{ 7 | pageNum:1, 8 | pageSize:20, 9 | leftHeight:0, 10 | rightHeight:0, 11 | hids:[] 12 | }, 13 | data : { 14 | toast:{ 15 | show: false, 16 | isMask: false, 17 | content: '' 18 | }, 19 | loadmore: { 20 | isLoading : false,//正在加载 则显示加载动画 同时触发底部不更新 加载完毕 设置为false 21 | hideOverTip : false, 22 | isOver : false//全部加载完毕 23 | }, 24 | isEmpty:false, 25 | leftList:[], 26 | rightList:[] 27 | }, 28 | 29 | onLoad: function(e){ 30 | this.getList(); 31 | var login = require("../../modules/login/index.js"); 32 | if(!login.isLogin()){ 33 | login.doLogin(); 34 | }else{ 35 | app.globalData.userInfo = login.getUserInfo(); 36 | } 37 | }, 38 | 39 | getList: function(){ 40 | var self = this; 41 | if(self.data.loadmore.isLoading || self.data.loadmore.isOver){ 42 | return; 43 | } 44 | 45 | self.setData({ 46 | "loadmore.isLoading" : true, 47 | }); 48 | util.request({ 49 | url : app.globalData.domain.request+"/wx.php?m=weapp&act=GetPhotoList", 50 | data : { 51 | page : self.scopeData.pageNum, 52 | pageSize : self.scopeData.pageSize 53 | }, 54 | complete : function(){ 55 | var data = { 56 | "loadmore.isLoading" : false 57 | } 58 | if(!self.data.leftList.length){ 59 | data.isEmpty = true; 60 | } 61 | self.setData(data); 62 | }, 63 | success : function(res){ 64 | 65 | util.checkAjaxResult({ 66 | data : res.data, 67 | success : function(rt){ 68 | var data = {}, 69 | item,imgInfo, 70 | res = rt.result.items, 71 | length = res.length, 72 | curPage = self.scopeData.pageNum; 73 | 74 | if(length){ 75 | for(var i=0; iheight){ 88 | height = curHeight; 89 | } 90 | } 91 | if(group.praiseIds){ 92 | group.praiseIds = group.praiseIds.split(','); 93 | } 94 | 95 | data = { 96 | from: self.scopeData.from, 97 | height: height+'rpx', 98 | items : self.data.items, 99 | group : group, 100 | praiseUser: praiseUser || [], 101 | praiseStatus:self.scopeData.userId?(~group.praiseIds.indexOf(self.scopeData.userId)?true:false):false 102 | }; 103 | //console.log(data) 104 | if(self.data.items.length<=1){ 105 | data.indicatorDots = false; 106 | } 107 | self.setData(data); 108 | } else { 109 | self.showError("该相册不存在"); 110 | } 111 | } 112 | }); 113 | }, 114 | fail : function(){ 115 | self.showError("获取相片列表失败"); 116 | } 117 | }); 118 | 119 | }, 120 | 121 | praise: function(e){ 122 | var self = this; 123 | if(this.data.praiseStatus){ 124 | return; 125 | } 126 | if(!this.scopeData.userId){ 127 | var msg = '点赞需要你授权允许使用你微信个人资料哦,请退出并删除小程序后再试'; 128 | toast.show(this,msg); 129 | return; 130 | } 131 | 132 | util.request({ 133 | url : app.globalData.domain.request+"/wx.php?m=weapp&act=Praise", 134 | data : { 135 | hid : self.scopeData.id, 136 | userid: self.scopeData.userId 137 | }, 138 | success : function(res){ 139 | //这里需要将proxy的接口数据进行过滤 再次检测实际接口的数据 140 | util.checkAjaxResult({ 141 | data : res.data, 142 | success : function(rt){ 143 | self.data.praiseUser || (self.data.praiseUser=[]) 144 | self.data.praiseUser.push({ 145 | id:app.globalData.userInfo.id, 146 | name:app.globalData.userInfo.nickName, 147 | img:app.globalData.userInfo.avatarUrl 148 | }); 149 | self.setData({ 150 | praiseUser: self.data.praiseUser, 151 | praiseStatus:true 152 | }); 153 | } 154 | }); 155 | }, 156 | fail : function(){ 157 | toast.show(self,'出错了哦'); 158 | } 159 | }); 160 | 161 | }, 162 | /** 163 | * 设置分享 164 | */ 165 | onShareAppMessage: function () { 166 | var self = this; 167 | return { 168 | title: self.data.group.title || '相册详情', 169 | desc: '萌娃如云,不看后悔', 170 | path: '/pages/item/index?from=share&id='+self.scopeData.id 171 | } 172 | }, 173 | goUserHome: function(e){ 174 | var id = e.currentTarget.dataset.id; 175 | wx.redirectTo({ 176 | url:'/pages/my/list?userid='+id 177 | }); 178 | }, 179 | 180 | previewImage: function (e) { 181 | var url = e.currentTarget.dataset.url; 182 | wx.previewImage({ 183 | current: url, 184 | urls: this.scopeData.imgs // 需要预览的图片http链接列表 185 | }) 186 | 187 | }, 188 | showError: function(msg){ 189 | toast.show(this,msg); 190 | wx.navigateBack(); 191 | } 192 | }); -------------------------------------------------------------------------------- /src/pages/item/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "相册详情" 3 | } -------------------------------------------------------------------------------- /src/pages/item/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {{praiseStatus?'已赞':'赞'}} 15 | 16 | 17 | {{group.title}} 18 | 19 | 20 | {{group.name}} 进入他的主页 21 | 22 | 23 | 查看更多小朋友 24 | 25 | 26 |