├── .eslintignore ├── .gitignore ├── .prettierrc ├── src ├── store │ ├── actions │ │ ├── index.js │ │ └── counter.js │ ├── types │ │ ├── index.js │ │ └── counter.js │ ├── reducers │ │ ├── index.js │ │ └── counter.js │ └── index.js ├── style │ ├── base │ │ ├── variable │ │ │ ├── weui-button.less │ │ │ ├── weui-grid.less │ │ │ ├── weui-progress.less │ │ │ ├── weui-dialog.less │ │ │ ├── weui-msg.less │ │ │ ├── global.less │ │ │ ├── color.less │ │ │ └── weui-cell.less │ │ ├── reset.less │ │ ├── fn.less │ │ └── mixin │ │ │ ├── text.less │ │ │ ├── setOnepx.less │ │ │ └── setArrow.less │ ├── widget │ │ ├── weui-flex │ │ │ └── weui-flex.less │ │ ├── weui-cell │ │ │ ├── weui-switch.less │ │ │ ├── weui-form.less │ │ │ ├── weui-check.less │ │ │ ├── weui-access.less │ │ │ ├── weui-form │ │ │ │ ├── weui-vcode.less │ │ │ │ ├── weui-select.less │ │ │ │ ├── weui-form_common.less │ │ │ │ └── weui-form-preview.less │ │ │ ├── weui-cell.less │ │ │ └── weui-uploader.less │ │ ├── weui-button │ │ │ └── weui-button.less │ │ ├── weui-progress │ │ │ └── weui-progress.less │ │ ├── weui-tab │ │ │ ├── weui-tab.less │ │ │ └── weui-navbar.less │ │ ├── weui-tips │ │ │ ├── weui-badge.less │ │ │ └── weui-loadmore.less │ │ ├── weui-page │ │ │ ├── weui-article.less │ │ │ └── weui-msg.less │ │ ├── weui-panel │ │ │ └── weui-panel.less │ │ ├── weui-agree │ │ │ └── weui-agree.less │ │ ├── weui-footer │ │ │ └── weui-footer.less │ │ ├── weui-grid │ │ │ └── weui-grid.less │ │ ├── weui-animate │ │ │ └── weui-animate.less │ │ ├── weui-searchbar │ │ │ └── weui-searchbar.less │ │ ├── weui-media-box │ │ │ └── weui-media-box.less │ │ └── weui-loading │ │ │ └── weui-loading.less │ └── weui.less ├── images │ ├── user.png │ ├── index.png │ ├── reply.png │ ├── trash.png │ ├── category.png │ ├── index_selected.png │ └── user_selected.png ├── utils │ ├── util.js │ └── api.js ├── mixins │ ├── test.js │ ├── unreadCount.js │ └── replyMixin.js ├── components │ ├── replyCreate.wpy │ ├── groupitem.wpy │ ├── panel.wpy │ ├── group.wpy │ ├── list.wpy │ ├── wepy-list.wpy │ ├── counter.wpy │ └── topicList.wpy ├── index.template.html ├── pages │ ├── topics │ │ ├── userIndex.wpy │ │ ├── index.wpy │ │ └── show.wpy │ ├── replies │ │ ├── userIndex.wpy │ │ ├── index.wpy │ │ └── create.wpy │ ├── users │ │ ├── show.wpy │ │ ├── me.wpy │ │ └── edit.wpy │ ├── auth │ │ ├── login.wpy │ │ └── register.wpy │ └── notifications │ │ └── index.wpy └── app.wpy ├── .wepyignore ├── .editorconfig ├── project.config.json ├── .eslintrc.js ├── README.md ├── package.json ├── wepy.config.js └── .wepycache /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/* 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .DB_store 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /src/store/actions/index.js: -------------------------------------------------------------------------------- 1 | export * from './counter' 2 | -------------------------------------------------------------------------------- /src/store/types/index.js: -------------------------------------------------------------------------------- 1 | export * from './counter' 2 | -------------------------------------------------------------------------------- /src/style/base/variable/weui-button.less: -------------------------------------------------------------------------------- 1 | @weuiBtnDefaultGap:15px; -------------------------------------------------------------------------------- /.wepyignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .DB_store 4 | *.wpy___jb_tmp___ 5 | -------------------------------------------------------------------------------- /src/images/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/summerblue/larabbs-weapp/HEAD/src/images/user.png -------------------------------------------------------------------------------- /src/images/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/summerblue/larabbs-weapp/HEAD/src/images/index.png -------------------------------------------------------------------------------- /src/images/reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/summerblue/larabbs-weapp/HEAD/src/images/reply.png -------------------------------------------------------------------------------- /src/images/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/summerblue/larabbs-weapp/HEAD/src/images/trash.png -------------------------------------------------------------------------------- /src/images/category.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/summerblue/larabbs-weapp/HEAD/src/images/category.png -------------------------------------------------------------------------------- /src/images/index_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/summerblue/larabbs-weapp/HEAD/src/images/index_selected.png -------------------------------------------------------------------------------- /src/images/user_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/summerblue/larabbs-weapp/HEAD/src/images/user_selected.png -------------------------------------------------------------------------------- /src/style/base/variable/weui-grid.less: -------------------------------------------------------------------------------- 1 | @weuiGridBorderColor:#D9D9D9; 2 | @weuiGridFontSize: 14px; 3 | @weuiGridIconSize: 28px; 4 | @weuiGridColumnCount: 3; -------------------------------------------------------------------------------- /src/store/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | import counter from './counter' 3 | 4 | export default combineReducers({ 5 | counter 6 | }) 7 | -------------------------------------------------------------------------------- /src/store/types/counter.js: -------------------------------------------------------------------------------- 1 | export const INCREMENT = 'INCREMENT' 2 | 3 | export const DECREMENT = 'DECREMENT' 4 | 5 | export const ASYNC_INCREMENT = 'ASYNC_INCREMENT' 6 | -------------------------------------------------------------------------------- /src/style/widget/weui-flex/weui-flex.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-flex { 4 | display: flex; 5 | } 6 | .weui-flex__item{ 7 | flex: 1; 8 | } 9 | -------------------------------------------------------------------------------- /src/style/base/reset.less: -------------------------------------------------------------------------------- 1 | @import "fn.less"; 2 | 3 | page { 4 | line-height: 1.6; 5 | font-family: @weuiFontDefault; 6 | } 7 | 8 | icon{ 9 | vertical-align: middle; 10 | } 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /src/style/base/variable/weui-progress.less: -------------------------------------------------------------------------------- 1 | @weuiProgressBg: #EBEBEB; 2 | @weuiProgressColor: #09BB07; 3 | @weuiProgressHeight: 3px; 4 | @weuiProgressCloseBg: #EF4F4F; 5 | @weuiProgressActiveBg: #C13E3E; 6 | -------------------------------------------------------------------------------- /src/style/base/variable/weui-dialog.less: -------------------------------------------------------------------------------- 1 | @weuiDialogBackgroundColor: #FFFFFF; 2 | @weuiDialogLineColor: #D5D5D6; 3 | @weuiDialogLinkColor: #3CC51F; 4 | @weuiDialogLinkActiveBc: #EEEEEE; 5 | @weuiDialogGapWidth: 1.6em; 6 | -------------------------------------------------------------------------------- /src/style/base/variable/weui-msg.less: -------------------------------------------------------------------------------- 1 | @weuiMsgPaddingTop:36px; 2 | @weuiMsgIconGap:30px; 3 | @weuiMsgTitleGap:5px; 4 | @weuiMsgTextGap:25px; 5 | @weuiMsgOprGap:25px; 6 | @weuiMsgExtraAreaGap:15px; 7 | @weuiMsgExtraAreaOfMinHeight:438px; -------------------------------------------------------------------------------- /src/style/base/variable/global.less: -------------------------------------------------------------------------------- 1 | // font 2 | @weuiFontEN:-apple-system-font,"Helvetica Neue"; 3 | @weuiFontCN:"PingFang SC","Hiragino Sans GB","Microsoft YaHei"; 4 | @weuiFontSans:sans-serif; 5 | @weuiFontDefault:@weuiFontEN,@weuiFontSans; -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-switch.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-cell_switch{ 4 | padding-top: (@weuiCellHeight - @weuiSwitchHeight) / 2; 5 | padding-bottom: (@weuiCellHeight - @weuiSwitchHeight) / 2; 6 | } 7 | -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-form.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | @import "./weui-form/weui-form_common.less"; 3 | @import "./weui-form/weui-form-preview.less"; 4 | @import "./weui-form/weui-select.less"; 5 | @import "./weui-form/weui-vcode.less"; 6 | -------------------------------------------------------------------------------- /src/utils/util.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment' 2 | import 'moment/locale/zh-cn' 3 | 4 | const diffForHumans = (date, format = 'YYYYMMDD H:mm:ss') => { 5 | moment.locale('zh-cn') 6 | return moment(date, format).fromNow() 7 | } 8 | 9 | export default { 10 | diffForHumans 11 | } 12 | -------------------------------------------------------------------------------- /src/style/widget/weui-button/weui-button.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-btn{ 4 | margin-top: @weuiBtnDefaultGap; 5 | &:first-child{ 6 | margin-top: 0; 7 | } 8 | } 9 | .weui-btn-area{ 10 | margin: @weuiCellsMarginTop @weuiBtnDefaultGap .3em; 11 | } 12 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from 'redux' 2 | import promiseMiddleware from 'redux-promise' 3 | import rootReducer from './reducers' 4 | 5 | export default function configStore () { 6 | const store = createStore(rootReducer, applyMiddleware(promiseMiddleware)) 7 | return store 8 | } 9 | -------------------------------------------------------------------------------- /src/style/widget/weui-progress/weui-progress.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-progress { 4 | display: flex; 5 | align-items: center; 6 | } 7 | 8 | .weui-progress__bar { 9 | flex: 1; 10 | } 11 | 12 | .weui-progress__opr { 13 | margin-left: 15px; 14 | font-size: 0; 15 | } 16 | -------------------------------------------------------------------------------- /src/store/actions/counter.js: -------------------------------------------------------------------------------- 1 | import { ASYNC_INCREMENT } from '../types/counter' 2 | import { createAction } from 'redux-actions' 3 | 4 | export const asyncInc = createAction(ASYNC_INCREMENT, () => { 5 | return new Promise(resolve => { 6 | setTimeout(() => { 7 | resolve(1) 8 | }, 1000) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /src/style/widget/weui-tab/weui-tab.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | @import "weui-navbar.less"; 3 | 4 | .weui-tab { 5 | position: relative; 6 | height: 100%; 7 | } 8 | 9 | .weui-tab__panel{ 10 | box-sizing: border-box; 11 | height: 100%; 12 | padding-top: 50px; 13 | overflow: auto; 14 | -webkit-overflow-scrolling: touch; 15 | } 16 | -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "larabbs weapp project", 3 | "setting": { 4 | "urlCheck": false, 5 | "es6": false, 6 | "postcss": false, 7 | "minified": false, 8 | "newFeature": true 9 | }, 10 | "compileType": "miniprogram", 11 | "appid": "wx756787de07ac71b1", 12 | "projectname": "larabbs-weapp", 13 | "miniprogramRoot": "dist/", 14 | "condition": {} 15 | } -------------------------------------------------------------------------------- /src/mixins/test.js: -------------------------------------------------------------------------------- 1 | import wepy from 'wepy' 2 | 3 | export default class testMixin extends wepy.mixin { 4 | data = { 5 | mixin: 'This is mixin data.' 6 | } 7 | methods = { 8 | tap () { 9 | this.mixin = 'mixin data was changed' 10 | console.log('mixin method tap') 11 | } 12 | } 13 | 14 | onShow() { 15 | console.log('mixin onShow') 16 | } 17 | 18 | onLoad() { 19 | console.log('mixin onLoad') 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/style/widget/weui-tips/weui-badge.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-badge { 4 | display: inline-block; 5 | padding: .15em .4em; 6 | min-width: 8px; 7 | border-radius: 18px; 8 | background-color: @weuiColorWarn; 9 | color: #FFFFFF; 10 | line-height: 1.2; 11 | text-align: center; 12 | font-size: 12px; 13 | vertical-align: middle; 14 | } 15 | .weui-badge_dot { 16 | padding: .4em; 17 | min-width: 0; 18 | } 19 | -------------------------------------------------------------------------------- /src/style/base/fn.less: -------------------------------------------------------------------------------- 1 | // mixin 2 | @import "mixin/setOnepx.less"; 3 | @import "mixin/setArrow.less"; 4 | @import "mixin/text.less"; 5 | 6 | 7 | // variable 8 | @import "variable/global.less"; 9 | @import "variable/color.less"; 10 | 11 | 12 | @import "variable/weui-cell.less"; 13 | @import "variable/weui-button.less"; 14 | @import "variable/weui-msg.less"; 15 | @import "variable/weui-grid.less"; 16 | @import "variable/weui-progress.less"; 17 | @import "variable/weui-dialog.less"; 18 | -------------------------------------------------------------------------------- /src/style/base/variable/color.less: -------------------------------------------------------------------------------- 1 | // color 2 | @weuiColorPrimary: #1AAD19; 3 | @weuiColorWarn: #E64340; 4 | 5 | // link 6 | @weuiLinkColorDefault: #586C94; 7 | 8 | // background 9 | @weuiBgColorDefault: #EFEFF4; 10 | @weuiBgColorActive: #ECECEC; 11 | 12 | // line 13 | @weuiLineColorLight: #E5E5E5; 14 | @weuiLineColorDark: #BCBAB6; 15 | 16 | // text 17 | @weuiTextColorTitle: #000000; 18 | @weuiTextColorTips: #B2B2B2; 19 | @weuiTextColorWarn: @weuiColorWarn; 20 | @weuiTextColorGray: #999999; -------------------------------------------------------------------------------- /src/style/base/mixin/text.less: -------------------------------------------------------------------------------- 1 | .ellipsis(@w:auto) { 2 | width: @w; 3 | overflow: hidden; 4 | text-overflow: ellipsis; 5 | white-space: nowrap; 6 | word-wrap: normal; 7 | } 8 | 9 | .ellipsisLn(@line) { 10 | overflow: hidden; 11 | text-overflow: ellipsis; 12 | display: -webkit-box; 13 | -webkit-box-orient: vertical; 14 | -webkit-line-clamp: @line; 15 | } 16 | .text_wrap() { 17 | word-wrap:break-word; 18 | word-break:break-all; 19 | } 20 | .hyphens() { 21 | word-wrap:break-word; 22 | -webkit-hyphens:auto; 23 | hyphens:auto; 24 | } -------------------------------------------------------------------------------- /src/style/widget/weui-page/weui-article.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-article { 4 | padding: 20px 15px; 5 | font-size: 15px; 6 | } 7 | .weui-article__section { 8 | margin-bottom: 1.5em; 9 | } 10 | .weui-article__h1 { 11 | font-size: 18px; 12 | font-weight:400; 13 | margin-bottom: .9em; 14 | } 15 | .weui-article__h2 { 16 | font-size: 16px; 17 | font-weight:400; 18 | margin-bottom: .34em; 19 | } 20 | .weui-article__h3 { 21 | font-weight:400; 22 | font-size: 15px; 23 | margin-bottom: .34em; 24 | } 25 | .weui-article__p { 26 | margin: 0 0 .8em; 27 | } 28 | -------------------------------------------------------------------------------- /src/store/reducers/counter.js: -------------------------------------------------------------------------------- 1 | import { handleActions } from 'redux-actions' 2 | import { INCREMENT, DECREMENT, ASYNC_INCREMENT } from '../types/counter' 3 | 4 | export default handleActions({ 5 | [INCREMENT] (state) { 6 | return { 7 | ...state, 8 | num: state.num + 1 9 | } 10 | }, 11 | [DECREMENT] (state) { 12 | return { 13 | ...state, 14 | num: state.num - 1 15 | } 16 | }, 17 | [ASYNC_INCREMENT] (state, action) { 18 | return { 19 | ...state, 20 | asyncNum: state.asyncNum + action.payload 21 | } 22 | } 23 | }, { 24 | num: 0, 25 | asyncNum: 0 26 | }) 27 | -------------------------------------------------------------------------------- /src/components/replyCreate.wpy: -------------------------------------------------------------------------------- 1 | 10 | 16 | 28 | -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-check.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | // icon 4 | .weui-icon-radio{ 5 | margin-left: 3.2px; 6 | margin-right: 3.2px; 7 | } 8 | .weui-icon-checkbox_circle, 9 | .weui-icon-checkbox_success{ 10 | margin-left: 4.6px; 11 | margin-right: 4.6px; 12 | } 13 | 14 | .weui-check__label{ 15 | &:active{ 16 | background-color: @weuiCellActiveBg; 17 | } 18 | } 19 | .weui-check{ 20 | position: absolute; 21 | left: -9999px; 22 | } 23 | .weui-check__hd_in-checkbox{ 24 | padding-right: @weuiCellInnerGapH; 25 | } 26 | .weui-cell__ft_in-radio{ 27 | padding-left: @weuiCellInnerGapH; 28 | } 29 | -------------------------------------------------------------------------------- /src/index.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 转 WEB DEMO 11 | 14 | 15 | 16 |
17 | 18 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /src/style/widget/weui-panel/weui-panel.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | 4 | .weui-panel { 5 | background-color: #FFFFFF; 6 | margin-top: 10px; 7 | &:first-child { 8 | margin-top: 0; 9 | } 10 | 11 | position: relative; 12 | overflow: hidden; 13 | &:before { 14 | .setTopLine(@weuiLineColorLight); 15 | } 16 | &:after { 17 | .setBottomLine(@weuiLineColorLight); 18 | } 19 | } 20 | 21 | .weui-panel__hd { 22 | padding: 14px 15px 10px; 23 | color: @weuiTextColorGray; 24 | font-size: 13px; 25 | position: relative; 26 | &:after { 27 | .setBottomLine(@weuiLineColorLight); 28 | left: 15px; 29 | } 30 | } 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/components/groupitem.wpy: -------------------------------------------------------------------------------- 1 | 5 | 11 | 28 | -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-access.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-cell_access { 4 | color: inherit; 5 | } 6 | .weui-cell__ft_in-access { 7 | padding-right: 13px; 8 | position: relative; 9 | &:after { 10 | content: " "; 11 | .setArrow(right, 6px, #C8C8CD, 2px); 12 | position: absolute; 13 | top: 50%; 14 | margin-top: -4px; 15 | right: 2px; 16 | } 17 | } 18 | .weui-cell_link{ 19 | color: @weuiLinkColorDefault; 20 | font-size: 14px; 21 | 22 | &:active{ 23 | background-color: @weuiCellActiveBg; 24 | } 25 | 26 | // 由于weui-cell:first-child的:before为隐藏,所以这里要重新显示出来 27 | &:first-child{ 28 | &:before{ 29 | display: block; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/style/widget/weui-agree/weui-agree.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-agree{ 4 | display: block; 5 | padding: .5em 15px; 6 | font-size: 13px; 7 | } 8 | .weui-agree__text{ 9 | color: @weuiTextColorGray; 10 | } 11 | .weui-agree__link{ 12 | display: inline; 13 | color: @weuiLinkColorDefault; 14 | } 15 | .weui-agree__checkbox{ 16 | position: absolute; 17 | left: -9999px; 18 | } 19 | .weui-agree__checkbox-icon{ 20 | position: relative; 21 | top: 2px; 22 | display: inline-block; 23 | border: 1px solid #D1D1D1; 24 | background-color: #FFFFFF; 25 | border-radius: 3px; 26 | width: 11px; 27 | height: 11px; 28 | } 29 | .weui-agree__checkbox-icon-check{ 30 | position: absolute; 31 | top: 1px; 32 | left: 1px; 33 | } 34 | -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-form/weui-vcode.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn.less"; 2 | 3 | .weui-cell_vcode { 4 | padding-right: 0; 5 | } 6 | .weui-vcode-img{ 7 | margin-left: 5px; 8 | height: unit(@weuiCellHeight / @weuiCellFontSize, em); 9 | vertical-align: middle; 10 | } 11 | .weui-vcode-btn { 12 | display: inline-block; 13 | height: unit(@weuiCellHeight / @weuiCellFontSize, em); 14 | margin-left: 5px; 15 | padding: 0 0.6em 0 0.7em; 16 | border-left: 1px solid @weuiLineColorLight; 17 | line-height: unit(@weuiCellHeight / @weuiCellFontSize, em); 18 | vertical-align: middle; 19 | font-size: @weuiCellFontSize; 20 | color: @weuiDialogLinkColor; 21 | white-space: nowrap; 22 | &:active { 23 | color: desaturate(@weuiDialogLinkColor, 30%); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | parserOptions: { 5 | sourceType: 'module' 6 | }, 7 | env: { 8 | browser: true 9 | }, 10 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 11 | extends: 'standard', 12 | // required to lint *.wpy files 13 | plugins: [ 14 | 'html' 15 | ], 16 | settings: { 17 | 'html/html-extensions': ['.html', '.wpy'] 18 | }, 19 | // add your custom rules here 20 | 'rules': { 21 | // allow paren-less arrow functions 22 | 'arrow-parens': 0, 23 | // allow async-await 24 | 'generator-star-spacing': 0, 25 | // allow debugger during development 26 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 27 | 'space-before-function-paren': 0 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/style/base/variable/weui-cell.less: -------------------------------------------------------------------------------- 1 | @weuiCellBg:#FFFFFF; 2 | @weuiCellBorderColor:#D9D9D9; 3 | @weuiCellGapV:10px; 4 | @weuiCellGapH:15px; 5 | @weuiCellInnerGapH:.35em; 6 | @weuiCellFontSize:17px; 7 | @weuiCellHeight: 44px; 8 | @weuiCellHeightEm: unit(@weuiCellHeight / @weuiCellFontSize, em); 9 | @weuiCellTipsFontSize:14px; 10 | @weuiCellLabelWidth:105px; 11 | @weuiCellActiveBg: #ECECEC; 12 | 13 | @weuiCellLineHeight: unit((@weuiCellHeight - 2 * @weuiCellGapV) / @weuiCellFontSize); // 高度为44px,减去上下padding的行高 14 | @weuiCellsMarginTop:unit(20 / @weuiCellFontSize, em); 15 | 16 | // weui switch 17 | @weuiSwitchHeight: 32px; 18 | 19 | // weui uploader 20 | @weuiUploaderBorderColor:#D9D9D9; 21 | @weuiUploaderActiveBorderColor:#999999; 22 | @weuiUploaderFileSpacing: 9px; 23 | @weuiUploaderSize: 79px; 24 | @weuiUploaderBorderWidth: 1px; -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-form/weui-select.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn.less"; 2 | 3 | .weui-cell_select { 4 | padding: 0; 5 | } 6 | .weui-select { 7 | position: relative; 8 | padding-left: @weuiCellGapH; 9 | padding-right: 30px; 10 | 11 | height: @weuiCellHeightEm; 12 | min-height: @weuiCellHeightEm; 13 | line-height: @weuiCellHeightEm; 14 | 15 | border-right: 1rpx solid @weuiCellBorderColor; 16 | 17 | &:before{ 18 | content: " "; 19 | .setArrow(right, 6px, #C8C8CD, 2px); 20 | 21 | position: absolute; 22 | top: 50%; 23 | right: @weuiCellGapH; 24 | margin-top: -4px; 25 | } 26 | &_in-select-after{ 27 | padding-left: 0; 28 | } 29 | } 30 | .weui-cell__hd_in-select-after, 31 | .weui-cell__bd_in-select-before{ 32 | padding-left: @weuiCellGapH; 33 | } 34 | -------------------------------------------------------------------------------- /src/style/widget/weui-footer/weui-footer.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-footer { 4 | color: @weuiTextColorGray; 5 | font-size: 14px; 6 | text-align: center; 7 | } 8 | .weui-footer_fixed-bottom{ 9 | position: fixed; 10 | bottom: .52em; 11 | left: 0; 12 | right: 0; 13 | } 14 | .weui-footer__links{ 15 | font-size: 0; 16 | } 17 | .weui-footer__link{ 18 | display: inline-block; 19 | vertical-align: top; 20 | margin: 0 .62em; 21 | position: relative; 22 | font-size: 14px; 23 | color: @weuiLinkColorDefault; 24 | &:before{ 25 | .setLeftLine(); 26 | left: -.65em; 27 | top: .36em; 28 | bottom: .36em; 29 | } 30 | &:first-child{ 31 | &:before{ 32 | display: none; 33 | } 34 | } 35 | } 36 | .weui-footer__text{ 37 | padding: 0 .34em; 38 | font-size: 12px; 39 | } 40 | -------------------------------------------------------------------------------- /src/style/base/mixin/setOnepx.less: -------------------------------------------------------------------------------- 1 | .setTopLine(@c: #C7C7C7) { 2 | content: " "; 3 | position: absolute; 4 | left: 0; 5 | top: 0; 6 | right: 0; 7 | height: 1px; 8 | border-top: 1rpx solid @c; 9 | color: @c; 10 | } 11 | 12 | .setBottomLine(@c: #C7C7C7) { 13 | content: " "; 14 | position: absolute; 15 | left: 0; 16 | bottom: 0; 17 | right: 0; 18 | height: 1px; 19 | border-bottom: 1rpx solid @c; 20 | color: @c; 21 | } 22 | 23 | .setLeftLine(@c: #C7C7C7) { 24 | content: " "; 25 | position: absolute; 26 | left: 0; 27 | top: 0; 28 | width: 1px; 29 | bottom: 0; 30 | border-left: 1rpx solid @c; 31 | color: @c; 32 | } 33 | 34 | .setRightLine(@c: #C7C7C7) { 35 | content: " "; 36 | position: absolute; 37 | right: 0; 38 | top: 0; 39 | width: 1px; 40 | bottom: 0; 41 | border-right: 1rpx solid @c; 42 | color: @c; 43 | } -------------------------------------------------------------------------------- /src/components/panel.wpy: -------------------------------------------------------------------------------- 1 | 29 | 38 | 44 | -------------------------------------------------------------------------------- /src/style/widget/weui-tab/weui-navbar.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | @weuiNavBarColor: #1AAD19; 4 | .weui-navbar { 5 | display: flex; 6 | position: absolute; 7 | z-index: 500; 8 | top: 0; 9 | width: 100%; 10 | border-bottom: 1rpx solid #CCCCCC; 11 | } 12 | 13 | .weui-navbar__item { 14 | position: relative; 15 | display: block; 16 | flex: 1; 17 | padding: 13px 0; 18 | text-align: center; 19 | font-size: 0; 20 | 21 | &.weui-bar__item_on { 22 | color: @weuiNavBarColor; 23 | } 24 | } 25 | .weui-navbar__slider { 26 | position: absolute; 27 | content: " "; 28 | left: 0; 29 | bottom: 0; 30 | width: 6em; 31 | height: 3px; 32 | background-color: @weuiNavBarColor; 33 | transition: transform .3s; 34 | } 35 | .weui-navbar__title{ 36 | display: inline-block; 37 | font-size: 15px; 38 | max-width: 8em; 39 | .ellipsis(); 40 | } 41 | -------------------------------------------------------------------------------- /src/mixins/unreadCount.js: -------------------------------------------------------------------------------- 1 | import wepy from 'wepy' 2 | 3 | export default class unreadCount extends wepy.mixin { 4 | data = { 5 | // 轮训 6 | interval: null, 7 | // 未读消息数 8 | unreadCount: 0 9 | } 10 | // 页面显示 11 | onShow() { 12 | this.updateUnreadCount() 13 | this.interval = setInterval(() => { 14 | this.updateUnreadCount() 15 | }, 30000) 16 | } 17 | // 页面隐藏 18 | onHide() { 19 | // 关闭轮训 20 | clearInterval(this.interval) 21 | } 22 | // 设置未读消息数 23 | updateUnreadCount() { 24 | // 从全局获取未读消息数 25 | this.unreadCount = this.$parent.globalData.unreadCount 26 | this.$apply() 27 | 28 | if (this.unreadCount) { 29 | // 设置 badge 30 | wepy.setTabBarBadge({ 31 | index: 1, 32 | text: this.unreadCount.toString() 33 | }) 34 | } else { 35 | // 移除 badge 36 | wepy.removeTabBarBadge({ 37 | index: 1 38 | }) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/components/group.wpy: -------------------------------------------------------------------------------- 1 | 4 | 15 | 36 | -------------------------------------------------------------------------------- /src/style/widget/weui-grid/weui-grid.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-grids { 4 | border-top: 1rpx solid @weuiGridBorderColor; 5 | border-left: 1rpx solid @weuiGridBorderColor; 6 | overflow: hidden; 7 | } 8 | .weui-grid { 9 | position: relative; 10 | float: left; 11 | padding: 20px 10px; 12 | width: 100% / @weuiGridColumnCount; 13 | box-sizing: border-box; 14 | 15 | border-right: 1rpx solid @weuiGridBorderColor; 16 | border-bottom: 1rpx solid @weuiGridBorderColor; 17 | &_active{ 18 | background-color: @weuiBgColorActive; 19 | } 20 | } 21 | .weui-grid__icon { 22 | display: block; 23 | width: @weuiGridIconSize; 24 | height: @weuiGridIconSize; 25 | margin: 0 auto; 26 | } 27 | .weui-grid__label { 28 | margin-top: 5px; 29 | display: block; 30 | text-align: center; 31 | color: @weuiTextColorTitle; 32 | font-size: @weuiGridFontSize; 33 | white-space: nowrap; 34 | text-overflow: ellipsis; 35 | overflow: hidden; 36 | } 37 | -------------------------------------------------------------------------------- /src/style/widget/weui-animate/weui-animate.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | @keyframes slideUp { 4 | from { 5 | transform: translate3d(0, 100%, 0); 6 | } 7 | 8 | to { 9 | transform: translate3d(0, 0, 0); 10 | } 11 | } 12 | 13 | .weui-animate-slide-up { 14 | animation: slideUp ease .3s forwards; 15 | } 16 | 17 | @keyframes slideDown { 18 | from { 19 | transform: translate3d(0, 0, 0); 20 | } 21 | 22 | to { 23 | transform: translate3d(0, 100%, 0); 24 | } 25 | } 26 | 27 | .weui-animate-slide-down { 28 | animation: slideDown ease .3s forwards; 29 | } 30 | 31 | @keyframes fadeIn { 32 | from { 33 | opacity: 0; 34 | } 35 | to { 36 | opacity: 1; 37 | } 38 | } 39 | 40 | .weui-animate-fade-in { 41 | animation: fadeIn ease .3s forwards; 42 | } 43 | 44 | @keyframes fadeOut { 45 | from { 46 | opacity: 1; 47 | } 48 | to { 49 | opacity: 0; 50 | } 51 | } 52 | 53 | .weui-animate-fade-out { 54 | animation: fadeOut ease .3s forwards; 55 | } 56 | -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-form/weui-form_common.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn.less"; 2 | 3 | .weui-cell_input{ 4 | padding-top: 0; 5 | padding-bottom: 0; 6 | } 7 | .weui-label{ 8 | width:@weuiCellLabelWidth; 9 | .text_wrap(); 10 | } 11 | .weui-input{ 12 | height: @weuiCellHeightEm; 13 | min-height: @weuiCellHeightEm; 14 | line-height: @weuiCellHeightEm; 15 | } 16 | .weui-toptips{ 17 | //display: none; // 通过 wx:if 来控制 18 | position: fixed; 19 | transform: translateZ(0); 20 | top: 0; 21 | left: 0; 22 | right: 0; 23 | padding: 5px; 24 | font-size: 14px; 25 | text-align: center; 26 | color: #FFFFFF; 27 | z-index: 5000; 28 | .text_wrap(); 29 | } 30 | .weui-toptips_warn{ 31 | background-color: @weuiColorWarn; 32 | } 33 | .weui-textarea{ 34 | display: block; 35 | width: 100%; 36 | } 37 | .weui-textarea-counter{ 38 | color: @weuiTextColorTips; 39 | text-align: right; 40 | } 41 | .weui-textarea-counter_warn{ 42 | color: @weuiTextColorWarn; 43 | } 44 | .weui-cell_warn{ 45 | color: @weuiTextColorWarn; 46 | } 47 | -------------------------------------------------------------------------------- /src/style/widget/weui-page/weui-msg.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-msg { 4 | padding-top: @weuiMsgPaddingTop; 5 | text-align: center; 6 | } 7 | .weui-msg__link{ 8 | display: inline; 9 | color: @weuiLinkColorDefault; 10 | } 11 | .weui-msg__icon-area { 12 | margin-bottom: @weuiMsgIconGap; 13 | } 14 | .weui-msg__text-area { 15 | margin-bottom: @weuiMsgTextGap; 16 | padding:0 20px; 17 | } 18 | .weui-msg__title { 19 | margin-bottom: @weuiMsgTitleGap; 20 | font-weight: 400; 21 | font-size: 20px; 22 | } 23 | .weui-msg__desc { 24 | font-size: 14px; 25 | color: @weuiTextColorGray; 26 | } 27 | .weui-msg__opr-area { 28 | margin-bottom: @weuiMsgOprGap; 29 | } 30 | .weui-msg__extra-area { 31 | margin-bottom: @weuiMsgExtraAreaGap; 32 | font-size: 14px; 33 | color: @weuiTextColorGray; 34 | } 35 | 36 | @media screen and (min-height: @weuiMsgExtraAreaOfMinHeight) { 37 | .weui-msg__extra-area { 38 | position: fixed; 39 | left: 0; 40 | bottom: 0; 41 | width: 100%; 42 | text-align: center; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/style/widget/weui-tips/weui-loadmore.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-loadmore{ 4 | width: 65%; 5 | margin:1.5em auto; 6 | line-height: 1.6em; 7 | font-size:14px; 8 | text-align: center; 9 | } 10 | .weui-loadmore__tips{ 11 | display: inline-block; 12 | vertical-align: middle; 13 | } 14 | .weui-loadmore_line{ 15 | border-top:1px solid @weuiLineColorLight; 16 | margin-top:2.4em; 17 | } 18 | .weui-loadmore__tips_in-line{ 19 | position: relative; 20 | top:-.9em; 21 | padding:0 .55em; 22 | background-color: #FFFFFF; 23 | color:@weuiTextColorGray; 24 | } 25 | .weui-loadmore_dot{ 26 | } 27 | .weui-loadmore__tips_in-dot{ 28 | position: relative; 29 | padding:0 .16em; 30 | width: 4px; 31 | height: 1.6em; 32 | &:before{ 33 | content: " "; 34 | position: absolute; 35 | top: 50%; 36 | left: 50%; 37 | margin-top: -1px; 38 | margin-left: -2px; 39 | width: 4px; 40 | height: 4px; 41 | border-radius: 50%; 42 | background-color: @weuiLineColorLight; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/style/weui.less: -------------------------------------------------------------------------------- 1 | @import "base/reset.less"; 2 | 3 | @import "widget/weui-cell/weui-cell.less"; 4 | @import "widget/weui-cell/weui-access.less"; 5 | @import "widget/weui-cell/weui-check.less"; 6 | @import "widget/weui-cell/weui-form.less"; 7 | @import "widget/weui-cell/weui-switch.less"; 8 | @import "widget/weui-cell/weui-uploader.less"; 9 | 10 | @import "./widget/weui-page/weui-article.less"; 11 | @import "./widget/weui-page/weui-msg.less"; 12 | 13 | @import "widget/weui-flex/weui-flex.less"; 14 | 15 | @import "widget/weui-button/weui-button.less"; 16 | 17 | @import "./widget/weui-agree/weui-agree.less"; 18 | 19 | @import "./widget/weui-footer/weui-footer.less"; 20 | 21 | @import "./widget/weui-grid/weui-grid.less"; 22 | 23 | @import "./widget/weui-loading/weui-loading.less"; 24 | 25 | @import "./widget/weui-tips/weui-badge.less"; 26 | @import "./widget/weui-tips/weui-loadmore.less"; 27 | 28 | @import "./widget/weui-panel/weui-panel.less"; 29 | 30 | @import "./widget/weui-media-box/weui-media-box.less"; 31 | 32 | @import "./widget/weui-progress/weui-progress.less"; 33 | 34 | @import "./widget/weui-tab/weui-tab.less"; 35 | 36 | @import "./widget/weui-searchbar/weui-searchbar.less"; 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 项目概述 3 | 4 | * 产品名称:LaraBBS-WEAPP 5 | * 项目代号:larabbs-weapp 6 | 7 | LaraBBS 是一个简洁的论坛应用,使用 Laravel5.5 编写而成。一步步开发此项目的教程请见 [《Web 开发实战进阶 - 从零开始构建论坛系统》](https://laravel-china.org/topics/6592)。LaraBBS-WEAPP 是利用 LaraBBS 接口实现的小程序,教程请见 [《Laravel 微信小程序开发》](https://laravel-china.org/courses/laravel-weapp) 8 | 9 | 10 | ## 在线体验 11 | 12 |

13 | 14 |

15 |

16 | 17 |

18 | 19 | 20 | ## 功能如下 21 | 22 | - 用户认证 —— 注册、登录、退出; 23 | - 个人页面 —— 用户个人信息,编辑资料,上传头像; 24 | - 用户授权 —— 作者才能删除自己的内容; 25 | - 话题 —— 列表,详情,删除; 26 | - 话题回复 —— 列表,发布,删除; 27 | - 消息通知 —— 轮训显示消息提示,消息列表,标记已读; 28 | - 用户权限; 29 | - 页面分享; 30 | 31 | 32 | ## 运行环境要求 33 | 34 | - WePY 1.7+ 35 | 36 | ## 开发环境部署/安装 37 | 38 | 本项目代码使用 WePY 框架 [WePY](https://github.com/Tencent/wepy) 开发 39 | 40 | ### 基础安装 41 | 42 | #### 1. 克隆源代码 43 | 44 | 克隆 `larabbs-weapp` 源代码到本地: 45 | 46 | > git clone git@github.com:summerblue/larabbs-weapp.git 47 | 48 | #### 2. 安装扩展包依赖 49 | 50 | ``` 51 | > yarn 52 | > yarn global add wepy-cli 53 | ``` 54 | 55 | #### 3. 编译 56 | 57 | ``` 58 | > npm run build 59 | ``` 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/components/list.wpy: -------------------------------------------------------------------------------- 1 | 9 | 21 | 56 | -------------------------------------------------------------------------------- /src/pages/topics/userIndex.wpy: -------------------------------------------------------------------------------- 1 | 8 | 48 | -------------------------------------------------------------------------------- /src/style/base/mixin/setArrow.less: -------------------------------------------------------------------------------- 1 | ._setArrow(@arrowsize, @borderColor, @borderWidth){ 2 | display: inline-block; 3 | height: @arrowsize; 4 | width: @arrowsize; 5 | border-width: @borderWidth @borderWidth 0 0; 6 | border-color: @borderColor; 7 | border-style: solid; 8 | } 9 | 10 | .setArrow(@direction, @arrowsize, @borderColor, @borderWidth) when (@direction = top) { 11 | ._setArrow(@arrowsize, @borderColor, @borderWidth); 12 | transform: matrix(0.71,-0.71,0.71,0.71,0,0); // rotate(-45deg) 13 | } 14 | 15 | .setArrow(@direction, @arrowsize, @borderColor,@borderWidth) when (@direction = right) { 16 | ._setArrow(@arrowsize, @borderColor, @borderWidth); 17 | transform: matrix(0.71,0.71,-0.71,0.71,0,0); // rotate(45deg); 18 | 19 | position: relative; 20 | top: -2px; 21 | } 22 | 23 | .setArrow(@direction, @arrowsize, @borderColor,@borderWidth) when (@direction = down) { 24 | ._setArrow(@arrowsize, @borderColor, @borderWidth); 25 | transform: matrix(-0.71,0.71,-0.71,-0.71,0,0); // rotate(135deg); 26 | 27 | position: relative; 28 | top: -3px; 29 | } 30 | 31 | .setArrow(@direction, @arrowsize, @borderColor,@borderWidth) when (@direction = left) { 32 | ._setArrow(@arrowsize, @borderColor, @borderWidth); 33 | transform: matrix(-0.71,-0.71,0.71,-0.71,0,0); // rotate(-135deg); 34 | 35 | position: relative; 36 | top: -2px; 37 | } -------------------------------------------------------------------------------- /src/components/wepy-list.wpy: -------------------------------------------------------------------------------- 1 | 9 | 21 | 56 | -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-cell.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-cells { 4 | position: relative; 5 | margin-top: @weuiCellsMarginTop; 6 | background-color: @weuiCellBg; 7 | line-height: @weuiCellLineHeight; 8 | font-size: @weuiCellFontSize; //cell中间有效高度23px,跟客户端默认图标尺寸一致 9 | &:before { 10 | .setTopLine(@weuiCellBorderColor); 11 | } 12 | &:after { 13 | .setBottomLine(@weuiCellBorderColor); 14 | } 15 | } 16 | 17 | .weui-cells__title { 18 | margin-top: .77em; // 15px - 行高 19 | margin-bottom: .3em; // 8px - 行高 20 | padding-left: @weuiCellGapH; 21 | padding-right: @weuiCellGapH; 22 | color: @weuiTextColorGray; 23 | font-size: @weuiCellTipsFontSize; 24 | } 25 | .weui-cells_after-title{ 26 | margin-top: 0; 27 | } 28 | 29 | .weui-cells__tips { 30 | margin-top: .3em; // 8px - 行高 31 | color: @weuiTextColorGray; 32 | padding-left: @weuiCellGapH; 33 | padding-right: @weuiCellGapH; 34 | font-size: @weuiCellTipsFontSize; 35 | } 36 | 37 | .weui-cell { 38 | padding: @weuiCellGapV @weuiCellGapH; 39 | position: relative; //这个是为了兼容cells容器onepx方案被before挡住而做的 40 | display: flex; 41 | align-items: center; 42 | &:before { 43 | .setTopLine(@weuiCellBorderColor); 44 | left: @weuiCellGapH; 45 | } 46 | &:first-child { 47 | &:before { 48 | display: none; 49 | } 50 | } 51 | } 52 | .weui-cell_active { 53 | background-color: @weuiCellActiveBg; 54 | } 55 | .weui-cell_primary{ 56 | align-items: flex-start; 57 | } 58 | .weui-cell__bd{ 59 | flex: 1; 60 | } 61 | .weui-cell__ft { 62 | text-align: right; 63 | color: @weuiTextColorGray; 64 | } 65 | -------------------------------------------------------------------------------- /src/style/widget/weui-searchbar/weui-searchbar.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | @weuiSearchBarHeight: 28px; 4 | 5 | .weui-search-bar { 6 | position: relative; 7 | padding: 8px 10px; 8 | display: flex; 9 | box-sizing: border-box; 10 | background-color: #EFEFF4; 11 | border-top: 1rpx solid #D7D6DC; 12 | border-bottom: 1rpx solid #D7D6DC; 13 | } 14 | .weui-icon-search { 15 | margin-right: 8px; 16 | font-size:inherit; 17 | } 18 | .weui-icon-search_in-box { 19 | position: absolute; 20 | left: 10px; 21 | top: 7px; 22 | } 23 | .weui-search-bar__text{ 24 | display: inline-block; 25 | font-size: 14px; 26 | vertical-align: middle; 27 | } 28 | .weui-search-bar__form { 29 | position: relative; 30 | flex: auto; 31 | border-radius: 5px; 32 | background: #FFFFFF; 33 | border: 1rpx solid #E6E6EA; 34 | } 35 | .weui-search-bar__box { 36 | position: relative; 37 | padding-left: 30px; 38 | padding-right: 30px; 39 | width: 100%; 40 | box-sizing: border-box; 41 | z-index: 1; 42 | } 43 | .weui-search-bar__input { 44 | height: @weuiSearchBarHeight; 45 | line-height: @weuiSearchBarHeight; 46 | font-size: 14px; 47 | } 48 | .weui-icon-clear { 49 | position: absolute; 50 | top: 0; 51 | right: 0; 52 | padding: 7px 8px; 53 | font-size: 0; 54 | } 55 | .weui-search-bar__label { 56 | position: absolute; 57 | top: 0; 58 | right: 0; 59 | bottom: 0; 60 | left: 0; 61 | z-index: 2; 62 | border-radius: 3px; 63 | text-align: center; 64 | color: #9B9B9B; 65 | background: #FFFFFF; 66 | line-height: @weuiSearchBarHeight; 67 | } 68 | .weui-search-bar__cancel-btn { 69 | margin-left: 10px; 70 | line-height: @weuiSearchBarHeight; 71 | color: #09BB07; 72 | white-space: nowrap; 73 | } 74 | -------------------------------------------------------------------------------- /src/style/widget/weui-media-box/weui-media-box.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-media-box { 4 | padding: 15px; 5 | position: relative; 6 | &:before { 7 | .setTopLine(@weuiLineColorLight); 8 | left: 15px; 9 | } 10 | &:first-child { 11 | &:before { 12 | display: none 13 | } 14 | } 15 | } 16 | .weui-media-box__title { 17 | font-weight: 400; 18 | font-size: 17px; 19 | .ellipsis(); 20 | word-wrap: break-word; 21 | word-break: break-all; 22 | } 23 | .weui-media-box__desc { 24 | color: @weuiTextColorGray; 25 | font-size: 13px; 26 | line-height: 1.2; 27 | .ellipsisLn(2); 28 | } 29 | .weui-media-box__info { 30 | margin-top: 15px; 31 | padding-bottom: 5px; 32 | font-size: 13px; 33 | color: #CECECE; 34 | line-height: 1em; 35 | list-style: none; 36 | overflow: hidden; 37 | } 38 | .weui-media-box__info__meta { 39 | float: left; 40 | padding-right: 1em; 41 | } 42 | .weui-media-box__info__meta_extra { 43 | padding-left: 1em; 44 | border-left: 1px solid #CECECE; 45 | } 46 | .weui-media-box_text { 47 | } 48 | .weui-media-box__title_in-text { 49 | margin-bottom: 8px; 50 | } 51 | .weui-media-box_appmsg { 52 | display: flex; 53 | align-items: center; 54 | } 55 | .weui-media-box__thumb { 56 | width: 100%; 57 | height: 100%; 58 | vertical-align: top; 59 | } 60 | .weui-media-box__hd_in-appmsg { 61 | margin-right: .8em; 62 | width: 60px; 63 | height: 60px; 64 | line-height: 60px; 65 | text-align: center; 66 | } 67 | .weui-media-box__bd_in-appmsg { 68 | flex: 1; 69 | min-width: 0; 70 | } 71 | .weui-media-box_small-appmsg { 72 | padding: 0; 73 | } 74 | .weui-cells_in-small-appmsg { 75 | margin-top: 0; 76 | &:before { 77 | display: none; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "larabbs-weapp", 3 | "version": "0.0.1", 4 | "description": "larabbs weapp project", 5 | "main": "dist/app.js", 6 | "scripts": { 7 | "dev": "wepy build --watch", 8 | "build": "cross-env NODE_ENV=production wepy build --no-cache", 9 | "dev:web": "wepy build --output web", 10 | "clean": "find ./dist -maxdepth 1 -not -name 'project.config.json' -not -name 'dist' | xargs rm -rf", 11 | "test": "echo \"Error: no test specified\" && exit 1", 12 | "eslint": "eslint --fix --ext .js,.wpy src" 13 | }, 14 | "wepy": { 15 | "module-a": false, 16 | "./src/components/list": "./src/components/wepy-list.wpy" 17 | }, 18 | "author": "liyu001989@gmail.com", 19 | "license": "MIT", 20 | "dependencies": { 21 | "moment": "^2.21.0", 22 | "npm": "^5.8.0", 23 | "promise-polyfill": "^7.1.0", 24 | "redux": "^3.7.2", 25 | "redux-actions": "^2.2.1", 26 | "redux-promise": "^0.5.3", 27 | "wepy": "^1.7.1", 28 | "wepy-async-function": "^1.4.5", 29 | "wepy-com-toast": "^1.0.2", 30 | "wepy-plugin-imagemin": "^1.5.3", 31 | "wepy-plugin-replace": "^1.5.10", 32 | "wepy-redux": "^1.5.3" 33 | }, 34 | "devDependencies": { 35 | "babel-eslint": "^7.2.1", 36 | "babel-plugin-transform-class-properties": "^6.24.1", 37 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 38 | "babel-plugin-transform-export-extensions": "^6.22.0", 39 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 40 | "babel-preset-env": "^1.6.1", 41 | "cross-env": "^5.1.4", 42 | "eslint": "^3.18.0", 43 | "eslint-config-standard": "^7.1.0", 44 | "eslint-friendly-formatter": "^2.0.7", 45 | "eslint-plugin-html": "^2.0.1", 46 | "eslint-plugin-promise": "^3.5.0", 47 | "eslint-plugin-standard": "^2.0.1", 48 | "less": "^3.8.1", 49 | "wepy-compiler-babel": "^1.5.2", 50 | "wepy-compiler-less": "^1.3.10", 51 | "wepy-eslint": "^1.5.3", 52 | "wepy-plugin-uglifyjs": "^1.3.7" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-form/weui-form-preview.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn.less"; 2 | 3 | .weui-form-preview{ 4 | position: relative; 5 | background-color: #FFFFFF; 6 | &:before{ 7 | .setTopLine(@weuiCellBorderColor); 8 | } 9 | &:after{ 10 | .setBottomLine(@weuiCellBorderColor); 11 | } 12 | } 13 | .weui-form-preview__value{ 14 | font-size: 14px; 15 | } 16 | .weui-form-preview__value_in-hd{ 17 | font-size: 26px; 18 | } 19 | .weui-form-preview__hd{ 20 | position: relative; 21 | padding: @weuiCellGapV @weuiCellGapH; 22 | text-align: right; 23 | line-height: 2.5em; 24 | &:after{ 25 | .setBottomLine(@weuiCellBorderColor); 26 | left: @weuiCellGapH; 27 | } 28 | } 29 | .weui-form-preview__bd{ 30 | padding: @weuiCellGapV @weuiCellGapH; 31 | font-size: .9em; 32 | text-align: right; 33 | color: @weuiTextColorGray; 34 | line-height: 2; 35 | } 36 | .weui-form-preview__ft{ 37 | position: relative; 38 | line-height: 50px; 39 | display: flex; 40 | &:after { 41 | .setTopLine(@weuiDialogLineColor); 42 | } 43 | } 44 | .weui-form-preview__item{ 45 | overflow: hidden; 46 | } 47 | .weui-form-preview__label{ 48 | float: left; 49 | margin-right: 1em; 50 | min-width: 4em; 51 | color: @weuiTextColorGray; 52 | text-align: justify; 53 | text-align-last: justify; 54 | } 55 | .weui-form-preview__value{ 56 | display: block; 57 | overflow: hidden; 58 | word-break:normal; 59 | word-wrap: break-word; 60 | } 61 | .weui-form-preview__btn { 62 | position: relative; 63 | display: block; 64 | flex: 1; 65 | color: @weuiDialogLinkColor; 66 | text-align: center; 67 | &:after { 68 | .setLeftLine(@weuiDialogLineColor); 69 | } 70 | &:first-child { 71 | &:after { 72 | display: none; 73 | } 74 | } 75 | } 76 | .weui-form-preview__btn_active{ 77 | background-color: @weuiDialogLinkActiveBc; 78 | } 79 | .weui-form-preview__btn_default { 80 | color: @weuiTextColorGray; 81 | } 82 | .weui-form-preview__btn_primary { 83 | color: #0BB20C; 84 | } 85 | -------------------------------------------------------------------------------- /wepy.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | var prod = process.env.NODE_ENV === 'production'; 3 | 4 | module.exports = { 5 | wpyExt: '.wpy', 6 | eslint: true, 7 | cliLogs: !prod, 8 | build: { 9 | web: { 10 | htmlTemplate: path.join('src', 'index.template.html'), 11 | htmlOutput: path.join('web', 'index.html'), 12 | jsOutput: path.join('web', 'index.js') 13 | } 14 | }, 15 | resolve: { 16 | alias: { 17 | counter: path.join(__dirname, 'src/components/counter'), 18 | '@': path.join(__dirname, 'src') 19 | }, 20 | aliasFields: ['wepy'], 21 | modules: ['node_modules'] 22 | }, 23 | compilers: { 24 | less: { 25 | compress: prod 26 | }, 27 | /*sass: { 28 | outputStyle: 'compressed' 29 | },*/ 30 | babel: { 31 | sourceMap: true, 32 | presets: [ 33 | 'env' 34 | ], 35 | plugins: [ 36 | 'transform-class-properties', 37 | 'transform-decorators-legacy', 38 | 'transform-object-rest-spread', 39 | 'transform-export-extensions', 40 | ] 41 | } 42 | }, 43 | plugins: { 44 | replace: { 45 | filter: /\.js$/, 46 | config: { 47 | find: /__BASE_URL__/g, 48 | replace: prod ? "'https://weapp.laravel-china.org/api'" : "'http://larabbs.test/api'" 49 | } 50 | } 51 | }, 52 | appConfig: { 53 | noPromiseAPI: ['createSelectorQuery'] 54 | } 55 | } 56 | 57 | if (prod) { 58 | 59 | // 压缩sass 60 | // module.exports.compilers['sass'] = {outputStyle: 'compressed'} 61 | 62 | // 压缩js 63 | module.exports.plugins = { 64 | uglifyjs: { 65 | filter: /\.js$/, 66 | config: { 67 | } 68 | }, 69 | imagemin: { 70 | filter: /\.(jpg|png|jpeg)$/, 71 | config: { 72 | jpg: { 73 | quality: 80 74 | }, 75 | png: { 76 | quality: 80 77 | } 78 | } 79 | }, 80 | replace: { 81 | filter: /\.js$/, 82 | config: { 83 | find: /__BASE_URL__/g, 84 | replace: prod ? "'https://weapp.liyu.wiki/api'" : "'http://larabbs.test/api'" 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/pages/replies/userIndex.wpy: -------------------------------------------------------------------------------- 1 | 10 | 37 | 57 | -------------------------------------------------------------------------------- /src/components/counter.wpy: -------------------------------------------------------------------------------- 1 | 17 | 29 | 88 | -------------------------------------------------------------------------------- /src/style/widget/weui-cell/weui-uploader.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn.less"; 2 | 3 | .weui-uploader{} 4 | .weui-uploader__hd{ 5 | display: flex; 6 | padding-bottom: @weuiCellGapV; 7 | align-items: center; 8 | } 9 | .weui-uploader__title{ 10 | flex: 1; 11 | } 12 | .weui-uploader__info{ 13 | color: @weuiTextColorTips; 14 | } 15 | .weui-uploader__bd{ 16 | margin-bottom: @weuiCellGapH - (@weuiCellGapV + @weuiUploaderFileSpacing); 17 | margin-right: -@weuiUploaderFileSpacing; 18 | overflow: hidden; 19 | } 20 | .weui-uploader__file{ 21 | float: left; 22 | margin-right: @weuiUploaderFileSpacing; 23 | margin-bottom: @weuiUploaderFileSpacing; 24 | } 25 | .weui-uploader__img{ 26 | display: block; 27 | width: @weuiUploaderSize; 28 | height: @weuiUploaderSize; 29 | } 30 | .weui-uploader__file_status{ 31 | position: relative; 32 | &:before{ 33 | content: " "; 34 | position: absolute; 35 | top: 0; 36 | right: 0; 37 | bottom: 0; 38 | left: 0; 39 | background-color: rgba(0, 0, 0, .5); 40 | } 41 | } 42 | .weui-uploader__file-content{ 43 | position: absolute; 44 | top: 50%; 45 | left: 50%; 46 | transform: translate(-50%, -50%); 47 | color: #FFFFFF; 48 | } 49 | .weui-uploader__input-box{ 50 | float:left; 51 | position: relative; 52 | margin-right: @weuiUploaderFileSpacing; 53 | margin-bottom: @weuiUploaderFileSpacing; 54 | width: @weuiUploaderSize - @weuiUploaderBorderWidth * 2; 55 | height: @weuiUploaderSize - @weuiUploaderBorderWidth * 2; 56 | border: @weuiUploaderBorderWidth solid @weuiUploaderBorderColor; 57 | &:before, &:after{ 58 | content: " "; 59 | position: absolute; 60 | top: 50%; 61 | left: 50%; 62 | transform: translate(-50%, -50%); 63 | background-color: @weuiUploaderBorderColor; 64 | } 65 | &:before{ 66 | width: @weuiUploaderBorderWidth + 1; 67 | height: @weuiUploaderSize / 2; 68 | } 69 | &:after{ 70 | width: @weuiUploaderSize / 2; 71 | height: @weuiUploaderBorderWidth + 1; 72 | } 73 | &:active{ 74 | border-color: @weuiUploaderActiveBorderColor; 75 | &:before, &:after{ 76 | background-color: @weuiUploaderActiveBorderColor; 77 | } 78 | } 79 | } 80 | .weui-uploader__input{ 81 | position: absolute; 82 | z-index: 1; 83 | top: 0; 84 | left: 0; 85 | width: 100%; 86 | height: 100%; 87 | opacity: 0; 88 | } 89 | -------------------------------------------------------------------------------- /src/pages/replies/index.wpy: -------------------------------------------------------------------------------- 1 | 21 | 56 | 87 | -------------------------------------------------------------------------------- /src/pages/replies/create.wpy: -------------------------------------------------------------------------------- 1 | 6 |