Repository: Taoshaoji/used-book-secondhand
Branch: master
Commit: ee31e684f858
Files: 564
Total size: 726.0 KB
Directory structure:
gitextract_m91prd5v/
├── .gitignore
├── .vscode/
│ └── settings.json
├── README.md
├── cloudfunctions/
│ ├── his/
│ │ ├── index.js
│ │ └── package.json
│ ├── imgSecCheck/
│ │ ├── config.json
│ │ ├── index.js
│ │ └── package.json
│ ├── login/
│ │ ├── config.json
│ │ ├── index.js
│ │ └── package.json
│ ├── node/
│ │ ├── config.json
│ │ ├── index.js
│ │ └── package.json
│ ├── pay/
│ │ ├── index.js
│ │ └── package.json
│ ├── poking/
│ │ ├── config.json
│ │ ├── index.js
│ │ └── package.json
│ ├── ref/
│ │ ├── index.js
│ │ └── package.json
│ ├── regist/
│ │ ├── RdWXBizDataCrypt.js
│ │ ├── cryptojs/
│ │ │ ├── cryptojs.js
│ │ │ ├── lib/
│ │ │ │ ├── AES.js
│ │ │ │ ├── BlockModes.js
│ │ │ │ ├── Crypto.js
│ │ │ │ ├── CryptoMath.js
│ │ │ │ ├── DES.js
│ │ │ │ ├── HMAC.js
│ │ │ │ ├── MARC4.js
│ │ │ │ ├── MD5.js
│ │ │ │ ├── PBKDF2.js
│ │ │ │ ├── PBKDF2Async.js
│ │ │ │ ├── Rabbit.js
│ │ │ │ ├── SHA1.js
│ │ │ │ └── SHA256.js
│ │ │ ├── package.json
│ │ │ └── test/
│ │ │ └── PBKDF2-test.js
│ │ ├── index.js
│ │ └── package.json
│ ├── removeChat/
│ │ ├── config.json
│ │ ├── index.js
│ │ └── package.json
│ ├── removeOrder/
│ │ ├── config.json
│ │ ├── index.js
│ │ └── package.json
│ ├── sell/
│ │ ├── config.json
│ │ ├── index.js
│ │ └── package.json
│ ├── sendMsg/
│ │ ├── config.json
│ │ ├── index.js
│ │ └── package.json
│ └── sendTip/
│ ├── config.json
│ ├── index.js
│ └── package.json
├── miniprogram/
│ ├── app.js
│ ├── app.json
│ ├── app.wxss
│ ├── common.wxml
│ ├── common.wxs
│ ├── components/
│ │ ├── add_tips/
│ │ │ ├── README.md
│ │ │ ├── index.js
│ │ │ ├── index.json
│ │ │ ├── index.wxml
│ │ │ └── index.wxss
│ │ ├── canvasdrawer/
│ │ │ ├── canvasdrawer.js
│ │ │ ├── canvasdrawer.json
│ │ │ ├── canvasdrawer.wxml
│ │ │ └── canvasdrawer.wxss
│ │ ├── chatroom/
│ │ │ ├── chatroom.js
│ │ │ ├── chatroom.json
│ │ │ ├── chatroom.wxml
│ │ │ └── chatroom.wxss
│ │ └── welcome/
│ │ ├── welcome.js
│ │ ├── welcome.json
│ │ ├── welcome.wxml
│ │ └── welcome.wxss
│ ├── config.js
│ ├── pages/
│ │ ├── about/
│ │ │ ├── about.js
│ │ │ ├── about.json
│ │ │ ├── about.wxml
│ │ │ └── about.wxss
│ │ ├── appreciateCode/
│ │ │ ├── appreciateCode.js
│ │ │ ├── appreciateCode.json
│ │ │ ├── appreciateCode.wxml
│ │ │ └── appreciateCode.wxss
│ │ ├── detail/
│ │ │ ├── detail.js
│ │ │ ├── detail.json
│ │ │ ├── detail.wxml
│ │ │ ├── detail.wxss
│ │ │ └── room/
│ │ │ ├── room.js
│ │ │ ├── room.json
│ │ │ ├── room.wxml
│ │ │ └── room.wxss
│ │ ├── edit/
│ │ │ ├── edit.js
│ │ │ ├── edit.json
│ │ │ ├── edit.wxml
│ │ │ └── edit.wxss
│ │ ├── help/
│ │ │ ├── help.js
│ │ │ ├── help.json
│ │ │ ├── help.wxml
│ │ │ └── help.wxss
│ │ ├── index/
│ │ │ ├── index.js
│ │ │ ├── index.json
│ │ │ ├── index.wxml
│ │ │ └── index.wxss
│ │ ├── kefu/
│ │ │ ├── kefu.js
│ │ │ ├── kefu.json
│ │ │ ├── kefu.wxml
│ │ │ └── kefu.wxss
│ │ ├── login/
│ │ │ ├── login.js
│ │ │ ├── login.json
│ │ │ ├── login.wxml
│ │ │ └── login.wxss
│ │ ├── message/
│ │ │ ├── message.js
│ │ │ ├── message.json
│ │ │ ├── message.wxml
│ │ │ └── message.wxss
│ │ ├── my/
│ │ │ ├── my.js
│ │ │ ├── my.json
│ │ │ ├── my.wxml
│ │ │ └── my.wxss
│ │ ├── order/
│ │ │ ├── detail/
│ │ │ │ ├── detail.js
│ │ │ │ ├── detail.json
│ │ │ │ ├── detail.wxml
│ │ │ │ └── detail.wxss
│ │ │ └── list/
│ │ │ ├── list.js
│ │ │ ├── list.json
│ │ │ ├── list.wxml
│ │ │ └── list.wxss
│ │ ├── publish/
│ │ │ ├── publish.js
│ │ │ ├── publish.json
│ │ │ ├── publish.wxml
│ │ │ └── publish.wxss
│ │ ├── search/
│ │ │ ├── search.js
│ │ │ ├── search.json
│ │ │ ├── search.wxml
│ │ │ └── search.wxss
│ │ ├── sell/
│ │ │ ├── detail/
│ │ │ │ ├── detail.js
│ │ │ │ ├── detail.json
│ │ │ │ ├── detail.wxml
│ │ │ │ └── detail.wxss
│ │ │ └── list/
│ │ │ ├── list.js
│ │ │ ├── list.json
│ │ │ ├── list.wxml
│ │ │ └── list.wxss
│ │ ├── start/
│ │ │ ├── start.js
│ │ │ ├── start.json
│ │ │ ├── start.wxml
│ │ │ └── start.wxss
│ │ ├── use/
│ │ │ ├── use.js
│ │ │ ├── use.json
│ │ │ ├── use.wxml
│ │ │ └── use.wxss
│ │ └── web/
│ │ ├── web.js
│ │ ├── web.json
│ │ ├── web.wxml
│ │ └── web.wxss
│ ├── sitemap.json
│ ├── utils/
│ │ └── util.js
│ └── vant/
│ ├── action-sheet/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── area/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── button/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── calendar/
│ │ ├── calendar.wxml
│ │ ├── components/
│ │ │ ├── header/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ └── month/
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── index.json
│ │ │ ├── index.wxml
│ │ │ ├── index.wxs
│ │ │ └── index.wxss
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ ├── index.wxss
│ │ ├── utils.d.ts
│ │ ├── utils.js
│ │ └── utils.wxs
│ ├── card/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── cell/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── cell-group/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── checkbox/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ └── index.wxss
│ ├── checkbox-group/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── circle/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── col/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── collapse/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── collapse-item/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── common/
│ │ ├── color.d.ts
│ │ ├── color.js
│ │ ├── component.d.ts
│ │ ├── component.js
│ │ ├── index.wxss
│ │ ├── style/
│ │ │ ├── clearfix.wxss
│ │ │ ├── ellipsis.wxss
│ │ │ ├── hairline.wxss
│ │ │ ├── mixins/
│ │ │ │ ├── clearfix.wxss
│ │ │ │ ├── ellipsis.wxss
│ │ │ │ └── hairline.wxss
│ │ │ ├── theme.wxss
│ │ │ └── var.wxss
│ │ ├── utils.d.ts
│ │ ├── utils.js
│ │ ├── version.d.ts
│ │ └── version.js
│ ├── count-down/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxss
│ │ ├── utils.d.ts
│ │ └── utils.js
│ ├── datetime-picker/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── definitions/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── weapp.d.ts
│ │ └── weapp.js
│ ├── dialog/
│ │ ├── dialog.d.ts
│ │ ├── dialog.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── divider/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── dropdown-item/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── dropdown-menu/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ └── index.wxss
│ ├── field/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ ├── index.wxss
│ │ ├── props.d.ts
│ │ └── props.js
│ ├── goods-action/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── goods-action-button/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── goods-action-icon/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── grid/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── grid-item/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── icon/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── image/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── index-anchor/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── index-bar/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── info/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── loading/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── mixins/
│ │ ├── basic.d.ts
│ │ ├── basic.js
│ │ ├── button.d.ts
│ │ ├── button.js
│ │ ├── link.d.ts
│ │ ├── link.js
│ │ ├── open-type.d.ts
│ │ ├── open-type.js
│ │ ├── page-scroll.d.ts
│ │ ├── page-scroll.js
│ │ ├── touch.d.ts
│ │ ├── touch.js
│ │ ├── transition.d.ts
│ │ └── transition.js
│ ├── nav-bar/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── notice-bar/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── notify/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxss
│ │ ├── notify.d.ts
│ │ └── notify.js
│ ├── overlay/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── panel/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── picker/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxss
│ │ ├── shared.d.ts
│ │ ├── shared.js
│ │ └── toolbar.wxml
│ ├── picker-column/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ └── index.wxss
│ ├── popup/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── progress/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ └── index.wxss
│ ├── radio/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── radio-group/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── rate/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── row/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── search/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── sidebar/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── sidebar-item/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── skeleton/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── slider/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ └── index.wxss
│ ├── stepper/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── steps/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── sticky/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ └── index.wxss
│ ├── submit-bar/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── swipe-cell/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── switch/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── tab/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── tabbar/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── tabbar-item/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── tabs/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ └── index.wxss
│ ├── tag/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── toast/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxss
│ │ ├── toast.d.ts
│ │ └── toast.js
│ ├── transition/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── tree-select/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxs
│ │ └── index.wxss
│ ├── uploader/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxss
│ │ ├── shared.d.ts
│ │ ├── shared.js
│ │ ├── utils.d.ts
│ │ └── utils.js
│ └── wxs/
│ ├── add-unit.wxs
│ ├── array.wxs
│ ├── bem.wxs
│ ├── memoize.wxs
│ ├── object.wxs
│ └── utils.wxs
└── project.config.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
node_modules/*
================================================
FILE: .vscode/settings.json
================================================
{
"git.ignoreLimitWarning": true
}
================================================
FILE: README.md
================================================
# Secondary_trading_applet
基于微信小程序的校园二手交易平台
## 校园二手商城微信小程序成果(云开发)
图片看不到可在B站搜索易珠观看效果
### 功能
**(1)用户登陆注册**:在小程序个人主页点击登录或注册,填写相关信息,即可登录或注册,拥有个人账号进行买卖操作。后续也可以修改用户资料。
**(2)用户(卖家)出售商品**:在小程序发布页面,上传商品图片,填写商品各种详细即可发布商品。在个人主页的发布信息中即可查看商品交易信息,可以删除订单,重新上架商品,删除商品。
**(3)用户浏览商品**:商城主页,用户可以通过分类查看各个商品信息,也可以搜索商品名,得到筛选后的商品。点击商品进入商品详情页,可查看商品详细信息。
**(4)用户(买家)购买商品**:在商品详情页,买家可点击立即购买,预定这个商品,可在个人主页的购买信息中查看自己的购买记录,也可以在放弃购买时删除该订单,或在收到商品交易达成后,点击确认收货。交易完成。
**(5)用户交流**:买家可在商品详情页点击聊天与卖家进行沟通。在个人主页的消息中心中,都可以查看聊天信息,进入聊天室。
### 用户操作举例
首先进入小程序进行登录授权,授权进入后,显示商城主页,当前为未登陆注册状态不能发布和购买商品。
点击下方导航栏‘我的’进入个人主页,点击**登录**,填写信息,注册或登录账号,登录注册成功,个人主页显示用户微信头像及昵称
用户想要**出售商品**,可在商城主页导航栏点击‘发布’,填写信息发布商品,在个人主页我的发布中查看出售情况,如不想出售也可在我的发布处点击删除,商品下架。
用户想要**入手商品**,可回到商城首页,分类浏览商品,也可以通过上方搜索栏搜索商品,用户可以点击商品,进入商品详情页,查看物品详情,卖家信息,备注等等
买卖双方**交易过程:**
1.买家购买商品:
买家购买商品后,如在线下收到商品,则可以通过确认收货通知卖家
2.买家中止交易:
买家可以点击取消订单按钮中途取消交易,卖家会收到消息提醒。商品会自动上架。
3.卖家中止交易:
卖家可中途中止交易。然后点击重新上架按钮,重新发布到首页展示。
买家可在商品详情页点击‘聊天’与卖家沟通
卖家可在个人主页消息中心中,看到买家的信息,进入聊天室与之交流。
### 部署教程:
本小程序已经上线,可先预览:
## 一、小程序端
### 1、下载导入
直接下载到本地,然后导入开发者工具
> 小程序开发综合文档地址:https://developers.weixin.qq.com/miniprogram/dev/framework/
### 2、开通云环境
不罗嗦,这都是基础,直接看官方说明操作即可
> 云开发官方文档说明:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html
### 3、配置前端config
找到config.js文件,然后按照我写的注释更改为你自己的
## 二、云函数
### 1、修改基础信息
每个云函数要修改的部分,我都捻出来放在了顶部,直接根据我做的注释信息进行修改,如下图所示
### 2、上传全部文件
挨个提交每个云函数,其中依赖包我已经一起上传了,无需再挨个本地去安装,直接上传所有文件即可
## 三、云开发数据库
### 1、创建集合 设置权限
分别创建下图所示的集合,然后将所有集合的权限设置为所有可读
### 2、设置banner
#### ①在banner集合下新增一条记录
#### ②按照下图所示添加字段
#### 补充说明
list数组下的img为图片地址,id为唯一区分字段,url为点击轮播后跳转的地址,这个地址必须为与此小程序关联的公众号文章或者为业务域名地址,如果没有就留空即可
### 3、设置启动页图片
#### ①在start集合下新增一条记录
#### ②按照下图所示添加字段
## 四、公众平台配置(小程序不上线则不需要执行此步骤)
### 1、设置基本信息
| 名称 | 配置 |
| ------ | ---------------------------- |
| 类目 | 生活服务 > 环保回收/废品回收 |
| 基础库 | 2.4.3 |
### 2、提交审核
审核页面路径:pages/index/index
### 3、设置在线客服
打开【设置】--【客服】--【添加】,绑定成功后,打开小程序【客服小助手】,状态设置为在线即可,到时候有客户咨询自动会推送到你的微信号上的
## 五、服务与反馈
#### 如果需要提供安装服务,直接联系我微信:XXXXXXXXXX 如果觉得对你有帮助可以支持一下!感谢!**(代码开源,但时间不“开源”,伸手党勿扰!)**
================================================
FILE: cloudfunctions/his/index.js
================================================
const envid = 'taoshaoji-46f0r'; //云开发环境id
/*
下
面
不
用
管
*/
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: envid,
})
const TcbRouter = require('tcb-router'); //云函数路由
const db = cloud.database();
// 云函数入口函数
exports.main = async(event, context) => {
const app = new TcbRouter({
event
});
//钱包充值
app.router('recharge', async(ctx) => {
const wxContext = cloud.getWXContext()
const openid = wxContext.OPENID;
const userinfo = await db.collection('user').where({
_openid: openid // 填入当前用户 openid
}).get()
try {
ctx.body = await db.collection('user').doc(userinfo.data[0]._id).update({
data: {
parse: userinfo.data[0].parse + parseInt(event.num)
}
});
} catch (e) {
console.error(e)
}
});
//买家确认收货
app.router('toseller', async(ctx) => {
//先增加历史记录
await db.collection('history').add({
// data 字段表示需新增的 JSON 数据
data: {
oid: event.seller,
name: '出售书籍',
num: event.num,
stamp: new Date().getTime(),
type: 1,
}
})
//再修改钱包值
let userinfo = await db.collection('user').where({
_openid: event.seller, // 卖家openid
}).get()
ctx.body = await db.collection('user').doc(userinfo.data[0]._id).update({
data: {
parse: userinfo.data[0].parse + parseInt(event.num)
}
});
});
//卖家取消订单退款
app.router('tobuyer', async(ctx) => {
//先增加历史记录
await db.collection('history').add({
// data 字段表示需新增的 JSON 数据
data: {
oid: event.buyer,
name: '卖家取消交易退款',
num: event.num,
stamp: new Date().getTime(),
type: 1,
}
})
//再修改钱包值
let userinfo = await db.collection('user').where({
_openid: event.buyer,
}).get()
ctx.body = await db.collection('user').doc(userinfo.data[0]._id).update({
data: {
parse: userinfo.data[0].parse + parseInt(event.num)
}
});
});
return app.serve();
}
================================================
FILE: cloudfunctions/his/package.json
================================================
{
"name": "his",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"tcb-router": "^1.1.2",
"wx-server-sdk": "^1.1.0"
}
}
================================================
FILE: cloudfunctions/imgSecCheck/config.json
================================================
{
"permissions": {
"openapi": [
"security.imgSecCheck"
]
}
}
================================================
FILE: cloudfunctions/imgSecCheck/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
try {
const result = await cloud.openapi.security.imgSecCheck({
media: {
contentType: 'image/png',
value: Buffer.from(event.img) // 这里必须要将小程序端传过来的进行Buffer转化,否则就会报错,接口异常
}
})
if (result && result.errCode.toString() === '87014') {
return { code: 500, msg: '内容含有违法违规内容', data: result }
} else {
return { code: 200, msg: '内容ok', data: result }
}
} catch (err) {
// 错误处理
if (err.errCode.toString() === '87014') {
return { code: 500, msg: '内容含有违法违规内容', data: err }
}
return { code: 502, msg: '调用imgSecCheck接口异常', data: err }
}
}
================================================
FILE: cloudfunctions/imgSecCheck/package.json
================================================
{
"name": "imgSecCheck",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.2.0"
}
}
================================================
FILE: cloudfunctions/login/config.json
================================================
{
"permissions": {
"openapi": []
}
}
================================================
FILE: cloudfunctions/login/index.js
================================================
// 云函数模板
// 部署:在 cloud-functions/login 文件夹右击选择 “上传并部署”
const cloud = require('wx-server-sdk')
// 初始化 cloud
cloud.init({
// API 调用都保持和云函数当前所在环境一致
env: "taoshaoji-46f0r"
})
/**
* 这个示例将经自动鉴权过的小程序用户 openid 返回给小程序端
*
* event 参数包含小程序端调用传入的 data
*
*/
exports.main = (event, context) => {
console.log(event)
console.log(context)
// 可执行其他自定义逻辑
// console.log 的内容可以在云开发云函数调用日志查看
// 获取 WX Context (微信调用上下文),包括 OPENID、APPID、及 UNIONID(需满足 UNIONID 获取条件)等信息
const wxContext = cloud.getWXContext()
return {
event,
openid: wxContext.OPENID,
appid: wxContext.appid,
unionid: wxContext.UNIONID,
env: wxContext.ENV,
}
}
================================================
FILE: cloudfunctions/login/package.json
================================================
{
"name": "login",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest"
}
}
================================================
FILE: cloudfunctions/node/config.json
================================================
{
"permissions": {
"openapi": [
]
}
}
================================================
FILE: cloudfunctions/node/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const _ = db.command
// 云函数入口函数
exports.main = async (event, _context) => {
try {
return await db.collection('publish').doc(event._id).update({
// data 传入需要局部更新的数据
data: {
status:event.status
}
})
} catch (e) {
console.error(e)
}
}
================================================
FILE: cloudfunctions/node/package.json
================================================
{
"name": "node",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.1.2"
}
}
================================================
FILE: cloudfunctions/pay/index.js
================================================
const config = {
appid: 'xxxxxxx', //服务商公众号Appid
envName: 'taoshaoji-46f0r', // 小程序云开发环境ID
mchid: 'xxxxxxxx', //商户号
partnerKey: 'xxxxxxxxxxxxx', //此处填服务商密钥
notify_url: 'https://mp.weixin.qq.com', //这个不要管
spbill_create_ip: '127.0.0.1'//这个不要管
};
/*
下
面
不
用
管
*/
const cloud = require('wx-server-sdk');
cloud.init({
env: config.envName
})
const db = cloud.database();
const TcbRouter = require('tcb-router'); //云函数路由
const rq = require('request');
const tenpay = require('tenpay');//支付核心模块
exports.main = async (event, context) => {
const app = new TcbRouter({
event
});
//支付回调
app.router('pay', async (ctx) => {
const wxContext = cloud.getWXContext();
// 在云函数参数中,提取商品 ID
const goodId = event.goodId;
// 根据商品的数据库_id将其它数据提取出来
let goods = await db.collection('publish').doc(goodId).get();
// 在云函数中提取数据,包括名称、价格才更合理安全,
// 因为从端里传过来的商品数据都是不可靠的
let good=goods.data;
const curTime = Date.now();
const api = tenpay.init(config)
let result = await api.getPayParams({
//商户订单号,我这里是定义的boolk+商品发布时间+当前时间戳
//微信这里限制订单号一次性不能重复,只需要唯一即可
out_trade_no: 'book'+good.creat + '' + curTime,
body: good.bookinfo.title, //商品名称,我设置的书名
total_fee: parseInt(good.price)*100, //金额,注意是数字,不是字符串
openid: wxContext.OPENID //***用户的openid
});
ctx.body = result;//返回前端结果
});
//充值钱包
app.router('recharge', async (ctx) => {
const wxContext = cloud.getWXContext();
const curTime = Date.now();
const api = tenpay.init(config)
let result = await api.getPayParams({
//商户订单号
out_trade_no: 'bookcz' + event.num + '' + curTime,
body: '充值钱包', //商品名称
total_fee: parseInt(event.num)*100, //金额,注意是数字,不是字符串
openid: wxContext.OPENID //***用户的openid
});
ctx.body = result;//返回前端结果
});
//修改卖家在售状态
app.router('changeP', async (ctx) => {
try {
return await db.collection('publish').doc(event._id).update({
data: {
status:event.status
}
})
} catch (e) {
console.error(e)
}
});
//修改订单状态
app.router('changeO', async (ctx) => {
try {
return await db.collection('order').doc(event._id).update({
data: {
status: event.status
}
})
} catch (e) {
console.error(e)
}
});
return app.serve();
}
================================================
FILE: cloudfunctions/pay/package.json
================================================
{
"name": "pay",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"request": "^2.88.0",
"tcb-router": "^1.1.2",
"tenpay": "^2.1.18",
"wx-server-sdk": "latest"
}
}
================================================
FILE: cloudfunctions/poking/config.json
================================================
{
"permissions": {
"openapi": [
]
}
}
================================================
FILE: cloudfunctions/poking/index.js
================================================
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async(event, context) => {
try {
const result = await cloud.openapi.subscribeMessage.send({
touser: event.openid, //要推送给那个用户
page: 'pages/index/index', //要跳转到那个小程序页面
data: {//推送的内容
thing1: {
value: event.nickName
},
phrase2: {
value: event.phrase,
},
thing3: {
value: event.tip
}
},
templateId: 'XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q' //模板id
})
console.log(result)
return result
} catch (err) {
console.log(err)
return err
}
}
================================================
FILE: cloudfunctions/poking/package.json
================================================
{
"name": "poking",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.2.0"
}
}
================================================
FILE: cloudfunctions/ref/index.js
================================================
const config = {
appid: 'wxd6beb52c8602bff4', //小程序Appid
envName: 'taoshaoji-46f0r', // 小程序云开发环境ID
mchid: '1111111111', //商户号
partnerKey: '1111111111111111111111', //此处填服务商密钥
pfx: '', //证书初始化
fileID: 'cloud://taoshaoji-46f0r.7461-taoshaoji-46f0r-1302243411/apiclient_cert.p12', //证书云存储id
actionName:'吉珠二手书商城小程序提现',
rate:1 //提现收取利率,1指的是每笔收取1%
};
/*
下
面
不
用
管
*/
const cloud = require('wx-server-sdk')
cloud.init({
env: config.envName
})
const db = cloud.database();
const tenpay = require('tenpay'); //支付核心模块
exports.main = async(event, context) => {
let userInfo = (await db.collection('user').doc(event.userid).get()).data;
if (parseInt(userInfo.parse)<=parseInt(event.num)){
return 0;
}
//首先获取证书文件
let fileres = await cloud.downloadFile({
fileID: config.fileID,
})
config.pfx = fileres.fileContent
let pay = new tenpay(config,true)
let result = await pay.transfers({
partner_trade_no: 'bookreflect' + Date.now() + event.num,
openid: userInfo._openid,
check_name: 'NO_CHECK',
amount: parseInt(event.num) * (100 - config.rate),
desc: config.actionName,
});
if (result.result_code == 'SUCCESS') {
//成功后操作
//以下是进行余额计算
let re=await db.collection('user').doc(event.userid).update({
data: {
parse: userInfo.parse - parseInt(event.num)
}
});
return re
}
}
================================================
FILE: cloudfunctions/ref/package.json
================================================
{
"name": "ref",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"tenpay": "^2.1.18",
"wx-server-sdk": "^1.2.1"
}
}
================================================
FILE: cloudfunctions/regist/RdWXBizDataCrypt.js
================================================
// 引入CryptoJS
var Crypto = require('cryptojs/cryptojs.js').Crypto;
function RdWXBizDataCrypt(appId, sessionKey) {
this.appId = appId
this.sessionKey = sessionKey
}
RdWXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
encryptedData = encryptedData.replace(/%/g, '%25')
// base64 decode :使用 CryptoJS 中 Crypto.util.base64ToBytes()进行 base64解码
var encryptedData = Crypto.util.base64ToBytes(encryptedData)
var key = Crypto.util.base64ToBytes(this.sessionKey);
var iv = Crypto.util.base64ToBytes(iv);
// 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充
var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
try {
// 解密
var bytes = Crypto.AES.decrypt(encryptedData, key, {
asBpytes: true,
iv: iv,
mode: mode
});
var decryptResult = JSON.parse(bytes);
} catch (err) {
console.log(err)
}
if (decryptResult.watermark.appid !== this.appId) {
console.log(err)
}
return decryptResult
}
module.exports = RdWXBizDataCrypt
================================================
FILE: cloudfunctions/regist/cryptojs/cryptojs.js
================================================
var Crypto = exports.Crypto = require('./lib/Crypto').Crypto;
[ 'CryptoMath'
, 'BlockModes'
, 'DES'
, 'AES'
, 'HMAC'
, 'MARC4'
, 'MD5'
, 'PBKDF2'
, 'PBKDF2Async'
, 'Rabbit'
, 'SHA1'
, 'SHA256'
].forEach( function (path) {
require('./lib/' + path);
});
================================================
FILE: cloudfunctions/regist/cryptojs/lib/AES.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8;
// Precomputed SBOX
var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ];
// Compute inverse SBOX lookup table
for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i;
// Compute mulitplication in GF(2^8) lookup tables
var MULT2 = [],
MULT3 = [],
MULT9 = [],
MULTB = [],
MULTD = [],
MULTE = [];
function xtime(a, b) {
for (var result = 0, i = 0; i < 8; i++) {
if (b & 1) result ^= a;
var hiBitSet = a & 0x80;
a = (a << 1) & 0xFF;
if (hiBitSet) a ^= 0x1b;
b >>>= 1;
}
return result;
}
for (var i = 0; i < 256; i++) {
MULT2[i] = xtime(i,2);
MULT3[i] = xtime(i,3);
MULT9[i] = xtime(i,9);
MULTB[i] = xtime(i,0xB);
MULTD[i] = xtime(i,0xD);
MULTE[i] = xtime(i,0xE);
}
// Precomputed RCon lookup
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
// Inner state
var state = [[], [], [], []],
keylength,
nrounds,
keyschedule;
var AES = C.AES = {
/**
* Public API
*/
encrypt: function (message, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions) mode.fixOptions(options);
var
// Convert to bytes if message is a string
m = (
message.constructor == String ?
UTF8.stringToBytes(message) :
message
),
// Generate random IV
iv = options.iv || util.randomBytes(AES._blocksize * 4),
// Generate key
k = (
password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password
);
// Encrypt
AES._init(k);
mode.encrypt(AES, m, iv);
// Return ciphertext
m = options.iv ? m : iv.concat(m);
return (options && options.asBytes) ? m : util.bytesToBase64(m);
},
decrypt: function (ciphertext, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions) mode.fixOptions(options);
var
// Convert to bytes if ciphertext is a string
c = (
ciphertext.constructor == String ?
util.base64ToBytes(ciphertext):
ciphertext
),
// Separate IV and message
iv = options.iv || c.splice(0, AES._blocksize * 4),
// Generate key
k = (
password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password
);
// Decrypt
AES._init(k);
mode.decrypt(AES, c, iv);
// Return plaintext
return (options && options.asBytes) ? c : UTF8.bytesToString(c);
},
/**
* Package private methods and properties
*/
_blocksize: 4,
_encryptblock: function (m, offset) {
// Set input
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = m[offset + col * 4 + row];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[col][row];
}
for (var round = 1; round < nrounds; round++) {
// Sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = SBOX[state[row][col]];
}
// Shift rows
state[1].push(state[1].shift());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].unshift(state[3].pop());
// Mix columns
for (var col = 0; col < 4; col++) {
var s0 = state[0][col],
s1 = state[1][col],
s2 = state[2][col],
s3 = state[3][col];
state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3;
state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3;
state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3];
state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[round * 4 + col][row];
}
}
// Sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = SBOX[state[row][col]];
}
// Shift rows
state[1].push(state[1].shift());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].unshift(state[3].pop());
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[nrounds * 4 + col][row];
}
// Set output
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
m[offset + col * 4 + row] = state[row][col];
}
},
_decryptblock: function (c, offset) {
// Set input
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = c[offset + col * 4 + row];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[nrounds * 4 + col][row];
}
for (var round = 1; round < nrounds; round++) {
// Inv shift rows
state[1].unshift(state[1].pop());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].push(state[3].shift());
// Inv sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = INVSBOX[state[row][col]];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row];
}
// Inv mix columns
for (var col = 0; col < 4; col++) {
var s0 = state[0][col],
s1 = state[1][col],
s2 = state[2][col],
s3 = state[3][col];
state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3];
state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3];
state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3];
state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3];
}
}
// Inv shift rows
state[1].unshift(state[1].pop());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].push(state[3].shift());
// Inv sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = INVSBOX[state[row][col]];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[col][row];
}
// Set output
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
c[offset + col * 4 + row] = state[row][col];
}
},
/**
* Private methods
*/
_init: function (k) {
keylength = k.length / 4;
nrounds = keylength + 6;
AES._keyexpansion(k);
},
// Generate a key schedule
_keyexpansion: function (k) {
keyschedule = [];
for (var row = 0; row < keylength; row++) {
keyschedule[row] = [
k[row * 4],
k[row * 4 + 1],
k[row * 4 + 2],
k[row * 4 + 3]
];
}
for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) {
var temp = [
keyschedule[row - 1][0],
keyschedule[row - 1][1],
keyschedule[row - 1][2],
keyschedule[row - 1][3]
];
if (row % keylength == 0) {
// Rot word
temp.push(temp.shift());
// Sub word
temp[0] = SBOX[temp[0]];
temp[1] = SBOX[temp[1]];
temp[2] = SBOX[temp[2]];
temp[3] = SBOX[temp[3]];
temp[0] ^= RCON[row / keylength];
} else if (keylength > 6 && row % keylength == 4) {
// Sub word
temp[0] = SBOX[temp[0]];
temp[1] = SBOX[temp[1]];
temp[2] = SBOX[temp[2]];
temp[3] = SBOX[temp[3]];
}
keyschedule[row] = [
keyschedule[row - keylength][0] ^ temp[0],
keyschedule[row - keylength][1] ^ temp[1],
keyschedule[row - keylength][2] ^ temp[2],
keyschedule[row - keylength][3] ^ temp[3]
];
}
}
};
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/BlockModes.js
================================================
/*!
* Crypto-JS contribution from Simon Greatrix
*/
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Create pad namespace
var C_pad = C.pad = {};
// Calculate the number of padding bytes required.
function _requiredPadding(cipher, message) {
var blockSizeInBytes = cipher._blocksize * 4;
var reqd = blockSizeInBytes - message.length % blockSizeInBytes;
return reqd;
};
// Remove padding when the final byte gives the number of padding bytes.
var _unpadLength = function (message) {
var pad = message.pop();
for (var i = 1; i < pad; i++) {
message.pop();
}
};
// No-operation padding, used for stream ciphers
C_pad.NoPadding = {
pad : function (cipher,message) {},
unpad : function (message) {}
};
// Zero Padding.
//
// If the message is not an exact number of blocks, the final block is
// completed with 0x00 bytes. There is no unpadding.
C_pad.ZeroPadding = {
pad : function (cipher, message) {
var blockSizeInBytes = cipher._blocksize * 4;
var reqd = message.length % blockSizeInBytes;
if( reqd!=0 ) {
for(reqd = blockSizeInBytes - reqd; reqd>0; reqd--) {
message.push(0x00);
}
}
},
unpad : function (message) {}
};
// ISO/IEC 7816-4 padding.
//
// Pads the plain text with an 0x80 byte followed by as many 0x00
// bytes are required to complete the block.
C_pad.iso7816 = {
pad : function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
message.push(0x80);
for (; reqd > 1; reqd--) {
message.push(0x00);
}
},
unpad : function (message) {
while (message.pop() != 0x80) {}
}
};
// ANSI X.923 padding
//
// The final block is padded with zeros except for the last byte of the
// last block which contains the number of padding bytes.
C_pad.ansix923 = {
pad : function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
for (var i = 1; i < reqd; i++) {
message.push(0x00);
}
message.push(reqd);
},
unpad : _unpadLength
};
// ISO 10126
//
// The final block is padded with random bytes except for the last
// byte of the last block which contains the number of padding bytes.
C_pad.iso10126 = {
pad : function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
for (var i = 1; i < reqd; i++) {
message.push(Math.floor(Math.random() * 256));
}
message.push(reqd);
},
unpad : _unpadLength
};
// PKCS7 padding
//
// PKCS7 is described in RFC 5652. Padding is in whole bytes. The
// value of each added byte is the number of bytes that are added,
// i.e. N bytes, each of value N are added.
C_pad.pkcs7 = {
pad : function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
for (var i = 0; i < reqd; i++) {
message.push(reqd);
}
},
unpad : _unpadLength
};
// Create mode namespace
var C_mode = C.mode = {};
/**
* Mode base "class".
*/
var Mode = C_mode.Mode = function (padding) {
if (padding) {
this._padding = padding;
}
};
Mode.prototype = {
encrypt: function (cipher, m, iv) {
this._padding.pad(cipher, m);
this._doEncrypt(cipher, m, iv);
},
decrypt: function (cipher, m, iv) {
this._doDecrypt(cipher, m, iv);
this._padding.unpad(m);
},
// Default padding
_padding: C_pad.iso7816
};
/**
* Electronic Code Book mode.
*
* ECB applies the cipher directly against each block of the input.
*
* ECB does not require an initialization vector.
*/
var ECB = C_mode.ECB = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var ECB_prototype = ECB.prototype = new Mode;
// Concrete steps for Mode template
ECB_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// Encrypt each block
for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
cipher._encryptblock(m, offset);
}
};
ECB_prototype._doDecrypt = function (cipher, c, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// Decrypt each block
for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
cipher._decryptblock(c, offset);
}
};
// ECB never uses an IV
ECB_prototype.fixOptions = function (options) {
options.iv = [];
};
/**
* Cipher block chaining
*
* The first block is XORed with the IV. Subsequent blocks are XOR with the
* previous cipher output.
*/
var CBC = C_mode.CBC = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var CBC_prototype = CBC.prototype = new Mode;
// Concrete steps for Mode template
CBC_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// Encrypt each block
for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
if (offset == 0) {
// XOR first block using IV
for (var i = 0; i < blockSizeInBytes; i++)
m[i] ^= iv[i];
} else {
// XOR this block using previous crypted block
for (var i = 0; i < blockSizeInBytes; i++)
m[offset + i] ^= m[offset + i - blockSizeInBytes];
}
// Encrypt block
cipher._encryptblock(m, offset);
}
};
CBC_prototype._doDecrypt = function (cipher, c, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// At the start, the previously crypted block is the IV
var prevCryptedBlock = iv;
// Decrypt each block
for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
// Save this crypted block
var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes);
// Decrypt block
cipher._decryptblock(c, offset);
// XOR decrypted block using previous crypted block
for (var i = 0; i < blockSizeInBytes; i++) {
c[offset + i] ^= prevCryptedBlock[i];
}
prevCryptedBlock = thisCryptedBlock;
}
};
/**
* Cipher feed back
*
* The cipher output is XORed with the plain text to produce the cipher output,
* which is then fed back into the cipher to produce a bit pattern to XOR the
* next block with.
*
* This is a stream cipher mode and does not require padding.
*/
var CFB = C_mode.CFB = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var CFB_prototype = CFB.prototype = new Mode;
// Override padding
CFB_prototype._padding = C_pad.NoPadding;
// Concrete steps for Mode template
CFB_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4,
keystream = iv.slice(0);
// Encrypt each byte
for (var i = 0; i < m.length; i++) {
var j = i % blockSizeInBytes;
if (j == 0) cipher._encryptblock(keystream, 0);
m[i] ^= keystream[j];
keystream[j] = m[i];
}
};
CFB_prototype._doDecrypt = function (cipher, c, iv) {
var blockSizeInBytes = cipher._blocksize * 4,
keystream = iv.slice(0);
// Encrypt each byte
for (var i = 0; i < c.length; i++) {
var j = i % blockSizeInBytes;
if (j == 0) cipher._encryptblock(keystream, 0);
var b = c[i];
c[i] ^= keystream[j];
keystream[j] = b;
}
};
/**
* Output feed back
*
* The cipher repeatedly encrypts its own output. The output is XORed with the
* plain text to produce the cipher text.
*
* This is a stream cipher mode and does not require padding.
*/
var OFB = C_mode.OFB = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var OFB_prototype = OFB.prototype = new Mode;
// Override padding
OFB_prototype._padding = C_pad.NoPadding;
// Concrete steps for Mode template
OFB_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4,
keystream = iv.slice(0);
// Encrypt each byte
for (var i = 0; i < m.length; i++) {
// Generate keystream
if (i % blockSizeInBytes == 0)
cipher._encryptblock(keystream, 0);
// Encrypt byte
m[i] ^= keystream[i % blockSizeInBytes];
}
};
OFB_prototype._doDecrypt = OFB_prototype._doEncrypt;
/**
* Counter
* @author Gergely Risko
*
* After every block the last 4 bytes of the IV is increased by one
* with carry and that IV is used for the next block.
*
* This is a stream cipher mode and does not require padding.
*/
var CTR = C_mode.CTR = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var CTR_prototype = CTR.prototype = new Mode;
// Override padding
CTR_prototype._padding = C_pad.NoPadding;
CTR_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
var counter = iv.slice(0);
for (var i = 0; i < m.length;) {
// do not lose iv
var keystream = counter.slice(0);
// Generate keystream for next block
cipher._encryptblock(keystream, 0);
// XOR keystream with block
for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) {
m[i] ^= keystream[j];
}
// Increase counter
if(++(counter[blockSizeInBytes-1]) == 256) {
counter[blockSizeInBytes-1] = 0;
if(++(counter[blockSizeInBytes-2]) == 256) {
counter[blockSizeInBytes-2] = 0;
if(++(counter[blockSizeInBytes-3]) == 256) {
counter[blockSizeInBytes-3] = 0;
++(counter[blockSizeInBytes-4]);
}
}
}
}
};
CTR_prototype._doDecrypt = CTR_prototype._doEncrypt;
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/Crypto.js
================================================
if (typeof Crypto == "undefined" || ! Crypto.util)
{
(function(){
var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// Global Crypto object
// with browser window or with node module
var Crypto = (typeof window === 'undefined') ? exports.Crypto = {} : window.Crypto = {};
// Crypto utilities
var util = Crypto.util = {
// Bit-wise rotate left
rotl: function (n, b) {
return (n << b) | (n >>> (32 - b));
},
// Bit-wise rotate right
rotr: function (n, b) {
return (n << (32 - b)) | (n >>> b);
},
// Swap big-endian to little-endian and vice versa
endian: function (n) {
// If number given, swap endian
if (n.constructor == Number) {
return util.rotl(n, 8) & 0x00FF00FF |
util.rotl(n, 24) & 0xFF00FF00;
}
// Else, assume array and swap all items
for (var i = 0; i < n.length; i++)
n[i] = util.endian(n[i]);
return n;
},
// Generate an array of any length of random bytes
randomBytes: function (n) {
for (var bytes = []; n > 0; n--)
bytes.push(Math.floor(Math.random() * 256));
return bytes;
},
// Convert a byte array to big-endian 32-bit words
bytesToWords: function (bytes) {
for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32);
return words;
},
// Convert big-endian 32-bit words to a byte array
wordsToBytes: function (words) {
for (var bytes = [], b = 0; b < words.length * 32; b += 8)
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
return bytes;
},
// Convert a byte array to a hex string
bytesToHex: function (bytes) {
for (var hex = [], i = 0; i < bytes.length; i++) {
hex.push((bytes[i] >>> 4).toString(16));
hex.push((bytes[i] & 0xF).toString(16));
}
return hex.join("");
},
// Convert a hex string to a byte array
hexToBytes: function (hex) {
for (var bytes = [], c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return bytes;
},
// Convert a byte array to a base-64 string
bytesToBase64: function (bytes) {
// Use browser-native function if it exists
if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes));
for(var base64 = [], i = 0; i < bytes.length; i += 3) {
var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 <= bytes.length * 8)
base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
else base64.push("=");
}
}
return base64.join("");
},
// Convert a base-64 string to a byte array
base64ToBytes: function (base64) {
// Use browser-native function if it exists
if (typeof atob == "function") return Binary.stringToBytes(atob(base64));
// Remove non-base-64 characters
base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) {
if (imod4 == 0) continue;
bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) |
(base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
}
return bytes;
}
};
// Crypto character encodings
var charenc = Crypto.charenc = {};
// UTF-8 encoding
var UTF8 = charenc.UTF8 = {
// Convert a string to a byte array
stringToBytes: function (str) {
return Binary.stringToBytes(unescape(encodeURIComponent(str)));
},
// Convert a byte array to a string
bytesToString: function (bytes) {
return decodeURIComponent(escape(Binary.bytesToString(bytes)));
}
};
// Binary encoding
var Binary = charenc.Binary = {
// Convert a string to a byte array
stringToBytes: function (str) {
for (var bytes = [], i = 0; i < str.length; i++)
bytes.push(str.charCodeAt(i) & 0xFF);
return bytes;
},
// Convert a byte array to a string
bytesToString: function (bytes) {
for (var str = [], i = 0; i < bytes.length; i++)
str.push(String.fromCharCode(bytes[i]));
return str.join("");
}
};
})();
}
================================================
FILE: cloudfunctions/regist/cryptojs/lib/CryptoMath.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcut
var util = C.util;
// Convert n to unsigned 32-bit integer
util.u32 = function (n) {
return n >>> 0;
};
// Unsigned 32-bit addition
util.add = function () {
var result = this.u32(arguments[0]);
for (var i = 1; i < arguments.length; i++)
result = this.u32(result + this.u32(arguments[i]));
return result;
};
// Unsigned 32-bit multiplication
util.mult = function (m, n) {
return this.add((n & 0xFFFF0000) * m,
(n & 0x0000FFFF) * m);
};
// Unsigned 32-bit greater than (>) comparison
util.gt = function (m, n) {
return this.u32(m) > this.u32(n);
};
// Unsigned 32-bit less than (<) comparison
util.lt = function (m, n) {
return this.u32(m) < this.u32(n);
};
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/DES.js
================================================
/**
* Definition of Data Encryption Standard (DES) taken from:
* http://www.itl.nist.gov/fipspubs/fip46-2.htm
*/
(function() {
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util, charenc = C.charenc, UTF8 = charenc.UTF8;
/***************************************************************************
*
* DES Key Schedule.
*
* The Key consists of 16 sub-keys of 48 bits each. As each sub-key is
* applied to an expanded 32-bit value where each 4 bits of input is
* expanded into 6 bits of output the sub-key can be broken down into 8
* 32-bit values which allows the key to be used without expansion.
*
* To create the 16 sub-keys, 56 bits are selected from the input 64 bit key
* according to PC1 . Each sub-key is generated by left rotating the
* bits a different amount and then selecting 48 bits according to PC2 .
*
**************************************************************************/
var KeySchedule;
/**
* Representation of a DES key schedule.
*
* @param {Array
* of 8 bytes} key The cipher key
*
* @constructor
*/
KeySchedule = function(key) {
/**
* The schedule of 16 keys
*/
this.keys = new Array(16);
this._initialiseKeys(key);
};
/**
* Permuted Choice 1 (PC1) byte offsets into the key. Each of the 56 entries
* selects one bit of DES's 56 bit key.
*
*
*
* The PC1 is defined as:
*
* 57, 49, 41, 33, 25, 17, 9,
* 1, 58, 50, 42, 34, 26, 18,
* 10, 2, 59, 51, 43, 35, 27,
* 19, 11, 3, 60, 52, 44, 36,
* 63, 55, 47, 39, 31, 23, 15,
* 7, 62, 54, 46, 38, 30, 22,
* 14, 6, 61, 53, 45, 37, 29,
* 21, 13, 5, 28, 20, 12, 4
*
*
* We represent this as an offset into an 8-byte array and a bit mask upon
* that byte. For example 57=(7*8)+1 so is the first (MSB) of the 7th byte.
*
* @constant
*/
KeySchedule.PC1_offsets = [ 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6,
5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 3, 2, 1, 0 ];
/**
* Permuted Choice 1 (PC1) bit masks. Each of the 56 entries selects one bit
* of DES's 56 bit key.
*
* @constant
*/
KeySchedule.PC1_masks = [ 128, 128, 128, 128, 128, 128, 128, 128, 64, 64,
64, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16,
16, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
8, 8, 8, 16, 16, 16, 16 ];
/**
* Permuted Choice 2 (PC2) selects the active 48 bits from the 56 bits of
* the key.
*
*
*
* The PC2 is defined as:
*
* 14, 17, 11, 24, 1, 5,
* 3, 28, 15, 6, 21, 10,
* 23, 19, 12, 4, 26, 8,
* 16, 7, 27, 20, 13, 2,
* 41, 52, 31, 37, 47, 55,
* 30, 40, 51, 45, 33, 48,
* 44, 49, 39, 56, 34, 53,
* 46, 42, 50, 36, 29, 32
*
*
* We invert the choice to specify what each bit adds to each 6-bit value of
* the key. For example, bit 1 is the 5th bit selected so this add 2 to the
* first 6-bit value.
*
* @constant
*/
KeySchedule.PC2_offsets1 = [ 0, 3, 1, 2, 0, 1, 3, 2, 0, 1, 0, 2, 3, 0, 1,
3, 0, 0, 2, 3, 1, 0, 2, 0, 0, 2, 3, 1 ];
/**
* PC2 offsets for 2nd block.
*
* @constant
*/
KeySchedule.PC2_offsets2 = [ 7, 5, 4, 7, 5, 6, 0, 7, 4, 0, 6, 5, 4, 7, 0,
6, 5, 7, 4, 5, 6, 7, 5, 4, 6, 0, 4, 6 ];
/**
* Permuted Choice 2 (PC2) masks for 1st block.
*
* @constant
*/
KeySchedule.PC2_masks1 = [ 2, 1, 32, 4, 1, 4, 16, 1, 0, 1, 8, 8, 2, 32, 8,
32, 16, 0, 16, 4, 2, 0, 32, 4, 0, 2, 8, 16 ];
/**
* PC2 masks for 2nd block.
*
* @constant
*/
KeySchedule.PC2_masks2 = [ 2, 32, 8, 1, 2, 2, 0, 4, 4, 0, 8, 16, 32, 16, 0,
32, 4, 32, 2, 1, 16, 8, 8, 16, 1, 0, 1, 4 ];
/**
* Cumulative key shifts.
*
* @constant
*/
KeySchedule.keyShifts = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23,
25, 27, 28 ];
KeySchedule.prototype._initialiseKeys = function(key) {
var i;
// extract 56 key bits in order determined by PC1
var bits = new Array(56);
for (i = 0; i < 56; i++) {
bits[i] = (key[KeySchedule.PC1_offsets[i]] & KeySchedule.PC1_masks[i]) != 0;
}
// split 56 bits into two 28-bit chunks
var bits1 = bits.slice(0, 28);
var bits2 = bits.slice(28, 56);
// duplicate each half to allow for easy bit shifts
bits1 = bits1.concat(bits1);
bits2 = bits2.concat(bits2);
// assemble the 16 keys
for (i = 0; i < 16; i++) {
var k = [ 0, 0, 0, 0, 0, 0, 0, 0 ];
// select the bits of the key according to PC2
var s = KeySchedule.keyShifts[i];
for ( var j = 0; j < 28; j++) {
if (bits1[j + s]) {
k[KeySchedule.PC2_offsets1[j]] += KeySchedule.PC2_masks1[j];
}
if (bits2[j + s]) {
k[KeySchedule.PC2_offsets2[j]] += KeySchedule.PC2_masks2[j];
}
}
// Scale each of the 8 blocks to a 32-bit mask.
k[0] = ((k[0] & 0x1f) << 27) + ((k[0] & 0x20) >> 5);
for ( var j = 1; j <= 6; j++) {
k[j] = k[j] << (27 - 4 * j);
}
k[7] = ((k[7] & 0x3e) >> 1) + ((k[7] & 0x1) << 31);
this.keys[i] = k;
}
};
/**
* Retrieve the key for a specified round
*
* @param i
* the round
* @returns the key
*/
KeySchedule.prototype.getKey = function(i) {
return this.keys[i];
};
/***************************************************************************
*
* DES Engine State
*
**************************************************************************/
var State;
/**
* The algorithm's state. DES operates on two sets of 32-bits, with each
* block of 32-bits treated as a single number.
*
* @class
*/
State = function() {
/** The LHS of the Feistel scheme */
this.lhs = 0;
/** The RHS of the Feistel scheme */
this.rhs = 0;
};
/**
* The masks that select the SBOX input. Each SBOX accepts 6 bits from the
* input.
*
* @constant
*/
State.SBOX_MASK = [ 0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,
0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f ];
/**
* The SBOXes. The 8 SBOXes each map 6 bit masked bit of the input to 4 bits
* of output. These SBOXes include the post SBOX permutation and benefit
* from JavaScript's sparse arrays to make specifying the input match
* simple.
*
* @constant
*/
State.SBOX = new Array(8);
var SBOX = State.SBOX;
SBOX[0] = new Array();
SBOX[0][0] = 0x808200; // 0 (0, 0) = 14
SBOX[0][268435456] = 0x8000; // 10000000 (0, 1) = 4
SBOX[0][536870912] = 0x808002; // 20000000 (0, 2) = 13
SBOX[0][805306368] = 0x2; // 30000000 (0, 3) = 1
SBOX[0][1073741824] = 0x200; // 40000000 (0, 4) = 2
SBOX[0][1342177280] = 0x808202; // 50000000 (0, 5) = 15
SBOX[0][1610612736] = 0x800202; // 60000000 (0, 6) = 11
SBOX[0][1879048192] = 0x800000; // 70000000 (0, 7) = 8
SBOX[0][-2147483648] = 0x202; // 80000000 (0, 8) = 3
SBOX[0][-1879048192] = 0x800200; // 90000000 (0, 9) = 10
SBOX[0][-1610612736] = 0x8200; // a0000000 (0, 10) = 6
SBOX[0][-1342177280] = 0x808000; // b0000000 (0, 11) = 12
SBOX[0][-1073741824] = 0x8002; // c0000000 (0, 12) = 5
SBOX[0][-805306368] = 0x800002; // d0000000 (0, 13) = 9
SBOX[0][-536870912] = 0x0; // e0000000 (0, 14) = 0
SBOX[0][-268435456] = 0x8202; // f0000000 (0, 15) = 7
SBOX[0][134217728] = 0x0; // 8000000 (1, 0) = 0
SBOX[0][402653184] = 0x808202; // 18000000 (1, 1) = 15
SBOX[0][671088640] = 0x8202; // 28000000 (1, 2) = 7
SBOX[0][939524096] = 0x8000; // 38000000 (1, 3) = 4
SBOX[0][1207959552] = 0x808200; // 48000000 (1, 4) = 14
SBOX[0][1476395008] = 0x200; // 58000000 (1, 5) = 2
SBOX[0][1744830464] = 0x808002; // 68000000 (1, 6) = 13
SBOX[0][2013265920] = 0x2; // 78000000 (1, 7) = 1
SBOX[0][-2013265920] = 0x800200; // 88000000 (1, 8) = 10
SBOX[0][-1744830464] = 0x8200; // 98000000 (1, 9) = 6
SBOX[0][-1476395008] = 0x808000; // a8000000 (1, 10) = 12
SBOX[0][-1207959552] = 0x800202; // b8000000 (1, 11) = 11
SBOX[0][-939524096] = 0x800002; // c8000000 (1, 12) = 9
SBOX[0][-671088640] = 0x8002; // d8000000 (1, 13) = 5
SBOX[0][-402653184] = 0x202; // e8000000 (1, 14) = 3
SBOX[0][-134217728] = 0x800000; // f8000000 (1, 15) = 8
SBOX[0][1] = 0x8000; // 1 (2, 0) = 4
SBOX[0][268435457] = 0x2; // 10000001 (2, 1) = 1
SBOX[0][536870913] = 0x808200; // 20000001 (2, 2) = 14
SBOX[0][805306369] = 0x800000; // 30000001 (2, 3) = 8
SBOX[0][1073741825] = 0x808002; // 40000001 (2, 4) = 13
SBOX[0][1342177281] = 0x8200; // 50000001 (2, 5) = 6
SBOX[0][1610612737] = 0x200; // 60000001 (2, 6) = 2
SBOX[0][1879048193] = 0x800202; // 70000001 (2, 7) = 11
SBOX[0][-2147483647] = 0x808202; // 80000001 (2, 8) = 15
SBOX[0][-1879048191] = 0x808000; // 90000001 (2, 9) = 12
SBOX[0][-1610612735] = 0x800002; // a0000001 (2, 10) = 9
SBOX[0][-1342177279] = 0x8202; // b0000001 (2, 11) = 7
SBOX[0][-1073741823] = 0x202; // c0000001 (2, 12) = 3
SBOX[0][-805306367] = 0x800200; // d0000001 (2, 13) = 10
SBOX[0][-536870911] = 0x8002; // e0000001 (2, 14) = 5
SBOX[0][-268435455] = 0x0; // f0000001 (2, 15) = 0
SBOX[0][134217729] = 0x808202; // 8000001 (3, 0) = 15
SBOX[0][402653185] = 0x808000; // 18000001 (3, 1) = 12
SBOX[0][671088641] = 0x800000; // 28000001 (3, 2) = 8
SBOX[0][939524097] = 0x200; // 38000001 (3, 3) = 2
SBOX[0][1207959553] = 0x8000; // 48000001 (3, 4) = 4
SBOX[0][1476395009] = 0x800002; // 58000001 (3, 5) = 9
SBOX[0][1744830465] = 0x2; // 68000001 (3, 6) = 1
SBOX[0][2013265921] = 0x8202; // 78000001 (3, 7) = 7
SBOX[0][-2013265919] = 0x8002; // 88000001 (3, 8) = 5
SBOX[0][-1744830463] = 0x800202; // 98000001 (3, 9) = 11
SBOX[0][-1476395007] = 0x202; // a8000001 (3, 10) = 3
SBOX[0][-1207959551] = 0x808200; // b8000001 (3, 11) = 14
SBOX[0][-939524095] = 0x800200; // c8000001 (3, 12) = 10
SBOX[0][-671088639] = 0x0; // d8000001 (3, 13) = 0
SBOX[0][-402653183] = 0x8200; // e8000001 (3, 14) = 6
SBOX[0][-134217727] = 0x808002; // f8000001 (3, 15) = 13
SBOX[1] = new Array();
SBOX[1][0] = 0x40084010; // 0 (0, 0) = 15
SBOX[1][16777216] = 0x4000; // 1000000 (0, 1) = 1
SBOX[1][33554432] = 0x80000; // 2000000 (0, 2) = 8
SBOX[1][50331648] = 0x40080010; // 3000000 (0, 3) = 14
SBOX[1][67108864] = 0x40000010; // 4000000 (0, 4) = 6
SBOX[1][83886080] = 0x40084000; // 5000000 (0, 5) = 11
SBOX[1][100663296] = 0x40004000; // 6000000 (0, 6) = 3
SBOX[1][117440512] = 0x10; // 7000000 (0, 7) = 4
SBOX[1][134217728] = 0x84000; // 8000000 (0, 8) = 9
SBOX[1][150994944] = 0x40004010; // 9000000 (0, 9) = 7
SBOX[1][167772160] = 0x40000000; // a000000 (0, 10) = 2
SBOX[1][184549376] = 0x84010; // b000000 (0, 11) = 13
SBOX[1][201326592] = 0x80010; // c000000 (0, 12) = 12
SBOX[1][218103808] = 0x0; // d000000 (0, 13) = 0
SBOX[1][234881024] = 0x4010; // e000000 (0, 14) = 5
SBOX[1][251658240] = 0x40080000; // f000000 (0, 15) = 10
SBOX[1][8388608] = 0x40004000; // 800000 (1, 0) = 3
SBOX[1][25165824] = 0x84010; // 1800000 (1, 1) = 13
SBOX[1][41943040] = 0x10; // 2800000 (1, 2) = 4
SBOX[1][58720256] = 0x40004010; // 3800000 (1, 3) = 7
SBOX[1][75497472] = 0x40084010; // 4800000 (1, 4) = 15
SBOX[1][92274688] = 0x40000000; // 5800000 (1, 5) = 2
SBOX[1][109051904] = 0x80000; // 6800000 (1, 6) = 8
SBOX[1][125829120] = 0x40080010; // 7800000 (1, 7) = 14
SBOX[1][142606336] = 0x80010; // 8800000 (1, 8) = 12
SBOX[1][159383552] = 0x0; // 9800000 (1, 9) = 0
SBOX[1][176160768] = 0x4000; // a800000 (1, 10) = 1
SBOX[1][192937984] = 0x40080000; // b800000 (1, 11) = 10
SBOX[1][209715200] = 0x40000010; // c800000 (1, 12) = 6
SBOX[1][226492416] = 0x84000; // d800000 (1, 13) = 9
SBOX[1][243269632] = 0x40084000; // e800000 (1, 14) = 11
SBOX[1][260046848] = 0x4010; // f800000 (1, 15) = 5
SBOX[1][268435456] = 0x0; // 10000000 (2, 0) = 0
SBOX[1][285212672] = 0x40080010; // 11000000 (2, 1) = 14
SBOX[1][301989888] = 0x40004010; // 12000000 (2, 2) = 7
SBOX[1][318767104] = 0x40084000; // 13000000 (2, 3) = 11
SBOX[1][335544320] = 0x40080000; // 14000000 (2, 4) = 10
SBOX[1][352321536] = 0x10; // 15000000 (2, 5) = 4
SBOX[1][369098752] = 0x84010; // 16000000 (2, 6) = 13
SBOX[1][385875968] = 0x4000; // 17000000 (2, 7) = 1
SBOX[1][402653184] = 0x4010; // 18000000 (2, 8) = 5
SBOX[1][419430400] = 0x80000; // 19000000 (2, 9) = 8
SBOX[1][436207616] = 0x80010; // 1a000000 (2, 10) = 12
SBOX[1][452984832] = 0x40000010; // 1b000000 (2, 11) = 6
SBOX[1][469762048] = 0x84000; // 1c000000 (2, 12) = 9
SBOX[1][486539264] = 0x40004000; // 1d000000 (2, 13) = 3
SBOX[1][503316480] = 0x40000000; // 1e000000 (2, 14) = 2
SBOX[1][520093696] = 0x40084010; // 1f000000 (2, 15) = 15
SBOX[1][276824064] = 0x84010; // 10800000 (3, 0) = 13
SBOX[1][293601280] = 0x80000; // 11800000 (3, 1) = 8
SBOX[1][310378496] = 0x40080000; // 12800000 (3, 2) = 10
SBOX[1][327155712] = 0x4000; // 13800000 (3, 3) = 1
SBOX[1][343932928] = 0x40004000; // 14800000 (3, 4) = 3
SBOX[1][360710144] = 0x40084010; // 15800000 (3, 5) = 15
SBOX[1][377487360] = 0x10; // 16800000 (3, 6) = 4
SBOX[1][394264576] = 0x40000000; // 17800000 (3, 7) = 2
SBOX[1][411041792] = 0x40084000; // 18800000 (3, 8) = 11
SBOX[1][427819008] = 0x40000010; // 19800000 (3, 9) = 6
SBOX[1][444596224] = 0x40004010; // 1a800000 (3, 10) = 7
SBOX[1][461373440] = 0x80010; // 1b800000 (3, 11) = 12
SBOX[1][478150656] = 0x0; // 1c800000 (3, 12) = 0
SBOX[1][494927872] = 0x4010; // 1d800000 (3, 13) = 5
SBOX[1][511705088] = 0x40080010; // 1e800000 (3, 14) = 14
SBOX[1][528482304] = 0x84000; // 1f800000 (3, 15) = 9
SBOX[2] = new Array();
SBOX[2][0] = 0x104; // 0 (0, 0) = 10
SBOX[2][1048576] = 0x0; // 100000 (0, 1) = 0
SBOX[2][2097152] = 0x4000100; // 200000 (0, 2) = 9
SBOX[2][3145728] = 0x10104; // 300000 (0, 3) = 14
SBOX[2][4194304] = 0x10004; // 400000 (0, 4) = 6
SBOX[2][5242880] = 0x4000004; // 500000 (0, 5) = 3
SBOX[2][6291456] = 0x4010104; // 600000 (0, 6) = 15
SBOX[2][7340032] = 0x4010000; // 700000 (0, 7) = 5
SBOX[2][8388608] = 0x4000000; // 800000 (0, 8) = 1
SBOX[2][9437184] = 0x4010100; // 900000 (0, 9) = 13
SBOX[2][10485760] = 0x10100; // a00000 (0, 10) = 12
SBOX[2][11534336] = 0x4010004; // b00000 (0, 11) = 7
SBOX[2][12582912] = 0x4000104; // c00000 (0, 12) = 11
SBOX[2][13631488] = 0x10000; // d00000 (0, 13) = 4
SBOX[2][14680064] = 0x4; // e00000 (0, 14) = 2
SBOX[2][15728640] = 0x100; // f00000 (0, 15) = 8
SBOX[2][524288] = 0x4010100; // 80000 (1, 0) = 13
SBOX[2][1572864] = 0x4010004; // 180000 (1, 1) = 7
SBOX[2][2621440] = 0x0; // 280000 (1, 2) = 0
SBOX[2][3670016] = 0x4000100; // 380000 (1, 3) = 9
SBOX[2][4718592] = 0x4000004; // 480000 (1, 4) = 3
SBOX[2][5767168] = 0x10000; // 580000 (1, 5) = 4
SBOX[2][6815744] = 0x10004; // 680000 (1, 6) = 6
SBOX[2][7864320] = 0x104; // 780000 (1, 7) = 10
SBOX[2][8912896] = 0x4; // 880000 (1, 8) = 2
SBOX[2][9961472] = 0x100; // 980000 (1, 9) = 8
SBOX[2][11010048] = 0x4010000; // a80000 (1, 10) = 5
SBOX[2][12058624] = 0x10104; // b80000 (1, 11) = 14
SBOX[2][13107200] = 0x10100; // c80000 (1, 12) = 12
SBOX[2][14155776] = 0x4000104; // d80000 (1, 13) = 11
SBOX[2][15204352] = 0x4010104; // e80000 (1, 14) = 15
SBOX[2][16252928] = 0x4000000; // f80000 (1, 15) = 1
SBOX[2][16777216] = 0x4010100; // 1000000 (2, 0) = 13
SBOX[2][17825792] = 0x10004; // 1100000 (2, 1) = 6
SBOX[2][18874368] = 0x10000; // 1200000 (2, 2) = 4
SBOX[2][19922944] = 0x4000100; // 1300000 (2, 3) = 9
SBOX[2][20971520] = 0x100; // 1400000 (2, 4) = 8
SBOX[2][22020096] = 0x4010104; // 1500000 (2, 5) = 15
SBOX[2][23068672] = 0x4000004; // 1600000 (2, 6) = 3
SBOX[2][24117248] = 0x0; // 1700000 (2, 7) = 0
SBOX[2][25165824] = 0x4000104; // 1800000 (2, 8) = 11
SBOX[2][26214400] = 0x4000000; // 1900000 (2, 9) = 1
SBOX[2][27262976] = 0x4; // 1a00000 (2, 10) = 2
SBOX[2][28311552] = 0x10100; // 1b00000 (2, 11) = 12
SBOX[2][29360128] = 0x4010000; // 1c00000 (2, 12) = 5
SBOX[2][30408704] = 0x104; // 1d00000 (2, 13) = 10
SBOX[2][31457280] = 0x10104; // 1e00000 (2, 14) = 14
SBOX[2][32505856] = 0x4010004; // 1f00000 (2, 15) = 7
SBOX[2][17301504] = 0x4000000; // 1080000 (3, 0) = 1
SBOX[2][18350080] = 0x104; // 1180000 (3, 1) = 10
SBOX[2][19398656] = 0x4010100; // 1280000 (3, 2) = 13
SBOX[2][20447232] = 0x0; // 1380000 (3, 3) = 0
SBOX[2][21495808] = 0x10004; // 1480000 (3, 4) = 6
SBOX[2][22544384] = 0x4000100; // 1580000 (3, 5) = 9
SBOX[2][23592960] = 0x100; // 1680000 (3, 6) = 8
SBOX[2][24641536] = 0x4010004; // 1780000 (3, 7) = 7
SBOX[2][25690112] = 0x10000; // 1880000 (3, 8) = 4
SBOX[2][26738688] = 0x4010104; // 1980000 (3, 9) = 15
SBOX[2][27787264] = 0x10104; // 1a80000 (3, 10) = 14
SBOX[2][28835840] = 0x4000004; // 1b80000 (3, 11) = 3
SBOX[2][29884416] = 0x4000104; // 1c80000 (3, 12) = 11
SBOX[2][30932992] = 0x4010000; // 1d80000 (3, 13) = 5
SBOX[2][31981568] = 0x4; // 1e80000 (3, 14) = 2
SBOX[2][33030144] = 0x10100; // 1f80000 (3, 15) = 12
SBOX[3] = new Array();
SBOX[3][0] = 0x80401000; // 0 (0, 0) = 7
SBOX[3][65536] = 0x80001040; // 10000 (0, 1) = 13
SBOX[3][131072] = 0x401040; // 20000 (0, 2) = 14
SBOX[3][196608] = 0x80400000; // 30000 (0, 3) = 3
SBOX[3][262144] = 0x0; // 40000 (0, 4) = 0
SBOX[3][327680] = 0x401000; // 50000 (0, 5) = 6
SBOX[3][393216] = 0x80000040; // 60000 (0, 6) = 9
SBOX[3][458752] = 0x400040; // 70000 (0, 7) = 10
SBOX[3][524288] = 0x80000000; // 80000 (0, 8) = 1
SBOX[3][589824] = 0x400000; // 90000 (0, 9) = 2
SBOX[3][655360] = 0x40; // a0000 (0, 10) = 8
SBOX[3][720896] = 0x80001000; // b0000 (0, 11) = 5
SBOX[3][786432] = 0x80400040; // c0000 (0, 12) = 11
SBOX[3][851968] = 0x1040; // d0000 (0, 13) = 12
SBOX[3][917504] = 0x1000; // e0000 (0, 14) = 4
SBOX[3][983040] = 0x80401040; // f0000 (0, 15) = 15
SBOX[3][32768] = 0x80001040; // 8000 (1, 0) = 13
SBOX[3][98304] = 0x40; // 18000 (1, 1) = 8
SBOX[3][163840] = 0x80400040; // 28000 (1, 2) = 11
SBOX[3][229376] = 0x80001000; // 38000 (1, 3) = 5
SBOX[3][294912] = 0x401000; // 48000 (1, 4) = 6
SBOX[3][360448] = 0x80401040; // 58000 (1, 5) = 15
SBOX[3][425984] = 0x0; // 68000 (1, 6) = 0
SBOX[3][491520] = 0x80400000; // 78000 (1, 7) = 3
SBOX[3][557056] = 0x1000; // 88000 (1, 8) = 4
SBOX[3][622592] = 0x80401000; // 98000 (1, 9) = 7
SBOX[3][688128] = 0x400000; // a8000 (1, 10) = 2
SBOX[3][753664] = 0x1040; // b8000 (1, 11) = 12
SBOX[3][819200] = 0x80000000; // c8000 (1, 12) = 1
SBOX[3][884736] = 0x400040; // d8000 (1, 13) = 10
SBOX[3][950272] = 0x401040; // e8000 (1, 14) = 14
SBOX[3][1015808] = 0x80000040; // f8000 (1, 15) = 9
SBOX[3][1048576] = 0x400040; // 100000 (2, 0) = 10
SBOX[3][1114112] = 0x401000; // 110000 (2, 1) = 6
SBOX[3][1179648] = 0x80000040; // 120000 (2, 2) = 9
SBOX[3][1245184] = 0x0; // 130000 (2, 3) = 0
SBOX[3][1310720] = 0x1040; // 140000 (2, 4) = 12
SBOX[3][1376256] = 0x80400040; // 150000 (2, 5) = 11
SBOX[3][1441792] = 0x80401000; // 160000 (2, 6) = 7
SBOX[3][1507328] = 0x80001040; // 170000 (2, 7) = 13
SBOX[3][1572864] = 0x80401040; // 180000 (2, 8) = 15
SBOX[3][1638400] = 0x80000000; // 190000 (2, 9) = 1
SBOX[3][1703936] = 0x80400000; // 1a0000 (2, 10) = 3
SBOX[3][1769472] = 0x401040; // 1b0000 (2, 11) = 14
SBOX[3][1835008] = 0x80001000; // 1c0000 (2, 12) = 5
SBOX[3][1900544] = 0x400000; // 1d0000 (2, 13) = 2
SBOX[3][1966080] = 0x40; // 1e0000 (2, 14) = 8
SBOX[3][2031616] = 0x1000; // 1f0000 (2, 15) = 4
SBOX[3][1081344] = 0x80400000; // 108000 (3, 0) = 3
SBOX[3][1146880] = 0x80401040; // 118000 (3, 1) = 15
SBOX[3][1212416] = 0x0; // 128000 (3, 2) = 0
SBOX[3][1277952] = 0x401000; // 138000 (3, 3) = 6
SBOX[3][1343488] = 0x400040; // 148000 (3, 4) = 10
SBOX[3][1409024] = 0x80000000; // 158000 (3, 5) = 1
SBOX[3][1474560] = 0x80001040; // 168000 (3, 6) = 13
SBOX[3][1540096] = 0x40; // 178000 (3, 7) = 8
SBOX[3][1605632] = 0x80000040; // 188000 (3, 8) = 9
SBOX[3][1671168] = 0x1000; // 198000 (3, 9) = 4
SBOX[3][1736704] = 0x80001000; // 1a8000 (3, 10) = 5
SBOX[3][1802240] = 0x80400040; // 1b8000 (3, 11) = 11
SBOX[3][1867776] = 0x1040; // 1c8000 (3, 12) = 12
SBOX[3][1933312] = 0x80401000; // 1d8000 (3, 13) = 7
SBOX[3][1998848] = 0x400000; // 1e8000 (3, 14) = 2
SBOX[3][2064384] = 0x401040; // 1f8000 (3, 15) = 14
SBOX[4] = new Array();
SBOX[4][0] = 0x80; // 0 (0, 0) = 2
SBOX[4][4096] = 0x1040000; // 1000 (0, 1) = 12
SBOX[4][8192] = 0x40000; // 2000 (0, 2) = 4
SBOX[4][12288] = 0x20000000; // 3000 (0, 3) = 1
SBOX[4][16384] = 0x20040080; // 4000 (0, 4) = 7
SBOX[4][20480] = 0x1000080; // 5000 (0, 5) = 10
SBOX[4][24576] = 0x21000080; // 6000 (0, 6) = 11
SBOX[4][28672] = 0x40080; // 7000 (0, 7) = 6
SBOX[4][32768] = 0x1000000; // 8000 (0, 8) = 8
SBOX[4][36864] = 0x20040000; // 9000 (0, 9) = 5
SBOX[4][40960] = 0x20000080; // a000 (0, 10) = 3
SBOX[4][45056] = 0x21040080; // b000 (0, 11) = 15
SBOX[4][49152] = 0x21040000; // c000 (0, 12) = 13
SBOX[4][53248] = 0x0; // d000 (0, 13) = 0
SBOX[4][57344] = 0x1040080; // e000 (0, 14) = 14
SBOX[4][61440] = 0x21000000; // f000 (0, 15) = 9
SBOX[4][2048] = 0x1040080; // 800 (1, 0) = 14
SBOX[4][6144] = 0x21000080; // 1800 (1, 1) = 11
SBOX[4][10240] = 0x80; // 2800 (1, 2) = 2
SBOX[4][14336] = 0x1040000; // 3800 (1, 3) = 12
SBOX[4][18432] = 0x40000; // 4800 (1, 4) = 4
SBOX[4][22528] = 0x20040080; // 5800 (1, 5) = 7
SBOX[4][26624] = 0x21040000; // 6800 (1, 6) = 13
SBOX[4][30720] = 0x20000000; // 7800 (1, 7) = 1
SBOX[4][34816] = 0x20040000; // 8800 (1, 8) = 5
SBOX[4][38912] = 0x0; // 9800 (1, 9) = 0
SBOX[4][43008] = 0x21040080; // a800 (1, 10) = 15
SBOX[4][47104] = 0x1000080; // b800 (1, 11) = 10
SBOX[4][51200] = 0x20000080; // c800 (1, 12) = 3
SBOX[4][55296] = 0x21000000; // d800 (1, 13) = 9
SBOX[4][59392] = 0x1000000; // e800 (1, 14) = 8
SBOX[4][63488] = 0x40080; // f800 (1, 15) = 6
SBOX[4][65536] = 0x40000; // 10000 (2, 0) = 4
SBOX[4][69632] = 0x80; // 11000 (2, 1) = 2
SBOX[4][73728] = 0x20000000; // 12000 (2, 2) = 1
SBOX[4][77824] = 0x21000080; // 13000 (2, 3) = 11
SBOX[4][81920] = 0x1000080; // 14000 (2, 4) = 10
SBOX[4][86016] = 0x21040000; // 15000 (2, 5) = 13
SBOX[4][90112] = 0x20040080; // 16000 (2, 6) = 7
SBOX[4][94208] = 0x1000000; // 17000 (2, 7) = 8
SBOX[4][98304] = 0x21040080; // 18000 (2, 8) = 15
SBOX[4][102400] = 0x21000000; // 19000 (2, 9) = 9
SBOX[4][106496] = 0x1040000; // 1a000 (2, 10) = 12
SBOX[4][110592] = 0x20040000; // 1b000 (2, 11) = 5
SBOX[4][114688] = 0x40080; // 1c000 (2, 12) = 6
SBOX[4][118784] = 0x20000080; // 1d000 (2, 13) = 3
SBOX[4][122880] = 0x0; // 1e000 (2, 14) = 0
SBOX[4][126976] = 0x1040080; // 1f000 (2, 15) = 14
SBOX[4][67584] = 0x21000080; // 10800 (3, 0) = 11
SBOX[4][71680] = 0x1000000; // 11800 (3, 1) = 8
SBOX[4][75776] = 0x1040000; // 12800 (3, 2) = 12
SBOX[4][79872] = 0x20040080; // 13800 (3, 3) = 7
SBOX[4][83968] = 0x20000000; // 14800 (3, 4) = 1
SBOX[4][88064] = 0x1040080; // 15800 (3, 5) = 14
SBOX[4][92160] = 0x80; // 16800 (3, 6) = 2
SBOX[4][96256] = 0x21040000; // 17800 (3, 7) = 13
SBOX[4][100352] = 0x40080; // 18800 (3, 8) = 6
SBOX[4][104448] = 0x21040080; // 19800 (3, 9) = 15
SBOX[4][108544] = 0x0; // 1a800 (3, 10) = 0
SBOX[4][112640] = 0x21000000; // 1b800 (3, 11) = 9
SBOX[4][116736] = 0x1000080; // 1c800 (3, 12) = 10
SBOX[4][120832] = 0x40000; // 1d800 (3, 13) = 4
SBOX[4][124928] = 0x20040000; // 1e800 (3, 14) = 5
SBOX[4][129024] = 0x20000080; // 1f800 (3, 15) = 3
SBOX[5] = new Array();
SBOX[5][0] = 0x10000008; // 0 (0, 0) = 12
SBOX[5][256] = 0x2000; // 100 (0, 1) = 1
SBOX[5][512] = 0x10200000; // 200 (0, 2) = 10
SBOX[5][768] = 0x10202008; // 300 (0, 3) = 15
SBOX[5][1024] = 0x10002000; // 400 (0, 4) = 9
SBOX[5][1280] = 0x200000; // 500 (0, 5) = 2
SBOX[5][1536] = 0x200008; // 600 (0, 6) = 6
SBOX[5][1792] = 0x10000000; // 700 (0, 7) = 8
SBOX[5][2048] = 0x0; // 800 (0, 8) = 0
SBOX[5][2304] = 0x10002008; // 900 (0, 9) = 13
SBOX[5][2560] = 0x202000; // a00 (0, 10) = 3
SBOX[5][2816] = 0x8; // b00 (0, 11) = 4
SBOX[5][3072] = 0x10200008; // c00 (0, 12) = 14
SBOX[5][3328] = 0x202008; // d00 (0, 13) = 7
SBOX[5][3584] = 0x2008; // e00 (0, 14) = 5
SBOX[5][3840] = 0x10202000; // f00 (0, 15) = 11
SBOX[5][128] = 0x10200000; // 80 (1, 0) = 10
SBOX[5][384] = 0x10202008; // 180 (1, 1) = 15
SBOX[5][640] = 0x8; // 280 (1, 2) = 4
SBOX[5][896] = 0x200000; // 380 (1, 3) = 2
SBOX[5][1152] = 0x202008; // 480 (1, 4) = 7
SBOX[5][1408] = 0x10000008; // 580 (1, 5) = 12
SBOX[5][1664] = 0x10002000; // 680 (1, 6) = 9
SBOX[5][1920] = 0x2008; // 780 (1, 7) = 5
SBOX[5][2176] = 0x200008; // 880 (1, 8) = 6
SBOX[5][2432] = 0x2000; // 980 (1, 9) = 1
SBOX[5][2688] = 0x10002008; // a80 (1, 10) = 13
SBOX[5][2944] = 0x10200008; // b80 (1, 11) = 14
SBOX[5][3200] = 0x0; // c80 (1, 12) = 0
SBOX[5][3456] = 0x10202000; // d80 (1, 13) = 11
SBOX[5][3712] = 0x202000; // e80 (1, 14) = 3
SBOX[5][3968] = 0x10000000; // f80 (1, 15) = 8
SBOX[5][4096] = 0x10002000; // 1000 (2, 0) = 9
SBOX[5][4352] = 0x10200008; // 1100 (2, 1) = 14
SBOX[5][4608] = 0x10202008; // 1200 (2, 2) = 15
SBOX[5][4864] = 0x2008; // 1300 (2, 3) = 5
SBOX[5][5120] = 0x200000; // 1400 (2, 4) = 2
SBOX[5][5376] = 0x10000000; // 1500 (2, 5) = 8
SBOX[5][5632] = 0x10000008; // 1600 (2, 6) = 12
SBOX[5][5888] = 0x202000; // 1700 (2, 7) = 3
SBOX[5][6144] = 0x202008; // 1800 (2, 8) = 7
SBOX[5][6400] = 0x0; // 1900 (2, 9) = 0
SBOX[5][6656] = 0x8; // 1a00 (2, 10) = 4
SBOX[5][6912] = 0x10200000; // 1b00 (2, 11) = 10
SBOX[5][7168] = 0x2000; // 1c00 (2, 12) = 1
SBOX[5][7424] = 0x10002008; // 1d00 (2, 13) = 13
SBOX[5][7680] = 0x10202000; // 1e00 (2, 14) = 11
SBOX[5][7936] = 0x200008; // 1f00 (2, 15) = 6
SBOX[5][4224] = 0x8; // 1080 (3, 0) = 4
SBOX[5][4480] = 0x202000; // 1180 (3, 1) = 3
SBOX[5][4736] = 0x200000; // 1280 (3, 2) = 2
SBOX[5][4992] = 0x10000008; // 1380 (3, 3) = 12
SBOX[5][5248] = 0x10002000; // 1480 (3, 4) = 9
SBOX[5][5504] = 0x2008; // 1580 (3, 5) = 5
SBOX[5][5760] = 0x10202008; // 1680 (3, 6) = 15
SBOX[5][6016] = 0x10200000; // 1780 (3, 7) = 10
SBOX[5][6272] = 0x10202000; // 1880 (3, 8) = 11
SBOX[5][6528] = 0x10200008; // 1980 (3, 9) = 14
SBOX[5][6784] = 0x2000; // 1a80 (3, 10) = 1
SBOX[5][7040] = 0x202008; // 1b80 (3, 11) = 7
SBOX[5][7296] = 0x200008; // 1c80 (3, 12) = 6
SBOX[5][7552] = 0x0; // 1d80 (3, 13) = 0
SBOX[5][7808] = 0x10000000; // 1e80 (3, 14) = 8
SBOX[5][8064] = 0x10002008; // 1f80 (3, 15) = 13
SBOX[6] = new Array();
SBOX[6][0] = 0x100000; // 0 (0, 0) = 4
SBOX[6][16] = 0x2000401; // 10 (0, 1) = 11
SBOX[6][32] = 0x400; // 20 (0, 2) = 2
SBOX[6][48] = 0x100401; // 30 (0, 3) = 14
SBOX[6][64] = 0x2100401; // 40 (0, 4) = 15
SBOX[6][80] = 0x0; // 50 (0, 5) = 0
SBOX[6][96] = 0x1; // 60 (0, 6) = 8
SBOX[6][112] = 0x2100001; // 70 (0, 7) = 13
SBOX[6][128] = 0x2000400; // 80 (0, 8) = 3
SBOX[6][144] = 0x100001; // 90 (0, 9) = 12
SBOX[6][160] = 0x2000001; // a0 (0, 10) = 9
SBOX[6][176] = 0x2100400; // b0 (0, 11) = 7
SBOX[6][192] = 0x2100000; // c0 (0, 12) = 5
SBOX[6][208] = 0x401; // d0 (0, 13) = 10
SBOX[6][224] = 0x100400; // e0 (0, 14) = 6
SBOX[6][240] = 0x2000000; // f0 (0, 15) = 1
SBOX[6][8] = 0x2100001; // 8 (1, 0) = 13
SBOX[6][24] = 0x0; // 18 (1, 1) = 0
SBOX[6][40] = 0x2000401; // 28 (1, 2) = 11
SBOX[6][56] = 0x2100400; // 38 (1, 3) = 7
SBOX[6][72] = 0x100000; // 48 (1, 4) = 4
SBOX[6][88] = 0x2000001; // 58 (1, 5) = 9
SBOX[6][104] = 0x2000000; // 68 (1, 6) = 1
SBOX[6][120] = 0x401; // 78 (1, 7) = 10
SBOX[6][136] = 0x100401; // 88 (1, 8) = 14
SBOX[6][152] = 0x2000400; // 98 (1, 9) = 3
SBOX[6][168] = 0x2100000; // a8 (1, 10) = 5
SBOX[6][184] = 0x100001; // b8 (1, 11) = 12
SBOX[6][200] = 0x400; // c8 (1, 12) = 2
SBOX[6][216] = 0x2100401; // d8 (1, 13) = 15
SBOX[6][232] = 0x1; // e8 (1, 14) = 8
SBOX[6][248] = 0x100400; // f8 (1, 15) = 6
SBOX[6][256] = 0x2000000; // 100 (2, 0) = 1
SBOX[6][272] = 0x100000; // 110 (2, 1) = 4
SBOX[6][288] = 0x2000401; // 120 (2, 2) = 11
SBOX[6][304] = 0x2100001; // 130 (2, 3) = 13
SBOX[6][320] = 0x100001; // 140 (2, 4) = 12
SBOX[6][336] = 0x2000400; // 150 (2, 5) = 3
SBOX[6][352] = 0x2100400; // 160 (2, 6) = 7
SBOX[6][368] = 0x100401; // 170 (2, 7) = 14
SBOX[6][384] = 0x401; // 180 (2, 8) = 10
SBOX[6][400] = 0x2100401; // 190 (2, 9) = 15
SBOX[6][416] = 0x100400; // 1a0 (2, 10) = 6
SBOX[6][432] = 0x1; // 1b0 (2, 11) = 8
SBOX[6][448] = 0x0; // 1c0 (2, 12) = 0
SBOX[6][464] = 0x2100000; // 1d0 (2, 13) = 5
SBOX[6][480] = 0x2000001; // 1e0 (2, 14) = 9
SBOX[6][496] = 0x400; // 1f0 (2, 15) = 2
SBOX[6][264] = 0x100400; // 108 (3, 0) = 6
SBOX[6][280] = 0x2000401; // 118 (3, 1) = 11
SBOX[6][296] = 0x2100001; // 128 (3, 2) = 13
SBOX[6][312] = 0x1; // 138 (3, 3) = 8
SBOX[6][328] = 0x2000000; // 148 (3, 4) = 1
SBOX[6][344] = 0x100000; // 158 (3, 5) = 4
SBOX[6][360] = 0x401; // 168 (3, 6) = 10
SBOX[6][376] = 0x2100400; // 178 (3, 7) = 7
SBOX[6][392] = 0x2000001; // 188 (3, 8) = 9
SBOX[6][408] = 0x2100000; // 198 (3, 9) = 5
SBOX[6][424] = 0x0; // 1a8 (3, 10) = 0
SBOX[6][440] = 0x2100401; // 1b8 (3, 11) = 15
SBOX[6][456] = 0x100401; // 1c8 (3, 12) = 14
SBOX[6][472] = 0x400; // 1d8 (3, 13) = 2
SBOX[6][488] = 0x2000400; // 1e8 (3, 14) = 3
SBOX[6][504] = 0x100001; // 1f8 (3, 15) = 12
SBOX[7] = new Array();
SBOX[7][0] = 0x8000820; // 0 (0, 0) = 13
SBOX[7][1] = 0x20000; // 1 (0, 1) = 2
SBOX[7][2] = 0x8000000; // 2 (0, 2) = 8
SBOX[7][3] = 0x20; // 3 (0, 3) = 4
SBOX[7][4] = 0x20020; // 4 (0, 4) = 6
SBOX[7][5] = 0x8020820; // 5 (0, 5) = 15
SBOX[7][6] = 0x8020800; // 6 (0, 6) = 11
SBOX[7][7] = 0x800; // 7 (0, 7) = 1
SBOX[7][8] = 0x8020000; // 8 (0, 8) = 10
SBOX[7][9] = 0x8000800; // 9 (0, 9) = 9
SBOX[7][10] = 0x20800; // a (0, 10) = 3
SBOX[7][11] = 0x8020020; // b (0, 11) = 14
SBOX[7][12] = 0x820; // c (0, 12) = 5
SBOX[7][13] = 0x0; // d (0, 13) = 0
SBOX[7][14] = 0x8000020; // e (0, 14) = 12
SBOX[7][15] = 0x20820; // f (0, 15) = 7
SBOX[7][-2147483648] = 0x800; // 80000000 (1, 0) = 1
SBOX[7][-2147483647] = 0x8020820; // 80000001 (1, 1) = 15
SBOX[7][-2147483646] = 0x8000820; // 80000002 (1, 2) = 13
SBOX[7][-2147483645] = 0x8000000; // 80000003 (1, 3) = 8
SBOX[7][-2147483644] = 0x8020000; // 80000004 (1, 4) = 10
SBOX[7][-2147483643] = 0x20800; // 80000005 (1, 5) = 3
SBOX[7][-2147483642] = 0x20820; // 80000006 (1, 6) = 7
SBOX[7][-2147483641] = 0x20; // 80000007 (1, 7) = 4
SBOX[7][-2147483640] = 0x8000020; // 80000008 (1, 8) = 12
SBOX[7][-2147483639] = 0x820; // 80000009 (1, 9) = 5
SBOX[7][-2147483638] = 0x20020; // 8000000a (1, 10) = 6
SBOX[7][-2147483637] = 0x8020800; // 8000000b (1, 11) = 11
SBOX[7][-2147483636] = 0x0; // 8000000c (1, 12) = 0
SBOX[7][-2147483635] = 0x8020020; // 8000000d (1, 13) = 14
SBOX[7][-2147483634] = 0x8000800; // 8000000e (1, 14) = 9
SBOX[7][-2147483633] = 0x20000; // 8000000f (1, 15) = 2
SBOX[7][16] = 0x20820; // 10 (2, 0) = 7
SBOX[7][17] = 0x8020800; // 11 (2, 1) = 11
SBOX[7][18] = 0x20; // 12 (2, 2) = 4
SBOX[7][19] = 0x800; // 13 (2, 3) = 1
SBOX[7][20] = 0x8000800; // 14 (2, 4) = 9
SBOX[7][21] = 0x8000020; // 15 (2, 5) = 12
SBOX[7][22] = 0x8020020; // 16 (2, 6) = 14
SBOX[7][23] = 0x20000; // 17 (2, 7) = 2
SBOX[7][24] = 0x0; // 18 (2, 8) = 0
SBOX[7][25] = 0x20020; // 19 (2, 9) = 6
SBOX[7][26] = 0x8020000; // 1a (2, 10) = 10
SBOX[7][27] = 0x8000820; // 1b (2, 11) = 13
SBOX[7][28] = 0x8020820; // 1c (2, 12) = 15
SBOX[7][29] = 0x20800; // 1d (2, 13) = 3
SBOX[7][30] = 0x820; // 1e (2, 14) = 5
SBOX[7][31] = 0x8000000; // 1f (2, 15) = 8
SBOX[7][-2147483632] = 0x20000; // 80000010 (3, 0) = 2
SBOX[7][-2147483631] = 0x800; // 80000011 (3, 1) = 1
SBOX[7][-2147483630] = 0x8020020; // 80000012 (3, 2) = 14
SBOX[7][-2147483629] = 0x20820; // 80000013 (3, 3) = 7
SBOX[7][-2147483628] = 0x20; // 80000014 (3, 4) = 4
SBOX[7][-2147483627] = 0x8020000; // 80000015 (3, 5) = 10
SBOX[7][-2147483626] = 0x8000000; // 80000016 (3, 6) = 8
SBOX[7][-2147483625] = 0x8000820; // 80000017 (3, 7) = 13
SBOX[7][-2147483624] = 0x8020820; // 80000018 (3, 8) = 15
SBOX[7][-2147483623] = 0x8000020; // 80000019 (3, 9) = 12
SBOX[7][-2147483622] = 0x8000800; // 8000001a (3, 10) = 9
SBOX[7][-2147483621] = 0x0; // 8000001b (3, 11) = 0
SBOX[7][-2147483620] = 0x20800; // 8000001c (3, 12) = 3
SBOX[7][-2147483619] = 0x820; // 8000001d (3, 13) = 5
SBOX[7][-2147483618] = 0x20020; // 8000001e (3, 14) = 6
SBOX[7][-2147483617] = 0x8020800; // 8000001f (3, 15) = 11
State.prototype._exchangeLR = function(v, m) {
var t = ((this.lhs >> v) ^ this.rhs) & m;
this.rhs ^= t;
this.lhs ^= (t << v);
};
State.prototype._exchangeRL = function(v, m) {
var t = ((this.rhs >> v) ^ this.lhs) & m;
this.lhs ^= t;
this.rhs ^= (t << v);
};
/**
* Perform the initial permutation of the input to create the starting state
* of the algorithm. The initial permutation maps each consecutive bit of
* the input into a different byte of the state.
*
*
* The initial permutation is defined to be:
*
* 58 50 42 34 26 18 10 2
* 60 52 44 36 28 20 12 4
* 62 54 46 38 30 22 14 6
* 64 56 48 40 32 24 16 8
* 57 49 41 33 25 17 9 1
* 59 51 43 35 27 19 11 3
* 61 53 45 37 29 21 13 5
* 63 55 47 39 31 23 15 7
*
*
*
* @param message
* The message as an array of unsigned bytes.
* @param offset
* The offset into the message that the current 64-bit block
* begins.
* @returns the initial engine state
*/
State.prototype.initialPerm = function(message, offset) {
var input = message.slice(offset, offset + 8);
this.lhs = (input[0] << 24) + (input[1] << 16) + (input[2] << 8)
+ input[3];
this.rhs = (input[4] << 24) + (input[5] << 16) + (input[6] << 8)
+ input[7];
this._exchangeLR(4, 0x0f0f0f0f);
this._exchangeLR(16, 0x0000ffff);
this._exchangeRL(2, 0x33333333);
this._exchangeRL(8, 0x00ff00ff);
this._exchangeLR(1, 0x55555555);
};
/**
* Perform one round of the DES algorithm using the given key. A round is
* defined as:
*
*
* L&rsquo = R
* R&rsquo = L ˆ f(R, k)
*
*
* where f consists of expanding, XORing with the key and contracting back
* with the SBOXes.
*
* Note that the final round is defined slightly differently as:
*
*
* L&rsquo = L ˆ f(R, k)
* R&rsquo = R
*
*
* Therefore in the final round this function produces LHS and RHS the wrong
* way around.
*
* @param k
* the key
*/
State.prototype.round = function(k) {
var r = this.rhs, l = this.lhs;
var f = 0;
for ( var i = 0; i < 8; i++) {
var v = (r ^ k[i]) & State.SBOX_MASK[i];
f += State.SBOX[i][v];
}
this.lhs = r;
this.rhs = l ^ f;
};
/**
* Apply the inverse of the initial permutation.
*
*
* The inverse is defined to be:
*
* 40 8 48 16 56 24 64 32
* 39 7 47 15 55 23 63 31
* 38 6 46 14 54 22 62 30
* 37 5 45 13 53 21 61 29
* 36 4 44 12 52 20 60 28
* 35 3 43 11 51 19 59 27
* 34 2 42 10 50 18 58 26
* 33 1 41 9 49 17 57 25
*
*
* @param cipherText
* @param offset
*/
State.prototype.finalPerm = function(cipherText, offset) {
var t = this.lhs;
this.lhs = this.rhs;
this.rhs = t;
this._exchangeLR(1, 0x55555555);
this._exchangeRL(8, 0x00ff00ff);
this._exchangeRL(2, 0x33333333);
this._exchangeLR(16, 0x0000ffff);
this._exchangeLR(4, 0x0f0f0f0f);
cipherText[offset] = (this.lhs >> 24) & 0xff;
cipherText[offset + 1] = (this.lhs >> 16) & 0xff;
cipherText[offset + 2] = (this.lhs >> 8) & 0xff;
cipherText[offset + 3] = (this.lhs) & 0xff;
cipherText[offset + 4] = (this.rhs >> 24) & 0xff;
cipherText[offset + 5] = (this.rhs >> 16) & 0xff;
cipherText[offset + 6] = (this.rhs >> 8) & 0xff;
cipherText[offset + 7] = (this.rhs) & 0xff;
};
/**
* DES cipher
*/
var DES = C.DES = {
_blocksize : 2,
_keyschedule : null,
_state : new State(),
_init : function(k) {
this._keyschedule = new KeySchedule(k);
},
encrypt : function(message, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions)
mode.fixOptions(options);
var
// Convert to bytes if message is a string
m = (message.constructor == String ? UTF8.stringToBytes(message)
: message),
// Generate random IV
iv = options.iv || util.randomBytes(8),
// Generate key
k = (password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 8, {
asBytes : true
}) :
// else, assume byte array representing cryptographic key
password);
// Create key schedule
this._keyschedule = new KeySchedule(k);
// Encrypt
mode.encrypt(DES, m, iv);
// Return ciphertext
m = options.iv ? m : iv.concat(m);
return (options && options.asBytes) ? m : util.bytesToBase64(m);
},
_encryptblock : function(message, offset) {
this._state.initialPerm(message, offset);
for ( var i = 0; i <= 15; i++) {
this._state.round(this._keyschedule.getKey(i));
}
this._state.finalPerm(message, offset);
},
decrypt : function(ciphertext, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions)
mode.fixOptions(options);
var
// Convert to bytes if ciphertext is a string
c = (ciphertext.constructor == String ? util
.base64ToBytes(ciphertext) : ciphertext),
// Separate IV and message
iv = options.iv || c.splice(0, 8),
// Generate key
k = (password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, {
asBytes : true
}) :
// else, assume byte array representing cryptographic key
password);
// Create key schedule
this._keyschedule = new KeySchedule(k);
mode.decrypt(DES, c, iv);
// Return plaintext
return (options && options.asBytes) ? c : UTF8.bytesToString(c);
},
_decryptblock : function(message, offset) {
this._state.initialPerm(message, offset);
for ( var i = 15; i >= 0; i--) {
this._state.round(this._keyschedule.getKey(i));
}
this._state.finalPerm(message, offset);
}
};
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/HMAC.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
C.HMAC = function (hasher, message, key, options) {
// Convert to byte arrays
if (message.constructor == String) message = UTF8.stringToBytes(message);
if (key.constructor == String) key = UTF8.stringToBytes(key);
/* else, assume byte arrays already */
// Allow arbitrary length keys
if (key.length > hasher._blocksize * 4)
key = hasher(key, { asBytes: true });
// XOR keys with pad constants
var okey = key.slice(0),
ikey = key.slice(0);
for (var i = 0; i < hasher._blocksize * 4; i++) {
okey[i] ^= 0x5C;
ikey[i] ^= 0x36;
}
var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true });
return options && options.asBytes ? hmacbytes :
options && options.asString ? Binary.bytesToString(hmacbytes) :
util.bytesToHex(hmacbytes);
};
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/MARC4.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
var MARC4 = C.MARC4 = {
/**
* Public API
*/
encrypt: function (message, password) {
var
// Convert to bytes
m = UTF8.stringToBytes(message),
// Generate random IV
iv = util.randomBytes(16),
// Generate key
k = password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password;
// Encrypt
MARC4._marc4(m, k, 1536);
// Return ciphertext
return util.bytesToBase64(iv.concat(m));
},
decrypt: function (ciphertext, password) {
var
// Convert to bytes
c = util.base64ToBytes(ciphertext),
// Separate IV and message
iv = c.splice(0, 16),
// Generate key
k = password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password;
// Decrypt
MARC4._marc4(c, k, 1536);
// Return plaintext
return UTF8.bytesToString(c);
},
/**
* Internal methods
*/
// The core
_marc4: function (m, k, drop) {
// State variables
var i, j, s, temp;
// Key setup
for (i = 0, s = []; i < 256; i++) s[i] = i;
for (i = 0, j = 0; i < 256; i++) {
j = (j + s[i] + k[i % k.length]) % 256;
// Swap
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
// Clear counters
i = j = 0;
// Encryption
for (var k = -drop; k < m.length; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
// Swap
temp = s[i];
s[i] = s[j];
s[j] = temp;
// Stop here if we're still dropping keystream
if (k < 0) continue;
// Encrypt
m[k] ^= s[(s[i] + s[j]) % 256];
}
}
};
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/MD5.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
// Public API
var MD5 = C.MD5 = function (message, options) {
var digestbytes = util.wordsToBytes(MD5._md5(message));
return options && options.asBytes ? digestbytes :
options && options.asString ? Binary.bytesToString(digestbytes) :
util.bytesToHex(digestbytes);
};
// The core
MD5._md5 = function (message) {
// Convert to byte array
if (message.constructor == String) message = UTF8.stringToBytes(message);
/* else, assume byte array already */
var m = util.bytesToWords(message),
l = message.length * 8,
a = 1732584193,
b = -271733879,
c = -1732584194,
d = 271733878;
// Swap endian
for (var i = 0; i < m.length; i++) {
m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF |
((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00;
}
// Padding
m[l >>> 5] |= 0x80 << (l % 32);
m[(((l + 64) >>> 9) << 4) + 14] = l;
// Method shortcuts
var FF = MD5._ff,
GG = MD5._gg,
HH = MD5._hh,
II = MD5._ii;
for (var i = 0; i < m.length; i += 16) {
var aa = a,
bb = b,
cc = c,
dd = d;
a = FF(a, b, c, d, m[i+ 0], 7, -680876936);
d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
c = FF(c, d, a, b, m[i+ 2], 17, 606105819);
b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
a = FF(a, b, c, d, m[i+ 4], 7, -176418897);
d = FF(d, a, b, c, m[i+ 5], 12, 1200080426);
c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
a = FF(a, b, c, d, m[i+ 8], 7, 1770035416);
d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
c = FF(c, d, a, b, m[i+10], 17, -42063);
b = FF(b, c, d, a, m[i+11], 22, -1990404162);
a = FF(a, b, c, d, m[i+12], 7, 1804603682);
d = FF(d, a, b, c, m[i+13], 12, -40341101);
c = FF(c, d, a, b, m[i+14], 17, -1502002290);
b = FF(b, c, d, a, m[i+15], 22, 1236535329);
a = GG(a, b, c, d, m[i+ 1], 5, -165796510);
d = GG(d, a, b, c, m[i+ 6], 9, -1069501632);
c = GG(c, d, a, b, m[i+11], 14, 643717713);
b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
a = GG(a, b, c, d, m[i+ 5], 5, -701558691);
d = GG(d, a, b, c, m[i+10], 9, 38016083);
c = GG(c, d, a, b, m[i+15], 14, -660478335);
b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
a = GG(a, b, c, d, m[i+ 9], 5, 568446438);
d = GG(d, a, b, c, m[i+14], 9, -1019803690);
c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
b = GG(b, c, d, a, m[i+ 8], 20, 1163531501);
a = GG(a, b, c, d, m[i+13], 5, -1444681467);
d = GG(d, a, b, c, m[i+ 2], 9, -51403784);
c = GG(c, d, a, b, m[i+ 7], 14, 1735328473);
b = GG(b, c, d, a, m[i+12], 20, -1926607734);
a = HH(a, b, c, d, m[i+ 5], 4, -378558);
d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
c = HH(c, d, a, b, m[i+11], 16, 1839030562);
b = HH(b, c, d, a, m[i+14], 23, -35309556);
a = HH(a, b, c, d, m[i+ 1], 4, -1530992060);
d = HH(d, a, b, c, m[i+ 4], 11, 1272893353);
c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
b = HH(b, c, d, a, m[i+10], 23, -1094730640);
a = HH(a, b, c, d, m[i+13], 4, 681279174);
d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
b = HH(b, c, d, a, m[i+ 6], 23, 76029189);
a = HH(a, b, c, d, m[i+ 9], 4, -640364487);
d = HH(d, a, b, c, m[i+12], 11, -421815835);
c = HH(c, d, a, b, m[i+15], 16, 530742520);
b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
a = II(a, b, c, d, m[i+ 0], 6, -198630844);
d = II(d, a, b, c, m[i+ 7], 10, 1126891415);
c = II(c, d, a, b, m[i+14], 15, -1416354905);
b = II(b, c, d, a, m[i+ 5], 21, -57434055);
a = II(a, b, c, d, m[i+12], 6, 1700485571);
d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
c = II(c, d, a, b, m[i+10], 15, -1051523);
b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
a = II(a, b, c, d, m[i+ 8], 6, 1873313359);
d = II(d, a, b, c, m[i+15], 10, -30611744);
c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
b = II(b, c, d, a, m[i+13], 21, 1309151649);
a = II(a, b, c, d, m[i+ 4], 6, -145523070);
d = II(d, a, b, c, m[i+11], 10, -1120210379);
c = II(c, d, a, b, m[i+ 2], 15, 718787259);
b = II(b, c, d, a, m[i+ 9], 21, -343485551);
a = (a + aa) >>> 0;
b = (b + bb) >>> 0;
c = (c + cc) >>> 0;
d = (d + dd) >>> 0;
}
return util.endian([a, b, c, d]);
};
// Auxiliary functions
MD5._ff = function (a, b, c, d, x, s, t) {
var n = a + (b & c | ~b & d) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
MD5._gg = function (a, b, c, d, x, s, t) {
var n = a + (b & d | c & ~d) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
MD5._hh = function (a, b, c, d, x, s, t) {
var n = a + (b ^ c ^ d) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
MD5._ii = function (a, b, c, d, x, s, t) {
var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
// Package private blocksize
MD5._blocksize = 16;
MD5._digestsize = 16;
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/PBKDF2.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
C.PBKDF2 = function (password, salt, keylen, options) {
// Convert to byte arrays
if (password.constructor == String) password = UTF8.stringToBytes(password);
if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
/* else, assume byte arrays already */
// Defaults
var hasher = options && options.hasher || C.SHA1,
iterations = options && options.iterations || 1;
// Pseudo-random function
function PRF(password, salt) {
return C.HMAC(hasher, salt, password, { asBytes: true });
}
// Generate key
var derivedKeyBytes = [],
blockindex = 1;
while (derivedKeyBytes.length < keylen) {
var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
for (var u = block, i = 1; i < iterations; i++) {
u = PRF(password, u);
for (var j = 0; j < block.length; j++) block[j] ^= u[j];
}
derivedKeyBytes = derivedKeyBytes.concat(block);
blockindex++;
}
// Truncate excess bytes
derivedKeyBytes.length = keylen;
return options && options.asBytes ? derivedKeyBytes :
options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
util.bytesToHex(derivedKeyBytes);
};
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/PBKDF2Async.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
if (!C.nextTick) {
// node.js has setTime out but prefer process.nextTick
if (typeof process != 'undefined' && typeof process.nextTick !== 'undefined') {
C.nextTick = process.nextTick;
} else if (typeof setTimeout !== 'undefined') {
C.nextTick = function (callback) {
setTimeout(callback, 0);
};
}
}
C.PBKDF2Async = function (password, salt, keylen, callback, options) {
// Convert to byte arrays
if (password.constructor == String) password = UTF8.stringToBytes(password);
if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
/* else, assume byte arrays already */
// Defaults
var hasher = options && options.hasher || C.SHA1,
iterations = options && options.iterations || 1;
// Progress callback option
var progressChangeHandler = options && options.onProgressChange;
var totalIterations = Math.ceil(keylen / hasher._digestsize) * iterations;
function fireProgressChange(currentIteration) {
if (progressChangeHandler) {
var iterationsSoFar = derivedKeyBytes.length / hasher._digestsize * iterations + currentIteration;
setTimeout(function () {
progressChangeHandler(Math.round(iterationsSoFar / totalIterations * 100));
}, 0);
}
}
// Pseudo-random function
function PRF(password, salt) {
return C.HMAC(hasher, salt, password, { asBytes: true });
}
var nextTick = C.nextTick;
// Generate key
var derivedKeyBytes = [],
blockindex = 1;
var outer, inner;
nextTick(outer = function () {
if (derivedKeyBytes.length < keylen) {
var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
fireProgressChange(1);
var u = block, i = 1;
nextTick(inner = function () {
if (i < iterations) {
u = PRF(password, u);
for (var j = 0; j < block.length; j++) block[j] ^= u[j];
i++;
fireProgressChange(i);
nextTick(inner);
} else {
derivedKeyBytes = derivedKeyBytes.concat(block);
blockindex++;
nextTick(outer);
}
});
} else {
// Truncate excess bytes
derivedKeyBytes.length = keylen;
callback(
options && options.asBytes ? derivedKeyBytes :
options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
util.bytesToHex(derivedKeyBytes));
}
});
};
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/Rabbit.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
// Inner state
var x = [],
c = [],
b;
var Rabbit = C.Rabbit = {
/**
* Public API
*/
encrypt: function (message, password) {
var
// Convert to bytes
m = UTF8.stringToBytes(message),
// Generate random IV
iv = util.randomBytes(8),
// Generate key
k = password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password;
// Encrypt
Rabbit._rabbit(m, k, util.bytesToWords(iv));
// Return ciphertext
return util.bytesToBase64(iv.concat(m));
},
decrypt: function (ciphertext, password) {
var
// Convert to bytes
c = util.base64ToBytes(ciphertext),
// Separate IV and message
iv = c.splice(0, 8),
// Generate key
k = password.constructor == String ?
// Derive key from passphrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password;
// Decrypt
Rabbit._rabbit(c, k, util.bytesToWords(iv));
// Return plaintext
return UTF8.bytesToString(c);
},
/**
* Internal methods
*/
// Encryption/decryption scheme
_rabbit: function (m, k, iv) {
Rabbit._keysetup(k);
if (iv) Rabbit._ivsetup(iv);
for (var s = [], i = 0; i < m.length; i++) {
if (i % 16 == 0) {
// Iterate the system
Rabbit._nextstate();
// Generate 16 bytes of pseudo-random data
s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16);
s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16);
s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16);
s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16);
// Swap endian
for (var j = 0; j < 4; j++) {
s[j] = ((s[j] << 8) | (s[j] >>> 24)) & 0x00FF00FF |
((s[j] << 24) | (s[j] >>> 8)) & 0xFF00FF00;
}
// Convert words to bytes
for (var b = 120; b >= 0; b -= 8)
s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF;
}
m[i] ^= s[i % 16];
}
},
// Key setup scheme
_keysetup: function (k) {
// Generate initial state values
x[0] = k[0];
x[2] = k[1];
x[4] = k[2];
x[6] = k[3];
x[1] = (k[3] << 16) | (k[2] >>> 16);
x[3] = (k[0] << 16) | (k[3] >>> 16);
x[5] = (k[1] << 16) | (k[0] >>> 16);
x[7] = (k[2] << 16) | (k[1] >>> 16);
// Generate initial counter values
c[0] = util.rotl(k[2], 16);
c[2] = util.rotl(k[3], 16);
c[4] = util.rotl(k[0], 16);
c[6] = util.rotl(k[1], 16);
c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF);
c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF);
c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF);
c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF);
// Clear carry bit
b = 0;
// Iterate the system four times
for (var i = 0; i < 4; i++) Rabbit._nextstate();
// Modify the counters
for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7];
},
// IV setup scheme
_ivsetup: function (iv) {
// Generate four subvectors
var i0 = util.endian(iv[0]),
i2 = util.endian(iv[1]),
i1 = (i0 >>> 16) | (i2 & 0xFFFF0000),
i3 = (i2 << 16) | (i0 & 0x0000FFFF);
// Modify counter values
c[0] ^= i0;
c[1] ^= i1;
c[2] ^= i2;
c[3] ^= i3;
c[4] ^= i0;
c[5] ^= i1;
c[6] ^= i2;
c[7] ^= i3;
// Iterate the system four times
for (var i = 0; i < 4; i++) Rabbit._nextstate();
},
// Next-state function
_nextstate: function () {
// Save old counter values
for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i];
// Calculate new counter values
c[0] = (c[0] + 0x4D34D34D + b) >>> 0;
c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0;
c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0;
c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0;
c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0;
c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0;
c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0;
c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0;
b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0;
// Calculate the g-values
for (var g = [], i = 0; i < 8; i++) {
var gx = (x[i] + c[i]) >>> 0;
// Construct high and low argument for squaring
var ga = gx & 0xFFFF,
gb = gx >>> 16;
// Calculate high and low result of squaring
var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb,
gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0;
// High XOR low
g[i] = gh ^ gl;
}
// Calculate new state values
x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16));
x[1] = g[1] + ((g[0] << 8) | (g[0] >>> 24)) + g[7];
x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16));
x[3] = g[3] + ((g[2] << 8) | (g[2] >>> 24)) + g[1];
x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16));
x[5] = g[5] + ((g[4] << 8) | (g[4] >>> 24)) + g[3];
x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16));
x[7] = g[7] + ((g[6] << 8) | (g[6] >>> 24)) + g[5];
}
};
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/SHA1.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
// Public API
var SHA1 = C.SHA1 = function (message, options) {
var digestbytes = util.wordsToBytes(SHA1._sha1(message));
return options && options.asBytes ? digestbytes :
options && options.asString ? Binary.bytesToString(digestbytes) :
util.bytesToHex(digestbytes);
};
// The core
SHA1._sha1 = function (message) {
// Convert to byte array
if (message.constructor == String) message = UTF8.stringToBytes(message);
/* else, assume byte array already */
var m = util.bytesToWords(message),
l = message.length * 8,
w = [],
H0 = 1732584193,
H1 = -271733879,
H2 = -1732584194,
H3 = 271733878,
H4 = -1009589776;
// Padding
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >>> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
var a = H0,
b = H1,
c = H2,
d = H3,
e = H4;
for (var j = 0; j < 80; j++) {
if (j < 16) w[j] = m[i + j];
else {
var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];
w[j] = (n << 1) | (n >>> 31);
}
var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
(H1 ^ H2 ^ H3) - 899497514);
H4 = H3;
H3 = H2;
H2 = (H1 << 30) | (H1 >>> 2);
H1 = H0;
H0 = t;
}
H0 += a;
H1 += b;
H2 += c;
H3 += d;
H4 += e;
}
return [H0, H1, H2, H3, H4];
};
// Package private blocksize
SHA1._blocksize = 16;
SHA1._digestsize = 20;
})();
================================================
FILE: cloudfunctions/regist/cryptojs/lib/SHA256.js
================================================
(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util,
charenc = C.charenc,
UTF8 = charenc.UTF8,
Binary = charenc.Binary;
// Constants
var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ];
// Public API
var SHA256 = C.SHA256 = function (message, options) {
var digestbytes = util.wordsToBytes(SHA256._sha256(message));
return options && options.asBytes ? digestbytes :
options && options.asString ? Binary.bytesToString(digestbytes) :
util.bytesToHex(digestbytes);
};
// The core
SHA256._sha256 = function (message) {
// Convert to byte array
if (message.constructor == String) message = UTF8.stringToBytes(message);
/* else, assume byte array already */
var m = util.bytesToWords(message),
l = message.length * 8,
H = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ],
w = [],
a, b, c, d, e, f, g, h, i, j,
t1, t2;
// Padding
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
a = H[0];
b = H[1];
c = H[2];
d = H[3];
e = H[4];
f = H[5];
g = H[6];
h = H[7];
for (var j = 0; j < 64; j++) {
if (j < 16) w[j] = m[j + i];
else {
var gamma0x = w[j - 15],
gamma1x = w[j - 2],
gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
((gamma0x << 14) | (gamma0x >>> 18)) ^
(gamma0x >>> 3),
gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
((gamma1x << 13) | (gamma1x >>> 19)) ^
(gamma1x >>> 10);
w[j] = gamma0 + (w[j - 7] >>> 0) +
gamma1 + (w[j - 16] >>> 0);
}
var ch = e & f ^ ~e & g,
maj = a & b ^ a & c ^ b & c,
sigma0 = ((a << 30) | (a >>> 2)) ^
((a << 19) | (a >>> 13)) ^
((a << 10) | (a >>> 22)),
sigma1 = ((e << 26) | (e >>> 6)) ^
((e << 21) | (e >>> 11)) ^
((e << 7) | (e >>> 25));
t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0);
t2 = sigma0 + maj;
h = g;
g = f;
f = e;
e = (d + t1) >>> 0;
d = c;
c = b;
b = a;
a = (t1 + t2) >>> 0;
}
H[0] += a;
H[1] += b;
H[2] += c;
H[3] += d;
H[4] += e;
H[5] += f;
H[6] += g;
H[7] += h;
}
return H;
};
// Package private blocksize
SHA256._blocksize = 16;
SHA256._digestsize = 32;
})();
================================================
FILE: cloudfunctions/regist/cryptojs/package.json
================================================
{
"author": "Jeff Guo ",
"name": "cryptojs",
"tags": ["Hash", "MD5", "SHA1", "SHA-1", "SHA256", "SHA-256", "RC4", "Rabbit", "AES", "DES", "PBKDF2", "HMAC", "OFB", "CFB", "CTR", "CBC", "Base64"],
"description": "Following googlecode project crypto-js, provide standard and secure cryptographic algorithms for NodeJS. Support MD5, SHA-1, SHA-256, RC4, Rabbit, AES, DES, PBKDF2, HMAC, OFB, CFB, CTR, CBC, Base64",
"version": "2.5.3",
"homepage": "https://github.com/gwjjeff/cryptojs",
"repository": {
"type": "git",
"url": "git://github.com/gwjjeff/cryptojs.git"
},
"main": "cryptojs.js",
"engines": {
"node": "*"
},
"dependencies": {},
"devDependencies": {}
}
================================================
FILE: cloudfunctions/regist/cryptojs/test/PBKDF2-test.js
================================================
var assert = require('assert');
var Crypto = require('../cryptojs').Crypto;
(function test_PBKDF2() {
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 128 / 8), "cdedb5281bb2f801565a1122b2563515");
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 256 / 8), "cdedb5281bb2f801565a1122b25635150ad1f7a04bb9f3a333ecc0e2e1f70837");
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 128 / 8, { iterations : 2 }), "01dbee7f4a9e243e988b62c73cda935d");
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 256 / 8, { iterations : 2 }), "01dbee7f4a9e243e988b62c73cda935da05378b93244ec8f48a99e61ad799d86");
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 128 / 8, { iterations : 1200}), "5c08eb61fdf71e4e4ec3cf6ba1f5512b");
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 256 / 8, { iterations : 1200}), "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13");
assert.strictEqual(Crypto.PBKDF2("password", "\x12\x34\x56\x78\x78\x56\x34\x12", 128 / 8, { iterations : 5 }), "d1daa78615f287e6a1c8b120d7062a49");
assert.strictEqual(Crypto.PBKDF2("password", "\x12\x34\x56\x78\x78\x56\x34\x12", 256 / 8, { iterations : 5 }), "d1daa78615f287e6a1c8b120d7062a493f98d203e6be49a6adf4fa574b6e64ee");
assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase equals block size", 128 / 8, { iterations : 1200 }), "139c30c0966bc32ba55fdbf212530ac9");
assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase equals block size", 256 / 8, { iterations : 1200 }), "139c30c0966bc32ba55fdbf212530ac9c5ec59f1a452f5cc9ad940fea0598ed1");
assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size", 128 / 8, { iterations : 1200 }), "9ccad6d468770cd51b10e6a68721be61");
assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size", 256 / 8, { iterations : 1200 }), "9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a");
assert.strictEqual(Crypto.PBKDF2([0xf0, 0x9d, 0x84, 0x9e], "EXAMPLE.COMpianist", 128 / 8, { iterations : 50 }), "6b9cf26d45455a43a5b8bb276a403b39");
assert.strictEqual(Crypto.PBKDF2([0xf0, 0x9d, 0x84, 0x9e], "EXAMPLE.COMpianist", 256 / 8, { iterations : 50 }), "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0c41e02c281ff3069e1e94f52");
})();
(function test_PBKSD2Async() {
Crypto.PBKDF2Async("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size", 256 / 8, function(result) {
assert.strictEqual(result, "9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a");
}, { iterations : 1200 });
})();
================================================
FILE: cloudfunctions/regist/index.js
================================================
const appid = 'wxd6beb52c8602bff4'; //你的小程序appid
const secret = 'b00457b478f63f2388ef03476bb5a60c'; //你的小程序secret
/*
下
面
不
用
管
*/
const cloud = require('wx-server-sdk');
cloud.init()//这里后面加的初始化
const TcbRouter = require('tcb-router'); //云函数路由
const rq = require('request');
const wxurl = 'https://api.weixin.qq.com';
var WXBizDataCrypt = require('./RdWXBizDataCrypt') // 用于手机号解密
cloud.init()
// 云函数入口函数
exports.main = async(event, context) => {
const app = new TcbRouter({
event
});
//获取电话号码
app.router('phone', async(ctx) => {
ctx.body = new Promise(resolve => {
rq({
url: wxurl + '/sns/jscode2session?appid=' + appid + '&secret=' + secret + '&js_code=' + event.code + '&grant_type=authorization_code',
method: "GET",
json: true,
}, function(error, response, body) {
const decrypt1 = new WXBizDataCrypt(appid, body.session_key) // -解密第一步
const decrypt2 = decrypt1.decryptData(event.encryptedData, event.iv) // 解密第二步*/
resolve({
data: decrypt2
})
});
});
});
//获取openid
app.router('getid', async(ctx) => {
const wxContext = cloud.getWXContext()
ctx.body = wxContext.OPENID;
});
return app.serve();
}
================================================
FILE: cloudfunctions/regist/package.json
================================================
{
"name": "regist",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"request": "^2.88.0",
"tcb-router": "^1.1.2",
"wx-server-sdk": "^2.0.4"
}
}
================================================
FILE: cloudfunctions/removeChat/config.json
================================================
{
"permissions": {
"openapi": [
]
}
}
================================================
FILE: cloudfunctions/removeChat/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
try {
await db.collection('rooms').doc(event.id).update({
data: {
deleted: 1
}
})
.then(console.log)
.catch(console.error)
} catch(e) {
console.error(e)
}
}
================================================
FILE: cloudfunctions/removeChat/package.json
================================================
{
"name": "removeChat",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.2.0"
}
}
================================================
FILE: cloudfunctions/removeOrder/config.json
================================================
{
"permissions": {
"openapi": [
]
}
}
================================================
FILE: cloudfunctions/removeOrder/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const _ = db.command
// 云函数入口函数
exports.main = async (event, _context) => {
try {
return await db.collection('order').doc(event._id).remove()
} catch (e) {
console.error(e)
}
}
================================================
FILE: cloudfunctions/removeOrder/package.json
================================================
{
"name": "removeOrder",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.2.0"
}
}
================================================
FILE: cloudfunctions/sell/config.json
================================================
{
"permissions": {
"openapi": [
]
}
}
================================================
FILE: cloudfunctions/sell/index.js
================================================
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const _ = db.command
// 云函数入口函数
exports.main = async (event, _context) => {
try {
return await db.collection('order').doc(event._id).update({
// data 传入需要局部更新的数据
data: {
status:event.status
}
})
} catch (e) {
console.error(e)
}
}
================================================
FILE: cloudfunctions/sell/package.json
================================================
{
"name": "node",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.1.2"
}
}
================================================
FILE: cloudfunctions/sendMsg/config.json
================================================
{
"permissions": {
"openapi": [
]
}
}
================================================
FILE: cloudfunctions/sendMsg/index.js
================================================
//编程小石头微信:2501902696
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async(event, context) => {
try {
const result = await cloud.openapi.subscribeMessage.send({
touser: event.openid, //要推送给那个用户
page: 'pages/index/index', //要跳转到那个小程序页面
data: {//推送的内容
thing3: {
value: event.good
},
thing1: {
value: event.status,
color: event.color
},
thing2: {
value: event.address
},
name4: {
value: event.nickName
},
thing6: {
value: event.describe
}
},
templateId: '6DGzsKqipoPxClnbkvwnxY9GqdXoLordLRdWTjJN1F0' //模板id
})
console.log(result)
return result
} catch (err) {
console.log(err)
return err
}
}
================================================
FILE: cloudfunctions/sendMsg/package.json
================================================
{
"name": "sendMsg",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest"
}
}
================================================
FILE: cloudfunctions/sendTip/config.json
================================================
{
"permissions": {
"openapi": [
]
}
}
================================================
FILE: cloudfunctions/sendTip/index.js
================================================
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async(event, context) => {
try {
const result = await cloud.openapi.subscribeMessage.send({
touser: event.openid, //要推送给那个用户
page: 'pages/index/index', //要跳转到那个小程序页面
data: {//推送的内容
thing1: {
value: event.nickName
},
phrase2:{
value: '申请聊天'
},
thing3:{
value: event.tip
}
},
templateId: 'XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q' //模板id
})
console.log(result)
return result
} catch (err) {
console.log(err)
return err
}
}
================================================
FILE: cloudfunctions/sendTip/package.json
================================================
{
"name": "sendTip",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.2.0"
}
}
================================================
FILE: miniprogram/app.js
================================================
const config = require("config.js");
App({
openid: '',
userinfo:'',
roomlist:[],
canReflect:true,
onLaunch: function() {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
env: JSON.parse(config.data).env,
traceUser: true,
})
}
this.systeminfo=wx.getSystemInfoSync();
}
})
================================================
FILE: miniprogram/app.json
================================================
{
"cloud": true,
"pages": [
"pages/start/start",
"pages/index/index",
"pages/login/login",
"pages/publish/publish",
"pages/my/my",
"pages/detail/detail",
"pages/order/list/list",
"pages/order/detail/detail",
"pages/kefu/kefu",
"pages/about/about",
"pages/sell/list/list",
"pages/sell/detail/detail",
"pages/search/search",
"pages/edit/edit",
"pages/web/web",
"pages/message/message",
"pages/detail/room/room",
"pages/use/use",
"pages/help/help",
"pages/appreciateCode/appreciateCode"
],
"window": {
"backgroundColor": "#fbbd08",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fbbd08",
"navigationBarTitleText": "吉珠二手交易平台",
"navigationBarTextStyle": "white"
},
"sitemapLocation": "sitemap.json",
"tabBar": {
"color": "#707070",
"selectedColor": "#000000",
"list": [{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "/images/tabbar/home.png",
"selectedIconPath": "/images/tabbar/home_on.png"
},
{
"pagePath": "pages/publish/publish",
"text": "发布",
"iconPath": "/images/tabbar/publish.png",
"selectedIconPath": "/images/tabbar/publish_on.png"
},
{
"pagePath": "pages/my/my",
"text": "我的",
"iconPath": "/images/tabbar/my.png",
"selectedIconPath": "/images/tabbar/my_on.png"
}
]
},
"usingComponents": {
"van-steps": "/vant/steps/index",
"van-transition": "/vant/transition/index",
"van-stepper": "/vant/stepper/index",
"van-action-sheet": "/vant/action-sheet/index",
"van-popup": "/vant/popup/index",
"canvasdrawer": "/components/canvasdrawer/canvasdrawer",
"tips": "components/add_tips/index",
"welcome": "components/welcome/welcome",
"van-dialog": "/vant/dialog/index",
"van-button": "/vant/button/index",
"van-picker": "/vant/picker/index",
"van-icon": "/vant/icon/index",
"van-uploader": "/vant/uploader/index",
"van-checkbox": "/vant/checkbox/index",
"van-checkbox-group": "/vant/checkbox-group/index",
"van-divider": "/vant/divider/index",
"van-notice-bar": "vant/notice-bar/index"
}
}
================================================
FILE: miniprogram/app.wxss
================================================
page {
background: #fff;
width: 100%;
height: 100%;
}
.shadow {
box-shadow: 0 0 18rpx rgb(236, 236, 236);
}
.text-cut {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.loadmore {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 30rpx 0;
}
.loadmore image {
width: 50rpx;
height: 50rpx;
}
.loadmore view {
font-size: 28rpx;
color: #b2b2b2;
letter-spacing: 4rpx;
}
.totop {
position: fixed;
right: 30rpx;
bottom: 80rpx;
}
.totop image {
width: 100rpx;
height: 100rpx;
z-index: 9;
}
================================================
FILE: miniprogram/common.wxml
================================================
已加载到底
================================================
FILE: miniprogram/common.wxs
================================================
function commentTimeHandle(dateStr) {
var publishTime = dateStr,
date = getDate(publishTime), //获取dateStr的标准格式 console.log(date) 打印结果 Thu Sep 06 2018 18:47:00 GMT+0800 (中国标准时间)
// 获取date 中的 年 月 日 时 分 秒
Y = date.getFullYear(),
M = date.getMonth() + 1,
D = date.getDate(),
H = date.getHours(),
m = date.getMinutes(),
s = date.getSeconds();
// 对 月 日 时 分 秒 小于10时, 加0显示 例如: 09-09 09:01
if (M < 10) {
M = '0' + M;
}
if (D < 10) {
D = '0' + D;
}
if (H < 10) {
H = '0' + H;
}
if (m < 10) {
m = '0' + m;
}
if (s < 10) {
s = '0' + s;
}
var nowTime = getDate().getTime(), //获取此时此刻日期的秒数
diffValue = (nowTime - publishTime) / 1000, // 获取此时 秒数 与 要处理的日期秒数 之间的差值
diff_days = parseInt(diffValue / 86400), // 一天86400秒 获取相差的天数 取整
diff_hours = parseInt(diffValue / 3600), // 一时3600秒
diff_minutes = parseInt(diffValue / 60),
diff_secodes = parseInt(diffValue);
if (diff_days > 0 && diff_days < 3) { //相差天数 0 < diff_days < 3 时, 直接返出
return diff_days + "天前";
} else if (diff_days <= 0 && diff_hours > 0) {
return diff_hours + "小时前";
} else if (diff_hours <= 0 && diff_minutes > 0) {
return diff_minutes + "分钟前";
} else if (diff_secodes < 60) {
if (diff_secodes <= 0) {
return "刚刚";
} else {
return diff_secodes + "秒前";
}
} else if (diff_days >= 3 && diff_days < 30) {
return M + '月' + D + '日';
} else if (diff_days >= 30) {
return M + '月' + D + '日';
}
}
function format(dateStr) {
var publishTime = dateStr,
date = getDate(publishTime), //获取dateStr的标准格式 console.log(date) 打印结果 Thu Sep 06 2018 18:47:00 GMT+0800 (中国标准时间)
// 获取date 中的 年 月 日 时 分 秒
Y = date.getFullYear(),
M = date.getMonth() + 1,
D = date.getDate(),
H = date.getHours(),
m = date.getMinutes(),
s = date.getSeconds();
// 对 月 日 时 分 秒 小于10时, 加0显示 例如: 09-09 09:01
if (M < 10) {
M = '0' + M;
}
if (D < 10) {
D = '0' + D;
}
if (H < 10) {
H = '0' + H;
}
if (m < 10) {
m = '0' + m;
}
if (s < 10) {
s = '0' + s;
}
return Y+'-'+M+'-'+D+' '+H+':'+m
}
module.exports = {
timelog: commentTimeHandle,
format:format
}
================================================
FILE: miniprogram/components/add_tips/README.md
================================================
# add-tips
> **微信小程序UI插件**
> 用于提示用户首次进入小程序时,点击右上角菜单进行【添加到我的小程序】操作
## 文档
首先,把这个仓库下载/克隆到你的小程序目录,比如`/components/weplug-add-tips/`
然后,在首页`index.json`配置文件中,引入该组件:
``` json
{
"usingComponents": {
"add-tips": "/components/weplug-add-tips/index"
}
}
```
最后,在首页`index.wxml`文件中,调用该组件即可:
``` wxml
```
## 参数
你可以传递两个参数进行自定义操作:
### 1. text:提示的文字内容
``` wxml
```
### 2. duration:提示关闭时间(单位秒)
``` wxml
```
================================================
FILE: miniprogram/components/add_tips/index.js
================================================
const STORAGE_KEY = 'PLUG-ADD-MYAPP-KEY';
Component({
/**
* 组件的属性列表
*/
properties: {
// 提示文字
text: {
type: String,
value: '点击「添加小程序」,下次访问更便捷 >'
},
// 多少秒后关闭
duration: {
type: Number,
value: 5
}
},
/**
* 组件的初始数据
*/
data: {
SHOW_TOP: false,
SHOW_MODAL: false
},
ready: function () {
// 判断是否已经显示过
let cache = wx.getStorageSync(STORAGE_KEY);
if (cache) return;
// 没显示过,则进行展示
this.setData({
SHOW_TOP: true
});
// 关闭时间
setTimeout(() => {
this.setData({
SHOW_TOP: false
})
}, this.data.duration * 1000);
},
/**
* 组件的方法列表
*/
methods: {
// 显示全屏添加说明
showModal: function () {
this.setData({
SHOW_TOP: false,
SHOW_MODAL: true
});
},
okHandler: function () {
this.setData({
SHOW_MODAL: false
});
wx.setStorage({
key: STORAGE_KEY,
data: +new Date,
});
}
}
})
================================================
FILE: miniprogram/components/add_tips/index.json
================================================
{
"component": true,
"usingComponents": {}
}
================================================
FILE: miniprogram/components/add_tips/index.wxml
================================================
{{text}}
1. 点击
2. 点击「添加到我的小程序」
3. 微信首页下拉,快速进入小程序
我知道了!
================================================
FILE: miniprogram/components/add_tips/index.wxss
================================================
.box {
position: fixed;
top: 0;
/* left: 0; */
right: 0;
z-index: 999;
display: flex;
justify-content: flex-end;
align-items: flex-end;
flex-direction: column;
width: 600rpx;
}
.arrow {
width: 0;
height: 0;
margin-right: 120rpx;
border-width: 20rpx;
border-style: solid;
border-color: transparent transparent #fbbd08;
}
.body {
background-color: #fbbd08;
box-shadow: 0 10rpx 20rpx -10rpx #fbbd08;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
height: 84rpx;
padding: 0 20rpx;
margin-right: 40rpx;
}
.body > text {
color: #FFF;
font-size: 28rpx;
font-weight: 400;
}
.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
background-color: rgba(255, 255, 255, 0.9);
padding: 20px;
}
.modal > view {
margin: 10px 0;
display: flex;
/* align-items: center; */
flex-direction: column;
}
.modal > view > text {
font-size: 16px;
font-weight: 400;
margin-bottom: 5px;
color: #333;
}
.modal > view > image {
border-radius: 10px;
}
.ok-btn {
width: 100%;
margin-top: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.ok-btn > view {
height: 40px;
width: 120px;
background-color: #fbbd08;
box-shadow: 0 5px 10px -px #fbbd08;
display: flex;
align-items: center;
justify-content: center;
border-radius: 40px;
}
.ok-btn > view > text {
font-size: 14px;
color: #fff;
font-weight: 400;
}
.btn-hover {
opacity: 0.6;
}
================================================
FILE: miniprogram/components/canvasdrawer/canvasdrawer.js
================================================
/* global Component wx */
Component({
properties: {
painting: {
type: Object,
value: {view: []},
observer (newVal, oldVal) {
if (!this.data.isPainting) {
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
if (newVal && newVal.width && newVal.height) {
this.setData({
showCanvas: true,
isPainting: true
})
this.readyPigment()
}
} else {
if (newVal && newVal.mode !== 'same') {
this.triggerEvent('getImage', {errMsg: 'canvasdrawer:samme params'})
}
}
}
}
}
},
data: {
showCanvas: false,
width: 100,
height: 100,
tempFileList: [],
isPainting: false
},
ctx: null,
cache: {},
ready () {
wx.removeStorageSync('canvasdrawer_pic_cache')
this.cache = wx.getStorageSync('canvasdrawer_pic_cache') || {}
this.ctx = wx.createCanvasContext('canvasdrawer', this)
},
methods: {
readyPigment () {
const { width, height, views } = this.data.painting
this.setData({
width,
height
})
const inter = setInterval(() => {
if (this.ctx) {
clearInterval(inter)
this.ctx.clearActions()
this.ctx.save()
this.getImagesInfo(views)
}
}, 100)
},
getImagesInfo (views) {
const imageList = []
for (let i = 0; i < views.length; i++) {
if (views[i].type === 'image') {
imageList.push(this.getImageInfo(views[i].url))
}
}
const loadTask = []
for (let i = 0; i < Math.ceil(imageList.length / 8); i++) {
loadTask.push(new Promise((resolve, reject) => {
Promise.all(imageList.splice(i * 8, 8)).then(res => {
resolve(res)
}).catch(res => {
reject(res)
})
}))
}
Promise.all(loadTask).then(res => {
let tempFileList = []
for (let i = 0; i < res.length; i++) {
tempFileList = tempFileList.concat(res[i])
}
this.setData({
tempFileList
})
this.startPainting()
})
},
startPainting () {
const { tempFileList, painting: { views } } = this.data
console.log(tempFileList)
for (let i = 0, imageIndex = 0; i < views.length; i++) {
if (views[i].type === 'image') {
this.drawImage({
...views[i],
url: tempFileList[imageIndex]
})
imageIndex++
} else if (views[i].type === 'text') {
if (!this.ctx.measureText) {
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用 measureText 功能,请升级到最新微信版本后重试。'
})
this.triggerEvent('getImage', {errMsg: 'canvasdrawer:version too low'})
return
} else {
this.drawText(views[i])
}
} else if (views[i].type === 'rect') {
this.drawRect(views[i])
}
}
this.ctx.draw(false, () => {
wx.setStorageSync('canvasdrawer_pic_cache', this.cache)
const system = wx.getSystemInfoSync().system
if (/ios/i.test(system)) {
this.saveImageToLocal()
} else {
// 延迟保存图片,解决安卓生成图片错位bug。
setTimeout(() => {
this.saveImageToLocal()
}, 800)
}
})
},
drawImage (params) {
this.ctx.save()
const { url, top = 0, left = 0, width = 0, height = 0, borderRadius = 0, deg = 0 } = params
// if (borderRadius) {
// this.ctx.beginPath()
// this.ctx.arc(left + borderRadius, top + borderRadius, borderRadius, 0, 2 * Math.PI)
// this.ctx.clip()
// this.ctx.drawImage(url, left, top, width, height)
// } else {
if (deg !== 0) {
this.ctx.translate(left + width/2, top + height/2)
this.ctx.rotate(deg * Math.PI / 180)
this.ctx.drawImage(url, -width/2, -height/2, width, height)
} else {
this.ctx.drawImage(url, left, top, width, height)
}
// }
this.ctx.restore()
},
drawText (params) {
this.ctx.save()
const {
MaxLineNumber = 2,
breakWord = false,
color = 'black',
content = '',
fontSize = 16,
top = 0,
left = 0,
lineHeight = 20,
textAlign = 'left',
width,
bolder = false,
textDecoration = 'none'
} = params
this.ctx.beginPath()
this.ctx.setTextBaseline('top')
this.ctx.setTextAlign(textAlign)
this.ctx.setFillStyle(color)
this.ctx.setFontSize(fontSize)
if (!breakWord) {
this.ctx.fillText(content, left, top)
this.drawTextLine(left, top, textDecoration, color, fontSize, content)
} else {
let fillText = ''
let fillTop = top
let lineNum = 1
for (let i = 0; i < content.length; i++) {
fillText += [content[i]]
if (this.ctx.measureText(fillText).width > width) {
if (lineNum === MaxLineNumber) {
if (i !== content.length) {
fillText = fillText.substring(0, fillText.length - 1) + '...'
this.ctx.fillText(fillText, left, fillTop)
this.drawTextLine(left, fillTop, textDecoration, color, fontSize, fillText)
fillText = ''
break
}
}
this.ctx.fillText(fillText, left, fillTop)
this.drawTextLine(left, fillTop, textDecoration, color, fontSize, fillText)
fillText = ''
fillTop += lineHeight
lineNum ++
}
}
this.ctx.fillText(fillText, left, fillTop)
this.drawTextLine(left, fillTop, textDecoration, color, fontSize, fillText)
}
this.ctx.restore()
if (bolder) {
this.drawText({
...params,
left: left + 0.3,
top: top + 0.3,
bolder: false,
textDecoration: 'none'
})
}
},
drawTextLine (left, top, textDecoration, color, fontSize, content) {
if (textDecoration === 'underline') {
this.drawRect({
background: color,
top: top + fontSize * 1.2,
left: left - 1,
width: this.ctx.measureText(content).width + 3,
height: 1
})
} else if (textDecoration === 'line-through') {
this.drawRect({
background: color,
top: top + fontSize * 0.6,
left: left - 1,
width: this.ctx.measureText(content).width + 3,
height: 1
})
}
},
drawRect (params) {
this.ctx.save()
const { background, top = 0, left = 0, width = 0, height = 0 } = params
this.ctx.setFillStyle(background)
this.ctx.fillRect(left, top, width, height)
this.ctx.restore()
},
getImageInfo (url) {
return new Promise((resolve, reject) => {
if (this.cache[url]) {
resolve(this.cache[url])
} else {
const objExp = new RegExp(/^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/)
if (objExp.test(url)) {
wx.getImageInfo({
src: url,
complete: res => {
if (res.errMsg === 'getImageInfo:ok') {
this.cache[url] = res.path
resolve(res.path)
} else {
this.triggerEvent('getImage', {errMsg: 'canvasdrawer:download fail'})
reject(new Error('getImageInfo fail'))
}
}
})
} else {
this.cache[url] = url
resolve(url)
}
}
})
},
saveImageToLocal () {
const { width, height } = this.data
wx.canvasToTempFilePath({
x: 0,
y: 0,
width,
height,
canvasId: 'canvasdrawer',
complete: res => {
if (res.errMsg === 'canvasToTempFilePath:ok') {
this.setData({
showCanvas: false,
isPainting: false,
tempFileList: []
})
this.triggerEvent('getImage', {tempFilePath: res.tempFilePath, errMsg: 'canvasdrawer:ok'})
} else {
this.triggerEvent('getImage', {errMsg: 'canvasdrawer:fail'})
}
}
}, this)
}
}
})
================================================
FILE: miniprogram/components/canvasdrawer/canvasdrawer.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/components/canvasdrawer/canvasdrawer.wxml
================================================
================================================
FILE: miniprogram/components/canvasdrawer/canvasdrawer.wxss
================================================
.board {
position: fixed;
top: 2000rpx;
}
================================================
FILE: miniprogram/components/chatroom/chatroom.js
================================================
var time = require('../../utils/util.js');
const FATAL_REBUILD_TOLERANCE = 10
const SETDATA_SCROLL_TO_BOTTOM = {
scrollTop: 100000,
scrollWithAnimation: true,
}
Component({
properties: {
envId: String,
collection: String,
groupId: String,
groupName: String,
userInfo: Object,
onGetUserInfo: {
type: Function,
},
getOpenID: {
type: Function,
},
},
data: {
chats: [],
textInputValue: '',
openId: '',
scrollTop: 0,
scrollToMessage: '',
hasKeyboard: false,
},
methods: {
onGetUserInfo(e) {
this.properties.onGetUserInfo(e)
},
getOpenID() {
return this.properties.getOpenID()
},
mergeCommonCriteria(criteria) {
return {
groupId: this.data.groupId,
...criteria,
}
},
async initRoom() {
this.try(async () => {
await this.initOpenID()
const {
envId,
collection
} = this.properties
const db = this.db = wx.cloud.database({
env: envId,
})
const _ = db.command
const {
data: initList
} = await db.collection(collection).where(this.mergeCommonCriteria()).orderBy('sendTimeTS', 'desc').get()
console.log('init query chats', initList)
this.setData({
chats: initList.reverse(),
scrollTop: 10000,
})
this.initWatch(initList.length ? {
sendTimeTS: _.gt(initList[initList.length - 1].sendTimeTS),
} : {})
}, '初始化失败')
},
async initOpenID() {
return this.try(async () => {
const openId = await this.getOpenID()
this.setData({
openId,
})
}, '初始化 openId 失败')
},
async initWatch(criteria) {
this.try(() => {
const {
collection
} = this.properties
const db = this.db
const _ = db.command
console.warn(`开始监听`, criteria)
this.messageListener = db.collection(collection).where(this.mergeCommonCriteria(criteria)).watch({
onChange: this.onRealtimeMessageSnapshot.bind(this),
onError: e => {
if (!this.inited || this.fatalRebuildCount >= FATAL_REBUILD_TOLERANCE) {
this.showError(this.inited ? '监听错误,已断开' : '初始化监听失败', e, '重连', () => {
this.initWatch(this.data.chats.length ? {
sendTimeTS: _.gt(this.data.chats[this.data.chats.length - 1].sendTimeTS),
} : {})
})
} else {
this.initWatch(this.data.chats.length ? {
sendTimeTS: _.gt(this.data.chats[this.data.chats.length - 1].sendTimeTS),
} : {})
}
},
})
}, '初始化监听失败')
},
onRealtimeMessageSnapshot(snapshot) {
console.warn(`收到消息`, snapshot)
if (snapshot.type === 'init') {
this.setData({
chats: [
...this.data.chats,
...[...snapshot.docs].sort((x, y) => x.sendTimeTS - y.sendTimeTS),
],
})
this.scrollToBottom()
this.inited = true
} else {
let hasNewMessage = false
let hasOthersMessage = false
const chats = [...this.data.chats]
for (const docChange of snapshot.docChanges) {
switch (docChange.queueType) {
case 'enqueue': {
hasOthersMessage = docChange.doc._openid !== this.data.openId
const ind = chats.findIndex(chat => chat._id === docChange.doc._id)
if (ind > -1) {
if (chats[ind].msgType === 'image' && chats[ind].tempFilePath) {
chats.splice(ind, 1, {
...docChange.doc,
tempFilePath: chats[ind].tempFilePath,
})
} else chats.splice(ind, 1, docChange.doc)
} else {
hasNewMessage = true
chats.push(docChange.doc)
}
break
}
}
}
this.setData({
chats: chats.sort((x, y) => x.sendTimeTS - y.sendTimeTS),
})
if (hasOthersMessage || hasNewMessage) {
this.scrollToBottom()
}
}
},
async onConfirmSendText(e) {
this.try(async () => {
if (!e.detail.value) {
return
}
const {
collection
} = this.properties
const db = this.db
const _ = db.command
const doc = {
_id: `${Math.random()}_${Date.now()}`,
groupId: this.data.groupId,
avatar: this.data.userInfo.avatarUrl,
nickName: this.data.userInfo.nickName,
msgType: 'text',
textContent: e.detail.value,
sendTime: new Date(),
sendTimeTS: time.formatTime(new Date(),'Y/M/D h:m:s'), // fallback
}
this.setData({
textInputValue: '',
chats: [
...this.data.chats,
{
...doc,
_openid: this.data.openId,
writeStatus: 'pending',
},
],
})
this.scrollToBottom(true)
await db.collection(collection).add({
data: doc,
})
this.setData({
chats: this.data.chats.map(chat => {
if (chat._id === doc._id) {
return {
...chat,
writeStatus: 'written',
}
} else return chat
}),
})
}, '发送文字失败')
},
async onChooseImage(e) {
wx.chooseImage({
count: 1,
sourceType: ['album', 'camera'],
success: async res => {
const {
envId,
collection
} = this.properties
const doc = {
_id: `${Math.random()}_${Date.now()}`,
groupId: this.data.groupId,
avatar: this.data.userInfo.avatarUrl,
nickName: this.data.userInfo.nickName,
msgType: 'image',
sendTime: new Date(),
sendTimeTS: time.formatTime(new Date(),'Y/M/D h:m:s'), // fallback
}
this.setData({
chats: [
...this.data.chats,
{
...doc,
_openid: this.data.openId,
tempFilePath: res.tempFilePaths[0],
writeStatus: 0,
},
]
})
this.scrollToBottom(true)
const uploadTask = wx.cloud.uploadFile({
cloudPath: `${this.data.openId}/${Math.random()}_${Date.now()}.${res.tempFilePaths[0].match(/\.(\w+)$/)[1]}`,
filePath: res.tempFilePaths[0],
config: {
env: envId,
},
success: res => {
this.try(async () => {
await this.db.collection(collection).add({
data: {
...doc,
imgFileID: res.fileID,
},
})
}, '发送图片失败')
},
fail: e => {
this.showError('发送图片失败', e)
},
})
uploadTask.onProgressUpdate(({
progress
}) => {
this.setData({
chats: this.data.chats.map(chat => {
if (chat._id === doc._id) {
return {
...chat,
writeStatus: progress,
}
} else return chat
})
})
})
},
})
},
onMessageImageTap(e) {
wx.previewImage({
urls: [e.target.dataset.fileid],
})
},
scrollToBottom(force) {
if (force) {
console.log('force scroll to bottom')
this.setData(SETDATA_SCROLL_TO_BOTTOM)
return
}
this.createSelectorQuery().select('.body').boundingClientRect(bodyRect => {
this.createSelectorQuery().select(`.body`).scrollOffset(scroll => {
if (scroll.scrollTop + bodyRect.height * 3 > scroll.scrollHeight) {
console.log('should scroll to bottom')
this.setData(SETDATA_SCROLL_TO_BOTTOM)
}
}).exec()
}).exec()
},
async onScrollToUpper() {
if (this.db && this.data.chats.length) {
const {
collection
} = this.properties
const _ = this.db.command
const {
data
} = await this.db.collection(collection).where(this.mergeCommonCriteria({
sendTimeTS: _.lt(this.data.chats[0].sendTimeTS),
})).orderBy('sendTimeTS', 'desc').get()
this.data.chats.unshift(...data.reverse())
this.setData({
chats: this.data.chats,
scrollToMessage: `item-${data.length}`,
scrollWithAnimation: false,
})
}
},
async try (fn, title) {
try {
await fn()
} catch (e) {
this.showError(title, e)
}
},
showError(title, content, confirmText, confirmCallback) {
console.error(title, content)
wx.showModal({
title,
content: content.toString(),
showCancel: confirmText ? true : false,
confirmText,
success: res => {
res.confirm && confirmCallback()
},
})
},
},
ready() {
global.chatroom = this
this.initRoom()
this.fatalRebuildCount = 0
},
})
================================================
FILE: miniprogram/components/chatroom/chatroom.json
================================================
{
"component": true,
"usingComponents": {
}
}
================================================
FILE: miniprogram/components/chatroom/chatroom.wxml
================================================
{{item.nickName}}
{{item.writeStatus}}%
{{item.sendTimeTS}}
···
{{item.textContent}}
{{item.sendTimeTS}}
================================================
FILE: miniprogram/components/chatroom/chatroom.wxss
================================================
.chatroom {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
/* .chatroom .header {
flex-basis: fit-content;
display: flex;
flex-direction: row;
border-bottom: 1px solid #ddd;
margin-top: -25px;
padding: 20rpx 0 30rpx;
font-size:25 rpx;
} */
.chatroom .header .left {
flex: 1;
}
.chatroom .header .middle {
flex: 2;
text-align: center;
}
.chatroom .header .right {
flex: 1;
}
.chatroom .body {
flex: 1;
display: flex;
flex-direction: column;
background: rgb(237,237,237);
padding-bottom: 16rpx;
}
.body .message {
display: flex;
flex-direction: row;
position: relative;
margin: 12rpx 0;
}
.body .message.message__self {
flex-direction: row-reverse;
}
.body .message .avatar {
position: relative;
top: 5rpx;
width: 60rpx;
height: 60rpx;
border-radius: 5rpx;
margin: 15rpx;
}
.body .message .main {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.body .message.message__self .main {
align-items: flex-end;
}
.body .message .nickname {
font-size: 24rpx;
color: #444;
}
.body .message .time {
font-size: 24rpx;
color: #444;
}
.body .message .text-content {
border: 1px solid transparent;
border-radius: 3px;
background-color: #fff;
margin: 2px 0 0 0;
padding: 4px 10px;
font-size: 30rpx;
display: inline-block;
}
.body .message.message__self .text-content {
background-color: paleturquoise;
}
.body .message .text-wrapper {
display: flex;
flex-direction: row;
align-items: center;
max-width: 80%;
}
.body .message.message__self .text-wrapper .loading{
font-size: 16rpx;
margin-right: 18rpx;
}
.body .message .image-wrapper {
display: flex;
flex-direction: row;
align-items: center;
}
.body .message .image-content {
max-width: 240rpx;
max-height: 240rpx;
}
.body .message.message__self .image-wrapper .loading {
font-size: 20rpx;
margin-right: 18rpx;
}
.chatroom .footer {
flex-basis: fit-content;
display: flex;
flex-direction: row;
border-top: 1px solid #ddd;
font-size: 10rpx;
padding: 20rpx 30rpx;
background: rgb(246,246,246);
}
.chatroom .footer .message-sender {
flex: 1;
display: flex;
flex-direction: row;
}
.message-sender .text-input {
flex: 1;
font-size: 16px;
border: 1px solid transparent;
border-radius: 5px;
padding: 3px 6px;
margin: 0 10px 0 5px;
background: #fff;
}
.message-sender .btn-send-image {
width: 50rpx;
height: 50rpx;
align-self: center;
}
button {
font-size: 30rpx;
}
button.userinfo {
background: darkturquoise;
color: aliceblue;
padding: 0 100rpx;
border: 1px solid #ddd;
border-radius: 20px;
}
================================================
FILE: miniprogram/components/welcome/welcome.js
================================================
const STORAGE1_KEY = 'PLUG-WELCOME-MYAPP-KEY';
Component({
/**
* 组件的属性列表
*/
// properties: {
// // 提示文字
// text: {
// type: String,
// value: '点击「添加小程序」,下次访问更便捷 >'
// },
// // 多少秒后关闭
// duration: {
// type: Number,
// value: 5
// }
// },
/**
* 组件的初始数据
*/
data: {
SHOW_MODAL:false
},
ready: function () {
// 判断是否已经显示过
let cache = wx.getStorageSync(STORAGE1_KEY);
if (cache) return;
// 没显示过,则进行展示
this.setData({
SHOW_MODAL: true
});
this.showModal();
},
/**
* 组件的方法列表
*/
methods: {
// 显示全屏添加说明
showModal: function () {
this.setData({
SHOW_MODAL: true
});
},
okHandler: function () {
this.setData({
SHOW_MODAL: false
});
wx.setStorage({
key: STORAGE1_KEY,
data: +new Date,
});
wx.requestSubscribeMessage({
tmplIds: ['6DGzsKqipoPxClnbkvwnxY9GqdXoLordLRdWTjJN1F0','XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q'], //这里填入我们生成的模板id
success(res) {
console.log('授权成功', res)
},
fail(res) {
console.log('授权失败', res)
}
})
wx.navigateTo({
url: '/pages/help/help',
})
}
},
})
================================================
FILE: miniprogram/components/welcome/welcome.json
================================================
{
"component": true,
"usingComponents": {}
}
================================================
FILE: miniprogram/components/welcome/welcome.wxml
================================================
1. 欢迎来到 易珠 小程序,感谢您的使用
2.同学们使用前可在(我的—用户手册)页面查看小程序使用详情,注册时请点击授权接受服务通知(并点击不在询问)以便能及时接收到信息
3. 关于为什么有广告出现问题,可在 (我的—使用说明) 页面处了解,感谢您的理解!
现在去康康>>
================================================
FILE: miniprogram/components/welcome/welcome.wxss
================================================
/* components/welcome.wxss */
.box {
position: fixed;
top: 0;
/* left: 0; */
right: 0;
z-index: 999;
display: flex;
justify-content: flex-end;
align-items: flex-end;
flex-direction: column;
width: 600rpx;
}
.arrow {
width: 0;
height: 0;
margin-right: 120rpx;
border-width: 20rpx;
border-style: solid;
border-color: transparent transparent #fbbd08;
}
.body {
background-color: #fbbd08;
box-shadow: 0 10rpx 20rpx -10rpx #fbbd08;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
height: 84rpx;
padding: 0 20rpx;
margin-right: 40rpx;
}
.body > text {
color: #FFF;
font-size: 28rpx;
font-weight: 400;
}
.font{
size: 20px;
}
.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
background-image: linear-gradient(to top, #dfe9f3 0%, white 100%);
padding: 10px;
}
.modal > view {
margin: 10px 0;
display: flex;
/* align-items: center; */
flex-direction: column;
}
.modal > view > text {
font-size: 16px;
font-weight: 400;
margin-bottom: 5px;
color: rgb(7, 7, 7);
}
.modal > view > image {
border-radius: 10px;
}
.ok-btn {
width: 100%;
margin-top: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.ok-btn > view {
height: 40px;
width: 120px;
background-color: #fbbd08;
box-shadow: 0 5px 10px -px #fbbd08;
display: flex;
align-items: center;
justify-content: center;
border-radius: 40px;
}
.ok-btn > view > text {
font-size: 14px;
color: #fff;
font-weight: 400;
}
.btn-hover {
opacity: 0.6;
}
================================================
FILE: miniprogram/config.js
================================================
var data = {
//云开发环境id
env: 'taoshaoji-46f0r',
//分享配置
share_title: '吉珠二手交易平台',
share_img: '/images/poster.jpg', //可以是网络地址,本地文件路径要填绝对位置
share_poster:'https://s2.ax1x.com/2019/11/20/Mhpqmt.png',//必须为网络地址
//客服联系方式
kefu: {
qq: '859162716',
weixin:'ttao527'
},
//默认启动页背景图,防止请求失败完全空白
//可以是网络地址,本地文件路径要填绝对位置
bgurl: '',
//校区
campus: [{
name: '竹园',
id: 0
},
{
name: '康园',
id: 1
},
{
name: '松园',
id: 2
},
{
name: '桂园',
id: 3
},
{
name: '梅园',
id: 4
},
{
name: '榕园',
id: 5
},
{
name: '松园',
id: 6
},
],
//配置学院,建议不要添加太多,不然前端不好看
college: [{
name: '通用',
id: -1
},
{
name: '学习用品',
id: 0
},
{
name: '日用品',
id: 1
},
{
name: '装饰品',
id: 2
},
{
name: '衣物',
id: 3
},
{
name: '运动器材',
id: 4
},
{
name: '化妆品',
id: 5
},
{
name: '其他',
id: 6
},
],
}
//下面的就别动了
function formTime(creatTime) {
let date = new Date(creatTime),
Y = date.getFullYear(),
M = date.getMonth() + 1,
D = date.getDate(),
H = date.getHours(),
m = date.getMinutes(),
s = date.getSeconds();
if (M < 10) {
M = '0' + M;
}
if (D < 10) {
D = '0' + D;
}
if (H < 10) {
H = '0' + H;
}
if (m < 10) {
m = '0' + m;
}
if (s < 10) {
s = '0' + s;
}
return Y + '-' + M + '-' + D + ' ' + H + ':' + m + ':' + s;
}
function days() {
let now = new Date();
let year = now.getFullYear();
let month = now.getMonth() + 1;
let day = now.getDate();
if (month < 10) {
month = '0' + month;
}
if (day < 10) {
day = '0' + day;
}
let date = year + "" + month + day;
return date;
}
module.exports = {
data: JSON.stringify(data),
formTime: formTime,
days: days
}
================================================
FILE: miniprogram/pages/about/about.js
================================================
// pages/about/about.js
Page({
/**
* 页面的初始数据
*/
data: {
imgs1: [{
url: 'tao.jpg',
name: '是芒果千层呀',
id: "0"
},
{
url: 'chen.jpg',
name: '楚利略',
id: "1"
},
],
des: '随着人们节约环保的消费意识的增强,在商品极丰富的大学校园里,二手物品交易市场迅速发展。大学生的消费金额限制、其节约意识以及每年大量的新生入学和毕业生离校,给予大学二手交易市场巨大的发展空间。然而我们观察发现,当前校园内的二手交易市场缺乏一个可靠实用的校园交易平台。考虑到微信小程序,方便快捷即用即走,速度快,安全性强等的优点,我们选择它作为交易平台。\n注意:\n本微信小程序只是提供物品交易的平台,不涉及金钱交易!主要服务于大学校园的学生与教师。'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 在页面中定义插屏广告
let interstitialAd = null
// 在页面onLoad回调事件中创建插屏广告实例
if (wx.createInterstitialAd) {
interstitialAd = wx.createInterstitialAd({
adUnitId: 'adunit-dfbad1c323913ca2'
})
interstitialAd.onLoad(() => {})
interstitialAd.onError((err) => {})
interstitialAd.onClose(() => {})
}
// 在适合的场景显示插屏广告
if (interstitialAd) {
interstitialAd.show().catch((err) => {
console.error(err)
})
}
},
//图片点击事件
img: function (event) {
let arr = [];
arr.push('https://7461-taoshaoji-46f0r-1302243411.tcb.qcloud.la/appreciate-code/appreciateimg.jpg?sign=7a94d719f891a5b8838fae33a1b79d22&t=1597422871')
wx.previewImage({
current: 'current', // 当前显示图片的http链接
urls: arr // 需要预览的图片http链接列表
})
},
onReady: function () {
},
//复制
copy(e) {
wx.setClipboardData({
data: e.currentTarget.dataset.copy,
success: res => {
wx.showToast({
title: '复制' + e.currentTarget.dataset.name + '成功',
icon: 'success',
duration: 1000,
})
}
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
================================================
FILE: miniprogram/pages/about/about.json
================================================
{
"usingComponents": {}
}
================================================
FILE: miniprogram/pages/about/about.wxml
================================================
开发:
{{item.name}}
程序简介
{{des}}
打赏我们
联系方式
公众号 :
拈花我把酒
QQ群 :
859162716
================================================
FILE: miniprogram/pages/about/about.wxss
================================================
page {
background: #eee;
}
.des_contain {
width: 618rpx;
height: 157rpx;
border-radius: 10rpx;
background: #fff;
display: flex;
box-sizing: border-box;
flex-direction: column;
justify-content: center;
padding: 0 0 0 90rpx;
}
.imagesize {
display: flex;
justify-content: center;
}
.imagesize image {
width: 400rpx;
height: 400rpx;
}
.name {
font-size: 36rpx;
line-height: 50rpx;
}
.sign {
margin-top: 10rpx;
font-size: 28rpx;
letter-spacing: 3rpx;
line-height: 45rpx;
color: #b8b8b8;
}
.avator_box {
position: absolute;
left: 0rpx;
top: 0rpx;
display: flex;
padding: 44rpx 0 0 40rpx;
}
.avator {
box-shadow: 0 0 10rpx #b8b8b8;
width: 110rpx;
height: 110rpx;
border-radius: 20rpx;
}
.contain {
width: 100%;
background: #eee;
display: flex;
flex-direction: column;
padding: 0 20rpx;
box-sizing: border-box;
}
.title {
margin-top: 20rpx;
line-height: 45rpx;
padding-left: 20rpx;
font-size: 32rpx;
letter-spacing: 3rpx;
color: #000;
}
.description {
width: 100%;
padding: 24rpx 30rpx;
background: #fff;
border-radius: 10rpx;
display: flex;
box-sizing: border-box;
flex-direction: column;
}
.description text {
width: 100%;
font-size: 28rpx;
line-height: 44rpx;
letter-spacing: 3rpx;
}
.tip {
display: flex;
align-items: center;
}
.tip view {
font-size: 30rpx;
letter-spacing: 2rpx;
padding: 15rpx 0;
width: 150rpx;
display: flex;
justify-content: space-between;
}
.tip text {
margin-left: 20rpx;
font-size: 28rpx;
color: #008ecf;
text-decoration-line: underline;
}
.main {
background: #fff;
margin: 0 3px;
position: relative;
padding: 4rpx 30px;
color: #1c1111;
font-size: 12px;
display: flex;
}
.image {
display: flex;
flex-wrap: wrap;
}
.im {
margin-left: 80rpx;
margin-top: 35rpx;
height: 145rpx;
width: 145rpx;
border-radius: 50%;
}
.txt {
width: 230rpx;
text-align: center
}
.t {
margin-left: 26px;
color: lightskyblue;
}
================================================
FILE: miniprogram/pages/appreciateCode/appreciateCode.js
================================================
const db = wx.cloud.database();
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
bigImg: '',
isExist: Boolean, //如果存在的话就是真,不存在的话就是假
openid: app.openid
},
onLoad() {
this.getCodeFromSet()
},
getCodeFromSet() {
let that = this;
let openid = app.openid
console.log(openid)
db.collection('appreciatecode').where({
_openid: openid,
}).get().then(res => {
if (res.data.length > 0) {
that.setData({
isExist: true,
bigImg: res.data[0].bigImg
})
console.log(res.data[0].bigImg)
console.log("isExist---->" + that.data.isExist)
} else {
that.setData({
isExist: false,
})
console.log("isExist---->" + that.data.isExist)
}
})
},
changeBigImg() {
let that = this;
let openid = app.openid
wx.chooseImage({
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
wx.showLoading({
title: '上传中',
});
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
let filePath = res.tempFilePaths[0];
const name = Math.random() * 1000000;
const cloudPath = 'appreciate-code/' + app.openid + '/' + name + filePath.match(/\.[^.]+?$/)[0]
wx.cloud.uploadFile({
cloudPath, //云存储图片名字
filePath, //临时路径
success: res => {
console.log('[上传图片] 成功:', res)
that.setData({
bigImg: res.fileID, //云存储图片路径,可以把这个路径存到集合,要用的时候再取出来
});
let fileID = res.fileID;
//把图片存到appreciatecode集合表
const db = wx.cloud.database();
if (that.data.isExist == false) {
db.collection("appreciatecode").add({
data: {
bigImg: fileID,
},
success: function () {
wx.showToast({
title: '赞赏码上传成功',
'icon': 'none',
duration: 3000
})
console.log("这里是第一次,用add")
that.setData({
isExist: true
})
},
fail: function () {
wx.showToast({
title: '赞赏码上传失败',
'icon': 'none',
duration: 3000
})
}
});
} else {
db.collection("appreciatecode").where({
_openid: openid
}).update({
data: {
bigImg: fileID,
},
success: function () {
wx.showToast({
title: '赞赏码上传成功',
'icon': 'none',
duration: 3000
})
console.log("这里是第二次,用update")
},
fail: function () {
wx.showToast({
title: '赞赏码上传失败',
'icon': 'none',
duration: 3000
})
}
});
}
},
fail: e => {
console.error('[上传图片] 失败:', e)
},
complete: () => {
wx.hideLoading()
}
});
}
})
},
})
================================================
FILE: miniprogram/pages/appreciateCode/appreciateCode.json
================================================
{
"usingComponents": {}
}
================================================
FILE: miniprogram/pages/appreciateCode/appreciateCode.wxml
================================================
{{(!isExist)?"上传赞赏码":"修改赞赏码"}}
上传申明
1、为什么要上传赞赏码?
因为微信小程序中无法识别收款码或者提供其它财产交易方式,所以我们采用小程序能够识别的赞赏码来进行付款交易
2、如何获取付款码?
用户可以在微信中我的-支付-钱包中的收付款页面下方选项-赞赏码获取,然后保存赞赏码上传到本小程序中,便可实现在线交易。后续我们会努力拿到微信支付的接口权限,简化交易过程。
作者声明
赞赏码的用途和收款码类似。只能用于收款,用户不用担心会因此产生不必要的财产损失。我们会将赞赏码附加于订单详情页,买家可以通过扫描赞赏码向卖家进行费用支付。\nTip:如果卖家不想上传赞赏码,可以在线下和买家进行沟通,面对面扫一扫交易也可。
================================================
FILE: miniprogram/pages/appreciateCode/appreciateCode.wxss
================================================
page {
background: #eee;
}
.imagesize {
display: flex;
justify-content: center;
}
.imagesize image {
width: 400rpx;
height: 400rpx;
}
.contain {
width: 100%;
background: #eee;
display: flex;
flex-direction: column;
padding: 0 20rpx;
box-sizing: border-box;
}
.btn {
background-image: linear-gradient(-225deg, #9EFBD3 0%, #57E9F2 48%, #45D4FB 100%);
margin-bottom: 20rpx;
width: 100%;
height: 100rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 100rpx;
color: #fff;
font-size: 40rpx;
letter-spacing: 4rpx;
border: none;
}
.shen_title {
margin-top: 40rpx;
font-size: 32rpx;
letter-spacing: 2rpx;
display: flex;
justify-content: flex-start;
align-items: center;
}
.about {
width: 32rpx;
height: 32rpx;
padding-right: 10rpx;
}
.title {
margin-top: 20rpx;
line-height: 56rpx;
padding-left: 20rpx;
font-size: 32rpx;
letter-spacing: 3rpx;
color: #000;
}
.description {
width: 100%;
padding: 24rpx 30rpx;
background: #fff;
border-radius: 10rpx;
display: flex;
box-sizing: border-box;
flex-direction: column;
}
.description text {
width: 100%;
font-size: 28rpx;
line-height: 44rpx;
letter-spacing: 3rpx;
}
.space {
width: 100%;
height: 20rpx;
background: #eee;
}
.nocontent {
width: 100%;
height: calc(100% - 400rpx);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
box-sizing: border-box;
}
.image {
display: flex;
justify-content: center;
align-items: center;
}
================================================
FILE: miniprogram/pages/detail/detail.js
================================================
const app = getApp()
const db = wx.cloud.database();
const config = require("../../config.js");
const _ = db.command;
let obj = ''
Page({
/**
* 页面的初始数据
*/
data: {
first_title: true,
place: '',
roomID: '',
goodssaller: '',
openid: '',
imgs: [],
isShow: true,
status: 0,
avatarUrl: '',
buyerInfo: [],
isExist: Boolean,
address:''
},
onLoad(e) {
obj = e;
this.getuserdetail();
this.data.id = e.scene;
this.getPublish(e.scene);
if (app.openid) {
this.setData({
openid: app.openid
})
} else {
console.log("no openid");
wx.showModal({
title: '温馨提示',
content: '该功能需要注册方可使用,是否马上去注册',
success(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login',
})
}
}
})
return false
}
this.getBuyer(this.data.openid)
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
},
//获取买家信息
getBuyer(m) {
let that = this;
db.collection('user').where({
_openid: m
}).get({
success: function (res) {
wx.hideLoading();
that.setData({
buyerInfo: res.data[0]
})
}
})
},
goo(e) {
var myid = this.data.openid;
var sallerid = this.data.goodssaller;
wx.cloud.init({
env: 'taoshaoji-46f0r',
traceUser: true
});
//初始化数据库
const db = wx.cloud.database();
if (myid != sallerid) {
db.collection('rooms').where({
p_b: myid,
p_s: sallerid
}).get().then(res => {
console.log(res.data);
if (res.data.length > 0) {
this.setData({
roomID: res.data[0]._id
})
db.collection("rooms").doc(res.data[0]._id).update({
data: {
deleted:0
},
}),
wx.navigateTo({
url: 'room/room?id=' + this.data.roomID,
})
} else {
db.collection('rooms').add({
data: {
p_b: myid,
p_s: sallerid,
deleted:0
},
}).then(res => {
console.log(res)
this.setData({
roomID: res._id
})
wx.navigateTo({
url: 'room/room?id=' + this.data.roomID,
})
})
}
})
} else {
wx.showToast({
title: '无法和自己建立聊天',
icon: 'none',
duration: 1500
})
}
},
changeTitle(e) {
let that = this;
that.setData({
first_title: e.currentTarget.dataset.id
})
},
//获取发布信息
getPublish(e) {
let that = this;
db.collection('publish').doc(e).get({
success: function (res) {
that.setData({
collegeName: JSON.parse(config.data).college[parseInt(res.data.collegeid) + 1],
publishinfo: res.data
})
that.getSeller(res.data._openid)
}
})
},
//获取卖家信息
getSeller(m, n) {
let that = this;
db.collection('user').where({
_openid: m
}).get({
success: function (res) {
console.log(res.data[0]._openid);
that.setData({
userinfo: res.data[0],
goodssaller: res.data[0]._openid
})
that.getBook(n)
}
})
},
//回到首页
home() {
wx.switchTab({
url: '/pages/index/index',
})
},
//回到我的
my() {
wx.switchTab({
url: '/pages/my/my',
})
},
//购买检测
buy() {
var myid = this.data.openid;
var sallerid = this.data.goodssaller;
let that = this;
if (myid == sallerid) {
wx.showToast({
title: '自己买不了自己的噢!',
icon: 'none',
duration: 1500
})
return false
}
if (!app.openid) {
wx.showModal({
title: '温馨提示',
content: '该功能需要注册方可使用,是否马上去注册',
success(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login',
})
}
}
})
return false
}
if (that.data.publishinfo.deliveryid == 1) {
if (that.data.place == '') {
wx.hideLoading();
wx.showToast({
title: '请输入您的收货地址',
icon: 'none'
})
return false
}
}
that.getStatus();
},
//获取订单状态
getStatus() {
let that = this;
let _id = that.data.publishinfo._id;
console.log(_id);
db.collection('publish').doc(_id).get({
success(e) {
if (e.data.status == 0) {
that.creatOrder(_id);
}
if (e.data.status == 1) {
wx.showToast({
title: '该物品刚刚被抢光了~',
icon: 'none'
})
}
if (e.data.status == 2) {
wx.showToast({
title: '该物品已出售',
icon: 'none'
})
}
if (e.data.status == 3) {
wx.showToast({
title: '该物品已下架',
icon: 'none'
})
}
}
})
},
//创建订单
creatOrder(iid) {
let that = this;
db.collection('order').where({
_id: iid
}).get().then(res => {
console.log(res.data);
if (res.data.length > 0) {
that.setData({
isExist: true
})
console.log("isExist:" + that.data.isExist)
} else {
that.setData({
isExist: false
})
console.log("isExist:" + that.data.isExist)
}
})
wx.showModal({
title: '确认提示',
content: '是否确认下单购买此商品?',
success(res) {
if (res.confirm) {
if (!that.data.isExist) {
wx.cloud.callFunction({
// 云函数名称
name: 'node',
// 传给云函数的参数
data: {
_id: iid,
status: 1
},
success: function (res) {
console.log(res)
},
fail: console.error
})
wx.getUserInfo({
success: function (res) {
that.setData({
buyerName: res.userInfo.nickName,
avatarUrl: res.userInfo.avatarUrl,
})
},
fail(){
console.log("调用getUserinfo失败")
}
})
db.collection('publish').doc({
iid
}).update({
data: {
status: 1
},
success() {
wx.hideLoading();
// that.getList();
db.collection('order').add({
data: {
creat: new Date().getTime(),
status: 1, //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;
price: that.data.publishinfo.price, //售价
deliveryid: that.data.publishinfo.deliveryid, //0自1配
ztplace: that.data.publishinfo.place, //自提时地址
psplace: that.data.place, //配送时买家填的地址
bookinfo: {
describe: that.data.publishinfo.bookinfo.describe,
pic: that.data.publishinfo.bookinfo.pic,
good: that.data.publishinfo.bookinfo.good,
},
buyerInfo: that.data.buyerInfo,
seller: that.data.publishinfo._openid,
sellid: that.data.publishinfo._id,
_id: that.data.publishinfo._id,
},
success() {
that.getAddress()
that.send(that.data.goodssaller)
wx.showToast({
title: '成功预订!',
icon: 'success',
duration: 3000
})
setTimeout(function () {
wx.switchTab({
url: '/pages/index/index',
})
}, 3000)
},
fail() {
wx.hideLoading();
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
},
fail() {
wx.hideLoading();
wx.showToast({
title: '操作失败',
icon: 'none'
})
}
})
that.onLoad(obj);
} else {
wx.cloud.callFunction({
// 云函数名称
name: 'node',
// 传给云函数的参数
data: {
_id: iid,
status: 1
},
success: function (res) {
console.log(res)
},
fail: console.error
})
db.collection('publish').doc({
iid
}).update({
data: {
status: 1
},
success() {
wx.hideLoading();
// that.getList();
wx.cloud.callFunction({
// 云函数名称
name: 'pay',
// 传给云函数的参数
data: {
$url: "changeO", //云函数路由参数
_id: iid,
status: 1
},
success() {
that.getAddress()
that.send(that.data.goodssaller)
wx.showToast({
title: '成功预订!',
icon: 'success',
duration: 3000
})
},
fail() {
wx.hideLoading();
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
},
fail() {
wx.hideLoading();
wx.showToast({
title: '操作失败',
icon: 'none'
})
}
})
that.onLoad(obj);
}
}
}
})
},
//发送模板消息到指定用户,推送之前要先获取用户的openid
send(openid) {
let that = this;
wx.cloud.callFunction({
name: "sendMsg",
data: {
openid: openid,
status: '买家已预定', //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;
address:that.data.address,
describe: that.data.publishinfo.bookinfo.describe,
good: that.data.publishinfo.bookinfo.good,
nickName: that.data.buyerInfo.info.nickName,
color: 'red'
}
}).then(res => {
console.log("推送消息成功", res)
}).catch(res => {
console.log("推送消息失败", res)
})
},
//路由
go(e) {
wx.navigateTo({
url: e.currentTarget.dataset.go,
})
},
//地址输入
placeInput(e) {
this.data.place = e.detail.value
},
//为了数据安全可靠,每次进入获取一次用户信息
getuserdetail() {
if (!app.openid) {
wx.cloud.callFunction({
name: 'regist', // 对应云函数名
data: {
$url: "getid", //云函数路由参数
},
success: re => {
db.collection('user').where({
_openid: re.result
}).get({
success: function (res) {
if (res.data.length !== 0) {
app.openid = re.result;
app.userinfo = res.data[0];
console.log(app)
}
console.log(res)
}
})
}
})
}
},
//图片点击事件
img: function (event) {
let arr = [];
arr.push(this.data.publishinfo.bookinfo.imgs);
var src = event.currentTarget.dataset.src; //获取data-src
// var imgList = that.data.result.images_fileID;
//图片预览
wx.previewImage({
current: src, // 当前显示图片的http链接
urls: arr[0] // 需要预览的图片http链接列表
})
},
/**
* 获取地址
*/
getAddress() {
let that = this;
if (that.data.publishinfo.deliveryid == 0) {
that.setData({
address: that.data.publishinfo.place
})
} else {
that.setData({
address: that.data.place
})
}
},
})
================================================
FILE: miniprogram/pages/detail/detail.json
================================================
{
"navigationBarTitleText": "物品详情"
}
================================================
FILE: miniprogram/pages/detail/detail.wxml
================================================
{{publishinfo.bookinfo.good}}
¥{{publishinfo.price}}元
发布信息
物品详情
{{userinfo.info.nickName}}
{{userinfo.campus.name}}
{{collegeName.name}}类物品
发布于{{morejs.timelog(publishinfo.creat)}}
取货方式:
{{publishinfo.deliveryid==0?'自提':'帮送'}}
{{publishinfo.place}}
备注信息:
{{publishinfo.notes}}
物品描述
{{publishinfo.bookinfo.describe}}
首页
我的
{{publishinfo.status==0?'立即购买':(publishinfo.status==1?'刚刚被抢光了':(publishinfo.status==2?'已出售':'已下架'))}}
私聊
================================================
FILE: miniprogram/pages/detail/detail.wxss
================================================
.top_contain {
display: flex;
flex-direction: column;
padding: 24rpx;
box-sizing: border-box;
}
.chou {
padding-top: 30rpx;
}
.top_img {
width: 100%;
display: flex;
justify-content: center;
}
.top_img image {
width: 300rpx;
height: 300rpx;
}
.title {
padding-top: 30rpx;
font-size: 32rpx;
font-weight: 600;
letter-spacing: 2rpx;
}
.author {
padding-top: 10rpx;
font-size: 26rpx;
color: rgb(172, 171, 171);
letter-spacing: 2rpx;
}
.price_box {
margin-top: 20rpx;
display: flex;
align-items: flex-end;
}
.now_price {
font-size: 34rpx;
color: rgb(255, 1, 1);
}
.pre_price {
padding-left: 30rpx;
font-size: 28rpx;
color: rgb(172, 171, 171);
text-decoration: line-through;
}
.blank {
width: 100%;
height: 24rpx;
background: #eee;
}
.center_contain {
width: 100%;
height: 80rpx;
display: flex;
box-sizing: border-box;
padding: 0 100rpx;
justify-content: space-around;
}
.c_title {
font-size: 30rpx;
width: 140rpx;
height: 100%;
display: flex;
letter-spacing: 2rpx;
align-items: center;
justify-content: center;
}
.title_on {
font-size: 32rpx;
font-weight: 600;
color: #000;
border-bottom: 4rpx solid #fbbd08;
}
.user_box {
width: 100%;
height: 148rpx;
display: flex;
padding: 24rpx;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
}
.user_box image {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
.des_box {
height: 100%;
width: 450rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-around;
padding: 10rpx 0;
}
.user_name {
font-size: 32rpx;
letter-spacing: 2rpx;
}
.local_box {
display: flex;
align-items: center;
}
.local_box image {
width: 30rpx;
height: 30rpx;
}
.local_box view {
padding-left: 5rpx;
font-size: 28rpx;
letter-spacing: 2rpx;
color: rgb(150, 150, 150);
}
.sex {
width: 100rpx;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.sex image {
width: 50rpx;
height: 50rpx;
border-radius: 50%;
}
.notes_box {
width: 100%;
padding: 24rpx 24rpx 0 24rpx;
display: flex;
box-sizing: border-box;
}
.notes {
width: 100%;
background: rgb(238, 238, 238);
color: #aaa;
padding: 20rpx 20rpx 10rpx 20rpx;
border-radius: 10rpx;
display: flex;
box-sizing: border-box;
flex-direction: column;
}
.notes_text {
letter-spacing: 2rpx;
font-size: 28rpx;
line-height: 45rpx;
padding-bottom: 10rpx;
}
.time_box {
width: 100%;
padding: 24rpx 24rpx 0 24rpx;
display: flex;
box-sizing: border-box;
justify-content: space-between;
}
.kind {
font-size: 28rpx;
letter-spacing: 2rpx;
}
.time {
font-size: 28rpx;
letter-spacing: 2rpx;
color: #8c9aa8;
}
.deliver_box {
width: 100%;
padding: 24rpx 24rpx 0 24rpx;
display: flex;
box-sizing: border-box;
justify-content: space-between;
}
.deliver_first {
display: flex;
align-items: center;
}
.deliver_title {
font-size: 28rpx;
letter-spacing: 2rpx;
}
.deliver_kind {
font-size: 28rpx;
letter-spacing: 2rpx;
color: #a5a5a5;
}
.deliver_place {
font-size: 28rpx;
letter-spacing: 2rpx;
}
.palceInput_box {
width: 100%;
padding: 24rpx 24rpx 0 24rpx;
display: flex;
box-sizing: border-box;
justify-content: center;
}
.palceInput_box input {
width: 100%;
height: 66rpx;
border: 1rpx solid #eee;
border-radius: 10rpx;
font-size: 26rpx;
padding: 0 20rpx;
letter-spacing: 2rpx;
}
.detail_contain {
width: 100%;
padding: 24rpx;
display: flex;
margin: 0;
flex-direction: column;
box-sizing: border-box;
}
.detail_card {
display: flex;
width: 100%;
box-sizing: border-box;
padding: 30rpx 0;
justify-content: space-between;
}
.detail_border {
border-bottom: 1rpx solid #eee;
}
.detail_title {
width: 20%;
font-size: 28rpx;
letter-spacing: 2rpx;
line-height: 45rpx;
}
.detail_content {
width: 78%;
font-size: 27rpx;
letter-spacing: 2rpx;
line-height: 44rpx;
color: #616161;
}
/*底部导航*/
.tabbar {
width: 100%;
height: 96rpx;
background: #fff;
opacity: 1;
position: fixed;
left: 0rpx;
bottom: 0rpx;
display: flex;
padding: 10rpx;
border-top: 1rpx solid #eee;
align-items: center;
box-sizing: border-box;
z-index: 8;
}
.t_card {
position: relative;
width: 30%;
height: 80rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.t_card image {
width: 40rpx;
height: 40rpx;
}
.t_card text {
display: flex;
align-items: flex-start;
justify-content: center;
height: calc(100% - 50rpx);
width: 100%;
font-size: 24rpx;
text-align: center;
white-space: nowrap;
padding-top: 4rpx;
}
.t_button {
width: 100%;
height: 100%;
position: absolute;
left: 0rpx;
top: 0rpx;
opacity: 0.01;
z-index: 9;
}
.buy_box {
width: 40%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.buy {
width: 90%;
height: 70rpx;
background: #fbbd08;
color: #000;
letter-spacing: 4rpx;
font-size: 28rpx;
border-radius: 35rpx;
display: flex;
justify-content: center;
align-items: center;
}
.contact_box {
z-index: 9;
position: fixed;
bottom: 110rpx;
right: 40rpx;
display: flex;
width: 100rpx;
flex-direction: column;
align-items: center;
background: rgba(255, 255, 255, 0.8);
padding: 20rpx 0;
border-radius: 50rpx 50rpx 20rpx 20rpx;
box-shadow: 0 0 20rpx #f0f0f0 !important;
}
.contact_box image {
width: 80rpx;
height: 80rpx;
}
.image{
display:flex;
justify-content: center;
}
.contact_box view {
font-size: 26rpx;
letter-spacing: 2rpx;
margin-top: 10rpx;
}
.imgList {
width: 100%;
}
.imgList .imgList-li {
width: 100%;
}
.imgList .imgList-li .img {
width: 400rpx;
height: 400rpx;
}
================================================
FILE: miniprogram/pages/detail/room/room.js
================================================
const app = getApp()
Page({
data: {
avatarUrl: './user-unlogin.png',
userInfo: null,
logged: false,
takeSession: false,
requestResult: '',
//chatRoomEnvId: 'release-f8415a',
chatRoomCollection: 'chatroom',
chatRoomGroupId: '',
chatRoomGroupName: '聊天室',
// functions for used in chatroom components
onGetUserInfo: null,
getOpenID: null,
},
onLoad: function (opentions) {
// 获取用户信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
this.setData({
avatarUrl: res.userInfo.avatarUrl,
userInfo: res.userInfo
})
}
})
}
}
})
this.setData({
onGetUserInfo: this.onGetUserInfo,
getOpenID: this.getOpenID,
chatRoomGroupId: opentions.id
})
wx.getSystemInfo({
success: res => {
console.log('system info', res)
if (res.safeArea) {
const {
top,
bottom
} = res.safeArea
this.setData({
containerStyle: `padding-top: ${(/ios/i.test(res.system) ? 10 : 20) + top}px; padding-bottom: ${20 + res.windowHeight - bottom}px`,
})
}
},
})
},
getOpenID: async function () {
if (app.openid) {
return app.openid
}
const {
result
} = await wx.cloud.callFunction({
name: 'login',
})
return result.openid
},
onGetUserInfo: function (e) {
if (!this.logged && e.detail.userInfo) {
this.setData({
logged: true,
avatarUrl: e.detail.userInfo.avatarUrl,
userInfo: e.detail.userInfo
})
}
},
onGetUserInfo: function (e) {
if (!this.logged && e.detail.userInfo) {
this.setData({
logged: true,
avatarUrl: e.detail.userInfo.avatarUrl,
userInfo: e.detail.userInfo
})
}
},
onShareAppMessage() {
return {
title: '聊天室',
path: '/pages/detail/room/room',
}
},
go(){
wx.navigateTo({
url: '/pages/message/message',
})
}
})
================================================
FILE: miniprogram/pages/detail/room/room.json
================================================
{
"usingComponents": {
"chatroom": "/components/chatroom/chatroom"
}
}
================================================
FILE: miniprogram/pages/detail/room/room.wxml
================================================
================================================
FILE: miniprogram/pages/detail/room/room.wxss
================================================
.container {
height: 98%;
position: absolute;
/* top: 0; */
bottom: 0;
left: 0;
right: 0;
padding-top: 80rpx;
padding-bottom: 30rpx;
width: 100%;
display: flex;
flex-direction: column;
}
.space {
width: 100%;
height: 15rpx;
background: #eee;
}
================================================
FILE: miniprogram/pages/edit/edit.js
================================================
const db = wx.cloud.database();
const app = getApp();
const config = require("../../config.js");
Page({
/**
* 页面的初始数据
*/
data: {
ids: -1,
wxnum: '',
qqnum: '',
email: '',
checked:false,
campus: JSON.parse(config.data).campus,
},
onChange(event) {
if(event.detail==true){
wx.requestSubscribeMessage({
tmplIds: ['6DGzsKqipoPxClnbkvwnxY9GqdXoLordLRdWTjJN1F0','XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q'], //这里填入我们生成的模板id
success(res) {
console.log('授权成功', res)
},
fail(res) {
console.log('授权失败', res)
}
})
}
this.setData({
checked: event.detail,
});
},
choose(e) {
let that = this;
that.setData({
ids: e.detail.value
})
//下面这种办法无法修改页面数据
/* this.data.ids = e.detail.value;*/
},
onLoad() {
this.getdetail();
},
getdetail() {
let that = this;
db.collection('user').where({
_openid: app.openid
}).get({
success: function(res) {
let info = res.data[0];
that.setData({
phone: info.phone,
qqnum: info.qqnum,
wxnum: info.wxnum,
email: info.email,
ids: info.campus.id,
_id: info._id
})
},
fail() {
wx.showToast({
title: '获取失败',
icon: 'none'
})
let e = setTimeout(
wx.navigateBack({}), 2000
)
}
})
},
wxInput(e) {
this.data.wxnum = e.detail.value;
},
qqInput(e) {
this.data.qqnum = e.detail.value;
},
emInput(e) {
this.data.email = e.detail.value;
},
getUserInfo(e) {
let that = this;
console.log(e);
let test = e.detail.errMsg.indexOf("ok");
if (test == '-1') {
wx.showToast({
title: '请授权后方可使用',
icon: 'none',
duration: 2000
});
} else {
that.setData({
userInfo: e.detail.userInfo
})
that.check();
}
},
//校检
check() {
let that = this;
//校检手机
let phone = that.data.phone;
if (phone == '') {
wx.showToast({
title: '请先获取您的电话',
icon: 'none',
duration: 2000
});
return false
}
//校检校区
let ids = that.data.ids;
let campus = that.data.campus;
if (ids == -1) {
wx.showToast({
title: '请先获取您的校区',
icon: 'none',
duration: 2000
});
}
//校检邮箱
let email = that.data.email;
if (!(/^\w+((.\w+)|(-\w+))@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+).[A-Za-z0-9]+$/.test(email))) {
wx.showToast({
title: '请输入常用邮箱',
icon: 'none',
duration: 2000
});
return false;
}
//校检QQ号
let qqnum = that.data.qqnum;
if (qqnum !== '') {
if (!(/^\s*[.0-9]{5,11}\s*$/.test(qqnum))) {
wx.showToast({
title: '请输入正确QQ号',
icon: 'none',
duration: 2000
});
return false;
}
}
//校检微信号
let wxnum = that.data.wxnum;
if (wxnum !== '') {
if (!(/^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$/.test(wxnum))) {
wx.showToast({
title: '请输入正确微信号',
icon: 'none',
duration: 2000
});
return false;
}
}
wx.showLoading({
title: '正在提交',
})
db.collection('user').doc(that.data._id).update({
data: {
phone: that.data.phone,
campus: that.data.campus[that.data.ids],
qqnum: that.data.qqnum,
email: that.data.email,
wxnum: that.data.wxnum,
info: that.data.userInfo,
updatedat: new Date().getTime(),
},
success: function(res) {
console.log(res)
db.collection('user').doc(that.data._id).get({
success: function(res) {
app.userinfo = res.data;
app.openid = res.data._openid;
wx.hideLoading();
wx.showToast({
title: '修改成功',
icon: 'success'
})
},
})
},
fail() {
wx.hideLoading();
wx.showToast({
title: '注册失败,请重新提交',
icon: 'none',
})
}
})
},
})
================================================
FILE: miniprogram/pages/edit/edit.json
================================================
{
"usingComponents": {}
}
================================================
FILE: miniprogram/pages/edit/edit.wxml
================================================
修改资料
当前选择:{{campus[ids].name}}
请选择您所在校区
授权接收订单消息通知
提交修改
使用申明
1. 请确保微信号、qq号和邮箱百分百有效,之后将用于发送实时订单通知。
2. 在未经您同意及确认之前,本程序不会将您的注册信息用于任何其它商业目的。
3. 本程序将对您所提供的资料进行严格的管理及保护,本程序将使用相应的技术,防止您的个人资料丢失、被盗用或遭篡改。
4. 请您放心使用!
================================================
FILE: miniprogram/pages/edit/edit.wxss
================================================
.top-bg {
position: absolute;
top: 0rpx;
left: 0rpx;
width: 100%;
height: 460rpx;
background:#fbbd08;
background-repeat: no-repeat;
background-size: 100%;
}
.contain {
position: absolute;
top: 30rpx;
left: 0rpx;
width: 100%;
padding: 0rpx 40rpx 0rpx 40rpx;
box-sizing: border-box;
}
.card {
border-radius: 32rpx;
width: 100%;
background: #fff;
padding: 50rpx 60rpx;
box-sizing: border-box;
box-shadow: 0 0 20rpx #eee;
}
.title {
width: 100%;
text-align: center;
font-size: 40rpx;
font-weight: 600;
letter-spacing: 6rpx;
}
.phone {
justify-content: space-between;
margin-top: 45rpx;
width: 100%;
height: 92rpx;
background: #f1f3f8;
border-radius: 10rpx;
text-align: left;
padding: 0 20rpx 0 36rpx;
box-sizing: border-box;
font-size: 32rpx;
display: flex;
align-items: center;
color: #8c9aa8;
border: none;
}
.phone::after {
border: none;
}
.campus {
margin-top: 24rpx;
width: 100%;
height: 92rpx;
background: #f1f3f8;
border-radius: 10rpx;
text-align: left;
padding: 0 20rpx 0 36rpx;
box-sizing: border-box;
font-size: 32rpx;
display: flex;
align-items: center;
justify-content: space-between;
color: #8c9aa8;
}
.right {
width: 30rpx;
height: 30rpx;
}
.contact {
margin-top: 24rpx;
width: 100%;
height: 92rpx;
background: #f1f3f8;
border-radius: 10rpx;
text-align: left;
padding: 0 36rpx;
box-sizing: border-box;
font-size: 32rpx;
display: flex;
align-items: center;
justify-content: space-between;
color: #8c9aa8;
}
.contact input {
width: 100%;
height: 100%;
}
.pache {
font-size: 32rpx;
color: #8c9aa8;
}
.confirm {
margin-top: 50rpx;
width: 100%;
height: 100rpx;
display: flex;
justify-content: center;
align-items: center;
background:linear-gradient(120deg, #e0c3fc 0%, #8ec5fc 100%);
border-radius: 60rpx;
color: #fff;
font-size: 40rpx;
letter-spacing: 4rpx;
box-shadow: 0 0 20rpx #eee;
border: none;
}
.confirm::after {
border: none;
}
.shen_title {
margin-top: 40rpx;
font-size: 32rpx;
letter-spacing: 2rpx;
display: flex;
justify-content: flex-start;
align-items: center;
}
.about {
width: 32rpx;
height: 32rpx;
padding-right: 10rpx;
}
.des {
padding-left: 30rpx;
padding-top: 20rpx;
font-size: 26rpx;
color: #acacac;
letter-spacing: 2rpx;
line-height: 42rpx;
}
================================================
FILE: miniprogram/pages/help/help.js
================================================
var app = getApp();
var db = wx.cloud.database();
Page({
/**
* 页面的初始数据
*/
data: {
list: [{
title: '小程序为什么会插入广告?',
id: 0,
des: ['对于本程序的正常运行,成本支出有以下几个方面', '1、程序部署上线,每年都需要微信认证300元。', '2、目前小程序每日CDN流量资费5元每天。', '3、云开发套餐,目前使用的是50元每月的套餐。', '小程序完全公益,不存在盈利目的,插入广告仅仅是为了本小程序的正常运行,望理解'],
check: true,
}, {
title: '该程序收费吗?',
id: 1,
des: ['本程序是完全的公益项目,永久承诺不收取任何中介费,您可以随心所欲的发布自己的闲置物品和购买。如过您觉得本小程序不错,欢迎各位支持打赏我们,请我们喝阔落。'],
check: false,
}, {
title: '该程序是做什么的?',
id: 2,
des: ['本程序主要是方便吉林大学珠海学院的同学发布自己不要了的二手书籍或者物品。',
'如果您是其它学校的同学,可以访问【关于程序】页面,根据说明给自己学校也部署一个'
],
check: false,
}, {
title: '本程序的通知形式?',
id: 3,
des: ['对于买家下单时,我们通过微信服务消息通知和邮件发送订单信息给卖家,通知与您联系完成交易', '当交易状态中途取消时,也会通过微信服务信息通知于您', '您也可以在订单详情页面通过买(卖)家留下的联系方式第一时间联系,这样更能提高效率'],
check: false,
},
{
title: '为什么要留下联系方式?',
id: 4,
des: ['本程序交易完全由交易双方沟通。', '除非程序出现问题导致交易故障,平台不参与任何交易'],
check: false,
}, {
title: '小程序发现异常(bug)怎么办?',
id: 5,
des: ['点击客服加群或关注公众号反馈,我们会有专人为您服务。您还可以向我们提出意见或者建议,我们会争取将小程序做得更好!!!希望我们能够一起打造一个完美的二手交易平台。'],
check: false,
},
]
},
onReady() {},
show(e) {
var that = this;
let ite = e.currentTarget.dataset.show;
let list = that.data.list;
if (!ite.check) {
list[ite.id].check = true;
} else {
list[ite.id].check = false;
}
that.setData({
list: list
})
},
//跳转页面
go(e) {
wx.navigateTo({
url: e.currentTarget.dataset.go
})
},
onLoad() {
},
})
================================================
FILE: miniprogram/pages/help/help.json
================================================
{
"navigationBarTitleText": "使用说明",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
================================================
FILE: miniprogram/pages/help/help.wxml
================================================
{{item.id+1}}.{{item.title}}
{{item}}
联系客服
去打赏
================================================
FILE: miniprogram/pages/help/help.wxss
================================================
.contain {
width: 100%;
padding: 30rpx 30rpx;
box-sizing: border-box;
}
.top {
display: flex;
justify-content: space-between;
align-items: center;
height: 50rpx;
margin-top: 20rpx;
}
.title {
font-size: 32rpx;
font-weight: 600;
letter-spacing: 2rpx;
width: calc( 100% - 60rpx);
line-height: 50rpx;
}
.ico {
width: 50rpx;
height: 50rpx;
}
.descontain {
margin-top: 30rpx;
background: #f8f8f8;
border-radius: 15rpx;
width: 100%;
padding: 14rpx 24rpx 24rpx 24rpx;
box-sizing: border-box;
}
.destext {
padding-top: 10rpx;
font-size: 29rpx;
line-height: 44rpx;
color: #a7adb8;
letter-spacing: 1rpx;
}
.contains {
width: 100%;
padding-bottom: 30rpx;
border-bottom: 1rpx solid #f8f8f8;
}
.bottom {
left: 0rpx;
bottom: 0rpx;
right: 0rpx;
position: fixed;
align-items: center;
display: flex;
width: 100%;
height: 100rpx;
box-shadow: 0 0 24rpx rgba(0, 0, 0, 0.212);
}
button {
width: 49%;
height: 100%;
background: #fff;
display: flex;
justify-content: center;
align-items: center;
border: none;
}
button::after {
border: none;
}
.btxt {
padding-left: 20rpx;
font-size: 34rpx;
letter-spacing: 2rpx;
}
.center {
font-weight: 2%;
border-right: 2rpx solid #a7adb8;
height: 32rpx;
}
================================================
FILE: miniprogram/pages/index/index.js
================================================
const app = getApp()
const db = wx.cloud.database();
const config = require("../../config.js");
const _ = db.command;
Page({
data: {
college: JSON.parse(config.data).college,
collegeCur: -2,
showList: false,
scrollTop: 0,
nomore: false,
adShow: false,
list: [],
banner: '',
indexTip: '',
openid: app.openid
},
// 用户点击右上角分享给好友,要先在分享好友这里设置menus的两个参数,才可以分享朋友圈
onShareAppMessage: function () {
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
},
//用户点击右上角分享朋友圈
onShareTimeline: function () {
return {
title: '',
query: {
key: value
},
imageUrl: ''
}
},
onLoad() {
this.listkind();
this.getbanner();
},
//监测屏幕滚动
onPageScroll: function (e) {
this.setData({
scrollTop: parseInt((e.scrollTop) * wx.getSystemInfoSync().pixelRatio)
})
},
//获取上次布局记忆
listkind() {
let that = this;
wx.getStorage({
key: 'iscard',
success: function (res) {
that.setData({
iscard: res.data
})
},
fail() {
that.setData({
iscard: true,
})
}
})
},
//布局方式选择
changeCard() {
let that = this;
if (that.data.iscard) {
that.setData({
iscard: false
})
wx.setStorage({
key: 'iscard',
data: false,
})
} else {
that.setData({
iscard: true
})
wx.setStorage({
key: 'iscard',
data: true,
})
}
},
//跳转搜索
search() {
wx.navigateTo({
url: '/pages/search/search',
})
},
//类别选择
collegeSelect(e) {
this.setData({
collegeCur: e.currentTarget.dataset.id - 1,
scrollLeft: (e.currentTarget.dataset.id - 3) * 100,
showList: false,
})
this.getList();
},
//选择全部
selectAll() {
this.setData({
collegeCur: -2,
scrollLeft: -200,
showList: false,
})
this.getList();
},
//展示列表小面板
showlist() {
let that = this;
if (that.data.showList) {
that.setData({
showList: false,
})
} else {
that.setData({
showList: true,
})
}
},
getList() {
console.log("调用了getlist")
let that = this;
if (that.data.collegeCur == -2) {
var collegeid = _.neq(-2); //除-2之外所有
} else {
var collegeid = that.data.collegeCur + '' //小程序搜索必须对应格式
}
db.collection('publish').where({
status: 0,
dura: _.gt(new Date().getTime()),
collegeid: collegeid
}).orderBy('creat', 'desc').limit(20).get({
success: function (res) {
wx.stopPullDownRefresh(); //暂停刷新动作
if (res.data.length == 0) {
that.setData({
nomore: true,
list: [],
})
return false;
}
if (res.data.length < 20) {
that.setData({
nomore: true,
page: 0,
list: res.data,
})
} else {
that.setData({
page: 0,
list: res.data,
nomore: false,
})
}
}
})
},
more() {
let that = this;
if (that.data.nomore || that.data.list.length < 20) {
return false
}
let page = that.data.page + 1;
if (that.data.collegeCur == -2) {
var collegeid = _.neq(-2); //除-2之外所有
} else {
var collegeid = that.data.collegeCur + '' //小程序搜索必须对应格式
}
db.collection('publish').where({
status: 0,
dura: _.gt(new Date().getTime()),
collegeid: collegeid
}).orderBy('creat', 'desc').skip(page * 20).limit(20).get({
success: function (res) {
if (res.data.length == 0) {
that.setData({
nomore: true
})
return false;
}
if (res.data.length < 20) {
that.setData({
nomore: true
})
}
that.setData({
page: page,
list: that.data.list.concat(res.data)
})
},
fail() {
wx.showToast({
title: '获取失败',
icon: 'none'
})
}
})
},
onReachBottom() {
this.more();
},
//下拉刷新
onPullDownRefresh() {
this.getList();
},
gotop() {
wx.pageScrollTo({
scrollTop: 0
})
},
//跳转详情
detail(e) {
let that = this;
wx.navigateTo({
url: '/pages/detail/detail?scene=' + e.currentTarget.dataset.id,
})
},
//获取轮播
getbanner() {
let that = this;
db.collection('banner').where({}).get({
success: function (res) {
that.setData({
banner: res.data[0].list
})
}
})
},
//跳转轮播链接
goweb(e) {
console.log(e.currentTarget.dataset.web.url)
wx.navigateTo({
url: '/pages/web/web?url=' + e.currentTarget.dataset.web.url,
})
},
onShareAppMessage() {
return {
title: JSON.parse(config.data).share_title,
imageUrl: JSON.parse(config.data).share_img,
path: '/pages/start/start'
}
},
onShow() {
this.getList(),
this.getTip()
},
getTip() {
let that = this
db.collection('Tip').where({}).get({
success: function (res) {
that.setData({
indexTip: res.data[0].tip
})
console.log("zhelishixiaoxi" + res)
},
})
},
})
================================================
FILE: miniprogram/pages/index/index.json
================================================
{
"enablePullDownRefresh": true
}
================================================
FILE: miniprogram/pages/index/index.wxml
================================================
搜索想要的物品,例如:杯子
全部
{{item.name}}
{{item.name}}
{{item.bookinfo.good}}
¥{{item.price}}元
{{item.bookinfo.good}}
¥{{item.price}}元
{{morejs.timelog(item.creat )}}发布
这里空空如也~
================================================
FILE: miniprogram/pages/index/index.wxss
================================================
.top_box {
width: 100%;
background: #fbbd08;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 30rpx;
box-sizing: border-box;
}
.top_list {
width: 50rpx;
height: 50rpx;
}
.search_box {
width: 620rpx;
height: 66rpx;
border-radius: 33rpx;
background: #fff;
display: flex;
align-items: center;
}
.search_ico {
padding-left: 30rpx;
width: 32rpx;
height: 32rpx;
}
.search_text {
padding-left: 10rpx;
font-size: 28rpx;
letter-spacing: 2rpx;
color: rgb(167, 167, 167);
}
.banner {
width: 100%;
display: flex;
box-sizing: border-box;
height: 240rpx;
}
/*
.banner_image {
width: auto;
display: flex;
box-sizing: border-box;
height: 240rpx;
} */
.banner_image {
width: 100%;
padding: 16rpx 16rpx 12rpx 16rpx;
display: flex;
box-sizing: border-box;
height: inherit;
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
.space {
width: 100%;
height: 15rpx;
background: #eee;
}
.kind_contain {
width: 100%;
height: 90rpx;
display: flex;
border-bottom: 1rpx solid #eee;
background: #fff;
align-items: center;
position: relative;
}
.nav {
width: calc(100% - 180rpx);
height: 100%;
white-space: nowrap;
display: flex;
box-sizing: border-box;
}
.nav-item {
width: 140rpx;
height: 100%;
display: inline-block;
font-size: 32rpx;
}
.nav-text {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
letter-spacing: 4rpx;
box-sizing: border-box;
}
.tab-on {
color: #fbbd08;
font-size: 32rpx !important;
font-weight: 600;
border-bottom: 4rpx solid #70f3ff !important;
}
.kind_img {
width: 60rpx;
height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
}
.kind_img image {
width: 32rpx;
height: 32rpx;
}
.kindlist_box {
position: absolute;
width: 100%;
top: 90rpx;
left: 0rpx;
border-bottom: 1rpx solid #eee;
}
.kindlist_card {
padding: 20rpx 20rpx 0 20rpx;
width: 100%;
display: flex;
box-sizing: border-box;
background: #fff;
}
.list_grid {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.list_one {
width: 25%;
padding: 0 10rpx 20rpx 10rpx;
display: flex;
box-sizing: border-box;
}
.list_one view {
width: 100%;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
border: 1rpx solid #eee;
border-radius: 10rpx;
font-size: 28rpx;
letter-spacing: 2rpx;
}
.list-on {
background: #fbbd08;
color: #fff;
border: none !important;
}
.card_grid {
width: 100%;
display: flex;
box-sizing: border-box;
padding: 20rpx 0rpx;
flex-wrap: wrap;
}
.card_one {
margin-top: 20rpx;
width: 50%;
padding: 20rpx;
display: flex;
box-sizing: border-box;
flex-direction: column;
align-items: center;
}
.card_poster {
width: 260rpx;
height: 260rpx;
}
.card_title {
width: 100%;
font-size: 30rpx;
letter-spacing: 3rpx;
margin-top: 20rpx;
line-height: 45rpx;
}
.card_author {
width: 100%;
font-size: 26rpx;
letter-spacing: 3rpx;
line-height: 40rpx;
color: rgb(129, 129, 129);
}
.card_between {
margin-top: 5rpx;
width: 100%;
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.card_price {
font-size: 33rpx;
color: rgb(255, 0, 0);
}
.card_buy {
padding-right: 10rpx;
width: 40rpx;
height: 40rpx;
}
.list_box {
width: 100%;
display: flex;
align-items: center;
padding: 20rpx;
box-sizing: border-box;
margin-top: 10rpx;
}
.list_poster {
width: 230rpx;
height: 230rpx;
}
.list_content {
height: 230rpx;
width: calc(100% - 230rpx);
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 0 10rpx;
box-sizing: border-box;
}
.list_word {
display: flex;
flex-direction: column;
width: 100%;
box-sizing: border-box;
}
.list_title {
width: 100%;
font-size: 32rpx;
letter-spacing: 3rpx;
line-height: 45rpx;
}
.list_author {
padding-top: 10rpx;
width: 100%;
font-size: 27rpx;
letter-spacing: 3rpx;
line-height: 40rpx;
color: rgb(129, 129, 129);
}
.list_between {
width: 100%;
display: flex;
justify-content: space-between;
align-items: flex-end;
border-bottom: 1rpx solid #eee;
padding-bottom: 10rpx;
}
.list_price {
font-size: 36rpx;
color: rgb(255, 0, 0);
}
.list_time {
font-size: 28rpx;
letter-spacing: 2rpx;
color: rgb(129, 129, 129);
}
.nocontent {
width: 100%;
height: calc(100% - 400rpx);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
box-sizing: border-box;
}
.nocontent image {
padding-left: 80rpx;
width: 340rpx;
height: 272rpx;
}
.blank_text {
padding-top: 40rpx;
font-size: 32rpx;
letter-spacing: 2rpx;
color: #c6c6c8;
}
.fixed {
position: fixed;
left: 0rpx;
top: 0rpx;
}
.nofixed {
height: 91rpx;
width: 100%;
background: #fff;
}
================================================
FILE: miniprogram/pages/kefu/kefu.js
================================================
var app = getApp();
const config = require("../../config.js");
Page({
/**
* 页面的初始数据
*/
data: {
weixin: JSON.parse(config.data).kefu.weixin,
qq: JSON.parse(config.data).kefu.qq,
gzh: JSON.parse(config.data).kefu.gzh,
phone: JSON.parse(config.data).kefu.phone,
banner: "/images/kefu.jpg",
img:['https://7461-taoshaoji-46f0r-1302243411.tcb.qcloud.la/gzh/%E6%89%AB%E7%A0%81_%E6%90%9C%E7%B4%A2%E8%81%94%E5%90%88%E4%BC%A0%E6%92%AD%E6%A0%B7%E5%BC%8F-%E7%99%BD%E8%89%B2%E7%89%88.png?sign=4419b51be1d0c768dbbc95273f956fec&t=1597217797',]
},
onLoad() {
},
//复制
copy(e) {
wx.setClipboardData({
data: e.currentTarget.dataset.copy,
success: res => {
wx.showToast({
title: '复制' + e.currentTarget.dataset.name+'成功',
icon: 'success',
duration: 1000,
})
}
})
},
//预览图片
preview(e) {
wx.previewImage({
current: 'current', // 当前显示图片的http链接
urls:this.data.img// 需要预览的图片http链接列表
})
},
})
================================================
FILE: miniprogram/pages/kefu/kefu.json
================================================
{
"navigationBarTitleText": "联系客服",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
================================================
FILE: miniprogram/pages/kefu/kefu.wxml
================================================
在线咨询
点击即可在线咨询客服
官方微信
点击即可复制官方微信
QQ联系
点击即可复制QQ群
官方公众号
识别二维码关注官方公众号
================================================
FILE: miniprogram/pages/kefu/kefu.wxss
================================================
.contain{
width: 100%;
padding: 0 46rpx;
box-sizing: border-box;
}
.slide-image{
width: 100%;
height: 310rpx;
border-radius: 20rpx;
}
.card{
margin-top: 40rpx;
border-radius: 20rpx;
width: 100%;
height: 162rpx;
box-sizing: border-box;
box-shadow: 0 0 20rpx #eee;
display: flex;
position: relative;
}
.card button{
width: 100%;
height: 100%;
position: absolute;
left: 0rpx;
top: 0rpx;
opacity: 0.01;
}
.card1{
width: 140rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.wechatimg{
width: 90rpx;
height:90rpx;
}
.borderbox{
width: 10rpx;
height: 100%;
display: flex;
align-items: center;
}
.border{
width: 4rpx;
height: 82rpx;
border-left: 3rpx solid #eee;
box-sizing: border-box;
}
.centercontain{
width: 420rpx;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 20rpx;
}
.name{
font-size: 32rpx;
font-weight: 600;
letter-spacing: 2rpx;
}
.des{
padding-top: 10rpx;
font-size: 28rpx;
color: rgb(161, 161, 161);
letter-spacing: 2rpx;
}
.rightico{
width: 40rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.rightimg{
width: 30rpx;
height: 30rpx;
}
================================================
FILE: miniprogram/pages/login/login.js
================================================
const db = wx.cloud.database();
const app = getApp();
const config = require("../../config.js");
Page({
/**
* 页面的初始数据
*/
data: {
ids: -1,
wxnum: '',
qqnum: '',
email: '',
checked:false,
campus: JSON.parse(config.data).campus,
},
onChange(event) {
if(event.detail==true){
wx.requestSubscribeMessage({
tmplIds: ['6DGzsKqipoPxClnbkvwnxY9GqdXoLordLRdWTjJN1F0','XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q'], //这里填入我们生成的模板id
success(res) {
console.log('授权成功', res)
},
fail(res) {
console.log('授权失败', res)
}
})
}
this.setData({
checked: event.detail,
});
},
choose(e) {
let that = this;
that.setData({
ids: e.detail.value
})
//下面这种办法无法修改页面数据
/* this.data.ids = e.detail.value;*/
},
wxInput(e) {
this.data.wxnum = e.detail.value;
},
qqInput(e) {
this.data.qqnum = e.detail.value;
},
emInput(e) {
this.data.email = e.detail.value;
},
getUserInfo(e) {
let that = this;
console.log(e);
let test = e.detail.errMsg.indexOf("ok");
if (test == '-1') {
wx.showToast({
title: '请授权后方可使用',
icon: 'none',
duration: 2000
});
} else {
that.setData({
userInfo: e.detail.userInfo
})
that.check();
}
},
//校检
check() {
let that = this;
//校检校区
let ids = that.data.ids;
let campus = that.data.campus;
if (ids == -1) {
wx.showToast({
title: '请先获取您的园区',
icon: 'none',
duration: 2000
});
}
// 检验授权选项
let event =that.data.checked;
if(event==false){
wx.showToast({
title: '请授权订单提醒',
icon: 'none',
duration: 2000
});
return false;
}
//校检邮箱
let email = that.data.email;
if (!(/^\w+((.\w+)|(-\w+))@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+).[A-Za-z0-9]+$/.test(email))) {
wx.showToast({
title: '请输入常用邮箱',
icon: 'none',
duration: 2000
});
return false;
}
//校检QQ号
let qqnum = that.data.qqnum;
if (qqnum !== '') {
if (!(/^\s*[.0-9]{5,11}\s*$/.test(qqnum))) {
wx.showToast({
title: '请输入正确QQ号',
icon: 'none',
duration: 2000
});
return false;
}
}
//校检微信号
let wxnum = that.data.wxnum;
if (wxnum !== '') {
if (!(/^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$/.test(wxnum))) {
wx.showToast({
title: '请输入正确微信号',
icon: 'none',
duration: 2000
});
return false;
}
}
wx.showLoading({
title: '正在提交',
})
db.collection('user').add({
data: {
phone: that.data.phone,
campus: that.data.campus[that.data.ids],
qqnum: that.data.qqnum,
email: that.data.email,
wxnum: that.data.wxnum,
stamp: new Date().getTime(),
info: that.data.userInfo,
useful: true,
parse: 0,
},
success: function(res) {
console.log(res)
db.collection('user').doc(res._id).get({
success: function(res) {
app.userinfo = res.data;
app.openid = res.data._openid;
wx.navigateBack({})
},
})
},
fail() {
wx.hideLoading();
wx.showToast({
title: '注册失败,请重新提交',
icon: 'none',
})
}
})
},
//获取授权的点击事件
shouquan() {
wx.requestSubscribeMessage({
tmplIds: ['6DGzsKqipoPxClnbkvwnxY9GqdXoLordLRdWTjJN1F0','XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q'], //这里填入我们生成的模板id
success(res) {
console.log('授权成功', res)
},
fail(res) {
console.log('授权失败', res)
}
})
},
})
================================================
FILE: miniprogram/pages/login/login.json
================================================
{
"navigationStyle":"custom"
}
================================================
FILE: miniprogram/pages/login/login.wxml
================================================
登记注册
当前选择:{{campus[ids].name}}
请选择您所在园区
授权接收订单消息通知
注册并登录
使用申明
1. 请确保微信号、qq号和邮箱百分百有效,之后将用于发送实时订单通知。
2. 在未经您同意及确认之前,本程序不会将您的注册信息用于任何其它商业目的。
3. 本程序将对您所提供的资料进行严格的管理及保护,本程序将使用相应的技术,防止您的个人资料丢失、被盗用或遭篡改。
4. 请您放心使用!
================================================
FILE: miniprogram/pages/login/login.wxss
================================================
.top-bg {
position: absolute;
top: 0rpx;
left: 0rpx;
width: 100%;
height: 460rpx;
background-repeat: no-repeat;
background-size: 100%;
}
.contain {
position: absolute;
top: 176rpx;
left: 0rpx;
width: 100%;
padding: 0rpx 40rpx 0rpx 40rpx;
box-sizing: border-box;
}
.card {
border-radius: 32rpx;
width: 100%;
background: #fff;
padding: 50rpx 60rpx;
box-sizing: border-box;
box-shadow: 0 0 20rpx #eee;
}
.title {
width: 100%;
text-align: center;
font-size: 40rpx;
font-weight: 600;
letter-spacing: 6rpx;
}
.phone {
justify-content: space-between;
margin-top: 45rpx;
width: 100%;
height: 92rpx;
background: #f1f3f8;
border-radius: 10rpx;
text-align: left;
padding: 0 20rpx 0 36rpx;
box-sizing: border-box;
font-size: 32rpx;
display: flex;
align-items: center;
color: #8c9aa8;
border: none;
}
.phone::after {
border: none;
}
.campus {
margin-top: 24rpx;
width: 100%;
height: 92rpx;
background: #f1f3f8;
border-radius: 10rpx;
text-align: left;
padding: 0 20rpx 0 36rpx;
box-sizing: border-box;
font-size: 32rpx;
display: flex;
align-items: center;
justify-content: space-between;
color: #8c9aa8;
}
.right {
width: 30rpx;
height: 30rpx;
}
.contact {
margin-top: 24rpx;
width: 100%;
height: 92rpx;
background: #f1f3f8;
border-radius: 10rpx;
text-align: left;
padding: 0 36rpx;
box-sizing: border-box;
font-size: 32rpx;
display: flex;
align-items: center;
justify-content: space-between;
color: #8c9aa8;
}
.contact input {
width: 100%;
height: 100%;
}
.pache {
font-size: 32rpx;
color: #8c9aa8;
}
.confirm {
margin-top: 50rpx;
width: 100%;
height: 100rpx;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(120deg, #e0c3fc 0%, #8ec5fc 100%);
border-radius: 60rpx;
color: #fff;
font-size: 40rpx;
letter-spacing: 4rpx;
box-shadow: 0 0 20rpx #eee;
border: none;
}
.confirm::after {
border: none;
}
.shen_title{
margin-top: 40rpx;
font-size: 32rpx;
letter-spacing: 2rpx;
display: flex;
justify-content: flex-start;
align-items: center;
}
.about{
width: 32rpx;
height: 32rpx;
padding-right: 10rpx;
}
.des{
padding-left: 30rpx;
padding-top: 20rpx;
font-size: 26rpx;
color: #acacac;
letter-spacing: 2rpx;
line-height: 42rpx;
}
.top-bg {
position: absolute;
top: 0rpx;
left: 0rpx;
width: 100%;
height: 460rpx;
background: #fbbd08;
background-repeat: no-repeat;
background-size: 100%;
}
================================================
FILE: miniprogram/pages/message/message.js
================================================
const app = getApp()
var time = require('../../utils/util.js');
const db = wx.cloud.database();
Page({
data: {
roomlist: [],
openid: '',
myNickName: '',
},
onLoad: function (_options) {
wx.stopPullDownRefresh({
success: (res) => {
console.log(res)
},
})
this.init_charList()
this.setData({
openid: app.openid,
roomlist: app.roomlist
})
if (!app.openid) {
wx.showModal({
title: '温馨提示',
content: '该功能需要注册方可使用,是否马上去注册',
success(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login',
})
}
}
})
return false
}
console.log("输出列表用户信息")
wx.cloud.init({
env: 'taoshaoji-46f0r',
traceUser: true
});
//初始化数据库
const db = wx.cloud.database();
var list = this.data.roomlist;
var that = this;
console.log(list);
for (var i = 0; i < list.length; i++) {
(function (i) {
db.collection('user').where({
_openid: list[i].openid
}).get().then(res => {
console.log(res.data[0]);
list[i].image = res.data[0].info.avatarUrl;
list[i].name = res.data[0].info.nickName;
//list[i].name = res.data[0]._id;
that.setData({
roomlist: list
})
console.log(list);
})
})(i);
}
},
/*
页面初始化
*/
init_charList() {
var myid = this.data.openid;
var list = []
wx.cloud.init({
env: 'taoshaoji-46f0r',
traceUser: true
});
//初始化数据库
const db = wx.cloud.database();
console.log("enter A");
db.collection('rooms').where({
p_s: myid,
deleted: 0
}).get().then(res => {
console.log(res.data);
console.log("1111111111111111111");
if (res.data.length > 0) {
for (var i = 0; i < res.data.length; i++) {
var dia = new Object();
dia.roomid = res.data[i]._id;
dia.openid = res.data[i].p_b;
dia.time = "";
dia.cha = "买家:";
dia.name = "";
dia.image = "";
list.push(dia);
console.log(list);
console.log("list111111111111");
}
app.roomlist = list;
}
})
db.collection('rooms').where({
p_b: myid,
deleted: 0
}).get().then(res => {
console.log(res.data);
if (res.data.length > 0) {
for (var i = 0; i < res.data.length; i++) {
var dia = new Object();
dia.roomid = res.data[i]._id;
dia.openid = res.data[i].p_s;
dia.time = "";
dia.cha = "卖家:";
dia.name = "";
dia.image = "";
list.push(dia);
}
app.roomlist = list;
}
})
},
/**
* 删除按钮事件
*/
slideButtonTap(e) {
var that = this
console.log('slide button tap', e)
wx.showModal({
title: '提示',
content: '是否确认删除',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '删除中..',
})
console.log('用户点击确定')
wx.cloud.callFunction({
name: 'removeChat',
data: {
id: e.currentTarget.dataset.delid
},
success: res => {
console.log('[云函数] [removeChat] 调用成功: ', res)
wx.showToast({
title: '删除成功',
})
wx.startPullDownRefresh()
},
fail: err => {
console.error('[云函数] [removeChat] 调用失败', err)
}
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
},
findtime() {
console.log("111111111111111111111111111");
wx.cloud.init({
env: 'taoshaoji-46f0r',
traceUser: true
});
//初始化数据库
const db = wx.cloud.database();
var list = this.data.roomlist;
var that = this;
console.log(list);
for (var i = 0; i < list.length; i++) {
(function (i) {
db.collection('chatroom').where({
groupId: list[i].roomid,
deleted: 0
}).get().then(res => {
console.log("输出聊天数据" + res.data.length);
console.log(res.data);
// list[i].time = time.formatTime(res.data[res.data.length - 1].sendTime);
list[i].time = res.data[res.data.length - 1].sendTimeTS;
that.setData({
roomlist: list
})
console.log(list);
})
})(i);
}
},
timesort() {
this.data.roomlist.sort(function (a, b) {
if (a.time > b.time) {
console.log("");
return -1;
} else if (a.time == b.time) {
console.log("不变变");
return 0;
} else {
console.log("我也不变变");
return 1;
}
});
var test1 = setTimeout(this.changetime, "1000");
},
changetime() {
var list = this.data.roomlist
for (var i = 0; i < list.length; i++) {
console.log("改格式" + time.formatTime(list[i].time, 'Y/M/D h:m:s'));
list[i].time = time.formatTime(list[i].time, 'Y/M/D h:m:s');
}
this.setData({
roomlist: list
})
},
go(e) {
wx.navigateTo({
url: '../detail/room/room?id=' + e.currentTarget.dataset.id,
})
},
onShow() {
this.init_charList()
},
//下拉刷新
onPullDownRefresh() {
this.onLoad();
},
getMyNickName() {
console.log("调用了getMyNickName")
let that = this;
var myopenid = app.openid
db.collection('user').where({
_openid: myopenid
}).get().then(res => {
that.setData({
myNickName: res.data[0]
})
console.log("res.data.info.nickName:" + res.data[0])
})
},
sendTip(e) {
let that = this;
that.onChange()
that.getMyNickName()
wx.showModal({
title: '温馨提示',
content: '您确定要发送消息通知提醒对方和你聊天吗?',
success(res) {
if (res.confirm) {
wx.cloud.callFunction({
name: "sendTip",
data: {
openid: e.currentTarget.dataset.opid,
nickName: that.data.myNickName.info.nickName,
tip: "快去消息中心看看吧!"
}
}).then(res => {
wx.showToast({
title: '提醒成功',
icon: 'success',
duration: 2000
})
console.log("推送消息成功", res)
console.log(e.currentTarget.dataset.id)
}).catch(res => {
console.log("推送消息失败", res)
})
}
}
})
},
onChange() {
wx.requestSubscribeMessage({
tmplIds: ['XXmEjf37meLWQaEsOX6qkkufcVH-YKAL3cHyY9Lru0Q'], //这里填入我们生成的模板id
success(res) {
console.log('授权成功', res)
},
fail(res) {
console.log('授权失败', res)
}
})
},
})
================================================
FILE: miniprogram/pages/message/message.json
================================================
{
"usingComponents": { },
"navigationBarTitleText": "消息中心",
"enablePullDownRefresh": true
}
================================================
FILE: miniprogram/pages/message/message.wxml
================================================
{{item.cha}}{{item.name}}
{{list[i].time}}
拍一拍
删除
================================================
FILE: miniprogram/pages/message/message.wxss
================================================
.list {
box-sizing: border-box;
width: 100%;
padding: 30rpx;
}
.item {
display: flex;
flex-wrap: nowrap;
justify-content: center;
box-sizing: border-box;
margin-bottom: 35rpx;
width: 100%;
height: 160rpx;
border-radius: 20rpx;
box-shadow: 0rpx 0rpx 10rpx rgba(0, 0, 0, 0.2);
overflow: hidden;
}
.left {
height: 100%;
width: 220rpx;
}
.left image {
width: 100%;
height: 100%;
}
.middle {
padding: 20rpx 0;
display: flex;
justify-content: center;
flex-wrap: wrap;
margin-left: 20rpx;
flex: 3;
}
.middle view {
margin: 5rpx 0;
}
.title {
font-size: 30rpx;
font-weight: 600;
width: 100%;
}
.date {
width: 100%;
color: #bbb;
font-size: 24rpx;
}
.desc {
width: 100%;
color: #000;
font-size: 24rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.right {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
}
button.btn {
padding: 0;
margin-right: 30rpx;
width: 100rpx;
height: 55rpx;
line-height: 55rpx;
text-align: center;
font-size: 24rpx;
font-weight: 600;
background-color: #fdb92c;
border-radius: 6rpx;
}
button.btn::after {
border: none;
}
================================================
FILE: miniprogram/pages/my/my.js
================================================
const app = getApp();
const config = require("../../config.js");
Page({
/**
* 页面的初始数据
*/
data: {
showShare: false,
poster: JSON.parse(config.data).share_poster,
username: '',
openid: '',
roomlist: []
},
onShow() {
this.setData({
userinfo: app.userinfo
})
},
onLoad: function (options) {
this.setData({
openid: app.openid
})
},
goo() {
console.log(app.roomlist);
if (!app.openid) {
wx.showModal({
title: '温馨提示',
content: '该功能需要注册方可使用,是否马上去注册',
success(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login',
})
}
}
})
return false
}else{
wx.navigateTo({
url: '../message/message',
})
}
},
go(e) {
if (e.currentTarget.dataset.status == '1') {
if (!app.openid) {
wx.showModal({
title: '温馨提示',
content: '该功能需要注册方可使用,是否马上去注册',
success(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login',
})
}
}
})
return false
}
}
wx.navigateTo({
url: e.currentTarget.dataset.go
})
},
//展示分享弹窗
showShare() {
this.setData({
showShare: true
});
},
//关闭弹窗
closePop() {
this.setData({
showShare: false,
});
},
//预览图片
preview(e) {
wx.previewImage({
urls: e.currentTarget.dataset.link.split(",")
});
},
onShareAppMessage() {
return {
title: JSON.parse(config.data).share_title,
imageUrl: JSON.parse(config.data).share_img,
path: '/pages/start/start'
}
},
// 用户点击右上角分享给好友,要先在分享好友这里设置menus的两个参数,才可以分享朋友圈
onShareAppMessage: function() {
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
},
//用户点击右上角分享朋友圈
onShareTimeline: function () {
return {
title: '',
query: {
key: value
},
imageUrl: ''
}
},
//获取授权的点击事件
shouquan() {
wx.requestSubscribeMessage({
tmplIds: ['6DGzsKqipoPxClnbkvwnxY9GqdXoLordLRdWTjJN1F0'], //这里填入我们生成的模板id
success(res) {
console.log('授权成功', res)
},
fail(res) {
console.log('授权失败', res)
}
})
},
})
================================================
FILE: miniprogram/pages/my/my.json
================================================
{
"navigationBarBackgroundColor": "#ffffff"
}
================================================
FILE: miniprogram/pages/my/my.wxml
================================================
点击登录
一秒登录,体验所有功能
点击修改资料
我的发布
我的购买
消息中心
上传赞赏码
使用说明
关于程序
联系客服
问题反馈
用户使用手册
================================================
FILE: miniprogram/pages/my/my.wxss
================================================
.top_box {
width: 100%;
padding: 0 30rpx 30rpx 30rpx;
display: flex;
box-sizing: border-box;
border-bottom: 1rpx solid #eee;
}
.top_1 {
display: flex;
flex-direction: column;
width: 70%;
justify-content: space-between;
height: 140rpx;
box-sizing: border-box;
padding: 10rpx 20rpx;
}
.top_1_1 {
font-size: 42rpx;
letter-spacing: 2rpx;
}
.top_1_2 {
font-size: 34rpx;
color: #919191;
line-height: 42rpx;
}
.top_2 {
width: 30%;
height: 140rpx;
display: flex;
justify-content: center;
align-items: center;
}
.avator {
width: 140rpx;
height: 140rpx;
border-radius: 70rpx;
overflow: hidden;
}
.avator image {
width: 140rpx;
height: 140rpx;
}
.center_box {
width: 100%;
padding: 20rpx 0;
height: 200rpx;
display: flex;
align-items: center;
justify-content: space-around;
box-sizing: border-box;
}
.center_1 {
width: 160rpx;
height: 160rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.center_1 view {
font-size: 26rpx;
padding-top: 20rpx;
}
.center_1 image {
width: 60rpx;
height: 60rpx;
}
.blank {
width: 100%;
height: 20rpx;
background: #f4f4f4;
}
.bottom_box {
width: 100%;
display: flex;
box-sizing: border-box;
padding: 0 40rpx;
flex-direction: column;
}
.bottom_card {
position: relative;
width: 100%;
height: 124rpx;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1rpx solid #eee;
background: #fff;
}
.bottom_card button{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
opacity: 0.01;
}
.bottom_card image {
width: 14rpx;
height: 25rpx;
}
.bottom_1 {
display: flex;
height: 100%;
align-items: center;
}
.bottom_1 image {
width: 40rpx;
height: 40rpx;
}
.bottom_1 view {
font-size: 30rpx;
letter-spacing: 3rpx;
padding-left: 30rpx;
}
.share_contain {
display: flex;
flex-direction: column;
align-items: center;
}
.share_box {
display: flex;
align-items: center;
padding: 10rpx 20rpx 25rpx 20rpx;
box-sizing: border-box;
width: 500rpx;
justify-content: space-around;
}
.share_one {
display: flex;
position: relative;
flex-direction: column;
align-items: center;
}
.share_one image {
width: 70rpx;
height: 70rpx;
}
.share_one view {
padding-top: 20rpx;
font-size: 26rpx;
}
.share_title {
font-size: 30rpx;
letter-spacing: 3rpx;
padding: 16rpx;
}
.share_border {
margin-top: 20rpx;
display: flex;
box-sizing: border-box;
height: 6rpx;
width: 60rpx;
border-radius: 3rpx;
border-bottom:6rpx solid #fbbd08;
}
.share_button {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.01;
border: none;
}
.share_button::after {
border: none;
}
.share_bor {
height: 60rpx;
width: 1rpx;
border-left: 1rpx solid #e7e7e7;
}
================================================
FILE: miniprogram/pages/order/detail/detail.js
================================================
const app = getApp()
const db = wx.cloud.database();
const config = require("../../../config.js");
const _ = db.command;
Page({
/**
* 页面的初始数据
*/
data: {
userinfo: [],
creatTime: '',
detail: [],
status: Number,
openid: app.openid,
appreciateCode: '',
address:'',
buyerInfo:[]
},
onLoad: function (e) {
if (app.openid) {
this.setData({
openid: app.openid
})
} else {
console.log("no openid");
wx.showModal({
title: '温馨提示',
content: '该功能需要注册方可使用,是否马上去注册',
success(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login',
})
}
}
})
return false
}
this.getdetail(e.id);
},
//回到首页
home() {
wx.switchTab({
url: '/pages/index/index',
})
},
//获取订单详情
getdetail(_id) {
let that = this;
db.collection('order').doc(_id).get({
success(e) {
that.setData({
creatTime: config.formTime(e.data.creat),
detail: e.data
})
that.getSeller(e.data.seller);
},
fail() {
wx.showToast({
title: '获取失败,请稍后到订单中心内查看',
icon: 'none'
})
}
})
},
//获取卖家信息
getSeller(m) {
let that = this;
db.collection('user').where({
_openid: m
}).get({
success: function (res) {
wx.hideLoading();
that.setData({
userinfo: res.data[0]
})
}
})
db.collection('appreciatecode').where({
_openid: m
}).get({
success: function (res) {
wx.hideLoading();
that.setData({
appreciateCode: res.data[0].bigImg
})
console.log(res.data[0].bigImg)
}
})
},
/**
* 获取地址
*/
getAddress() {
let that = this;
if (that.data.detail.deliveryid == 0) {
that.setData({
address: that.data.detail.ztplace
})
} else {
that.setData({
address: that.data.detail.psplace
})
}
},
getBuyerInfo(){
db.collection('user').where({
_openid:app.openid
}).get().then(res => {
this.setData({
buyerInfo:res.data[0].info
})
})
},
//发送模板消息到指定用户,推送之前要先获取用户的openid
send() {
let that = this;
wx.cloud.callFunction({
name: "sendMsg",
data: {
openid: that.data.detail.seller,
status: '买家已确认收货,请确认是否收到钱款', //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;
address: that.data.address,
describe: that.data.detail.bookinfo.describe,
good: that.data.detail.bookinfo.good,
nickName: that.data.buyerInfo.nickName,
}
}).then(res => {
console.log("推送消息成功", res)
}).catch(res => {
console.log("推送消息失败", res)
})
},
//确认收货
confirm() {
let that = this;
that.getAddress()
that.getBuyerInfo()
wx.showModal({
title: '温馨提示',
content: '您确认已收货吗',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在处理',
duration:1000
})
wx.cloud.callFunction({
name: 'pay',
data: {
$url: "changeP", //云函数路由参数
_id: that.data.detail.sellid,
status: 5 //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;3、交易作废,退还买家钱款;5、等待卖家确认交易
},
success: res => {
wx.cloud.callFunction({
name: 'pay',
data: {
$url: "changeO", //云函数路由参数
_id: that.data.detail._id,
status: 5 //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;3、交易作废,退还买家钱款;5、等待卖家确认交易
},
success: res => {
wx.showToast({
title: '确认收货成功',
icon:'success',
duration:1000
})
that.send()
that.getdetail(that.data.detail.sellid)
},
fail(e) {
wx.hideLoading();
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
},
fail(e) {
wx.hideLoading();
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
}
}
})
},
//删除订单
delete() {
let that = this;
wx.showModal({
title: '温馨提示',
content: '您确认要删除此订单吗',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在处理',
})
db.collection('order').doc(that.data.detail._id).remove({
success() {
//页面栈返回
let i = getCurrentPages()
wx.navigateBack({
success: function () {
i[i.length - 2].getlist();
}
});
},
fail: console.error
})
}
}
})
},
//复制
copy(e) {
wx.setClipboardData({
data: e.currentTarget.dataset.copy,
success: res => {
wx.showToast({
title: '复制' + e.currentTarget.dataset.name + '成功',
icon: 'success',
duration: 1000,
})
}
})
},
//历史记录
history(name, num, type) {
let that = this;
db.collection('history').add({
data: {
stamp: new Date().getTime(),
type: type, //1充值2支付
name: name,
num: num,
oid: app.openid
},
success: function (res) {
console.log(res)
},
fail: console.error
})
},
goo(e) {
var myid = this.data.openid;
var sallerid = this.data.detail.seller;
wx.cloud.init({
env: 'taoshaoji-46f0r',
traceUser: true
});
//初始化数据库
const db = wx.cloud.database();
if (myid != sallerid) {
db.collection('rooms').where({
p_b: myid,
p_s: sallerid,
deleted :0
}).get().then(res => {
console.log(res.data);
if (res.data.length > 0) {
this.setData({
roomID: res.data[0]._id
})
wx.navigateTo({
url: '/pages/detail/room/room?id=' + this.data.roomID,
})
} else {
db.collection('rooms').add({
data: {
p_b: myid,
p_s: sallerid,
deleted :0
},
}).then(res => {
console.log(res)
this.setData({
roomID: res._id
})
wx.navigateTo({
url: '/pages/detail/room/room?id=' + this.data.roomID,
})
})
}
})
} else {
wx.showToast({
title: '无法和自己建立聊天',
icon: 'none',
duration: 1500
})
}
},
//图片点击事件
img: function (event) {
let arr = [];
arr.push(this.data.appreciateCode)
wx.previewImage({
current: 'current', // 当前显示图片的http链接
urls: arr // 需要预览的图片http链接列表
})
},
})
================================================
FILE: miniprogram/pages/order/detail/detail.json
================================================
{
"navigationBarTitleText": "订单详情"
}
================================================
FILE: miniprogram/pages/order/detail/detail.wxml
================================================
{{detail.bookinfo.good}}
卖家:{{userinfo.info.nickName}}
¥{{detail.price}}元
{{detail.deliveryid==0?'需要自提':'卖家帮送'}}
地址:{{detail.deliveryid==0?detail.ztplace:detail.psplace}}
{{detail.status==1?'等待收货中':(detail.status==2?'交易完成':'订单已取消')}}
{{detail.status==1?'系统已通知卖家准备':(detail.status==2?'要不再来一单':'祝您生活愉快')}}
ORDER FARE
下单时间
{{creatTime}}
支付金额
¥{{detail.price}}.00元
CONTACT SELLER
邮箱
{{userinfo.email}}
QQ
{{userinfo.qqnum}}
确认收货
等待卖家确认交易
删除订单
扫描下方二维码付款
私聊
================================================
FILE: miniprogram/pages/order/detail/detail.wxss
================================================
page {
background-image: linear-gradient(to top, #dad4ec 0%, #dad4ec 1%, #f3e7e9 100%);
}
.contain {
display: flex;
padding: 20rpx 28rpx;
width: 100%;
box-sizing: border-box;
}
.imagesize {
display: flex;
justify-content: center;
}
.imagesize image {
width: 400rpx;
height: 400rpx;
}
.card {
width: 100%;
background: #fff;
position: relative;
display: flex;
flex-direction: column;
box-sizing: border-box;
padding: 40rpx 25rpx;
}
.top_over {
width: 100%;
height: 20rpx;
position: absolute;
left: 0rpx;
top: -10rpx;
}
.bot_over {
width: 100%;
height: 20rpx;
position: absolute;
left: 0rpx;
bottom: -10rpx;
}
.goods_box {
width: 100%;
display: flex;
box-sizing: border-box;
align-items: center;
height: 100rpx;
}
.goods_img {
width: 90rpx;
height: 90rpx;
}
.goods_content {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 20rpx;
width: calc(100% - 240rpx);
height: 90%;
}
.goods_title {
font-size: 29rpx;
letter-spacing: 3rpx;
}
.goods_author {
font-size: 26rpx;
letter-spacing: 2rpx;
color: rgb(150, 150, 150);
}
.goods_price {
width: 150rpx;
height: 100%;
font-size: 32rpx;
color: #f00;
white-space: nowrap;
display: flex;
justify-content: center;
align-items: center;
}
.border {
width: 100%;
height: 20rpx;
border-bottom: 1rpx solid #eee;
}
.list {
width: 100%;
display: flex;
flex-direction: column;
padding: 30rpx 0 10rpx 0;
}
.list_1 {
font-size: 26rpx;
color: rgb(167, 167, 167);
letter-spacing: 2rpx;
}
.list_2 {
padding-top: 10rpx;
font-size: 32rpx;
letter-spacing: 3rpx;
}
.orderfare {
margin-top: 28rpx;
font-size: 22rpx;
font-weight: 600;
letter-spacing: 2rpx;
color: rgb(167, 167, 167);
padding-bottom: 20rpx;
}
.paycode {
margin-top: 28rpx;
font-size: 25rpx;
font-weight: 600;
letter-spacing: 2rpx;
color: rgb(33, 47, 104);
padding-bottom: 20rpx;
}
.fare_box {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
padding: 10rpx 0;
}
.fare_title {
font-size: 28rpx;
letter-spacing: 2rpx;
}
.fare_des {
font-size: 27rpx;
color: rgb(167, 167, 167);
}
.bot_box {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.cancel {
font-size: 30rpx;
width: 620rpx;
height: 80rpx;
background: #000;
color: #fff;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 40rpx;
letter-spacing: 4rpx;
}
.contact {
font-size: 30rpx;
width: 620rpx;
height: 80rpx;
background: #fbbd08;
color: #000;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20rpx;
letter-spacing: 4rpx;
}
.delete {
font-size: 30rpx;
width: 620rpx;
height: 80rpx;
background: #adadad;
color: #fff;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20rpx;
letter-spacing: 4rpx;
}
.contact_box {
z-index: 9;
position: fixed;
bottom: 200rpx;
right: 40rpx;
display: flex;
width: 100rpx;
flex-direction: column;
align-items: center;
background: rgba(255, 255, 255, 0.8);
padding: 20rpx 10rpx;
border-radius: 50rpx 50rpx 20rpx 20rpx;
box-shadow: 0 0 20rpx #f0f0f0 !important;
}
.contact_box image {
width: 80rpx;
height: 80rpx;
}
.contact_box view {
font-size: 26rpx;
letter-spacing: 2rpx;
margin-top: 10rpx;
}
================================================
FILE: miniprogram/pages/order/list/list.js
================================================
const app = getApp()
const db = wx.cloud.database();
const config = require("../../../config.js");
const _ = db.command;
Page({
/**
* 页面的初始数据
*/
data: {
scrollTop: 0,
nomore: false,
tab: [{
name: '全部',
id: 0,
},
{
name: '交易中',
id: 1,
},
{
name: '交易完成',
id: 2,
},
// {
// name: '已取消',
// id: 3,
// }
],
tabid: 0,
detail: [],
address: ''
},
//导航栏切换
changeTab(e) {
let that = this;
that.setData({
tabid: e.currentTarget.dataset.id
})
that.getlist();
},
//跳转详情页
godetail(e) {
let that = this;
let detail = e.currentTarget.dataset.id;
wx.navigateTo({
url: '/pages/order/detail/detail?id=' + detail,
})
},
onShow() {
this.getlist();
},
onLoad() {
wx.showLoading({
title: '加载中',
})
this.getlist();
},
//获取列表
getlist() {
let that = this;
let status = that.data.tabid;
if (status == 0) {
var statusid = _.neq(0); //除-2之外所有
} else {
var statusid = parseInt(status) //小程序搜索必须对应格式
}
db.collection('order').where({
status: statusid,
_openid: app.openid
}).orderBy('creat', 'desc').get({
success(re) {
wx.stopPullDownRefresh(); //暂停刷新动作
that.setData({
nomore: false,
page: 0,
list: re.data
})
wx.hideLoading();
}
})
},
/**
* 获取地址
*/
getAddress() {
let that = this;
if (that.data.detail.deliveryid == 0) {
that.setData({
address: that.data.detail.ztplace
})
} else {
that.setData({
address: that.data.detail.psplace
})
}
},
//取消订单(仅当订单为交易中时候,取消后卖家状态恢复)
cancel(ord) {
let that = this;
let detail = ord.currentTarget.dataset.ord;
that.setData({
detail: detail
})
that.getAddress()
wx.showModal({
title: '温馨提示',
content: '您确认要取消并删除该订单吗',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在处理',
})
wx.cloud.callFunction({
name: 'removeOrder',
data: {
_id: detail._id,
},
success: res => {
wx.showToast({
title: '取消订单成功',
icon:'success',
duration:1000
})
that.sendCancel(that.data.detail.seller)
that.onShow()
},
fail(e) {
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
//调用node函数去修改publish的状态
wx.cloud.callFunction({
// 云函数名称
name: 'node',
// 传给云函数的参数
data: {
_id: detail._id,
status: 0
},
success: function (res) {
console.log("cancel(ord)输出的" + res);
},
fail() {
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
}
}
})
console.log(that.data.detail.seller)
},
//发送模板消息到指定用户,推送之前要先获取用户的openid
sendCancel(openid) {
let that = this;
wx.cloud.callFunction({
name: "sendMsg",
data: {
openid: that.data.detail.seller,
status: '买家取消订单,已重新上架物品', //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;
address: that.data.address,
describe: that.data.detail.bookinfo.describe,
good: that.data.detail.bookinfo.good,
nickName: that.data.detail.buyerInfo.info.nickName,
}
}).then(res => {
console.log("推送消息成功", res)
}).catch(res => {
console.log("推送消息失败", res)
})
},
send() {
let that = this;
wx.cloud.callFunction({
name: "sendMsg",
data: {
openid: that.data.detail.seller,
status: '买家已确认收货,请确认是否收到钱款',
address: that.data.address,
describe: that.data.detail.bookinfo.describe,
good: that.data.detail.bookinfo.good,
nickName: that.data.detail.buyerInfo.info.nickName,
}
}).then(res => {
console.log("推送消息成功", res)
}).catch(res => {
console.log("推送消息失败", res)
})
},
//下拉刷新
onPullDownRefresh() {
this.getlist();
},
//确认收货
confirm(ord) {
let that = this;
let detail = ord.currentTarget.dataset.ord;
that.setData({
detail: detail
})
that.getAddress()
wx.showModal({
title: '温馨提示',
content: '您确认已收货吗',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在处理',
})
wx.cloud.callFunction({
// 云函数名称
name: 'node',
// 传给云函数的参数
data: {
_id: detail._id,
status: 5, //状态5为等待卖家确认交易中,也就是在确认收货后
},
success: function (res) {
wx.showToast({
title: '确认收货成功',
icon: 'success',
duration: 1000
})
that.send()
that.getlist()
console.log("调用云函数成功!")
},
fail() {
console.log("调用云函数失败!")
}
})
db.collection('order').doc(detail._id).update({
data: {
status: 5, //状态5为等待卖家确认交易中,也就是在确认收货后
},
success() {
that.getList();
},
fail() {
wx.showToast({
title: '操作失败',
icon: 'none'
})
}
})
}
}
})
},
//删除订单
delete(ord) {
let that = this;
let detail = ord.currentTarget.dataset.ord;
wx.showModal({
title: '温馨提示',
content: '您确认要删除此订单吗',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在处理',
})
db.collection('order').doc(detail._id).remove({
success() {
that.getlist();
},
fail: console.error
})
}
}
})
},
//至顶
gotop() {
wx.pageScrollTo({
scrollTop: 0
})
},
//监测屏幕滚动
onPageScroll: function (e) {
this.setData({
scrollTop: parseInt((e.scrollTop) * wx.getSystemInfoSync().pixelRatio)
})
},
onReachBottom() {
this.more();
},
//加载更多
more() {
let that = this;
if (that.data.nomore || that.data.list.length < 20) {
return false
}
let page = that.data.page + 1;
let status = that.data.tabid;
if (status == 0) {
var statusid = _.neq(0); //除-2之外所有
} else {
var statusid = parseInt(status) //小程序搜索必须对应格式
}
db.collection('order').where({
status: statusid,
_openid: app.openid
}).orderBy('creat', 'desc').skip(page * 20).limit(20).get({
success: function (res) {
if (res.data.length == 0) {
that.setData({
nomore: true
})
return false;
}
if (res.data.length < 20) {
that.setData({
nomore: true
})
}
that.setData({
page: page,
list: that.data.list.concat(res.data)
})
},
fail() {
wx.showToast({
title: '获取失败',
icon: 'none'
})
}
})
},
})
================================================
FILE: miniprogram/pages/order/list/list.json
================================================
{
"navigationBarTitleText": "我的购买",
"enablePullDownRefresh": true
}
================================================
FILE: miniprogram/pages/order/list/list.wxml
================================================
{{item.name}}
{{item.status==1||item.status==5?'交易中':(item.status== 2?'已完成':(item.status==3||item.status==4?'已取消':'待出售'))}}
{{morejs.timelog(item.creat)}}
{{item.bookinfo.good}}
¥{{item.price}}元
卖家取消交易
取消订单
确认收货
等待卖家确认交易
删除订单
这里空空如也~
================================================
FILE: miniprogram/pages/order/list/list.wxss
================================================
.tab_contain {
width: 100%;
height: 90rpx;
display: flex;
align-items: center;
box-sizing: border-box;
border-bottom: 1rpx solid #eee;
}
.tab_one {
width: 33%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.tab_one view {
height: 100%;
display: flex;
align-items: center;
font-size: 30rpx;
letter-spacing: 2rpx;
}
.tab_on {
font-size: 32rpx;
font-weight: 600;
border-bottom: 4rpx solid #fbbd08;
}
.contain {
width: 100%;
padding: 24rpx;
display: flex;
box-sizing: border-box;
flex-direction: column;
}
.card {
width: 100%;
padding: 30rpx;
display: flex;
box-sizing: border-box;
border-radius: 15rpx;
margin-bottom: 30rpx;
flex-direction: column;
}
.top {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
}
.text-red{
color: #f80202;
}
.top1 {
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
}
.date {
font-size: 28rpx;
color: #b2b2b2;
letter-spacing: 2rpx;
}
.title {
display: flex;
align-items: center;
}
.title image {
width: 36rpx;
height: 36rpx;
}
.title view {
padding-left: 10rpx;
letter-spacing: 3rpx;
font-size: 30rpx;
font-weight: 600;
}
.del {
display: flex;
align-items: center;
border: 1rpx solid #c2c2c2;
border-radius: 20rpx;
padding: 0 10rpx;
box-sizing: border-box;
height: 40rpx;
}
.del image {
width: 28rpx;
height: 28rpx;
}
.del view {
font-size: 26rpx;
color: #c2c2c2;
letter-spacing: 3rpx;
}
.center {
width: 100%;
display: flex;
align-items: center;
box-sizing: border-box;
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
}
.center image {
width: 130rpx;
height: 130rpx;
}
.content {
width: calc(100% - 130rpx);
padding: 0 20rpx;
height: 130rpx;
display: flex;
flex-direction: column;
box-sizing: border-box;
justify-content: space-between;
}
.book {
display: flex;
flex-direction: column;
width: 100%;
}
.book_name {
font-size: 30rpx;
letter-spacing: 2rpx;
}
.book_author {
padding-top: 10rpx;
font-size: 26rpx;
letter-spacing: 3rpx;
color: #c2c2c2;
}
.price {
display: flex;
justify-content: flex-end;
font-size: 32rpx;
color: #f80202;
}
.bottom {
width: 100%;
display: flex;
justify-content: flex-end;
padding: 20rpx 0 0 0;
}
.cancel {
width: 110rpx;
font-size: 26rpx;
display: flex;
justify-content: center;
align-items: center;
padding: 0 20rpx;
height: 50rpx;
border-radius: 25rpx;
color: #c2c2c2;
border: 1rpx solid #c2c2c2;
margin-left: 20rpx;
}
.confirm {
width: 110rpx;
font-size: 26rpx;
display: flex;
justify-content: center;
align-items: center;
padding: 0 20rpx;
height: 50rpx;
border-radius: 25rpx;
color: #fbbd08;
border: 1rpx solid #fbbd08;
margin-left: 20rpx;
}
.nocontent {
width: 100%;
height: calc(100% - 90rpx);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
box-sizing: border-box;
}
.nocontent image {
padding-left: 80rpx;
width: 340rpx;
height: 272rpx;
}
.blank_text {
padding-top: 40rpx;
font-size: 32rpx;
letter-spacing: 2rpx;
color: #c6c6c8;
}
================================================
FILE: miniprogram/pages/publish/publish.js
================================================
const db = wx.cloud.database();
const app = getApp();
const config = require("../../config.js");
const MAX_IMG_NUM = 8;
Page({
data: {
isExist: '',
selectPhoto: true,
systeminfo: app.systeminfo,
params: {
imgUrl: new Array(),
},
tempFilePaths: [],
entime: {
enter: 600,
leave: 300
}, //进入褪出动画时长
college: JSON.parse(config.data).college.splice(1),
steps: [{
text: '步骤一',
desc: '补充物品信息'
},
{
text: '步骤二',
desc: '发布成功',
},
],
},
//恢复初始态
initial() {
let that = this;
that.setData({
dura: 30,
price: 15,
place: '',
chooseDelivery: 0,
cids: '-1', //类别选择的默认值
show_b: true,
show_c: false,
active: 0,
chooseCollege: false,
note_counts: 0,
desc_counts: 0,
notes: '',
describe: '',
good: '',
kindid: 0,
showorhide: true,
tempFilePaths: [],
params: {
imgUrl: new Array(),
},
imgUrl: [],
kind: [{
name: '通用',
id: 0,
check: true,
}, {
name: '用途',
id: 1,
check: false
}],
delivery: [{
name: '自提',
id: 0,
check: true,
}, {
name: '帮送',
id: 1,
check: false
}],
selectPhoto:true
})
},
onLoad() {
this.initial();
this.getCodeFromSet();
},
onShow() {
},
//价格输入改变
priceChange(e) {
this.data.price = e.detail;
},
//时长才输入改变
duraChange(e) {
this.data.dura = e.detail;
},
//地址输入
placeInput(e) {
console.log(e)
this.data.place = e.detail.value
},
//物品输入
goodInput(e) {
console.log(e)
this.data.good = e.detail.value
},
//类别选择
kindChange(e) {
let that = this;
let kind = that.data.kind;
let id = e.detail.value;
for (let i = 0; i < kind.length; i++) {
kind[i].check = false
}
kind[id].check = true;
if (id == 1) {
that.setData({
kind: kind,
chooseCollege: true,
kindid: id
})
} else {
that.setData({
kind: kind,
cids: '-1',
chooseCollege: false,
kindid: id
})
}
},
//选择专业
choCollege(e) {
let that = this;
that.setData({
cids: e.detail.value
})
},
//取货方式改变
delChange(e) {
let that = this;
let delivery = that.data.delivery;
let id = e.detail.value;
for (let i = 0; i < delivery.length; i++) {
delivery[i].check = false
}
delivery[id].check = true;
if (id == 1) {
that.setData({
delivery: delivery,
chooseDelivery: 1
})
} else {
that.setData({
delivery: delivery,
chooseDelivery: 0
})
}
},
//输入备注
noteInput(e) {
let that = this;
that.setData({
note_counts: e.detail.cursor,
notes: e.detail.value,
})
},
//输入描述
describeInput(e) {
let that = this;
that.setData({
desc_counts: e.detail.cursor,
describe: e.detail.value,
})
},
//发布校检
check_pub() {
let that = this;
//如果用户选择了用途,需要选择用途类别
if (that.data.kind[1].check) {
if (that.data.cids == -1) {
wx.showToast({
title: '请选择用途',
icon: 'none',
});
return false;
}
}
//如果用户选择了自提,需要填入详细地址
if (that.data.delivery[0].check) {
if (that.data.place == '') {
wx.showToast({
title: '请输入地址',
icon: 'none',
});
return false;
}
}
that.publish();
},
//正式发布
publish() {
let that = this;
if (!app.openid) {
wx.showModal({
title: '温馨提示',
content: '该功能需要注册方可使用,是否马上去注册',
success(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login',
})
}
}
})
return false
}
if (that.data.good == '') {
wx.showToast({
title: '请输入商品名称',
icon: 'none',
});
return false;
}
if (that.data.describe == '') {
wx.showToast({
title: '请输入商品的详细描述',
icon: 'none',
});
return false;
}
if (that.data.imgUrl == '') {
wx.showToast({
title: '请选择图片',
icon: 'none',
});
return false;
}
if (that.data.notes == '') {
wx.showToast({
title: '请输入相关的备注信息(如取货时间,新旧程度等)',
icon: 'none',
});
return false;
}
wx.showModal({
title: '温馨提示',
content: '经检测您填写的信息无误,是否马上发布?',
success(res) {
if (res.confirm) {
db.collection('publish').add({
data: {
creat: new Date().getTime(),
dura: new Date().getTime() + that.data.dura * (24 * 60 * 60 * 1000),
status: 0, //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;3、交易作废,退还买家钱款
price: that.data.price, //售价
//分类
kindid: that.data.kindid, //区别通用还是用途
collegeid: that.data.cids, //学院id,-1表示通用类
deliveryid: that.data.chooseDelivery, //0自1配
place: that.data.place, //选择自提时地址
notes: that.data.notes, //备注
bookinfo: {
pic: that.data.imgUrl,
good: that.data.good,
describe: that.data.describe,
imgs: that.data.imgUrl
},
key: that.data.good,
},
success(e) {
console.log(e)
that.setData({
show_b: false,
show_c: true,
active: 2,
detail_id: e._id
});
wx.showToast({
title: '正在上传...',
icon: 'loading',
mask: true,
duration: 1000
})
setTimeout(function () {
//判断卖家是否已经上传了赞赏码
if (that.data.isExist == false) {
wx.showModal({
title: '商品发布成功',
content: '您未上传赞赏码用于交易,是否现在去上传?',
showCancel: true, //是否显示取消按钮
cancelText: "稍后再传", //默认是“取消”
cancelColor: '#fbbd08', //取消文字的颜色
success(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/appreciateCode/appreciateCode',
})
}
}
})
}
}, 2000)
that.setData({
show_b: false,
show_c: true,
active: 2,
detail_id: e._id,
});
//滚动到顶部
wx.pageScrollTo({
scrollTop: 0,
})
}
})
}
}
})
},
getCodeFromSet() {
let that = this;
let openid = app.openid
console.log(openid)
db.collection('appreciatecode').where({
_openid: openid,
}).get().then(res => {
if (res.data.length > 0) {
that.setData({
isExist: true,
bigImg: res.data[0].bigImg
})
console.log(res.data[0].bigImg)
console.log("isExist---->" + that.data.isExist)
} else {
that.setData({
isExist: false,
})
console.log("isExist---->" + that.data.isExist)
}
})
},
doUpload(filePath) {
const that = this;
// var timestamp = (new Date()).valueOf();
const cloudPath = 'goods-pic/' + app.openid + '/' + Math.floor(Math.random() * 10000 + 10000) + '.png';
wx.cloud.uploadFile({
cloudPath,
filePath
}).then(res => {
console.log('[上传文件] 成功:', res)
const {
params
} = that.data;
const {
imgUrl
} = params;
imgUrl.push(res.fileID);
params['imgUrl'] = imgUrl;
that.setData({
imgUrl,
});
}).catch(error => {
console.error('[上传文件] 失败:', error);
wx.showToast({
icon: 'none',
title: '上传失败',
duration: 1000
})
})
},
chooseImage: function () {
const that = this;
// 还能再选几张图片,初始值设置最大的数量-当前的图片的长度
let max = MAX_IMG_NUM - this.data.tempFilePaths.length;
// 选择图片
wx.chooseImage({
count: max, // count表示最多可以选择的图片张数
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFiles = res.tempFiles;
const filePath = res.tempFilePaths;
//将选择的图片上传
filePath.forEach((path, _index) => {
setTimeout(() => that.doUpload(path), _index); //加不同的延迟,避免多图上传时文件名相同
});
const {
tempFilePaths
} = that.data;
that.setData({
tempFilePaths: tempFilePaths.concat(filePath)
}, () => {
console.log(that.data.tempFilePaths)
})
// 还能再选几张图片
max = MAX_IMG_NUM - this.data.tempFilePaths.length
this.setData({
selectPhoto: max <= 0 ? false : true // 当超过8张时,加号隐藏
})
},
fail: e => {
console.error(e)
}
})
},
deletePic(e) {
console.log(e);
let index = e.currentTarget.dataset.index
let imgUrl = this.data.params.imgUrl
const {
tempFilePaths
} = this.data;
tempFilePaths.splice(index, 1);
imgUrl.splice(index, 1)
this.setData({
['params.imgUrl']: imgUrl,
tempFilePaths,
})
// 当添加的图片达到设置最大的数量时,添加按钮隐藏,不让新添加图片
if (this.data.tempFilePaths.length == MAX_IMG_NUM - 1) {
this.setData({
selectPhoto: true,
})
}
},
detail() {
let that = this;
wx.navigateTo({
url: '/pages/detail/detail?scene=' + that.data.detail_id,
})
}
})
================================================
FILE: miniprogram/pages/publish/publish.json
================================================
{
"navigationBarTitleText": "发布物品"
}
================================================
FILE: miniprogram/pages/publish/publish.wxml
================================================
{{desc_counts}}/200
价格(元)
类别
{{item.name}}
选择用途
当前选择:{{college[cids].name}}
请选择用途类别
取货方式
{{item.name}}
备注信息
※必填
{{note_counts}}/100
发布时长(天)
* 此时长内您的发布信息将会展示给所有同学,超时后您只需去个人中心处擦亮即可再次展示
马上发布
如果你喜欢我们的小程序,支持我们一下,我们才有动力做出更好的功能
恭喜您 发布成功
订单的实时状态请在我的主页查看
查看详情
再来一个
================================================
FILE: miniprogram/pages/publish/publish.wxss
================================================
page {
background: #f6f7fa;
}
.top_steps {
position: fixed;
top: 0rpx;
left: 0rpx;
width: 100%;
z-index: 9;
}
.font{
font-size: 23rpx;
color: red;
}
.a_contain {
padding: 32rpx;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
box-sizing: border-box;
background: #fff;
box-shadow: 0 30rpx 20rpx rgb(240, 240, 240);
}
.a_inp {
width: 100%;
height: 76rpx;
background: #f8fafd;
display: flex;
align-items: center;
justify-content: space-between;
overflow: hidden;
border-radius: 38rpx;
}
.a_scan {
width: 40rpx;
height: 38rpx;
padding-left: 30rpx;
}
.a_inp input {
width: 420rpx;
font-size: 28rpx;
color: #aaaaab;
height: 100%;
letter-spacing: 2rpx;
}
.a_pla {
font-size: 27rpx;
color: #aaaaab;
}
.a_confirm {
width: 170rpx;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background:#000;
border-radius: 36rpx;
color: #fff;
font-size: 28rpx;
letter-spacing: 4rpx;
}
.a_isbn {
margin-top: 40rpx;
width: 350rpx;
height: 350rpx;
}
.a_des {
margin-top: 30rpx;
font-size: 30rpx;
color: #aaaaab;
width: 450rpx;
text-align: center;
letter-spacing: 3rpx;
line-height: 50rpx;
}
.a_next {
padding-top: 20rpx;
width: 40rpx;
height: 30rpx;
}
.a_sao {
width: 100%;
padding-top: 50rpx;
display: flex;
justify-content: center;
}
.a_sao button {
width: 500rpx;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
background: #FF6666;
color: #fff;
border-radius: 40rpx;
letter-spacing: 4rpx;
font-size: 32rpx;
border: none;
font-weight: 500;
}
.a_sao button::after {
border: none;
}
/*步骤二*/
.b_contain {
padding: 32rpx;
width: 100%;
display: flex;
flex-direction: column;
box-sizing: border-box;
background: #fff;
box-shadow: 0 30rpx 20rpx rgb(240, 240, 240);
}
.b_top {
display: flex;
width: 100%;
}
.b_poster {
width: 270rpx;
display: flex;
justify-content: center;
}
.b_poster image {
width: 250rpx;
height: 250rpx;
}
.b_title {
width: 100%;
font-size: 32rpx;
line-height: 50rpx;
font-weight: 600;
letter-spacing: 2rpx;
}
.b_content {
width: 100%;
height: 250rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.b_dcontain {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 4rpx;
}
.b_author {
font-size: 28rpx;
letter-spacing: 2rpx;
color: #000;
}
.b_price {
font-size: 30rpx;
color: rgb(255, 0, 0);
letter-spacing: 2rpx;
white-space: nowrap;
}
.b_des {
font-size: 26rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
overflow: hidden;
text-overflow: ellipsis;
color: #aaaaab;
}
/*步骤二输入内容*/
.b_ccontain {
width: 100%;
padding: 32rpx;
display: flex;
box-sizing: border-box;
flex-direction: column;
}
.b_card {
width: 100%;
padding: 40rpx 30rpx;
display: flex;
border-radius: 18rpx;
box-shadow: 0 0 20rpx #ebebeb;
flex-direction: column;
background: #fff;
box-sizing: border-box;
}
.b_border {
border-bottom: 1rpx solid #eee;
width: 100%;
height: 2rpx;
}
.b_bar {
height: 90rpx;
width: 100%;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
}
.kind-group {
display: flex;
}
.b_radio {
padding-left: 20rpx;
font-size: 28rpx;
display: flex;
align-items: center;
}
.b_radio radio {
transform: scale(0.8);
}
.b_name {
font-size: 30rpx;
letter-spacing: 2rpx;
}
.b_picker {
font-size: 28rpx;
line-height: 30rpx;
display: flex;
align-items: center;
color: #8c9aa8;
}
.right {
padding-left: 10rpx;
width: 26rpx;
height: 26rpx;
}
picker {
display: flex;
align-items: center;
}
.b_notes {
width: 100%;
padding: 10rpx;
display: flex;
box-sizing: border-box;
}
.b_text {
width: 100%;
height: 150rpx;
padding: 20rpx;
border-radius: 10rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
box-sizing: border-box;
background: rgb(238, 238, 238);
}
.b_text textarea {
width: 100%;
height: 150rpx;
font-size: 28rpx;
color: #8c9aa8;
border-spacing: 2rpx;
}
.b_less {
display: flex;
justify-content: flex-end;
font-size: 28rpx;
letter-spacing: 2rpx;
color: #8c9aa8;
}
.b_place {
width: 100%;
padding: 10rpx;
display: flex;
box-sizing: border-box;
}
.b_plecebox {
width: 100%;
height: 80rpx;
padding: 0 20rpx;
border-radius: 10rpx;
display: flex;
align-items: center;
box-sizing: border-box;
background: rgb(238, 238, 238);
}
.b_plecebox input {
width: 100%;
font-size: 28rpx;
letter-spacing: 2rpx;
color: #8c9aa8;
}
.b_tips {
font-size: 26rpx;
line-height: 45rpx;
color: #8c9aa8;
}
.b_tips text {
color: rgb(255, 0, 0);
font-size: 30rpx;
}
.b_nobi {
font-size: 28rpx;
color: #8c9aa8;
}
.b_publish {
margin-top: 30rpx;
width: 100%;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
background:#fbbd08;
color: #fff;
border-radius: 40rpx;
letter-spacing: 4rpx;
font-size: 32rpx;
border: none;
font-weight: 500;
}
.ban_publish {
margin-top: 30rpx;
width: 100%;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
background:gray;
color: #fff;
border-radius: 40rpx;
letter-spacing: 4rpx;
font-size: 32rpx;
border: none;
font-weight: 500;
}
.c_contain {
position: relative;
width: 100%;
background: #fff;
display: flex;
align-items: center;
flex-direction: column;
box-sizing: border-box;
}
.c_success {
width: 145rpx;
height: 184rpx;
margin-top: 130rpx;
}
.c_title {
font-size: 40rpx;
margin-top: 30rpx;
font-weight: 600;
}
.c_des {
margin-top: 30rpx;
font-size: 28rpx;
line-height: 45rpx;
color: #898989;
}
.c_see {
margin-top: 40rpx;
font-size: 32rpx;
letter-spacing: 3rpx;
color: #4f93ea;
}
.c_again {
margin-top: 40rpx;
width: 500rpx;
height: 80rpx;
border-radius: 40rpx;
background: #fbbd08;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
letter-spacing: 4rpx;
}
.title{
border-bottom: solid 2rpx #eee;
}
.title input{
font-size:30rpx;
}
.description textarea{
height: 240rpx !important;
}
.main{
position: relative;
background-color: white;
padding-bottom: 30rpx;
/*height: 560rpx;*/
}
.van-icon-plus{
position: absolute !important;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.upload-img{
font-size: 100rpx;
color: gray;
position: relative;
/*bottom: 25rpx;
left: 30rpx;*/
}
.pictures{
background-color: white;
display: flex;
flex-direction: row;
flex-wrap:wrap;
}
.img_item{
position: relative;
background-color: #eee;
width: 150rpx;
height: 150rpx;
border-radius: 8rpx;
margin-left: 30rpx;
margin-block-end: 20rpx;
}
.img_item .van-icon-close{
position: absolute;
top:-10rpx;
right:-10rpx;
color:red;
}
.img_item image{
width: 150rpx;
height: 150rpx;
border-radius: 8rpx;
}
.new_tag{
margin-left: 30rpx;
margin-top: 20rpx;
}
.new_tag .van-checkbox__label{
font-size: 28rpx;
color: gray;
}
.sale_detail{
margin-top: 20rpx;
}
.publish_btn{
width: 80%;
background-color: #0fb7e0;
border: none;
color: white;
margin-top: 40rpx;
}
================================================
FILE: miniprogram/pages/search/search.js
================================================
const app = getApp()
const db = wx.cloud.database();
const config = require("../../config.js");
const _ = db.command;
Page({
/**
* 页面的初始数据
*/
data: {
scrollTop: 0,
newlist: [],
list: [],
key: '',
blank: false,
hislist: [],
nomore:false,
},
onLoad: function(options) {
this.gethis();
this.getnew();
},
//获取本地记录
gethis() {
let that = this;
wx.getStorage({
key: 'history',
success: function(res) {
let hislist = JSON.parse(res.data);
//限制长度
if (hislist.length > 5) {
hislist.length = 5
}
that.setData({
hislist: hislist
})
},
})
},
//选择历史搜索关键词
choosekey(e) {
this.data.key = e.currentTarget.dataset.key;
this.search('his');
},
//最新推荐书籍
getnew() {
let that = this;
db.collection('publish').where({
status: 0,
dura: _.gt(new Date().getTime()),
}).orderBy('creat', 'desc').get({
success: function(res) {
let newlist = res.data;
//限定5个推荐内容
if (newlist.length > 5) {
newlist.length = 5;
}
that.setData({
newlist: newlist,
})
}
})
},
//跳转详情
detail(e) {
let that = this;
wx.navigateTo({
url: '/pages/detail/detail?scene=' + e.currentTarget.dataset.id,
})
},
//搜索结果
search(n) {
let that = this;
let key = that.data.key;
if (key == '') {
wx.showToast({
title: '请输入关键词',
icon: 'none',
})
return false;
}
wx.setNavigationBarTitle({
title:'"'+ that.data.key + '"的搜索结果',
})
wx.showLoading({
title: '加载中',
})
if (n !== 'his') {
that.history(key);
}
db.collection('publish').where({
status: 0,
dura: _.gt(new Date().getTime()),
key: db.RegExp({
regexp: '.*' + key + '.*',
options: 'i',
})
}).orderBy('creat', 'desc').limit(20).get({
success(e) {
wx.hideLoading();
that.setData({
blank: true,
page: 0,
list: e.data,
nomore: false,
})
}
})
},
onReachBottom() {
this.more();
},
//添加到搜索历史
history(key) {
let that = this;
wx.getStorage({
key: 'history',
success(res) {
let oldarr = JSON.parse(res.data); //字符串转数组
let newa = [key]; //对象转为数组
let newarr = JSON.stringify(newa.concat(oldarr)); //连接数组\转字符串
wx.setStorage({
key: 'history',
data: newarr,
})
},
fail(res) {
//第一次打开时获取为null
let newa = [key]; //对象转为数组
var newarr = JSON.stringify(newa); //数组转字符串
wx.setStorage({
key: 'history',
data: newarr,
})
}
});
},
keyInput(e) {
this.data.key = e.detail.value
},
//至顶
gotop() {
wx.pageScrollTo({
scrollTop: 0
})
},
//监测屏幕滚动
onPageScroll: function (e) {
this.setData({
scrollTop: parseInt((e.scrollTop) * wx.getSystemInfoSync().pixelRatio)
})
},
//加载更多
more() {
let that = this;
if (that.data.nomore || that.data.list.length < 20) {
return false
}
let page = that.data.page + 1;
if (that.data.collegeCur == -2) {
var collegeid = _.neq(-2); //除-2之外所有
} else {
var collegeid = that.data.collegeCur + '' //小程序搜索必须对应格式
}
db.collection('publish').where({
status: 0,
dura: _.gt(new Date().getTime()),
key: db.RegExp({
regexp: '.*' + that.data.key + '.*',
options: 'i',
})
}).orderBy('creat', 'desc').skip(page * 20).limit(20).get({
success: function (res) {
if (res.data.length == 0) {
that.setData({
nomore: true
})
return false;
}
if (res.data.length < 20) {
that.setData({
nomore: true
})
}
that.setData({
page: page,
list: that.data.list.concat(res.data)
})
},
fail() {
wx.showToast({
title: '获取失败',
icon: 'none'
})
}
})
},
})
================================================
FILE: miniprogram/pages/search/search.json
================================================
{
"usingComponents": {}
}
================================================
FILE: miniprogram/pages/search/search.wxml
================================================
搜索
搜索历史
您还没搜索过哟,赶快试试吧
{{index+1}}. {{item}}
搜索结果
暂无{{key}}相关物品哟~
更多推荐
暂无相关推荐
{{item.bookinfo.good}}
¥{{item.price}}元
{{morejs.timelog(item.creat )}}发布
搜索结果
{{item.bookinfo.good}}
¥{{item.price}}元
{{morejs.timelog(item.creat )}}发布
================================================
FILE: miniprogram/pages/search/search.wxss
================================================
.top_contain {
width: 100%;
display: flex;
justify-content: space-between;
padding: 20rpx 30rpx;
box-sizing: border-box;
background: #fbbd08;
height: 106rpx;
align-items: center;
}
.search_box {
width: 80%;
height: 66rpx;
border-radius: 33rpx 0 0 33rpx;
background: #fff;
display: flex;
align-items: center;
}
.search_box image {
padding-left: 30rpx;
width: 32rpx;
height: 32rpx;
}
.search_box input {
padding-left: 10rpx;
font-size: 28rpx;
letter-spacing: 2rpx;
color: rgb(167, 167, 167);
background: #fff;
height: 66rpx;
width: 500rpx;
}
.search {
width: 20%;
height: 66rpx;
display: flex;
justify-content: center;
align-items: center;
background:#fbbd08;
color: #fff;
font-size: 28rpx;
border-radius: 0 33rpx 33rpx 0;
letter-spacing: 4rpx;
}
.contain {
width: 100%;
padding: 0 30rpx;
display: flex;
box-sizing: border-box;
flex-direction: column;
}
.a {
display: flex;
align-items: center;
border-bottom: 1rpx solid #eee;
width: 100%;
padding: 20rpx 0;
}
.a image {
width: 36rpx;
height: 36rpx;
}
.a view {
font-size: 30rpx;
letter-spacing: 2rpx;
padding-left: 20rpx;
}
.hisitem {
width: 100%;
font-size: 28rpx;
letter-spacing: 2rpx;
color: #919191;
padding: 16rpx 0;
}
.list_box {
width: 100%;
display: flex;
align-items: center;
padding: 20rpx 0;
box-sizing: border-box;
margin-top: 10rpx;
}
.list_poster {
width: 200rpx;
height: 200rpx;
}
.list_content {
height: 200rpx;
width: calc(100% - 230rpx);
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 0 10rpx;
box-sizing: border-box;
}
.list_word {
display: flex;
flex-direction: column;
width: 100%;
box-sizing: border-box;
}
.list_title {
width: 100%;
font-size: 32rpx;
letter-spacing: 3rpx;
line-height: 45rpx;
}
.list_author {
padding-top: 10rpx;
width: 100%;
font-size: 27rpx;
letter-spacing: 3rpx;
line-height: 40rpx;
color: rgb(129, 129, 129);
}
.list_between {
width: 100%;
display: flex;
justify-content: space-between;
align-items: flex-end;
border-bottom: 1rpx solid #eee;
padding-bottom: 10rpx;
}
.list_price {
font-size: 36rpx;
color: rgb(255, 0, 0);
}
.list_time {
font-size: 28rpx;
letter-spacing: 2rpx;
color: rgb(129, 129, 129);
}
.nocontent {
width: 100%;
height: 400rpx;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
box-sizing: border-box;
}
.nocontent image {
padding-left: 80rpx;
width: 300rpx;
height: 240rpx;
}
.blank_text{
padding-top: 40rpx;
font-size: 28rpx;
letter-spacing: 2rpx;
color: #c6c6c8;
}
.nosearch{
width: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
height: 100rpx;
color: #919191;
letter-spacing: 4rpx;
}
================================================
FILE: miniprogram/pages/sell/detail/detail.js
================================================
const app = getApp()
const db = wx.cloud.database();
const config = require("../../../config.js");
const _ = db.command;
Page({
/**
* 页面的初始数据
*/
data: {
userinfo: [],
creatTime: '',
detail: [],
status: Number,
openid: app.openid,
},
onLoad: function (e) {
if (app.openid) {
this.setData({
openid: app.openid
})
} else {
console.log("no openid");
wx.showModal({
title: '温馨提示',
content: '该功能需要注册方可使用,是否马上去注册',
success(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login',
})
}
}
})
return false
}
this.getdetail(e.id);
},
//回到首页
home() {
wx.switchTab({
url: '/pages/index/index',
})
},
//获取订单详情,差一个获取买家昵称
getdetail(_id) {
let that = this;
db.collection('order').doc(_id).get({
success(e) {
that.setData({
creatTime: config.formTime(e.data.creat),
detail: e.data
})
that.getSeller(e.data.seller);
},
fail() {
wx.showToast({
title: '获取失败,请稍后到订单中心内查看',
icon: 'none'
})
}
})
},
//获取卖家信息
getSeller(m) {
let that = this;
db.collection('user').where({
_openid: m
}).get({
success: function (res) {
wx.hideLoading();
that.setData({
userinfo: res.data[0]
})
}
})
},
//确认收货
confirm() {
let that = this;
wx.showModal({
title: '温馨提示',
content: '您确定要此条订单完成了吗?',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在处理',
})
wx.cloud.callFunction({
name: 'pay',
data: {
$url: "changeP", //云函数路由参数
_id: that.data.detail.sellid,
status: 2 //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;3、交易作废,退还买家钱款
},
success: res => {
console.log('修改订单状态成功')
wx.cloud.callFunction({
name: 'pay',
data: {
$url: "changeO", //云函数路由参数
_id: that.data.detail._id,
status: 2 //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;3、交易作废,退还买家钱款
},
success: res => {
wx.showToast({
title: '交易成功!',
icon: 'none'
})
that.getdetail(that.data.detail._id);
wx.showModal({
title: '打赏小程序',
content: '请开发者喝阔落?',
showCancel: true,
cancelText:'下次一定',
confirmText:'现在就去',
confirmColor: '#fbbd08',
success(res) {
if (res.confirm) {
wx.previewImage({
urls: ['https://7461-taoshaoji-46f0r-1302243411.tcb.qcloud.la/appreciate-code/appreciateimg.jpg?sign=b6789b4ae3b6c830689f41ddca8f183e&t=1597523262'],
})
}
}
})
},
fail(e) {
wx.hideLoading();
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
},
fail(e) {
wx.hideLoading();
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
}
}
})
},
//删除订单
delete() {
let that = this;
wx.showModal({
title: '温馨提示',
content: '您确认要删除此订单吗',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在处理',
})
db.collection('publish').doc(that.data.detail._id).remove({
success() {
//页面栈返回
let i = getCurrentPages()
wx.navigateBack({
success: function () {
i[i.length - 2].getlist();
}
});
},
fail: console.error
})
}
}
})
},
//复制
copy(e) {
wx.setClipboardData({
data: e.currentTarget.dataset.copy,
success: res => {
wx.showToast({
title: '复制' + e.currentTarget.dataset.name + '成功',
icon: 'success',
duration: 1000,
})
}
})
},
//历史记录
history(name, num, type) {
let that = this;
db.collection('history').add({
data: {
stamp: new Date().getTime(),
type: type, //1充值2支付
name: name,
num: num,
oid: app.openid
},
success: function (res) {
console.log(res)
},
fail: console.error
})
},
goo(e) {
var myid = this.data.detail.buyerInfo._openid;
var sallerid = this.data.detail.seller;
wx.cloud.init({
env: 'taoshaoji-46f0r',
traceUser: true
});
//初始化数据库
const db = wx.cloud.database();
if (myid != sallerid) {
db.collection('rooms').where({
p_b: myid,
p_s: sallerid,
deleted :0
}).get().then(res => {
console.log(res.data);
if (res.data.length > 0) {
this.setData({
roomID: res.data[0]._id
})
wx.navigateTo({
url: '/pages/detail/room/room?id=' + this.data.roomID,
})
} else {
db.collection('rooms').add({
data: {
p_b: myid,
p_s: sallerid,
deleted :0
},
}).then(res => {
console.log(res)
this.setData({
roomID: res._id
})
wx.navigateTo({
url: '/pages/detail/room/room?id=' + this.data.roomID,
})
})
}
})
} else {
wx.showToast({
title: '无法和自己建立聊天',
icon: 'none',
duration: 1500
})
}
},
})
================================================
FILE: miniprogram/pages/sell/detail/detail.json
================================================
{
"navigationBarTitleText": "订单详情"
}
================================================
FILE: miniprogram/pages/sell/detail/detail.wxml
================================================
{{detail.bookinfo.good}}
买家:{{detail.buyerInfo.info.nickName}}
¥{{detail.price}}元
{{detail.deliveryid==0?'需要自提':'卖家帮送'}}
买家地址:{{detail.deliveryid==0?detail.ztplace:detail.psplace}}
ORDER FARE
下单时间
{{creatTime}}
支付金额
¥{{detail.price}}.00元
CONTACT BUYER
邮箱
{{detail.buyerInfo.email}}
QQ
{{detail.buyerInfo.qqnum}}
买家未确认收货
完成交易
删除订单
私聊
================================================
FILE: miniprogram/pages/sell/detail/detail.wxss
================================================
page {
background-image: linear-gradient(to top, #dad4ec 0%, #dad4ec 1%, #f3e7e9 100%);
}
.contain {
display: flex;
padding: 20rpx 28rpx;
width: 100%;
box-sizing: border-box;
}
.card {
width: 100%;
background: #fff;
position: relative;
display: flex;
flex-direction: column;
box-sizing: border-box;
padding: 40rpx 25rpx;
}
.top_over {
width: 100%;
height: 20rpx;
position: absolute;
left: 0rpx;
top: -10rpx;
}
.bot_over {
width: 100%;
height: 20rpx;
position: absolute;
left: 0rpx;
bottom: -10rpx;
}
.goods_box {
width: 100%;
display: flex;
box-sizing: border-box;
align-items: center;
height: 100rpx;
}
.goods_img {
width: 90rpx;
height: 90rpx;
}
.goods_content {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 20rpx;
width: calc(100% - 240rpx);
height: 90%;
}
.goods_title {
font-size: 29rpx;
letter-spacing: 3rpx;
}
.goods_author {
font-size: 26rpx;
letter-spacing: 2rpx;
color: rgb(150, 150, 150);
}
.goods_price {
width: 150rpx;
height: 100%;
font-size: 32rpx;
color: #f00;
white-space: nowrap;
display: flex;
justify-content: center;
align-items: center;
}
.border {
width: 100%;
height: 20rpx;
border-bottom: 1rpx solid #eee;
}
.list {
width: 100%;
display: flex;
flex-direction: column;
padding: 30rpx 0 10rpx 0;
}
.list_1 {
font-size: 26rpx;
color: rgb(167, 167, 167);
letter-spacing: 2rpx;
}
.list_2 {
padding-top: 10rpx;
font-size: 32rpx;
letter-spacing: 3rpx;
}
.orderfare {
margin-top: 28rpx;
font-size: 22rpx;
font-weight: 600;
letter-spacing: 2rpx;
color: rgb(167, 167, 167);
padding-bottom: 20rpx;
}
.fare_box {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
padding: 10rpx 0;
}
.fare_title {
font-size: 28rpx;
letter-spacing: 2rpx;
}
.fare_des {
font-size: 27rpx;
color: rgb(167, 167, 167);
}
.bot_box{
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.cancel {
font-size: 30rpx;
width: 620rpx;
height: 80rpx;
background: #000;
color: #fff;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 40rpx;
letter-spacing: 4rpx;
}
.contact {
font-size: 30rpx;
width: 620rpx;
height: 80rpx;
background: #fbbd08;
color: #000;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20rpx;
letter-spacing: 4rpx;
}
.delete{
font-size: 30rpx;
width: 620rpx;
height: 80rpx;
background: #adadad;
color: #fff;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20rpx;
letter-spacing: 4rpx;
}
.contact_box {
z-index: 9;
position: fixed;
bottom: 200rpx;
right: 40rpx;
display: flex;
width: 100rpx;
flex-direction: column;
align-items: center;
background: rgba(255, 255, 255, 0.8);
padding: 20rpx 0;
border-radius: 50rpx 50rpx 20rpx 20rpx;
box-shadow: 0 0 20rpx #f0f0f0 !important;
}
.contact_box image {
width: 80rpx;
height: 80rpx;
}
.contact_box view {
font-size: 26rpx;
letter-spacing: 2rpx;
margin-top: 10rpx;
}
================================================
FILE: miniprogram/pages/sell/list/list.js
================================================
const app = getApp()
const db = wx.cloud.database();
const config = require("../../../config.js");
const _ = db.command;
Page({
/**
* 页面的初始数据
*/
data: {
list: [],
page: 1,
scrollTop: 0,
nomore: false,
roomlist: [],
buyerInfo: [],
address: '',
sellerInfo: '',
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.showLoading({
title: '加载中',
})
this.getList();
},
/**
* 获取买家名字
*/
getBuyerInfo(orderid) {
let that = this;
db.collection('order').where({
sellid: orderid,
}).get({
success: function (res) {
that.setData({
buyerInfo: res.data[0],
})
}
})
},
getList() {
let that = this;
db.collection('publish').where({
_openid: app.openid
}).orderBy('creat', 'desc').limit(20).get({
success: function (res) {
wx.hideLoading();
wx.stopPullDownRefresh(); //暂停刷新动作
that.setData({
list: res.data,
nomore: false,
page: 0,
})
console.log(res.data)
}
})
},
//删除
del(e) {
let that = this;
let del = e.currentTarget.dataset.del;
wx.showModal({
title: '温馨提示',
content: '您确定要删除此条订单吗?',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在删除'
})
db.collection('publish').doc(del._id).remove({
success() {
wx.hideLoading();
wx.showToast({
title: '成功删除',
})
that.getList();
},
fail() {
wx.hideLoading();
wx.showToast({
title: '删除失败',
icon: 'none'
})
}
})
}
}
})
},
//擦亮
crash(e) {
let that = this;
let crash = e.currentTarget.dataset.crash;
wx.showModal({
title: '温馨提示',
content: '您确定要擦亮此条订单吗?',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在擦亮'
})
db.collection('publish').doc(crash._id).update({
data: {
creat: new Date().getTime(),
dura: new Date().getTime() + 7 * (24 * 60 * 60 * 1000), //每次擦亮管7天
},
success() {
wx.hideLoading();
wx.showToast({
title: '成功擦亮',
})
that.getList();
},
fail() {
wx.hideLoading();
wx.showToast({
title: '操作失败',
icon: 'none'
})
}
})
}
}
})
},
//取消交易
quxiao(e) {
let that = this;
let quxiao = e.currentTarget.dataset.quxiao;
that.getBuyerInfo(quxiao._id);
that.getSellerInfo()
console.log("sellname--->" + that.data.sellerName)
wx.showModal({
title: '温馨提示',
content: '您确定要取消此条订单吗?',
success(res) {
if (res.confirm) {
that.getAddress()
wx.showLoading({
title: '正在取消'
})
db.collection('publish').doc(quxiao._id).update({
data: {
status: 3,
},
success() {
wx.cloud.callFunction({
name: 'removeOrder',
data: {
_id: quxiao._id,
},
success: res => {
wx.hideLoading();
wx.showToast({
title: '成功取消该订单',
})
that.sendCancel(that.data.buyerInfo._openid)
that.getList();
},
fail(e) {
wx.hideLoading();
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
},
fail() {
wx.hideLoading();
wx.showToast({
title: '操作失败',
icon: 'none'
})
}
})
}
}
})
},
//获取当前的用户昵称
getSellerInfo() {
let that = this;
db.collection('user').where({
_openid: app.openid
}).get().then(res => {
console.log(res.data[0]);
that.setData({
sellerInfo: res.data[0].info
})
})
},
/**
* 获取地址
*/
getAddress() {
let that = this;
if (that.data.buyerInfo.deliveryid == 0) {
that.setData({
address: that.data.buyerInfo.ztplace
})
} else {
that.setData({
address: that.data.buyerInfo.psplace
})
}
},
//发送模板消息到指定用户,推送之前要先获取用户的openid
sendCancel(openid) {
let that = this;
wx.cloud.callFunction({
name: "sendMsg",
data: {
openid: openid,
status: '卖家取消交易', //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;
address: that.data.address,
describe: that.data.buyerInfo.bookinfo.describe,
good: that.data.buyerInfo.bookinfo.good,
nickName: that.data.sellerInfo.nickName,
color: 'yellow'
}
}).then(res => {
console.log("推送消息成功", res)
}).catch(res => {
console.log("推送消息失败", res)
})
},
//完成交易
wancheng(e) {
let that = this;
let wancheng = e.currentTarget.dataset.wancheng._id;
console.log("wancheng:" + wancheng)
wx.showModal({
title: '温馨提示',
content: '您确定要此条订单完成了吗?',
success(res) {
console.log(e.currentTarget.data)
db.collection('order').doc(wancheng).get({
success(e) {
if (res.confirm) {
if (e.data.status == 5) {
wx.showLoading({
title: '正在操作'
})
wx.cloud.callFunction({
name: 'pay',
data: {
$url: "changeP", //云函数路由参数
_id: wancheng,
status: 2 //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;3、交易作废,退还买家钱款;4、等待卖家确认交易
},
success: res => {
console.log('修改卖家订单状态成功')
wx.cloud.callFunction({
name: 'pay',
data: {
$url: "changeO", //云函数路由参数
_id: wancheng,
status: 2 //0在售;1买家已付款,但卖家未发货;2买家确认收获,交易完成;3、交易作废,退还买家钱款;4、等待卖家确认交易
},
success: res => {
wx.showToast({
title: '交易成功!',
icon: 'none'
})
that.getList();
wx.showModal({
title: '打赏小程序',
content: '请开发者喝阔落?',
showCancel: true,
cancelText:'下次一定',
confirmText:'现在就去',
confirmColor: '#fbbd08',
success(res) {
if (res.confirm) {
wx.previewImage({
urls: ['https://7461-taoshaoji-46f0r-1302243411.tcb.qcloud.la/appreciate-code/appreciateimg.jpg?sign=b6789b4ae3b6c830689f41ddca8f183e&t=1597523262'],
})
}
}
})
},
fail(e) {
wx.hideLoading();
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
},
fail(e) {
wx.hideLoading();
wx.showToast({
title: '发生异常,请及时和管理人员联系处理',
icon: 'none'
})
}
})
that.getList();
} else {
wx.hideLoading();
wx.showToast({
title: '操作失败,买家未确认收货',
icon: 'none'
})
}
}
}
})
}
})
},
//重新上架
up(e) {
let that = this;
let up = e.currentTarget.dataset.up;
wx.showModal({
title: '温馨提示',
content: '您确定要重新上架该商品吗?',
success(res) {
if (res.confirm) {
wx.showLoading({
title: '正在操作'
})
db.collection('publish').doc(up._id).update({
data: {
status: 0,
},
success() {
wx.hideLoading();
wx.showToast({
title: '该商品成功上架',
})
that.getList();
},
fail() {
wx.hideLoading();
wx.showToast({
title: '操作失败',
icon: 'none'
})
}
})
}
}
})
},
//查看详情
detail(e) {
let that = this;
let detail = e.currentTarget.dataset.detail;
if (detail.status == 0 || detail.status == 3) {
wx.navigateTo({
url: '/pages/detail/detail?scene=' + detail._id,
})
} else {
wx.navigateTo({
url: '/pages/sell/detail/detail?id=' + detail._id,
})
}
},
//下拉刷新
onPullDownRefresh() {
this.getList();
},
//至顶
gotop() {
wx.pageScrollTo({
scrollTop: 0
})
},
//监测屏幕滚动
onPageScroll: function (e) {
this.setData({
scrollTop: parseInt((e.scrollTop) * wx.getSystemInfoSync().pixelRatio)
})
},
onReachBottom() {
this.more();
},
//加载更多
more() {
let that = this;
if (that.data.nomore || that.data.list.length < 20) {
return false
}
let page = that.data.page + 1;
db.collection('publish').where({
_openid: app.openid
}).orderBy('creat', 'desc').skip(page * 20).limit(20).get({
success: function (res) {
if (res.data.length == 0) {
that.setData({
nomore: true
})
return false;
}
if (res.data.length < 20) {
that.setData({
nomore: true
})
}
that.setData({
page: page,
list: that.data.list.concat(res.data)
})
},
fail() {
wx.showToast({
title: '获取失败',
icon: 'none'
})
}
})
},
onShow() {
this.getList()
}
})
================================================
FILE: miniprogram/pages/sell/list/list.json
================================================
{
"navigationBarTitleText": "我的发布",
"enablePullDownRefresh": true
}
================================================
FILE: miniprogram/pages/sell/list/list.wxml
================================================
{{item.status==0?'待出售':(item.status==1||item.status==5?'交易中':(item.status==2?'已完成':'已取消'))}}
{{morejs.timelog(item.creat)}}
{{item.bookinfo.good}}
¥{{item.price}}元
删除
重新上架
取消交易
完成交易
擦亮
这里空空如也~
================================================
FILE: miniprogram/pages/sell/list/list.wxss
================================================
.contain {
width: 100%;
display: flex;
box-sizing: border-box;
flex-direction: column;
padding: 24rpx;
}
.card {
width: 100%;
display: flex;
flex-direction: column;
padding: 30rpx;
box-sizing: border-box;
box-shadow: 0 0 20rpx #eee;
border-radius: 16rpx;
margin-bottom: 30rpx;
}
.a {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #eee;
padding-bottom: 24rpx;
}
.a1 {
font-size: 30rpx;
letter-spacing: 2rpx;
display: flex;
}
.text-red {
color: #f80202;
}
.a1 image {
width: 40rpx;
height: 40rpx;
padding-right: 10rpx;
}
.a2 {
font-size: 28rpx;
color: #b2b2b2;
letter-spacing: 2rpx;
}
.b {
width: 100%;
display: flex;
align-items: center;
box-sizing: border-box;
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
}
.b image {
width: 130rpx;
height: 130rpx;
}
.b1 {
width: calc(100% - 130rpx);
padding: 0 20rpx;
height: 130rpx;
display: flex;
flex-direction: column;
box-sizing: border-box;
justify-content: space-between;
}
.b11 {
display: flex;
flex-direction: column;
width: 100%;
}
.b111 {
font-size: 30rpx;
letter-spacing: 2rpx;
}
.b112 {
padding-top: 10rpx;
font-size: 26rpx;
letter-spacing: 3rpx;
color: #c2c2c2;
}
.b12 {
display: flex;
justify-content: flex-end;
font-size: 32rpx;
color: #f80202;
}
.c {
width: 100%;
display: flex;
justify-content: flex-end;
padding-top: 20rpx;
}
.c1 {
width: 120rpx;
height: 50rpx;
border-radius: 10rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 26rpx;
letter-spacing: 2rpx;
margin-left: 20rpx;
}
.bg-grey {
background: #eee;
}
.bg-yellow {
background: #fbbd08;
color: #fff;
}
.bg-green {
background:#6f86d6;
color: #fff;
}
.bg-red {
background:red;
}
.c2 {
width: 200rpx;
height:53rpx;
border-radius: 10rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 26rpx;
letter-spacing: 4rpx;
margin-left: 20rpx;
color: #fff;
}
.nocontent {
width: 100%;
height: calc(100% - 100rpx);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
box-sizing: border-box;
}
.nocontent image {
padding-left: 80rpx;
width: 340rpx;
height: 272rpx;
}
.blank_text {
padding-top: 40rpx;
font-size: 32rpx;
letter-spacing: 2rpx;
color: #c6c6c8;
}
================================================
FILE: miniprogram/pages/start/start.js
================================================
const app = getApp()
const db = wx.cloud.database();
const config = require("../../config.js");
const _ = db.command;
Page({
/**
* 页面的初始数据
*/
data: {
count: 3,
bgurl:[]
},
onLoad(){
this.getimg();
this.countDown();
this.getuserdetail();
},
go() {
wx.switchTab({
url: '/pages/index/index',
})
},
countDown: function() {
let that = this;
let total = 3;
this.interval = setInterval(function() {
total > 0 && (total--, that.setData({
count: total
})), 0 === total && (that.setData({
count: total
}), wx.switchTab({
url: "/pages/index/index"
}), clearInterval(that.interval));
}, 1e3);
},
//为了数据安全可靠,每次进入获取一次用户信息
getuserdetail() {
if (!app.openid) {
wx.cloud.callFunction({
name: 'regist', // 对应云函数名
data: {
$url: "getid", //云函数路由参数
},
success: re => {
db.collection('user').where({
_openid: re.result
}).get({
success: function (res) {
if (res.data.length !== 0) {
app.openid = re.result;
app.userinfo = res.data[0];
console.log(app)
}
console.log(res)
}
})
}
})
}
},
//获取背景图
getimg() {
let that = this;
db.collection('start').where({}).get({
success: function (res) {
console.log(res)
that.setData({
bgurl: res.data[0].url
})
},
fail(){
that.setData({
bgurl: JSON.parse(config.data).bgurl,
})
}
})
},
})
================================================
FILE: miniprogram/pages/start/start.json
================================================
{
"navigationStyle":"custom"
}
================================================
FILE: miniprogram/pages/start/start.wxml
================================================
跳过{{count}}s
================================================
FILE: miniprogram/pages/start/start.wxss
================================================
.contain {
width: 100%;
height: 100%;
position: relative;
}
.bg {
position: absolute;
left: 0rpx;
top: 0rpx;
width: 100%;
height: 100%;
z-index: -1;
}
.go {
position: absolute;
right: 30rpx;
top: 150rpx;
z-index: 9;
}
.go button {
font-size: 28rpx;
letter-spacing: 4rpx;
border-radius: 30rpx;
color: #000;
background: rgba(255, 255, 255, 0.781);
display: flex;
justify-content: center;
align-items: center;
text-align: center;
width: 160rpx;
height: 60rpx;
}
================================================
FILE: miniprogram/pages/use/use.js
================================================
// miniprogram/pages/use/use.js
Page({
/**
* 页面的初始数据
*/
data: {
des:'待补充'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
================================================
FILE: miniprogram/pages/use/use.json
================================================
{
"usingComponents": {}
}
================================================
FILE: miniprogram/pages/use/use.wxml
================================================
================================================
FILE: miniprogram/pages/use/use.wxss
================================================
================================================
FILE: miniprogram/pages/web/web.js
================================================
// pages/web/web.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(e) {
this.setData({
url: e.url
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function() {
}
})
================================================
FILE: miniprogram/pages/web/web.json
================================================
{
"usingComponents": {}
}
================================================
FILE: miniprogram/pages/web/web.wxml
================================================
================================================
FILE: miniprogram/pages/web/web.wxss
================================================
/* pages/web/web.wxss */
================================================
FILE: miniprogram/sitemap.json
================================================
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [
{
"action": "allow",
"page": "/pages/detail/detail",
"params": [
"scene"
],
"matching": "exact"
},
{
"action": "allow",
"page": "/pages/start/start"
},
{
"action": "allow",
"page": "/pages/about/about"
},
{
"action": "disallow",
"page": "*"
}
]
}
================================================
FILE: miniprogram/utils/util.js
================================================
function formatTime(date) {
var date = new Date(date);
var year = date.getFullYear()
var month = date.getMonth() + 1
var day = date.getDate()
var hour = date.getHours()
var minute = date.getMinutes()
var second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
function formatNumber(n) {
n = n.toString()
return n[1] ? n : '0' + n
}
/**
* 时间戳转化为年 月 日 时 分 秒
* number: 传入时间戳
* format:返回格式,支持自定义,但参数必须与formateArr里保持一致
*/
function formatTimeTwo(number, format) {
var formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];
var returnArr = [];
var date = new Date(number * 1000);
returnArr.push(date.getFullYear());
returnArr.push(formatNumber(date.getMonth() + 1));
returnArr.push(formatNumber(date.getDate()));
returnArr.push(formatNumber(date.getHours()));
returnArr.push(formatNumber(date.getMinutes()));
returnArr.push(formatNumber(date.getSeconds()));
for (var i in returnArr) {
format = format.replace(formateArr[i], returnArr[i]);
}
return format;
}
module.exports = {
formatTime: formatTime,
formatTimeTwo: formatTimeTwo
}
================================================
FILE: miniprogram/vant/action-sheet/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/action-sheet/index.js
================================================
import { VantComponent } from '../common/component';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
mixins: [button, openType],
props: {
show: Boolean,
title: String,
cancelText: String,
description: String,
round: {
type: Boolean,
value: true,
},
zIndex: {
type: Number,
value: 100,
},
actions: {
type: Array,
value: [],
},
overlay: {
type: Boolean,
value: true,
},
closeOnClickOverlay: {
type: Boolean,
value: true,
},
closeOnClickAction: {
type: Boolean,
value: true,
},
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
},
methods: {
onSelect(event) {
const { index } = event.currentTarget.dataset;
const item = this.data.actions[index];
if (item && !item.disabled && !item.loading) {
this.$emit('select', item);
if (this.data.closeOnClickAction) {
this.onClose();
}
}
},
onCancel() {
this.$emit('cancel');
},
onClose() {
this.$emit('close');
},
onClickOverlay() {
this.$emit('click-overlay');
this.onClose();
},
},
});
================================================
FILE: miniprogram/vant/action-sheet/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-popup": "../popup/index",
"van-loading": "../loading/index"
}
}
================================================
FILE: miniprogram/vant/action-sheet/index.wxml
================================================
{{ description }}
{{ item.name }}
{{ item.subname }}
{{ cancelText }}
================================================
FILE: miniprogram/vant/action-sheet/index.wxss
================================================
@import '../common/index.wxss';.van-action-sheet{max-height:90%!important;max-height:var(--action-sheet-max-height,90%)!important;color:#323233;color:var(--action-sheet-item-text-color,#323233)}.van-action-sheet__cancel,.van-action-sheet__item{text-align:center;font-size:16px;font-size:var(--action-sheet-item-font-size,16px);line-height:50px;line-height:var(--action-sheet-item-height,50px);background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-action-sheet__cancel:before{display:block;content:" ";height:8px;height:var(--action-sheet-cancel-padding-top,8px);background-color:#f7f8fa;background-color:var(--action-sheet-cancel-padding-color,#f7f8fa)}.van-action-sheet__item--disabled{color:#c8c9cc;color:var(--action-sheet-item-disabled-text-color,#c8c9cc)}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__subname{margin-left:4px;margin-left:var(--padding-base,4px);font-size:12px;font-size:var(--action-sheet-subname-font-size,12px);color:#646566;color:var(--action-sheet-subname-color,#646566)}.van-action-sheet__header{text-align:center;font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--action-sheet-header-font-size,16px);line-height:44px;line-height:var(--action-sheet-header-height,44px)}.van-action-sheet__description{text-align:center;padding:16px;padding:var(--padding-md,16px);color:#646566;color:var(--action-sheet-description-color,#646566);font-size:14px;font-size:var(--action-sheet-description-font-size,14px);line-height:20px;line-height:var(--action-sheet-description-line-height,20px)}.van-action-sheet__close{position:absolute!important;top:0;right:0;line-height:inherit!important;padding:0 12px;padding:var(--action-sheet-close-icon-padding,0 12px);font-size:18px!important;font-size:var(--action-sheet-close-icon-size,18px)!important;color:#969799;color:var(--action-sheet-close-icon-color,#969799)}.van-action-sheet__loading{display:-webkit-flex!important;display:flex!important;height:50px;height:var(--action-sheet-item-height,50px)}
================================================
FILE: miniprogram/vant/area/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/area/index.js
================================================
import { VantComponent } from '../common/component';
import { pickerProps } from '../picker/shared';
const COLUMNSPLACEHOLDERCODE = '000000';
VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign(Object.assign({}, pickerProps), {
value: {
type: String,
observer(value) {
this.code = value;
this.setValues();
},
},
areaList: {
type: Object,
value: {},
observer: 'setValues',
},
columnsNum: {
type: null,
value: 3,
observer(value) {
this.setData({
displayColumns: this.data.columns.slice(0, +value),
});
},
},
columnsPlaceholder: {
type: Array,
observer(val) {
this.setData({
typeToColumnsPlaceholder: {
province: val[0] || '',
city: val[1] || '',
county: val[2] || '',
},
});
},
},
}),
data: {
columns: [{ values: [] }, { values: [] }, { values: [] }],
displayColumns: [{ values: [] }, { values: [] }, { values: [] }],
typeToColumnsPlaceholder: {},
},
mounted() {
setTimeout(() => {
this.setValues();
}, 0);
},
methods: {
getPicker() {
if (this.picker == null) {
this.picker = this.selectComponent('.van-area__picker');
}
return this.picker;
},
onCancel(event) {
this.emit('cancel', event.detail);
},
onConfirm(event) {
const { index } = event.detail;
let { value } = event.detail;
value = this.parseOutputValues(value);
this.emit('confirm', { value, index });
},
emit(type, detail) {
detail.values = detail.value;
delete detail.value;
this.$emit(type, detail);
},
// parse output columns data
parseOutputValues(values) {
const { columnsPlaceholder } = this.data;
return values.map((value, index) => {
// save undefined value
if (!value) return value;
value = JSON.parse(JSON.stringify(value));
if (!value.code || value.name === columnsPlaceholder[index]) {
value.code = '';
value.name = '';
}
return value;
});
},
onChange(event) {
const { index, picker, value } = event.detail;
this.code = value[index].code;
this.setValues().then(() => {
this.$emit('change', {
picker,
values: this.parseOutputValues(picker.getValues()),
index,
});
});
},
getConfig(type) {
const { areaList } = this.data;
return (areaList && areaList[`${type}_list`]) || {};
},
getList(type, code) {
const { typeToColumnsPlaceholder } = this.data;
let result = [];
if (type !== 'province' && !code) {
return result;
}
const list = this.getConfig(type);
result = Object.keys(list).map((code) => ({
code,
name: list[code],
}));
if (code) {
// oversea code
if (code[0] === '9' && type === 'city') {
code = '9';
}
result = result.filter((item) => item.code.indexOf(code) === 0);
}
if (typeToColumnsPlaceholder[type] && result.length) {
// set columns placeholder
const codeFill =
type === 'province'
? ''
: type === 'city'
? COLUMNSPLACEHOLDERCODE.slice(2, 4)
: COLUMNSPLACEHOLDERCODE.slice(4, 6);
result.unshift({
code: `${code}${codeFill}`,
name: typeToColumnsPlaceholder[type],
});
}
return result;
},
getIndex(type, code) {
let compareNum = type === 'province' ? 2 : type === 'city' ? 4 : 6;
const list = this.getList(type, code.slice(0, compareNum - 2));
// oversea code
if (code[0] === '9' && type === 'province') {
compareNum = 1;
}
code = code.slice(0, compareNum);
for (let i = 0; i < list.length; i++) {
if (list[i].code.slice(0, compareNum) === code) {
return i;
}
}
return 0;
},
setValues() {
const county = this.getConfig('county');
let { code } = this;
if (!code) {
if (this.data.columnsPlaceholder.length) {
code = COLUMNSPLACEHOLDERCODE;
} else if (Object.keys(county)[0]) {
code = Object.keys(county)[0];
} else {
code = '';
}
}
const province = this.getList('province');
const city = this.getList('city', code.slice(0, 2));
const picker = this.getPicker();
if (!picker) {
return;
}
const stack = [];
stack.push(picker.setColumnValues(0, province, false));
stack.push(picker.setColumnValues(1, city, false));
if (city.length && code.slice(2, 4) === '00') {
[{ code }] = city;
}
stack.push(
picker.setColumnValues(
2,
this.getList('county', code.slice(0, 4)),
false
)
);
return Promise.all(stack)
.catch(() => {})
.then(() =>
picker.setIndexes([
this.getIndex('province', code),
this.getIndex('city', code),
this.getIndex('county', code),
])
)
.catch(() => {});
},
getValues() {
const picker = this.getPicker();
return picker ? picker.getValues().filter((value) => !!value) : [];
},
getDetail() {
const values = this.getValues();
const area = {
code: '',
country: '',
province: '',
city: '',
county: '',
};
if (!values.length) {
return area;
}
const names = values.map((item) => item.name);
area.code = values[values.length - 1].code;
if (area.code[0] === '9') {
area.country = names[1] || '';
area.province = names[2] || '';
} else {
area.province = names[0] || '';
area.city = names[1] || '';
area.county = names[2] || '';
}
return area;
},
reset(code) {
this.code = code || '';
return this.setValues();
},
},
});
================================================
FILE: miniprogram/vant/area/index.json
================================================
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}
================================================
FILE: miniprogram/vant/area/index.wxml
================================================
================================================
FILE: miniprogram/vant/area/index.wxss
================================================
@import '../common/index.wxss';
================================================
FILE: miniprogram/vant/button/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/button/index.js
================================================
import { VantComponent } from '../common/component';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
mixins: [button, openType],
classes: ['hover-class', 'loading-class'],
data: {
baseStyle: '',
},
props: {
icon: String,
classPrefix: {
type: String,
value: 'van-icon',
},
plain: Boolean,
block: Boolean,
round: Boolean,
square: Boolean,
loading: Boolean,
hairline: Boolean,
disabled: Boolean,
loadingText: String,
customStyle: String,
loadingType: {
type: String,
value: 'circular',
},
type: {
type: String,
value: 'default',
},
dataset: null,
size: {
type: String,
value: 'normal',
},
loadingSize: {
type: String,
value: '20px',
},
color: {
type: String,
observer(color) {
let style = '';
if (color) {
style += `color: ${this.data.plain ? color : 'white'};`;
if (!this.data.plain) {
// Use background instead of backgroundColor to make linear-gradient work
style += `background: ${color};`;
}
// hide border when color is linear-gradient
if (color.indexOf('gradient') !== -1) {
style += 'border: 0;';
} else {
style += `border-color: ${color};`;
}
}
if (style !== this.data.baseStyle) {
this.setData({ baseStyle: style });
}
},
},
},
methods: {
onClick() {
if (!this.data.loading) {
this.$emit('click');
}
},
noop() {},
},
});
================================================
FILE: miniprogram/vant/button/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-loading": "../loading/index"
}
}
================================================
FILE: miniprogram/vant/button/index.wxml
================================================
{{ loadingText }}
function get(type, color,plain) {
if(plain) {
return color ? color: '#c9c9c9';
}
if(type === 'default') {
return '#c9c9c9';
}
return 'white';
}
module.exports = get;
================================================
FILE: miniprogram/vant/button/index.wxss
================================================
@import '../common/index.wxss';.van-button{position:relative;display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;padding:0;text-align:center;vertical-align:middle;-webkit-appearance:none;-webkit-text-size-adjust:100%;height:44px;height:var(--button-default-height,44px);line-height:20px;line-height:var(--button-line-height,20px);font-size:16px;font-size:var(--button-default-font-size,16px);transition:opacity .2s;transition:opacity var(--animation-duration-fast,.2s);border-radius:2px;border-radius:var(--button-border-radius,2px)}.van-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;border:inherit;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" ";background-color:#000;background-color:var(--black,#000);border-color:#000;border-color:var(--black,#000)}.van-button:after{border-width:0}.van-button--active:before{opacity:.15}.van-button--unclickable:after{display:none}.van-button--default{color:#323233;color:var(--button-default-color,#323233);background:#fff;background:var(--button-default-background-color,#fff);border:1px solid #ebedf0;border:var(--button-border-width,1px) solid var(--button-default-border-color,#ebedf0)}.van-button--primary{color:#fff;color:var(--button-primary-color,#fff);background:#07c160;background:var(--button-primary-background-color,#07c160);border:1px solid #07c160;border:var(--button-border-width,1px) solid var(--button-primary-border-color,#07c160)}.van-button--info{color:#fff;color:var(--button-info-color,#fff);background:#1989fa;background:var(--button-info-background-color,#1989fa);border:1px solid #1989fa;border:var(--button-border-width,1px) solid var(--button-info-border-color,#1989fa)}.van-button--danger{color:#fff;color:var(--button-danger-color,#fff);background:#ee0a24;background:var(--button-danger-background-color,#ee0a24);border:1px solid #ee0a24;border:var(--button-border-width,1px) solid var(--button-danger-border-color,#ee0a24)}.van-button--warning{color:#fff;color:var(--button-warning-color,#fff);background:#ff976a;background:var(--button-warning-background-color,#ff976a);border:1px solid #ff976a;border:var(--button-border-width,1px) solid var(--button-warning-border-color,#ff976a)}.van-button--plain{background:#fff;background:var(--button-plain-background-color,#fff)}.van-button--plain.van-button--primary{color:#07c160;color:var(--button-primary-background-color,#07c160)}.van-button--plain.van-button--info{color:#1989fa;color:var(--button-info-background-color,#1989fa)}.van-button--plain.van-button--danger{color:#ee0a24;color:var(--button-danger-background-color,#ee0a24)}.van-button--plain.van-button--warning{color:#ff976a;color:var(--button-warning-background-color,#ff976a)}.van-button--large{width:100%;height:50px;height:var(--button-large-height,50px)}.van-button--normal{padding:0 15px;font-size:14px;font-size:var(--button-normal-font-size,14px)}.van-button--small{min-width:60px;min-width:var(--button-small-min-width,60px);height:30px;height:var(--button-small-height,30px);padding:0 8px;padding:0 var(--padding-xs,8px);font-size:12px;font-size:var(--button-small-font-size,12px)}.van-button--mini{display:inline-block;min-width:50px;min-width:var(--button-mini-min-width,50px);height:22px;height:var(--button-mini-height,22px);font-size:10px;font-size:var(--button-mini-font-size,10px)}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{display:-webkit-flex;display:flex;width:100%}.van-button--round{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--square{border-radius:0}.van-button--disabled{opacity:.5;opacity:var(--button-disabled-opacity,.5)}.van-button__text{display:inline}.van-button__icon+.van-button__text:not(:empty),.van-button__loading-text{margin-left:4px}.van-button__icon{min-width:1em;line-height:inherit!important;vertical-align:top}.van-button--hairline{padding-top:1px;border-width:0}.van-button--hairline:after{border-color:inherit;border-width:1px;border-radius:4px;border-radius:calc(var(--button-border-radius, 2px)*2)}.van-button--hairline.van-button--round:after{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--hairline.van-button--square:after{border-radius:0}
================================================
FILE: miniprogram/vant/calendar/calendar.wxml
================================================
================================================
FILE: miniprogram/vant/calendar/components/header/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/calendar/components/header/index.js
================================================
import { VantComponent } from '../../../common/component';
VantComponent({
props: {
title: {
type: String,
value: '日期选择',
},
subtitle: String,
showTitle: Boolean,
showSubtitle: Boolean,
},
data: {
weekdays: ['日', '一', '二', '三', '四', '五', '六'],
},
methods: {},
});
================================================
FILE: miniprogram/vant/calendar/components/header/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/calendar/components/header/index.wxml
================================================
================================================
FILE: miniprogram/vant/calendar/components/header/index.wxss
================================================
@import '../../../common/index.wxss';.van-calendar__header{-webkit-flex-shrink:0;flex-shrink:0;box-shadow:0 2px 10px rgba(125,126,128,.16);box-shadow:var(--calendar-header-box-shadow,0 2px 10px rgba(125,126,128,.16))}.van-calendar__header-subtitle,.van-calendar__header-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__header-title+.van-calendar__header-title,.van-calendar__header-title:empty{display:none}.van-calendar__header-title:empty+.van-calendar__header-title{display:block!important}.van-calendar__weekdays{display:-webkit-flex;display:flex}.van-calendar__weekday{-webkit-flex:1;flex:1;text-align:center;font-size:12px;font-size:var(--calendar-weekdays-font-size,12px);line-height:30px;line-height:var(--calendar-weekdays-height,30px)}
================================================
FILE: miniprogram/vant/calendar/components/month/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/calendar/components/month/index.js
================================================
import { VantComponent } from '../../../common/component';
import {
getMonthEndDay,
compareDay,
getPrevDay,
getNextDay,
} from '../../utils';
VantComponent({
props: {
date: {
type: null,
observer: 'setDays',
},
type: {
type: String,
observer: 'setDays',
},
color: String,
minDate: {
type: null,
observer: 'setDays',
},
maxDate: {
type: null,
observer: 'setDays',
},
showMark: Boolean,
rowHeight: [Number, String],
formatter: {
type: null,
observer: 'setDays',
},
currentDate: {
type: [null, Array],
observer: 'setDays',
},
allowSameDay: Boolean,
showSubtitle: Boolean,
showMonthTitle: Boolean,
},
data: {
visible: true,
days: [],
},
methods: {
onClick(event) {
const { index } = event.currentTarget.dataset;
const item = this.data.days[index];
if (item.type !== 'disabled') {
this.$emit('click', item);
}
},
setDays() {
const days = [];
const startDate = new Date(this.data.date);
const year = startDate.getFullYear();
const month = startDate.getMonth();
const totalDay = getMonthEndDay(
startDate.getFullYear(),
startDate.getMonth() + 1
);
for (let day = 1; day <= totalDay; day++) {
const date = new Date(year, month, day);
const type = this.getDayType(date);
let config = {
date,
type,
text: day,
bottomInfo: this.getBottomInfo(type),
};
if (this.data.formatter) {
config = this.data.formatter(config);
}
days.push(config);
}
this.setData({ days });
},
getMultipleDayType(day) {
const { currentDate } = this.data;
if (!Array.isArray(currentDate)) {
return '';
}
const isSelected = (date) =>
currentDate.some((item) => compareDay(item, date) === 0);
if (isSelected(day)) {
const prevDay = getPrevDay(day);
const nextDay = getNextDay(day);
const prevSelected = isSelected(prevDay);
const nextSelected = isSelected(nextDay);
if (prevSelected && nextSelected) {
return 'multiple-middle';
}
if (prevSelected) {
return 'end';
}
return nextSelected ? 'start' : 'multiple-selected';
}
return '';
},
getRangeDayType(day) {
const { currentDate, allowSameDay } = this.data;
if (!Array.isArray(currentDate)) {
return;
}
const [startDay, endDay] = currentDate;
if (!startDay) {
return;
}
const compareToStart = compareDay(day, startDay);
if (!endDay) {
return compareToStart === 0 ? 'start' : '';
}
const compareToEnd = compareDay(day, endDay);
if (compareToStart === 0 && compareToEnd === 0 && allowSameDay) {
return 'start-end';
}
if (compareToStart === 0) {
return 'start';
}
if (compareToEnd === 0) {
return 'end';
}
if (compareToStart > 0 && compareToEnd < 0) {
return 'middle';
}
},
getDayType(day) {
const { type, minDate, maxDate, currentDate } = this.data;
if (compareDay(day, minDate) < 0 || compareDay(day, maxDate) > 0) {
return 'disabled';
}
if (type === 'single') {
return compareDay(day, currentDate) === 0 ? 'selected' : '';
}
if (type === 'multiple') {
return this.getMultipleDayType(day);
}
/* istanbul ignore else */
if (type === 'range') {
return this.getRangeDayType(day);
}
},
getBottomInfo(type) {
if (this.data.type === 'range') {
if (type === 'start') {
return '开始';
}
if (type === 'end') {
return '结束';
}
if (type === 'start-end') {
return '开始/结束';
}
}
},
},
});
================================================
FILE: miniprogram/vant/calendar/components/month/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/calendar/components/month/index.wxml
================================================
{{ computed.formatMonthTitle(date) }}
{{ computed.getMark(date) }}
{{ item.topInfo }}
{{ item.text }}
{{ item.bottomInfo }}
{{ item.topInfo }}
{{ item.text }}
{{ item.bottomInfo }}
================================================
FILE: miniprogram/vant/calendar/components/month/index.wxs
================================================
/* eslint-disable */
var utils = require('../../utils.wxs');
function getMark(date) {
return getDate(date).getMonth() + 1;
}
var ROW_HEIGHT = 64;
function getDayStyle(type, index, date, rowHeight, color) {
var style = [];
var offset = getDate(date).getDay();
if (index === 0) {
style.push(['margin-left', (100 * offset) / 7 + '%']);
}
if (rowHeight !== ROW_HEIGHT) {
style.push(['height', rowHeight + 'px']);
}
if (color) {
if (
type === 'start' ||
type === 'end' ||
type === 'multiple-selected' ||
type === 'multiple-middle'
) {
style.push(['background', color]);
} else if (type === 'middle') {
style.push(['color', color]);
}
}
return style
.map(function(item) {
return item.join(':');
})
.join(';');
}
function formatMonthTitle(date) {
date = getDate(date);
return date.getFullYear() + '年' + (date.getMonth() + 1) + '月';
}
function getMonthStyle(visible, date, rowHeight) {
if (!visible) {
date = getDate(date);
var totalDay = utils.getMonthEndDay(
date.getFullYear(),
date.getMonth() + 1
);
var offset = getDate(date).getDay();
var padding = Math.ceil((totalDay + offset) / 7) * rowHeight;
return 'padding-bottom:' + padding + 'px';
}
}
module.exports = {
getMark: getMark,
getDayStyle: getDayStyle,
formatMonthTitle: formatMonthTitle,
getMonthStyle: getMonthStyle
};
================================================
FILE: miniprogram/vant/calendar/components/month/index.wxss
================================================
@import '../../../common/index.wxss';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;height:100%;background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__month-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);font-size:14px;font-size:var(--calendar-month-title-font-size,14px);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__days{position:relative;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-user-select:none;user-select:none}.van-calendar__month-mark{position:absolute;top:50%;left:50%;z-index:0;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);pointer-events:none;color:rgba(242,243,245,.8);color:var(--calendar-month-mark-color,rgba(242,243,245,.8));font-size:160px;font-size:var(--calendar-month-mark-font-size,160px)}.van-calendar__day,.van-calendar__selected-day{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;text-align:center}.van-calendar__day{position:relative;width:14.285%;height:64px;height:var(--calendar-day-height,64px);font-size:16px;font-size:var(--calendar-day-font-size,16px)}.van-calendar__day--end,.van-calendar__day--multiple-middle,.van-calendar__day--multiple-selected,.van-calendar__day--start,.van-calendar__day--start-end{color:#fff;color:var(--calendar-range-edge-color,#fff);background-color:#ee0a24;background-color:var(--calendar-range-edge-background-color,#ee0a24)}.van-calendar__day--start{border-radius:4px 0 0 4px;border-radius:var(--border-radius-md,4px) 0 0 var(--border-radius-md,4px)}.van-calendar__day--end{border-radius:0 4px 4px 0;border-radius:0 var(--border-radius-md,4px) var(--border-radius-md,4px) 0}.van-calendar__day--multiple-selected,.van-calendar__day--start-end{border-radius:4px;border-radius:var(--border-radius-md,4px)}.van-calendar__day--middle{color:#ee0a24;color:var(--calendar-range-middle-color,#ee0a24)}.van-calendar__day--middle:after{position:absolute;top:0;right:0;bottom:0;left:0;background-color:currentColor;content:"";opacity:.1;opacity:var(--calendar-range-middle-background-opacity,.1)}.van-calendar__day--disabled{cursor:default;color:#c8c9cc;color:var(--calendar-day-disabled-color,#c8c9cc)}.van-calendar__bottom-info,.van-calendar__top-info{position:absolute;right:0;left:0;font-size:10px;font-size:var(--calendar-info-font-size,10px);line-height:14px;line-height:var(--calendar-info-line-height,14px)}@media (max-width:350px){.van-calendar__bottom-info,.van-calendar__top-info{font-size:9px}}.van-calendar__top-info{top:6px}.van-calendar__bottom-info{bottom:6px}.van-calendar__selected-day{width:54px;width:var(--calendar-selected-day-size,54px);height:54px;height:var(--calendar-selected-day-size,54px);color:#fff;color:var(--calendar-selected-day-color,#fff);background-color:#ee0a24;background-color:var(--calendar-selected-day-background-color,#ee0a24);border-radius:4px;border-radius:var(--border-radius-md,4px)}
================================================
FILE: miniprogram/vant/calendar/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/calendar/index.js
================================================
import { VantComponent } from '../common/component';
import {
ROW_HEIGHT,
getNextDay,
compareDay,
copyDates,
calcDateNum,
formatMonthTitle,
compareMonth,
getMonths,
getDayByOffset,
} from './utils';
import Toast from '../toast/toast';
VantComponent({
props: {
title: {
type: String,
value: '日期选择',
},
color: String,
show: {
type: Boolean,
observer(val) {
if (val) {
this.initRect();
this.scrollIntoView();
}
},
},
formatter: null,
confirmText: {
type: String,
value: '确定',
},
rangePrompt: String,
defaultDate: {
type: [Number, Array],
observer(val) {
this.setData({ currentDate: val });
this.scrollIntoView();
},
},
allowSameDay: Boolean,
confirmDisabledText: String,
type: {
type: String,
value: 'single',
observer: 'reset',
},
minDate: {
type: null,
value: Date.now(),
},
maxDate: {
type: null,
value: new Date(
new Date().getFullYear(),
new Date().getMonth() + 6,
new Date().getDate()
).getTime(),
},
position: {
type: String,
value: 'bottom',
},
rowHeight: {
type: [Number, String],
value: ROW_HEIGHT,
},
round: {
type: Boolean,
value: true,
},
poppable: {
type: Boolean,
value: true,
},
showMark: {
type: Boolean,
value: true,
},
showTitle: {
type: Boolean,
value: true,
},
showConfirm: {
type: Boolean,
value: true,
},
showSubtitle: {
type: Boolean,
value: true,
},
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
closeOnClickOverlay: {
type: Boolean,
value: true,
},
maxRange: {
type: [Number, String],
value: null,
},
},
data: {
subtitle: '',
currentDate: null,
scrollIntoView: '',
},
created() {
this.setData({
currentDate: this.getInitialDate(),
});
},
mounted() {
if (this.data.show || !this.data.poppable) {
this.initRect();
this.scrollIntoView();
}
},
methods: {
reset() {
this.setData({ currentDate: this.getInitialDate() });
this.scrollIntoView();
},
initRect() {
if (this.contentObserver != null) {
this.contentObserver.disconnect();
}
const contentObserver = this.createIntersectionObserver({
thresholds: [0, 0.1, 0.9, 1],
observeAll: true,
});
this.contentObserver = contentObserver;
contentObserver.relativeTo('.van-calendar__body');
contentObserver.observe('.month', (res) => {
if (res.boundingClientRect.top <= res.relativeRect.top) {
// @ts-ignore
this.setData({ subtitle: formatMonthTitle(res.dataset.date) });
}
});
},
getInitialDate() {
const { type, defaultDate, minDate } = this.data;
if (type === 'range') {
const [startDay, endDay] = defaultDate || [];
return [
startDay || minDate,
endDay || getNextDay(new Date(minDate)).getTime(),
];
}
if (type === 'multiple') {
return [defaultDate || minDate];
}
return defaultDate || minDate;
},
scrollIntoView() {
setTimeout(() => {
const {
currentDate,
type,
show,
poppable,
minDate,
maxDate,
} = this.data;
const targetDate = type === 'single' ? currentDate : currentDate[0];
const displayed = show || !poppable;
if (!targetDate || !displayed) {
return;
}
const months = getMonths(minDate, maxDate);
months.some((month, index) => {
if (compareMonth(month, targetDate) === 0) {
this.setData({ scrollIntoView: `month${index}` });
return true;
}
return false;
});
}, 100);
},
onOpen() {
this.$emit('open');
},
onOpened() {
this.$emit('opened');
},
onClose() {
this.$emit('close');
},
onClosed() {
this.$emit('closed');
},
onClickDay(event) {
const { date } = event.detail;
const { type, currentDate, allowSameDay } = this.data;
if (type === 'range') {
const [startDay, endDay] = currentDate;
if (startDay && !endDay) {
const compareToStart = compareDay(date, startDay);
if (compareToStart === 1) {
this.select([startDay, date], true);
} else if (compareToStart === -1) {
this.select([date, null]);
} else if (allowSameDay) {
this.select([date, date]);
}
} else {
this.select([date, null]);
}
} else if (type === 'multiple') {
let selectedIndex;
const selected = currentDate.some((dateItem, index) => {
const equal = compareDay(dateItem, date) === 0;
if (equal) {
selectedIndex = index;
}
return equal;
});
if (selected) {
const cancelDate = currentDate.splice(selectedIndex, 1);
this.setData({ currentDate });
this.unselect(cancelDate);
} else {
this.select([...currentDate, date]);
}
} else {
this.select(date, true);
}
},
unselect(dateArray) {
const date = dateArray[0];
if (date) {
this.$emit('unselect', copyDates(date));
}
},
select(date, complete) {
if (complete && this.data.type === 'range') {
const valid = this.checkRange(date);
if (!valid) {
// auto selected to max range if showConfirm
if (this.data.showConfirm) {
this.emit([
date[0],
getDayByOffset(date[0], this.data.maxRange - 1),
]);
} else {
this.emit(date);
}
return;
}
}
this.emit(date);
if (complete && !this.data.showConfirm) {
this.onConfirm();
}
},
emit(date) {
const getTime = (date) => (date instanceof Date ? date.getTime() : date);
this.setData({
currentDate: Array.isArray(date) ? date.map(getTime) : getTime(date),
});
this.$emit('select', copyDates(date));
},
checkRange(date) {
const { maxRange, rangePrompt } = this.data;
if (maxRange && calcDateNum(date) > maxRange) {
Toast({
context: this,
message: rangePrompt || `选择天数不能超过 ${maxRange} 天`,
});
return false;
}
return true;
},
onConfirm() {
if (this.data.type === 'range' && !this.checkRange()) {
return;
}
wx.nextTick(() => {
this.$emit('confirm', copyDates(this.data.currentDate));
});
},
},
});
================================================
FILE: miniprogram/vant/calendar/index.json
================================================
{
"component": true,
"usingComponents": {
"header": "./components/header/index",
"month": "./components/month/index",
"van-button": "../button/index",
"van-popup": "../popup/index"
}
}
================================================
FILE: miniprogram/vant/calendar/index.wxml
================================================
================================================
FILE: miniprogram/vant/calendar/index.wxs
================================================
/* eslint-disable */
var utils = require('./utils.wxs');
function getMonths(minDate, maxDate) {
var months = [];
var cursor = getDate(minDate);
cursor.setDate(1);
do {
months.push(cursor.getTime());
cursor.setMonth(cursor.getMonth() + 1);
} while (utils.compareMonth(cursor, getDate(maxDate)) !== 1);
return months;
}
function getButtonDisabled(type, currentDate) {
if (currentDate == null) {
return true;
}
if (type === 'range') {
return !currentDate[0] || !currentDate[1];
}
if (type === 'multiple') {
return !currentDate.length;
}
return !currentDate;
}
module.exports = {
getMonths: getMonths,
getButtonDisabled: getButtonDisabled
};
================================================
FILE: miniprogram/vant/calendar/index.wxss
================================================
@import '../common/index.wxss';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;height:100%;height:var(--calendar-height,100%);background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__close-icon{top:11px}.van-calendar__popup--bottom,.van-calendar__popup--top{height:80%;height:var(--calendar-popup-height,80%)}.van-calendar__popup--left,.van-calendar__popup--right{height:100%}.van-calendar__body{-webkit-flex:1;flex:1;overflow:auto;-webkit-overflow-scrolling:touch}.van-calendar__footer{-webkit-flex-shrink:0;flex-shrink:0;padding:0 16px;padding:0 var(--padding-md,16px)}.van-calendar__footer--safe-area-inset-bottom{padding-bottom:env(safe-area-inset-bottom)}.van-calendar__footer+.van-calendar__footer,.van-calendar__footer:empty{display:none}.van-calendar__footer:empty+.van-calendar__footer{display:block!important}.van-calendar__confirm{height:36px!important;height:var(--calendar-confirm-button-height,36px)!important;margin:7px 0!important;margin:var(--calendar-confirm-button-margin,7px 0)!important;line-height:34px!important;line-height:var(--calendar-confirm-button-line-height,34px)!important}
================================================
FILE: miniprogram/vant/calendar/utils.d.ts
================================================
export declare const ROW_HEIGHT = 64;
export declare function formatMonthTitle(date: Date): string;
export declare function compareMonth(
date1: Date | number,
date2: Date | number
): 0 | 1 | -1;
export declare function compareDay(
day1: Date | number,
day2: Date | number
): 0 | 1 | -1;
export declare function getDayByOffset(date: Date, offset: number): Date;
export declare function getPrevDay(date: Date): Date;
export declare function getNextDay(date: Date): Date;
export declare function calcDateNum(date: [Date, Date]): number;
export declare function copyDates(dates: Date | Date[]): Date | Date[];
export declare function getMonthEndDay(year: number, month: number): number;
export declare function getMonths(minDate: number, maxDate: number): any[];
================================================
FILE: miniprogram/vant/calendar/utils.js
================================================
export const ROW_HEIGHT = 64;
export function formatMonthTitle(date) {
if (!(date instanceof Date)) {
date = new Date(date);
}
return `${date.getFullYear()}年${date.getMonth() + 1}月`;
}
export function compareMonth(date1, date2) {
if (!(date1 instanceof Date)) {
date1 = new Date(date1);
}
if (!(date2 instanceof Date)) {
date2 = new Date(date2);
}
const year1 = date1.getFullYear();
const year2 = date2.getFullYear();
const month1 = date1.getMonth();
const month2 = date2.getMonth();
if (year1 === year2) {
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
}
return year1 > year2 ? 1 : -1;
}
export function compareDay(day1, day2) {
if (!(day1 instanceof Date)) {
day1 = new Date(day1);
}
if (!(day2 instanceof Date)) {
day2 = new Date(day2);
}
const compareMonthResult = compareMonth(day1, day2);
if (compareMonthResult === 0) {
const date1 = day1.getDate();
const date2 = day2.getDate();
return date1 === date2 ? 0 : date1 > date2 ? 1 : -1;
}
return compareMonthResult;
}
export function getDayByOffset(date, offset) {
date = new Date(date);
date.setDate(date.getDate() + offset);
return date;
}
export function getPrevDay(date) {
return getDayByOffset(date, -1);
}
export function getNextDay(date) {
return getDayByOffset(date, 1);
}
export function calcDateNum(date) {
const day1 = new Date(date[0]).getTime();
const day2 = new Date(date[1]).getTime();
return (day2 - day1) / (1000 * 60 * 60 * 24) + 1;
}
export function copyDates(dates) {
if (Array.isArray(dates)) {
return dates.map((date) => {
if (date === null) {
return date;
}
return new Date(date);
});
}
return new Date(dates);
}
export function getMonthEndDay(year, month) {
return 32 - new Date(year, month - 1, 32).getDate();
}
export function getMonths(minDate, maxDate) {
const months = [];
const cursor = new Date(minDate);
cursor.setDate(1);
do {
months.push(cursor.getTime());
cursor.setMonth(cursor.getMonth() + 1);
} while (compareMonth(cursor, maxDate) !== 1);
return months;
}
================================================
FILE: miniprogram/vant/calendar/utils.wxs
================================================
/* eslint-disable */
function getMonthEndDay(year, month) {
return 32 - getDate(year, month - 1, 32).getDate();
}
function compareMonth(date1, date2) {
date1 = getDate(date1);
date2 = getDate(date2);
var year1 = date1.getFullYear();
var year2 = date2.getFullYear();
var month1 = date1.getMonth();
var month2 = date2.getMonth();
if (year1 === year2) {
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
}
return year1 > year2 ? 1 : -1;
}
module.exports = {
getMonthEndDay: getMonthEndDay,
compareMonth: compareMonth
};
================================================
FILE: miniprogram/vant/card/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/card/index.js
================================================
import { link } from '../mixins/link';
import { VantComponent } from '../common/component';
VantComponent({
classes: [
'num-class',
'desc-class',
'thumb-class',
'title-class',
'price-class',
'origin-price-class',
],
mixins: [link],
props: {
tag: String,
num: String,
desc: String,
thumb: String,
title: String,
price: {
type: String,
observer: 'updatePrice',
},
centered: Boolean,
lazyLoad: Boolean,
thumbLink: String,
originPrice: String,
thumbMode: {
type: String,
value: 'aspectFit',
},
currency: {
type: String,
value: '¥',
},
},
methods: {
updatePrice() {
const { price } = this.data;
const priceArr = price.toString().split('.');
this.setData({
integerStr: priceArr[0],
decimalStr: priceArr[1] ? `.${priceArr[1]}` : '',
});
},
onClickThumb() {
this.jumpLink('thumbLink');
},
},
});
================================================
FILE: miniprogram/vant/card/index.json
================================================
{
"component": true,
"usingComponents": {
"van-tag": "../tag/index"
}
}
================================================
FILE: miniprogram/vant/card/index.wxml
================================================
================================================
FILE: miniprogram/vant/card/index.wxss
================================================
@import '../common/index.wxss';.van-card{position:relative;box-sizing:border-box;padding:8px 16px;padding:var(--card-padding,8px 16px);font-size:12px;font-size:var(--card-font-size,12px);color:#323233;color:var(--card-text-color,#323233);background-color:#fafafa;background-color:var(--card-background-color,#fafafa)}.van-card__header{display:-webkit-flex;display:flex}.van-card__header--center{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-card__thumb{position:relative;-webkit-flex:none;flex:none;width:88px;width:var(--card-thumb-size,88px);height:88px;height:var(--card-thumb-size,88px);margin-right:8px;margin-right:var(--padding-xs,8px)}.van-card__thumb:empty{display:none}.van-card__img{width:100%;height:100%;border-radius:8px;border-radius:var(--border-radius-lg,8px)}.van-card__content{position:relative;display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:space-between;justify-content:space-between;min-width:0;min-height:88px;min-height:var(--card-thumb-size,88px)}.van-card__content--center{-webkit-justify-content:center;justify-content:center}.van-card__desc,.van-card__title{word-wrap:break-word}.van-card__title{font-weight:700;line-height:16px;line-height:var(--card-title-line-height,16px)}.van-card__desc{line-height:20px;line-height:var(--card-desc-line-height,20px);color:#646566;color:var(--card-desc-color,#646566)}.van-card__bottom{line-height:20px}.van-card__price{display:inline-block;font-weight:700;color:#ee0a24;color:var(--card-price-color,#ee0a24);font-size:12px;font-size:var(--card-price-font-size,12px)}.van-card__price-integer{font-size:16px;font-size:var(--card-price-integer-font-size,16px)}.van-card__price-decimal,.van-card__price-integer{font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--card-price-font-family,Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif)}.van-card__origin-price{display:inline-block;margin-left:5px;text-decoration:line-through;font-size:10px;font-size:var(--card-origin-price-font-size,10px);color:#646566;color:var(--card-origin-price-color,#646566)}.van-card__num{float:right}.van-card__tag{position:absolute;top:2px;left:0}.van-card__footer{-webkit-flex:none;flex:none;width:100%;text-align:right}
================================================
FILE: miniprogram/vant/cell/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/cell/index.js
================================================
import { link } from '../mixins/link';
import { VantComponent } from '../common/component';
VantComponent({
classes: [
'title-class',
'label-class',
'value-class',
'right-icon-class',
'hover-class',
],
mixins: [link],
props: {
title: null,
value: null,
icon: String,
size: String,
label: String,
center: Boolean,
isLink: Boolean,
required: Boolean,
clickable: Boolean,
titleWidth: String,
customStyle: String,
arrowDirection: String,
useLabelSlot: Boolean,
border: {
type: Boolean,
value: true,
},
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
},
},
});
================================================
FILE: miniprogram/vant/cell/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/cell/index.wxml
================================================
{{ title }}
{{ label }}
{{ value }}
================================================
FILE: miniprogram/vant/cell/index.wxss
================================================
@import '../common/index.wxss';.van-cell{position:relative;display:-webkit-flex;display:flex;box-sizing:border-box;width:100%;padding:10px 16px;padding:var(--cell-vertical-padding,10px) var(--cell-horizontal-padding,16px);font-size:14px;font-size:var(--cell-font-size,14px);line-height:24px;line-height:var(--cell-line-height,24px);color:#323233;color:var(--cell-text-color,#323233);background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:auto;right:0;bottom:0;left:16px;border-bottom:1px solid #ebedf0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell__label{margin-top:3px;margin-top:var(--cell-label-margin-top,3px);font-size:12px;font-size:var(--cell-label-font-size,12px);line-height:18px;line-height:var(--cell-label-line-height,18px);color:#969799;color:var(--cell-label-color,#969799)}.van-cell__value{overflow:hidden;text-align:right;vertical-align:middle;color:#969799;color:var(--cell-value-color,#969799)}.van-cell__title,.van-cell__value{-webkit-flex:1;flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:24px;height:var(--cell-line-height,24px);font-size:16px;font-size:var(--cell-icon-size,16px)}.van-cell__left-icon-wrap{margin-right:5px}.van-cell__right-icon-wrap{margin-left:5px;color:#969799;color:var(--cell-right-icon-color,#969799)}.van-cell__left-icon{vertical-align:middle}.van-cell__left-icon,.van-cell__right-icon{line-height:24px;line-height:var(--cell-line-height,24px)}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5;background-color:var(--cell-active-color,#f2f3f5)}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;content:"*";left:8px;left:var(--padding-xs,8px);font-size:14px;font-size:var(--cell-font-size,14px);color:#ee0a24;color:var(--cell-required-color,#ee0a24)}.van-cell--center{-webkit-align-items:center;align-items:center}.van-cell--large{padding-top:12px;padding-top:var(--cell-large-vertical-padding,12px);padding-bottom:12px;padding-bottom:var(--cell-large-vertical-padding,12px)}.van-cell--large .van-cell__title{font-size:16px;font-size:var(--cell-large-title-font-size,16px)}.van-cell--large .van-cell__value{font-size:16px;font-size:var(--cell-large-value-font-size,16px)}.van-cell--large .van-cell__label{font-size:14px;font-size:var(--cell-large-label-font-size,14px)}
================================================
FILE: miniprogram/vant/cell-group/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/cell-group/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
props: {
title: String,
border: {
type: Boolean,
value: true,
},
},
});
================================================
FILE: miniprogram/vant/cell-group/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/cell-group/index.wxml
================================================
{{ title }}
================================================
FILE: miniprogram/vant/cell-group/index.wxss
================================================
@import '../common/index.wxss';.van-cell-group__title{padding:16px 16px 8px;padding:var(--cell-group-title-padding,16px 16px 8px);font-size:14px;font-size:var(--cell-group-title-font-size,14px);line-height:16px;line-height:var(--cell-group-title-line-height,16px);color:#969799;color:var(--cell-group-title-color,#969799)}
================================================
FILE: miniprogram/vant/checkbox/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/checkbox/index.js
================================================
import { VantComponent } from '../common/component';
function emit(target, value) {
target.$emit('input', value);
target.$emit('change', value);
}
VantComponent({
field: true,
relation: {
name: 'checkbox-group',
type: 'ancestor',
current: 'checkbox',
},
classes: ['icon-class', 'label-class'],
props: {
value: Boolean,
disabled: Boolean,
useIconSlot: Boolean,
checkedColor: String,
labelPosition: String,
labelDisabled: Boolean,
shape: {
type: String,
value: 'round',
},
iconSize: {
type: null,
value: 20,
},
},
data: {
parentDisabled: false,
},
methods: {
emitChange(value) {
if (this.parent) {
this.setParentValue(this.parent, value);
} else {
emit(this, value);
}
},
toggle() {
const { parentDisabled, disabled, value } = this.data;
if (!disabled && !parentDisabled) {
this.emitChange(!value);
}
},
onClickLabel() {
const { labelDisabled, parentDisabled, disabled, value } = this.data;
if (!disabled && !labelDisabled && !parentDisabled) {
this.emitChange(!value);
}
},
setParentValue(parent, value) {
const parentValue = parent.data.value.slice();
const { name } = this.data;
const { max } = parent.data;
if (value) {
if (max && parentValue.length >= max) {
return;
}
if (parentValue.indexOf(name) === -1) {
parentValue.push(name);
emit(parent, parentValue);
}
} else {
const index = parentValue.indexOf(name);
if (index !== -1) {
parentValue.splice(index, 1);
emit(parent, parentValue);
}
}
},
},
});
================================================
FILE: miniprogram/vant/checkbox/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/checkbox/index.wxml
================================================
================================================
FILE: miniprogram/vant/checkbox/index.wxs
================================================
/* eslint-disable */
var utils = require('../wxs/utils.wxs');
function iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) {
var styles = [['font-size', utils.addUnit(iconSize)]];
if (checkedColor && value && !disabled && !parentDisabled) {
styles.push(['border-color', checkedColor]);
styles.push(['background-color', checkedColor]);
}
return styles
.map(function(item) {
return item.join(':');
})
.join(';');
}
module.exports = {
iconStyle: iconStyle
};
================================================
FILE: miniprogram/vant/checkbox/index.wxss
================================================
@import '../common/index.wxss';.van-checkbox{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox__icon-wrap,.van-checkbox__label{line-height:20px;line-height:var(--checkbox-size,20px)}.van-checkbox__icon-wrap{-webkit-flex:none;flex:none}.van-checkbox__icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:1em;height:1em;color:transparent;text-align:center;transition-property:color,border-color,background-color;font-size:20px;font-size:var(--checkbox-size,20px);border:1px solid #c8c9cc;border:1px solid var(--checkbox-border-color,#c8c9cc);transition-duration:.2s;transition-duration:var(--checkbox-transition-duration,.2s)}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{color:#fff;color:var(--white,#fff);background-color:#1989fa;background-color:var(--checkbox-checked-icon-color,#1989fa);border-color:#1989fa;border-color:var(--checkbox-checked-icon-color,#1989fa)}.van-checkbox__icon--disabled{background-color:#ebedf0;background-color:var(--checkbox-disabled-background-color,#ebedf0);border-color:#c8c9cc;border-color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:#c8c9cc;color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__label{word-wrap:break-word;margin-left:10px;margin-left:var(--checkbox-label-margin,10px);color:#323233;color:var(--checkbox-label-color,#323233)}.van-checkbox__label--left{float:left;margin:0 10px 0 0;margin:0 var(--checkbox-label-margin,10px) 0 0}.van-checkbox__label--disabled{color:#c8c9cc;color:var(--checkbox-disabled-label-color,#c8c9cc)}.van-checkbox__label:empty{margin:0}
================================================
FILE: miniprogram/vant/checkbox-group/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/checkbox-group/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'checkbox',
type: 'descendant',
current: 'checkbox-group',
linked(target) {
this.updateChild(target);
},
},
props: {
max: Number,
value: {
type: Array,
observer: 'updateChildren',
},
disabled: {
type: Boolean,
observer: 'updateChildren',
},
},
methods: {
updateChildren() {
(this.children || []).forEach((child) => this.updateChild(child));
},
updateChild(child) {
const { value, disabled } = this.data;
child.setData({
value: value.indexOf(child.data.name) !== -1,
parentDisabled: disabled,
});
},
},
});
================================================
FILE: miniprogram/vant/checkbox-group/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/checkbox-group/index.wxml
================================================
================================================
FILE: miniprogram/vant/checkbox-group/index.wxss
================================================
@import '../common/index.wxss';
================================================
FILE: miniprogram/vant/circle/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/circle/index.js
================================================
import { VantComponent } from '../common/component';
import { isObj } from '../common/utils';
import { BLUE, WHITE } from '../common/color';
function format(rate) {
return Math.min(Math.max(rate, 0), 100);
}
const PERIMETER = 2 * Math.PI;
const BEGIN_ANGLE = -Math.PI / 2;
const STEP = 1;
VantComponent({
props: {
text: String,
lineCap: {
type: String,
value: 'round',
},
value: {
type: Number,
value: 0,
observer: 'reRender',
},
speed: {
type: Number,
value: 50,
},
size: {
type: Number,
value: 100,
},
fill: String,
layerColor: {
type: String,
value: WHITE,
},
color: {
type: [String, Object],
value: BLUE,
observer: 'setHoverColor',
},
type: {
type: String,
value: '',
},
strokeWidth: {
type: Number,
value: 4,
},
clockwise: {
type: Boolean,
value: true,
},
},
data: {
hoverColor: BLUE,
},
methods: {
getContext() {
if (!this.ctx) {
this.ctx = wx.createCanvasContext('van-circle', this);
}
return this.ctx;
},
setHoverColor() {
const { color, size, type } = this.data;
const context = type ? this.getContext(type) : this.getContext();
let hoverColor = color;
if (isObj(color)) {
const LinearColor = context.createLinearGradient(size, 0, 0, 0);
Object.keys(color)
.sort((a, b) => parseFloat(a) - parseFloat(b))
.map((key) =>
LinearColor.addColorStop(parseFloat(key) / 100, color[key])
);
hoverColor = LinearColor;
}
this.setData({ hoverColor });
},
presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
const { strokeWidth, lineCap, clockwise, size } = this.data;
const position = size / 2;
const radius = position - strokeWidth / 2;
context.setStrokeStyle(strokeStyle);
context.setLineWidth(strokeWidth);
context.setLineCap(lineCap);
context.beginPath();
context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
context.stroke();
if (fill) {
context.setFillStyle(fill);
context.fill();
}
},
renderLayerCircle(context) {
const { layerColor, fill } = this.data;
this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
},
renderHoverCircle(context, formatValue) {
const { clockwise, hoverColor } = this.data;
// 结束角度
const progress = PERIMETER * (formatValue / 100);
const endAngle = clockwise
? BEGIN_ANGLE + progress
: 3 * Math.PI - (BEGIN_ANGLE + progress);
this.presetCanvas(context, hoverColor, BEGIN_ANGLE, endAngle);
},
drawCircle(currentValue) {
const { size, type } = this.data;
const context = type ? this.getContext(type) : this.getContext();
context.clearRect(0, 0, size, size);
this.renderLayerCircle(context);
const formatValue = format(currentValue);
if (formatValue !== 0) {
this.renderHoverCircle(context, formatValue);
}
context.draw();
},
reRender() {
// tofector 动画暂时没有想到好的解决方案
const { value, speed } = this.data;
if (speed <= 0 || speed > 1000) {
this.drawCircle(value);
return;
}
this.clearInterval();
this.currentValue = this.currentValue || 0;
this.interval = setInterval(() => {
if (this.currentValue !== value) {
if (this.currentValue < value) {
this.currentValue += STEP;
} else {
this.currentValue -= STEP;
}
this.drawCircle(this.currentValue);
} else {
this.clearInterval();
}
}, 1000 / speed);
},
clearInterval() {
if (this.interval) {
clearInterval(this.interval);
this.interval = null;
}
},
},
created() {
const { value } = this.data;
this.currentValue = value;
this.drawCircle(value);
},
destroyed() {
this.ctx = null;
this.clearInterval();
},
});
================================================
FILE: miniprogram/vant/circle/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/circle/index.wxml
================================================
{{ text }}
================================================
FILE: miniprogram/vant/circle/index.wxss
================================================
@import '../common/index.wxss';.van-circle{position:relative;display:inline-block;text-align:center}.van-circle__text{position:absolute;top:50%;left:0;width:100%;-webkit-transform:translateY(-50%);transform:translateY(-50%);color:#323233;color:var(--circle-text-color,#323233)}
================================================
FILE: miniprogram/vant/col/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/col/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'row',
type: 'ancestor',
current: 'col',
},
props: {
span: Number,
offset: Number,
},
data: {
viewStyle: '',
},
methods: {
setGutter(gutter) {
const padding = `${gutter / 2}px`;
const viewStyle = gutter
? `padding-left: ${padding}; padding-right: ${padding};`
: '';
if (viewStyle !== this.data.viewStyle) {
this.setData({ viewStyle });
}
},
},
});
================================================
FILE: miniprogram/vant/col/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/col/index.wxml
================================================
================================================
FILE: miniprogram/vant/col/index.wxss
================================================
@import '../common/index.wxss';.van-col{float:left;box-sizing:border-box}.van-col--1{width:4.16666667%}.van-col--offset-1{margin-left:4.16666667%}.van-col--2{width:8.33333333%}.van-col--offset-2{margin-left:8.33333333%}.van-col--3{width:12.5%}.van-col--offset-3{margin-left:12.5%}.van-col--4{width:16.66666667%}.van-col--offset-4{margin-left:16.66666667%}.van-col--5{width:20.83333333%}.van-col--offset-5{margin-left:20.83333333%}.van-col--6{width:25%}.van-col--offset-6{margin-left:25%}.van-col--7{width:29.16666667%}.van-col--offset-7{margin-left:29.16666667%}.van-col--8{width:33.33333333%}.van-col--offset-8{margin-left:33.33333333%}.van-col--9{width:37.5%}.van-col--offset-9{margin-left:37.5%}.van-col--10{width:41.66666667%}.van-col--offset-10{margin-left:41.66666667%}.van-col--11{width:45.83333333%}.van-col--offset-11{margin-left:45.83333333%}.van-col--12{width:50%}.van-col--offset-12{margin-left:50%}.van-col--13{width:54.16666667%}.van-col--offset-13{margin-left:54.16666667%}.van-col--14{width:58.33333333%}.van-col--offset-14{margin-left:58.33333333%}.van-col--15{width:62.5%}.van-col--offset-15{margin-left:62.5%}.van-col--16{width:66.66666667%}.van-col--offset-16{margin-left:66.66666667%}.van-col--17{width:70.83333333%}.van-col--offset-17{margin-left:70.83333333%}.van-col--18{width:75%}.van-col--offset-18{margin-left:75%}.van-col--19{width:79.16666667%}.van-col--offset-19{margin-left:79.16666667%}.van-col--20{width:83.33333333%}.van-col--offset-20{margin-left:83.33333333%}.van-col--21{width:87.5%}.van-col--offset-21{margin-left:87.5%}.van-col--22{width:91.66666667%}.van-col--offset-22{margin-left:91.66666667%}.van-col--23{width:95.83333333%}.van-col--offset-23{margin-left:95.83333333%}.van-col--24{width:100%}.van-col--offset-24{margin-left:100%}
================================================
FILE: miniprogram/vant/collapse/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/collapse/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'collapse-item',
type: 'descendant',
current: 'collapse',
},
props: {
value: {
type: null,
observer: 'updateExpanded',
},
accordion: {
type: Boolean,
observer: 'updateExpanded',
},
border: {
type: Boolean,
value: true,
},
},
methods: {
updateExpanded() {
this.children.forEach((child) => {
child.updateExpanded();
});
},
switch(name, expanded) {
const { accordion, value } = this.data;
const changeItem = name;
if (!accordion) {
name = expanded
? (value || []).concat(name)
: (value || []).filter((activeName) => activeName !== name);
} else {
name = expanded ? name : '';
}
if (expanded) {
this.$emit('open', changeItem);
} else {
this.$emit('close', changeItem);
}
this.$emit('change', name);
this.$emit('input', name);
},
},
});
================================================
FILE: miniprogram/vant/collapse/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/collapse/index.wxml
================================================
================================================
FILE: miniprogram/vant/collapse/index.wxss
================================================
@import '../common/index.wxss';
================================================
FILE: miniprogram/vant/collapse-item/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/collapse-item/index.js
================================================
import { VantComponent } from '../common/component';
const nextTick = () => new Promise((resolve) => setTimeout(resolve, 20));
VantComponent({
classes: ['title-class', 'content-class'],
relation: {
name: 'collapse',
type: 'ancestor',
current: 'collapse-item',
},
props: {
name: null,
title: null,
value: null,
icon: String,
label: String,
disabled: Boolean,
clickable: Boolean,
border: {
type: Boolean,
value: true,
},
isLink: {
type: Boolean,
value: true,
},
},
data: {
contentHeight: 0,
expanded: false,
transition: false,
},
mounted() {
this.updateExpanded()
.then(nextTick)
.then(() => {
const data = { transition: true };
if (this.data.expanded) {
data.contentHeight = 'auto';
}
this.setData(data);
});
},
methods: {
updateExpanded() {
if (!this.parent) {
return Promise.resolve();
}
const { value, accordion } = this.parent.data;
const { children = [] } = this.parent;
const { name } = this.data;
const index = children.indexOf(this);
const currentName = name == null ? index : name;
const expanded = accordion
? value === currentName
: (value || []).some((name) => name === currentName);
const stack = [];
if (expanded !== this.data.expanded) {
stack.push(this.updateStyle(expanded));
}
stack.push(this.set({ index, expanded }));
return Promise.all(stack);
},
updateStyle(expanded) {
return this.getRect('.van-collapse-item__content')
.then((rect) => rect.height)
.then((height) => {
if (expanded) {
return this.set({
contentHeight: height ? `${height}px` : 'auto',
});
}
return this.set({ contentHeight: `${height}px` })
.then(nextTick)
.then(() => this.set({ contentHeight: 0 }));
});
},
onClick() {
if (this.data.disabled) {
return;
}
const { name, expanded } = this.data;
const index = this.parent.children.indexOf(this);
const currentName = name == null ? index : name;
this.parent.switch(currentName, !expanded);
},
onTransitionEnd() {
if (this.data.expanded) {
this.setData({
contentHeight: 'auto',
});
}
},
},
});
================================================
FILE: miniprogram/vant/collapse-item/index.json
================================================
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index"
}
}
================================================
FILE: miniprogram/vant/collapse-item/index.wxml
================================================
================================================
FILE: miniprogram/vant/collapse-item/index.wxss
================================================
@import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{-webkit-transform:rotate(90deg);transform:rotate(90deg);transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;transition:-webkit-transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s),-webkit-transform var(--collapse-item-transition-duration,.3s)}.van-collapse-item__title--expanded .van-cell__right-icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:#c8c9cc!important;color:var(--collapse-item-title-disabled-color,#c8c9cc)!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important;background-color:var(--white,#fff)!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__wrapper--transition{transition:height .3s ease-in-out}.van-collapse-item__content{padding:15px;padding:var(--collapse-item-content-padding,15px);color:#969799;color:var(--collapse-item-content-text-color,#969799);font-size:13px;font-size:var(--collapse-item-content-font-size,13px);line-height:1.5;line-height:var(--collapse-item-content-line-height,1.5);background-color:#fff;background-color:var(--collapse-item-content-background-color,#fff)}
================================================
FILE: miniprogram/vant/common/color.d.ts
================================================
export declare const RED = "#ee0a24";
export declare const BLUE = "#1989fa";
export declare const WHITE = "#fff";
export declare const GREEN = "#07c160";
export declare const ORANGE = "#ff976a";
export declare const GRAY = "#323233";
export declare const GRAY_DARK = "#969799";
================================================
FILE: miniprogram/vant/common/color.js
================================================
export const RED = '#ee0a24';
export const BLUE = '#1989fa';
export const WHITE = '#fff';
export const GREEN = '#07c160';
export const ORANGE = '#ff976a';
export const GRAY = '#323233';
export const GRAY_DARK = '#969799';
================================================
FILE: miniprogram/vant/common/component.d.ts
================================================
import { VantComponentOptions, CombinedComponentInstance } from '../definitions/index';
declare function VantComponent(vantOptions?: VantComponentOptions>): void;
export { VantComponent };
================================================
FILE: miniprogram/vant/common/component.js
================================================
import { basic } from '../mixins/basic';
const relationFunctions = {
ancestor: {
linked(parent) {
this.parent = parent;
},
unlinked() {
this.parent = null;
},
},
descendant: {
linked(child) {
this.children = this.children || [];
this.children.push(child);
},
unlinked(child) {
this.children = (this.children || []).filter((it) => it !== child);
},
},
};
function mapKeys(source, target, map) {
Object.keys(map).forEach((key) => {
if (source[key]) {
target[map[key]] = source[key];
}
});
}
function makeRelation(options, vantOptions, relation) {
const { type, name, linked, unlinked, linkChanged } = relation;
const { beforeCreate, destroyed } = vantOptions;
if (type === 'descendant') {
options.created = function () {
beforeCreate && beforeCreate.bind(this)();
this.children = this.children || [];
};
options.detached = function () {
this.children = [];
destroyed && destroyed.bind(this)();
};
}
options.relations = Object.assign(options.relations || {}, {
[`../${name}/index`]: {
type,
linked(node) {
relationFunctions[type].linked.bind(this)(node);
linked && linked.bind(this)(node);
},
linkChanged(node) {
linkChanged && linkChanged.bind(this)(node);
},
unlinked(node) {
relationFunctions[type].unlinked.bind(this)(node);
unlinked && unlinked.bind(this)(node);
},
},
});
}
function VantComponent(vantOptions = {}) {
const options = {};
mapKeys(vantOptions, options, {
data: 'data',
props: 'properties',
mixins: 'behaviors',
methods: 'methods',
beforeCreate: 'created',
created: 'attached',
mounted: 'ready',
relations: 'relations',
destroyed: 'detached',
classes: 'externalClasses',
});
const { relation } = vantOptions;
if (relation) {
makeRelation(options, vantOptions, relation);
}
// add default externalClasses
options.externalClasses = options.externalClasses || [];
options.externalClasses.push('custom-class');
// add default behaviors
options.behaviors = options.behaviors || [];
options.behaviors.push(basic);
// map field to form-field behavior
if (vantOptions.field) {
options.behaviors.push('wx://form-field');
}
if (options.properties) {
Object.keys(options.properties).forEach((name) => {
if (Array.isArray(options.properties[name])) {
// miniprogram do not allow multi type
options.properties[name] = null;
}
});
}
// add default options
options.options = {
multipleSlots: true,
addGlobalClass: true,
};
Component(options);
}
export { VantComponent };
================================================
FILE: miniprogram/vant/common/index.wxss
================================================
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}.van-clearfix:after{display:table;clear:both;content:""}.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
================================================
FILE: miniprogram/vant/common/style/clearfix.wxss
================================================
.van-clearfix:after{display:table;clear:both;content:""}
================================================
FILE: miniprogram/vant/common/style/ellipsis.wxss
================================================
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}
================================================
FILE: miniprogram/vant/common/style/hairline.wxss
================================================
.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
================================================
FILE: miniprogram/vant/common/style/mixins/clearfix.wxss
================================================
================================================
FILE: miniprogram/vant/common/style/mixins/ellipsis.wxss
================================================
================================================
FILE: miniprogram/vant/common/style/mixins/hairline.wxss
================================================
================================================
FILE: miniprogram/vant/common/style/theme.wxss
================================================
================================================
FILE: miniprogram/vant/common/style/var.wxss
================================================
================================================
FILE: miniprogram/vant/common/utils.d.ts
================================================
///
export declare function isDef(value: any): boolean;
export declare function isObj(x: any): boolean;
export declare function isNumber(value: any): boolean;
export declare function range(num: number, min: number, max: number): number;
export declare function nextTick(fn: Function): void;
export declare function getSystemInfoSync(): WechatMiniprogram.GetSystemInfoSyncResult;
export declare function addUnit(value?: string | number): string | undefined;
================================================
FILE: miniprogram/vant/common/utils.js
================================================
export function isDef(value) {
return value !== undefined && value !== null;
}
export function isObj(x) {
const type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
export function isNumber(value) {
return /^\d+(\.\d+)?$/.test(value);
}
export function range(num, min, max) {
return Math.min(Math.max(num, min), max);
}
export function nextTick(fn) {
setTimeout(() => {
fn();
}, 1000 / 30);
}
let systemInfo = null;
export function getSystemInfoSync() {
if (systemInfo == null) {
systemInfo = wx.getSystemInfoSync();
}
return systemInfo;
}
export function addUnit(value) {
if (!isDef(value)) {
return undefined;
}
value = String(value);
return isNumber(value) ? `${value}px` : value;
}
================================================
FILE: miniprogram/vant/common/version.d.ts
================================================
export declare function canIUseModel(): boolean;
================================================
FILE: miniprogram/vant/common/version.js
================================================
import { getSystemInfoSync } from './utils';
function compareVersion(v1, v2) {
v1 = v1.split('.');
v2 = v2.split('.');
const len = Math.max(v1.length, v2.length);
while (v1.length < len) {
v1.push('0');
}
while (v2.length < len) {
v2.push('0');
}
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i], 10);
const num2 = parseInt(v2[i], 10);
if (num1 > num2) {
return 1;
}
if (num1 < num2) {
return -1;
}
}
return 0;
}
export function canIUseModel() {
const system = getSystemInfoSync();
return compareVersion(system.SDKVersion, '2.9.3') >= 0;
}
================================================
FILE: miniprogram/vant/count-down/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/count-down/index.js
================================================
import { VantComponent } from '../common/component';
import { isSameSecond, parseFormat, parseTimeData } from './utils';
function simpleTick(fn) {
return setTimeout(fn, 30);
}
VantComponent({
props: {
useSlot: Boolean,
millisecond: Boolean,
time: {
type: Number,
observer: 'reset',
},
format: {
type: String,
value: 'HH:mm:ss',
},
autoStart: {
type: Boolean,
value: true,
},
},
data: {
timeData: parseTimeData(0),
formattedTime: '0',
},
destroyed() {
clearTimeout(this.tid);
this.tid = null;
},
methods: {
// 开始
start() {
if (this.counting) {
return;
}
this.counting = true;
this.endTime = Date.now() + this.remain;
this.tick();
},
// 暂停
pause() {
this.counting = false;
clearTimeout(this.tid);
},
// 重置
reset() {
this.pause();
this.remain = this.data.time;
this.setRemain(this.remain);
if (this.data.autoStart) {
this.start();
}
},
tick() {
if (this.data.millisecond) {
this.microTick();
} else {
this.macroTick();
}
},
microTick() {
this.tid = simpleTick(() => {
this.setRemain(this.getRemain());
if (this.remain !== 0) {
this.microTick();
}
});
},
macroTick() {
this.tid = simpleTick(() => {
const remain = this.getRemain();
if (!isSameSecond(remain, this.remain) || remain === 0) {
this.setRemain(remain);
}
if (this.remain !== 0) {
this.macroTick();
}
});
},
getRemain() {
return Math.max(this.endTime - Date.now(), 0);
},
setRemain(remain) {
this.remain = remain;
const timeData = parseTimeData(remain);
if (this.data.useSlot) {
this.$emit('change', timeData);
}
this.setData({
formattedTime: parseFormat(this.data.format, timeData),
});
if (remain === 0) {
this.pause();
this.$emit('finish');
}
},
},
});
================================================
FILE: miniprogram/vant/count-down/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/count-down/index.wxml
================================================
{{ formattedTime }}
================================================
FILE: miniprogram/vant/count-down/index.wxss
================================================
@import '../common/index.wxss';.van-count-down{color:#323233;color:var(--count-down-text-color,#323233);font-size:14px;font-size:var(--count-down-font-size,14px);line-height:20px;line-height:var(--count-down-line-height,20px)}
================================================
FILE: miniprogram/vant/count-down/utils.d.ts
================================================
export declare type TimeData = {
days: number;
hours: number;
minutes: number;
seconds: number;
milliseconds: number;
};
export declare function parseTimeData(time: number): TimeData;
export declare function parseFormat(format: string, timeData: TimeData): string;
export declare function isSameSecond(time1: number, time2: number): boolean;
================================================
FILE: miniprogram/vant/count-down/utils.js
================================================
function padZero(num, targetLength = 2) {
let str = num + '';
while (str.length < targetLength) {
str = '0' + str;
}
return str;
}
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
export function parseTimeData(time) {
const days = Math.floor(time / DAY);
const hours = Math.floor((time % DAY) / HOUR);
const minutes = Math.floor((time % HOUR) / MINUTE);
const seconds = Math.floor((time % MINUTE) / SECOND);
const milliseconds = Math.floor(time % SECOND);
return {
days,
hours,
minutes,
seconds,
milliseconds,
};
}
export function parseFormat(format, timeData) {
const { days } = timeData;
let { hours, minutes, seconds, milliseconds } = timeData;
if (format.indexOf('DD') === -1) {
hours += days * 24;
} else {
format = format.replace('DD', padZero(days));
}
if (format.indexOf('HH') === -1) {
minutes += hours * 60;
} else {
format = format.replace('HH', padZero(hours));
}
if (format.indexOf('mm') === -1) {
seconds += minutes * 60;
} else {
format = format.replace('mm', padZero(minutes));
}
if (format.indexOf('ss') === -1) {
milliseconds += seconds * 1000;
} else {
format = format.replace('ss', padZero(seconds));
}
return format.replace('SSS', padZero(milliseconds, 3));
}
export function isSameSecond(time1, time2) {
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000);
}
================================================
FILE: miniprogram/vant/datetime-picker/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/datetime-picker/index.js
================================================
import { VantComponent } from '../common/component';
import { isDef } from '../common/utils';
import { pickerProps } from '../picker/shared';
const currentYear = new Date().getFullYear();
function isValidDate(date) {
return isDef(date) && !isNaN(new Date(date).getTime());
}
function range(num, min, max) {
return Math.min(Math.max(num, min), max);
}
function padZero(val) {
return `00${val}`.slice(-2);
}
function times(n, iteratee) {
let index = -1;
const result = Array(n < 0 ? 0 : n);
while (++index < n) {
result[index] = iteratee(index);
}
return result;
}
function getTrueValue(formattedValue) {
if (!formattedValue) return;
while (isNaN(parseInt(formattedValue, 10))) {
formattedValue = formattedValue.slice(1);
}
return parseInt(formattedValue, 10);
}
function getMonthEndDay(year, month) {
return 32 - new Date(year, month - 1, 32).getDate();
}
const defaultFormatter = (_, value) => value;
VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign(Object.assign({}, pickerProps), {
value: {
type: null,
observer: 'updateValue',
},
filter: null,
type: {
type: String,
value: 'datetime',
observer: 'updateValue',
},
showToolbar: {
type: Boolean,
value: true,
},
formatter: {
type: null,
value: defaultFormatter,
},
minDate: {
type: Number,
value: new Date(currentYear - 10, 0, 1).getTime(),
observer: 'updateValue',
},
maxDate: {
type: Number,
value: new Date(currentYear + 10, 11, 31).getTime(),
observer: 'updateValue',
},
minHour: {
type: Number,
value: 0,
observer: 'updateValue',
},
maxHour: {
type: Number,
value: 23,
observer: 'updateValue',
},
minMinute: {
type: Number,
value: 0,
observer: 'updateValue',
},
maxMinute: {
type: Number,
value: 59,
observer: 'updateValue',
},
}),
data: {
innerValue: Date.now(),
columns: [],
},
methods: {
updateValue() {
const { data } = this;
const val = this.correctValue(this.data.value);
const isEqual = val === data.innerValue;
if (!isEqual) {
this.updateColumnValue(val).then(() => {
this.$emit('input', val);
});
} else {
this.updateColumns();
}
},
getPicker() {
if (this.picker == null) {
this.picker = this.selectComponent('.van-datetime-picker');
const { picker } = this;
const { setColumnValues } = picker;
picker.setColumnValues = (...args) =>
setColumnValues.apply(picker, [...args, false]);
}
return this.picker;
},
updateColumns() {
const { formatter = defaultFormatter } = this.data;
const results = this.getOriginColumns().map((column) => ({
values: column.values.map((value) => formatter(column.type, value)),
}));
return this.set({ columns: results });
},
getOriginColumns() {
const { filter } = this.data;
const results = this.getRanges().map(({ type, range }) => {
let values = times(range[1] - range[0] + 1, (index) => {
let value = range[0] + index;
value = type === 'year' ? `${value}` : padZero(value);
return value;
});
if (filter) {
values = filter(type, values);
}
return { type, values };
});
return results;
},
getRanges() {
const { data } = this;
if (data.type === 'time') {
return [
{
type: 'hour',
range: [data.minHour, data.maxHour],
},
{
type: 'minute',
range: [data.minMinute, data.maxMinute],
},
];
}
const {
maxYear,
maxDate,
maxMonth,
maxHour,
maxMinute,
} = this.getBoundary('max', data.innerValue);
const {
minYear,
minDate,
minMonth,
minHour,
minMinute,
} = this.getBoundary('min', data.innerValue);
const result = [
{
type: 'year',
range: [minYear, maxYear],
},
{
type: 'month',
range: [minMonth, maxMonth],
},
{
type: 'day',
range: [minDate, maxDate],
},
{
type: 'hour',
range: [minHour, maxHour],
},
{
type: 'minute',
range: [minMinute, maxMinute],
},
];
if (data.type === 'date') result.splice(3, 2);
if (data.type === 'year-month') result.splice(2, 3);
return result;
},
correctValue(value) {
const { data } = this;
// validate value
const isDateType = data.type !== 'time';
if (isDateType && !isValidDate(value)) {
value = data.minDate;
} else if (!isDateType && !value) {
const { minHour } = data;
value = `${padZero(minHour)}:00`;
}
// time type
if (!isDateType) {
let [hour, minute] = value.split(':');
hour = padZero(range(hour, data.minHour, data.maxHour));
minute = padZero(range(minute, data.minMinute, data.maxMinute));
return `${hour}:${minute}`;
}
// date type
value = Math.max(value, data.minDate);
value = Math.min(value, data.maxDate);
return value;
},
getBoundary(type, innerValue) {
const value = new Date(innerValue);
const boundary = new Date(this.data[`${type}Date`]);
const year = boundary.getFullYear();
let month = 1;
let date = 1;
let hour = 0;
let minute = 0;
if (type === 'max') {
month = 12;
date = getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
hour = 23;
minute = 59;
}
if (value.getFullYear() === year) {
month = boundary.getMonth() + 1;
if (value.getMonth() + 1 === month) {
date = boundary.getDate();
if (value.getDate() === date) {
hour = boundary.getHours();
if (value.getHours() === hour) {
minute = boundary.getMinutes();
}
}
}
}
return {
[`${type}Year`]: year,
[`${type}Month`]: month,
[`${type}Date`]: date,
[`${type}Hour`]: hour,
[`${type}Minute`]: minute,
};
},
onCancel() {
this.$emit('cancel');
},
onConfirm() {
this.$emit('confirm', this.data.innerValue);
},
onChange() {
const { data } = this;
let value;
const picker = this.getPicker();
if (data.type === 'time') {
const indexes = picker.getIndexes();
value = `${+data.columns[0].values[indexes[0]]}:${+data.columns[1]
.values[indexes[1]]}`;
} else {
const values = picker.getValues();
const year = getTrueValue(values[0]);
const month = getTrueValue(values[1]);
const maxDate = getMonthEndDay(year, month);
let date = getTrueValue(values[2]);
if (data.type === 'year-month') {
date = 1;
}
date = date > maxDate ? maxDate : date;
let hour = 0;
let minute = 0;
if (data.type === 'datetime') {
hour = getTrueValue(values[3]);
minute = getTrueValue(values[4]);
}
value = new Date(year, month - 1, date, hour, minute);
}
value = this.correctValue(value);
this.updateColumnValue(value).then(() => {
this.$emit('input', value);
this.$emit('change', picker);
});
},
updateColumnValue(value) {
let values = [];
const { type, formatter = defaultFormatter } = this.data;
const picker = this.getPicker();
if (type === 'time') {
const pair = value.split(':');
values = [formatter('hour', pair[0]), formatter('minute', pair[1])];
} else {
const date = new Date(value);
values = [
formatter('year', `${date.getFullYear()}`),
formatter('month', padZero(date.getMonth() + 1)),
];
if (type === 'date') {
values.push(formatter('day', padZero(date.getDate())));
}
if (type === 'datetime') {
values.push(
formatter('day', padZero(date.getDate())),
formatter('hour', padZero(date.getHours())),
formatter('minute', padZero(date.getMinutes()))
);
}
}
return this.set({ innerValue: value })
.then(() => this.updateColumns())
.then(() => picker.setValues(values));
},
},
created() {
const innerValue = this.correctValue(this.data.value);
this.updateColumnValue(innerValue).then(() => {
this.$emit('input', innerValue);
});
},
});
================================================
FILE: miniprogram/vant/datetime-picker/index.json
================================================
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}
================================================
FILE: miniprogram/vant/datetime-picker/index.wxml
================================================
================================================
FILE: miniprogram/vant/datetime-picker/index.wxss
================================================
@import '../common/index.wxss';
================================================
FILE: miniprogram/vant/definitions/index.d.ts
================================================
///
import { Weapp } from './weapp';
declare type RecordToAny = {
[K in keyof T]: any;
};
export declare type CombinedComponentInstance = Methods & WechatMiniprogram.Component.TrivialInstance & Weapp.FormField & {
data: Data & RecordToAny;
};
export interface VantComponentOptions {
data?: Data;
field?: boolean;
classes?: string[];
mixins?: string[];
props?: Props & Weapp.PropertyOption;
relation?: Weapp.RelationOption & {
type: 'ancestor' | 'descendant';
name: string;
current: string;
};
relations?: {
[componentName: string]: Weapp.RelationOption;
};
methods?: Methods & Weapp.MethodOption;
beforeCreate?: (this: Instance) => void;
created?: (this: Instance) => void;
mounted?: (this: Instance) => void;
destroyed?: (this: Instance) => void;
}
export {};
================================================
FILE: miniprogram/vant/definitions/index.js
================================================
================================================
FILE: miniprogram/vant/definitions/weapp.d.ts
================================================
///
export declare namespace Weapp {
export interface FormField {
data: {
name: string;
value: any;
};
}
interface Target {
id: string;
tagName: string;
dataset: {
[key: string]: any;
};
}
export interface Event {
/**
* 代表事件的类型。
*/
type: string;
/**
* 页面打开到触发事件所经过的毫秒数。
*/
timeStamp: number;
/**
* 触发事件的源组件。
*/
target: Target;
/**
* 事件绑定的当前组件。
*/
currentTarget: Target;
/**
* 额外的信息
*/
detail: any;
}
interface Touch {
/**
* 触摸点的标识符
*/
identifier: number;
/**
* 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
*/
pageX: number;
/**
* 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
*/
pageY: number;
/**
* 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
*/
clientX: number;
/**
* 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
*/
clientY: number;
}
export interface TouchEvent extends Event {
touches: Array;
changedTouches: Array;
}
/**
* relation定义,miniprogram-api-typings缺少this定义
*/
export interface RelationOption {
/** 目标组件的相对关系 */
type: 'parent' | 'child' | 'ancestor' | 'descendant';
/** 关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件attached生命周期之后 */
linked?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void;
/** 关系生命周期函数,当关系在页面节点树中发生改变时触发,触发时机在组件moved生命周期之后 */
linkChanged?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void;
/** 关系生命周期函数,当关系脱离页面节点树时触发,触发时机在组件detached生命周期之后 */
unlinked?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void;
/** 如果这一项被设置,则它表示关联的目标节点所应具有的behavior,所有拥有这一behavior的组件节点都会被关联 */
target?: string;
}
/**
* obverser定义,miniprogram-api-typings缺少this定义
*/
type Observer = (this: Instance, newVal: T, oldVal: T, changedPath: Array) => void;
/**
* methods定义,miniprogram-api-typings缺少this定义
*/
export interface MethodOption {
[name: string]: (this: Instance, ...args: any[]) => any;
}
export interface ComputedOption {
[name: string]: (this: Instance) => any;
}
type PropertyType = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor | FunctionConstructor | null;
export interface PropertyOption {
[name: string]: PropertyType | PropertyType[] | {
/** 属性类型 */
type: PropertyType | PropertyType[];
/** 属性初始值 */
value?: any;
/** 属性值被更改时的响应函数 */
observer?: string | Observer;
/** 属性的类型(可以指定多个) */
optionalTypes?: PropertyType[];
};
}
export {};
}
================================================
FILE: miniprogram/vant/definitions/weapp.js
================================================
================================================
FILE: miniprogram/vant/dialog/dialog.d.ts
================================================
///
declare type DialogAction = 'confirm' | 'cancel';
declare type DialogOptions = {
lang?: string;
show?: boolean;
title?: string;
width?: string | number;
zIndex?: number;
context?: WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance;
message?: string;
overlay?: boolean;
selector?: string;
ariaLabel?: string;
className?: string;
customStyle?: string;
transition?: string;
asyncClose?: boolean;
businessId?: number;
sessionFrom?: string;
overlayStyle?: string;
appParameter?: string;
messageAlign?: string;
sendMessageImg?: string;
showMessageCard?: boolean;
sendMessagePath?: string;
sendMessageTitle?: string;
confirmButtonText?: string;
cancelButtonText?: string;
showConfirmButton?: boolean;
showCancelButton?: boolean;
closeOnClickOverlay?: boolean;
confirmButtonOpenType?: string;
};
interface Dialog {
(options: DialogOptions): Promise;
alert?: (options: DialogOptions) => Promise;
confirm?: (options: DialogOptions) => Promise;
close?: () => void;
stopLoading?: () => void;
install?: () => void;
setDefaultOptions?: (options: DialogOptions) => void;
resetDefaultOptions?: () => void;
defaultOptions?: DialogOptions;
currentOptions?: DialogOptions;
}
declare const Dialog: Dialog;
export default Dialog;
================================================
FILE: miniprogram/vant/dialog/dialog.js
================================================
let queue = [];
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
const Dialog = (options) => {
options = Object.assign(Object.assign({}, Dialog.currentOptions), options);
return new Promise((resolve, reject) => {
const context = options.context || getContext();
const dialog = context.selectComponent(options.selector);
delete options.context;
delete options.selector;
if (dialog) {
dialog.setData(
Object.assign({ onCancel: reject, onConfirm: resolve }, options)
);
queue.push(dialog);
} else {
console.warn(
'未找到 van-dialog 节点,请确认 selector 及 context 是否正确'
);
}
});
};
Dialog.defaultOptions = {
show: true,
title: '',
width: null,
message: '',
zIndex: 100,
overlay: true,
selector: '#van-dialog',
className: '',
asyncClose: false,
transition: 'scale',
customStyle: '',
messageAlign: '',
overlayStyle: '',
confirmButtonText: '确认',
cancelButtonText: '取消',
showConfirmButton: true,
showCancelButton: false,
closeOnClickOverlay: false,
confirmButtonOpenType: '',
};
Dialog.alert = Dialog;
Dialog.confirm = (options) =>
Dialog(Object.assign({ showCancelButton: true }, options));
Dialog.close = () => {
queue.forEach((dialog) => {
dialog.close();
});
queue = [];
};
Dialog.stopLoading = () => {
queue.forEach((dialog) => {
dialog.stopLoading();
});
};
Dialog.setDefaultOptions = (options) => {
Object.assign(Dialog.currentOptions, options);
};
Dialog.resetDefaultOptions = () => {
Dialog.currentOptions = Object.assign({}, Dialog.defaultOptions);
};
Dialog.resetDefaultOptions();
export default Dialog;
================================================
FILE: miniprogram/vant/dialog/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/dialog/index.js
================================================
import { VantComponent } from '../common/component';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
import { GRAY, BLUE } from '../common/color';
VantComponent({
mixins: [button, openType],
props: {
show: {
type: Boolean,
observer(show) {
!show && this.stopLoading();
},
},
title: String,
message: String,
useSlot: Boolean,
className: String,
customStyle: String,
asyncClose: Boolean,
messageAlign: String,
overlayStyle: String,
useTitleSlot: Boolean,
showCancelButton: Boolean,
closeOnClickOverlay: Boolean,
confirmButtonOpenType: String,
width: null,
zIndex: {
type: Number,
value: 2000,
},
confirmButtonText: {
type: String,
value: '确认',
},
cancelButtonText: {
type: String,
value: '取消',
},
confirmButtonColor: {
type: String,
value: BLUE,
},
cancelButtonColor: {
type: String,
value: GRAY,
},
showConfirmButton: {
type: Boolean,
value: true,
},
overlay: {
type: Boolean,
value: true,
},
transition: {
type: String,
value: 'scale',
},
},
data: {
loading: {
confirm: false,
cancel: false,
},
},
methods: {
onConfirm() {
this.handleAction('confirm');
},
onCancel() {
this.handleAction('cancel');
},
onClickOverlay() {
this.onClose('overlay');
},
handleAction(action) {
if (this.data.asyncClose) {
this.setData({
[`loading.${action}`]: true,
});
}
this.onClose(action);
},
close() {
this.setData({
show: false,
});
},
stopLoading() {
this.setData({
loading: {
confirm: false,
cancel: false,
},
});
},
onClose(action) {
if (!this.data.asyncClose) {
this.close();
}
this.$emit('close', action);
// 把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading
this.$emit(action, { dialog: this });
const callback = this.data[
action === 'confirm' ? 'onConfirm' : 'onCancel'
];
if (callback) {
callback(this);
}
},
},
});
================================================
FILE: miniprogram/vant/dialog/index.json
================================================
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"van-button": "../button/index"
}
}
================================================
FILE: miniprogram/vant/dialog/index.wxml
================================================
{{ message }}
================================================
FILE: miniprogram/vant/dialog/index.wxss
================================================
@import '../common/index.wxss';.van-dialog{top:45%!important;overflow:hidden;width:320px;width:var(--dialog-width,320px);font-size:16px;font-size:var(--dialog-font-size,16px);border-radius:16px;border-radius:var(--dialog-border-radius,16px);background-color:#fff;background-color:var(--dialog-background-color,#fff)}@media (max-width:321px){.van-dialog{width:90%;width:var(--dialog-small-screen-width,90%)}}.van-dialog__header{text-align:center;padding-top:24px;padding-top:var(--dialog-header-padding-top,24px);font-weight:500;font-weight:var(--dialog-header-font-weight,500);line-height:24px;line-height:var(--dialog-header-line-height,24px)}.van-dialog__header--isolated{padding:24px 0;padding:var(--dialog-header-isolated-padding,24px 0)}.van-dialog__message{overflow-y:auto;text-align:center;-webkit-overflow-scrolling:touch;font-size:14px;font-size:var(--dialog-message-font-size,14px);line-height:20px;line-height:var(--dialog-message-line-height,20px);max-height:60vh;max-height:var(--dialog-message-max-height,60vh);padding:24px;padding:var(--dialog-message-padding,24px)}.van-dialog__message-text{word-wrap:break-word}.van-dialog__message--has-title{padding-top:12px;padding-top:var(--dialog-has-title-message-padding-top,12px);color:#646566;color:var(--dialog-has-title-message-text-color,#646566)}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__footer{display:-webkit-flex;display:flex}.van-dialog__button{-webkit-flex:1;flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog-bounce-enter{-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7);opacity:0}.van-dialog-bounce-leave-active{-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9);opacity:0}
================================================
FILE: miniprogram/vant/divider/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/divider/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
props: {
dashed: {
type: Boolean,
value: false,
},
hairline: {
type: Boolean,
value: false,
},
contentPosition: {
type: String,
value: '',
},
fontSize: {
type: Number,
value: '',
},
borderColor: {
type: String,
value: '',
},
textColor: {
type: String,
value: '',
},
customStyle: {
type: String,
value: '',
},
},
});
================================================
FILE: miniprogram/vant/divider/index.json
================================================
{
"component": true,
"usingComponents": {}
}
================================================
FILE: miniprogram/vant/divider/index.wxml
================================================
================================================
FILE: miniprogram/vant/divider/index.wxss
================================================
@import '../common/index.wxss';.van-divider{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;margin:16px 0;margin:var(--divider-margin,16px 0);color:#969799;color:var(--divider-text-color,#969799);font-size:14px;font-size:var(--divider-font-size,14px);line-height:24px;line-height:var(--divider-line-height,24px);border:0 solid #ebedf0;border-color:var(--divider-border-color,#ebedf0)}.van-divider:after,.van-divider:before{display:block;-webkit-flex:1;flex:1;box-sizing:border-box;height:1px;border-color:inherit;border-style:inherit;border-width:1px 0 0}.van-divider:before{content:""}.van-divider--hairline:after,.van-divider--hairline:before{-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-divider--dashed{border-style:dashed}.van-divider--center:before,.van-divider--left:before,.van-divider--right:before{margin-right:16px;margin-right:var(--divider-content-padding,16px)}.van-divider--center:after,.van-divider--left:after,.van-divider--right:after{content:"";margin-left:16px;margin-left:var(--divider-content-padding,16px)}.van-divider--left:before{max-width:10%;max-width:var(--divider-content-left-width,10%)}.van-divider--right:after{max-width:10%;max-width:var(--divider-content-right-width,10%)}
================================================
FILE: miniprogram/vant/dropdown-item/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/dropdown-item/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'dropdown-menu',
type: 'ancestor',
current: 'dropdown-item',
linked() {
this.updateDataFromParent();
},
},
props: {
value: {
type: null,
observer: 'rerender',
},
title: {
type: String,
observer: 'rerender',
},
disabled: Boolean,
titleClass: {
type: String,
observer: 'rerender',
},
options: {
type: Array,
value: [],
observer: 'rerender',
},
popupStyle: String,
},
data: {
transition: true,
showPopup: false,
showWrapper: false,
displayTitle: '',
},
methods: {
rerender() {
wx.nextTick(() => {
this.parent && this.parent.updateItemListData();
});
},
updateDataFromParent() {
if (this.parent) {
const {
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction,
} = this.parent.data;
this.setData({
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction,
});
}
},
onOpen() {
this.$emit('open');
},
onOpened() {
this.$emit('opened');
},
onClose() {
this.$emit('close');
},
onClosed() {
this.$emit('closed');
this.setData({ showWrapper: false });
},
onOptionTap(event) {
const { option } = event.currentTarget.dataset;
const { value } = option;
const shouldEmitChange = this.data.value !== value;
this.setData({ showPopup: false, value });
this.$emit('close');
this.rerender();
if (shouldEmitChange) {
this.$emit('change', value);
}
},
toggle(show, options = {}) {
const { showPopup } = this.data;
if (typeof show !== 'boolean') {
show = !showPopup;
}
if (show === showPopup) {
return;
}
this.setData({
transition: !options.immediate,
showPopup: show,
});
if (show) {
this.parent.getChildWrapperStyle().then((wrapperStyle) => {
this.setData({ wrapperStyle, showWrapper: true });
this.rerender();
});
} else {
this.rerender();
}
},
},
});
================================================
FILE: miniprogram/vant/dropdown-item/index.json
================================================
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"van-cell": "../cell/index",
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/dropdown-item/index.wxml
================================================
{{ item.text }}
================================================
FILE: miniprogram/vant/dropdown-item/index.wxss
================================================
@import '../common/index.wxss';.van-dropdown-item{position:fixed;right:0;left:0;overflow:hidden}.van-dropdown-item__option{text-align:left}.van-dropdown-item__option--active .van-dropdown-item__icon,.van-dropdown-item__option--active .van-dropdown-item__title{color:#1989fa;color:var(--dropdown-menu-option-active-color,#1989fa)}.van-dropdown-item--up{top:0}.van-dropdown-item--down{bottom:0}.van-dropdown-item__icon{display:block;line-height:inherit}
================================================
FILE: miniprogram/vant/dropdown-menu/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/dropdown-menu/index.js
================================================
import { VantComponent } from '../common/component';
import { addUnit } from '../common/utils';
let ARRAY = [];
VantComponent({
field: true,
relation: {
name: 'dropdown-item',
type: 'descendant',
current: 'dropdown-menu',
linked() {
this.updateItemListData();
},
unlinked() {
this.updateItemListData();
},
},
props: {
activeColor: {
type: String,
observer: 'updateChildrenData',
},
overlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData',
},
zIndex: {
type: Number,
value: 10,
},
duration: {
type: Number,
value: 200,
observer: 'updateChildrenData',
},
direction: {
type: String,
value: 'down',
observer: 'updateChildrenData',
},
closeOnClickOverlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData',
},
closeOnClickOutside: {
type: Boolean,
value: true,
},
},
data: {
itemListData: [],
},
beforeCreate() {
const { windowHeight } = wx.getSystemInfoSync();
this.windowHeight = windowHeight;
ARRAY.push(this);
},
destroyed() {
ARRAY = ARRAY.filter((item) => item !== this);
},
methods: {
updateItemListData() {
this.setData({
itemListData: this.children.map((child) => child.data),
});
},
updateChildrenData() {
this.children.forEach((child) => {
child.updateDataFromParent();
});
},
toggleItem(active) {
this.children.forEach((item, index) => {
const { showPopup } = item.data;
if (index === active) {
item.toggle();
} else if (showPopup) {
item.toggle(false, { immediate: true });
}
});
},
close() {
this.children.forEach((child) => {
child.toggle(false, { immediate: true });
});
},
getChildWrapperStyle() {
const { zIndex, direction } = this.data;
return this.getRect('.van-dropdown-menu').then((rect) => {
const { top = 0, bottom = 0 } = rect;
const offset = direction === 'down' ? bottom : this.windowHeight - top;
let wrapperStyle = `z-index: ${zIndex};`;
if (direction === 'down') {
wrapperStyle += `top: ${addUnit(offset)};`;
} else {
wrapperStyle += `bottom: ${addUnit(offset)};`;
}
return wrapperStyle;
});
},
onTitleTap(event) {
const { index } = event.currentTarget.dataset;
const child = this.children[index];
if (!child.data.disabled) {
ARRAY.forEach((menuItem) => {
if (
menuItem &&
menuItem.data.closeOnClickOutside &&
menuItem !== this
) {
menuItem.close();
}
});
this.toggleItem(index);
}
},
},
});
================================================
FILE: miniprogram/vant/dropdown-menu/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/dropdown-menu/index.wxml
================================================
================================================
FILE: miniprogram/vant/dropdown-menu/index.wxs
================================================
/* eslint-disable */
function displayTitle(item) {
if (item.title) {
return item.title;
}
var match = item.options.filter(function(option) {
return option.value === item.value;
});
var displayTitle = match.length ? match[0].text : '';
return displayTitle;
}
module.exports = {
displayTitle: displayTitle
};
================================================
FILE: miniprogram/vant/dropdown-menu/index.wxss
================================================
@import '../common/index.wxss';.van-dropdown-menu{display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none;height:50px;height:var(--dropdown-menu-height,50px);background-color:#fff;background-color:var(--dropdown-menu-background-color,#fff)}.van-dropdown-menu__item{display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;min-width:0}.van-dropdown-menu__item:active{opacity:.7}.van-dropdown-menu__item--disabled:active{opacity:1}.van-dropdown-menu__item--disabled .van-dropdown-menu__title{color:#969799;color:var(--dropdown-menu-title-disabled-text-color,#969799)}.van-dropdown-menu__title{position:relative;box-sizing:border-box;max-width:100%;padding:0 8px;padding:var(--dropdown-menu-title-padding,0 8px);color:#323233;color:var(--dropdown-menu-title-text-color,#323233);font-size:15px;font-size:var(--dropdown-menu-title-font-size,15px);line-height:18px;line-height:var(--dropdown-menu-title-line-height,18px)}.van-dropdown-menu__title:after{position:absolute;top:50%;right:-4px;margin-top:-5px;border-color:transparent transparent currentcolor currentcolor;border-style:solid;border-width:3px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:.8;content:""}.van-dropdown-menu__title--active{color:#1989fa;color:var(--dropdown-menu-title-active-text-color,#1989fa)}.van-dropdown-menu__title--down:after{margin-top:-1px;-webkit-transform:rotate(135deg);transform:rotate(135deg)}
================================================
FILE: miniprogram/vant/field/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/field/index.js
================================================
import { VantComponent } from '../common/component';
import { commonProps, inputProps, textareaProps } from './props';
import { canIUseModel } from '../common/version';
VantComponent({
field: true,
classes: ['input-class', 'right-icon-class'],
props: Object.assign(
Object.assign(
Object.assign(Object.assign({}, commonProps), inputProps),
textareaProps
),
{
size: String,
icon: String,
label: String,
error: Boolean,
center: Boolean,
isLink: Boolean,
leftIcon: String,
rightIcon: String,
autosize: [Boolean, Object],
readonly: {
type: Boolean,
observer: 'setShowClear',
},
required: Boolean,
iconClass: String,
clearable: {
type: Boolean,
observer: 'setShowClear',
},
clickable: Boolean,
inputAlign: String,
customStyle: String,
errorMessage: String,
arrowDirection: String,
showWordLimit: Boolean,
errorMessageAlign: String,
border: {
type: Boolean,
value: true,
},
titleWidth: {
type: String,
value: '90px',
},
}
),
data: {
focused: false,
innerValue: '',
showClear: false,
},
created() {
this.value = this.data.value;
this.setData({ innerValue: this.value });
},
methods: {
onInput(event) {
const { value = '' } = event.detail || {};
this.value = value;
this.setShowClear();
this.emitChange();
},
onFocus(event) {
this.focused = true;
this.setShowClear();
this.$emit('focus', event.detail);
},
onBlur(event) {
this.focused = false;
this.setShowClear();
this.$emit('blur', event.detail);
},
onClickIcon() {
this.$emit('click-icon');
},
onClear() {
this.setData({ innerValue: '' });
this.value = '';
this.setShowClear();
wx.nextTick(() => {
this.emitChange();
this.$emit('clear', '');
});
},
onConfirm(event) {
const { value = '' } = event.detail || {};
this.value = value;
this.setShowClear();
this.$emit('confirm', value);
},
setValue(value) {
this.value = value;
this.setShowClear();
if (value === '') {
this.setData({ innerValue: '' });
}
this.emitChange();
},
onLineChange(event) {
this.$emit('linechange', event.detail);
},
onKeyboardHeightChange(event) {
this.$emit('keyboardheightchange', event.detail);
},
emitChange() {
if (canIUseModel()) {
this.setData({ value: this.value });
}
wx.nextTick(() => {
this.$emit('input', this.value);
this.$emit('change', this.value);
});
},
setShowClear() {
const { clearable, readonly } = this.data;
const { focused, value } = this;
this.setData({
showClear: !!clearable && !!focused && !!value && !readonly,
});
},
noop() {},
},
});
================================================
FILE: miniprogram/vant/field/index.json
================================================
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index",
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/field/index.wxml
================================================
{{ value.length }} /{{ maxlength }}
{{ errorMessage }}
================================================
FILE: miniprogram/vant/field/index.wxs
================================================
/* eslint-disable */
var utils = require('../wxs/utils.wxs');
function inputStyle(autosize) {
if (autosize && autosize.constructor === 'Object') {
var style = '';
if (autosize.minHeight) {
style += 'min-height:' + utils.addUnit(autosize.minHeight) + ';';
}
if (autosize.maxHeight) {
style += 'max-height:' + utils.addUnit(autosize.maxHeight) + ';';
}
return style;
}
return '';
}
module.exports = {
inputStyle: inputStyle
};
================================================
FILE: miniprogram/vant/field/index.wxss
================================================
@import '../common/index.wxss';.van-field{--cell-icon-size:16px;--cell-icon-size:var(--field-icon-size,16px)}.van-field__body{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center}.van-field__body--textarea{line-height:1.2em}.van-field__body--textarea,.van-field__input{min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__input{position:relative;display:block;box-sizing:border-box;width:100%;margin:0;padding:0;line-height:inherit;text-align:left;background-color:initial;border:0;resize:none;color:#323233;color:var(--field-input-text-color,#323233);height:24px;height:var(--cell-line-height,24px)}.van-field__input--textarea{height:18px;height:var(--field-text-area-min-height,18px);min-height:18px;min-height:var(--field-text-area-min-height,18px)}.van-field__input--error{color:#ee0a24;color:var(--field-input-error-text-color,#ee0a24)}.van-field__input--disabled{background-color:initial;opacity:1;color:#969799;color:var(--field-input-disabled-text-color,#969799)}.van-field__input--center{text-align:center}.van-field__input--right{text-align:right}.van-field__placeholder{position:absolute;top:0;right:0;left:0;pointer-events:none;color:#c8c9cc;color:var(--field-placeholder-text-color,#c8c9cc)}.van-field__placeholder--error{color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__icon-root{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__clear-root,.van-field__icon-container{line-height:inherit;vertical-align:middle;padding:0 8px;padding:0 var(--padding-xs,8px);margin-right:-8px;margin-right:-var(--padding-xs,8px)}.van-field__button,.van-field__clear-root,.van-field__icon-container{-webkit-flex-shrink:0;flex-shrink:0}.van-field__clear-root{font-size:16px;font-size:var(--field-clear-icon-size,16px);color:#c8c9cc;color:var(--field-clear-icon-color,#c8c9cc)}.van-field__icon-container{font-size:16px;font-size:var(--field-icon-size,16px);color:#969799;color:var(--field-icon-container-color,#969799)}.van-field__icon-container:empty{display:none}.van-field__button{padding-left:8px;padding-left:var(--padding-xs,8px)}.van-field__button:empty{display:none}.van-field__error-message{text-align:left;font-size:12px;font-size:var(--field-error-message-text-font-size,12px);color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__error-message--center{text-align:center}.van-field__error-message--right{text-align:right}.van-field__word-limit{text-align:right;margin-top:4px;margin-top:var(--padding-base,4px);color:#646566;color:var(--field-word-limit-color,#646566);font-size:12px;font-size:var(--field-word-limit-font-size,12px);line-height:16px;line-height:var(--field-word-limit-line-height,16px)}.van-field__word-num{display:inline}.van-field__word-num--full{color:#ee0a24;color:var(--field-word-num-full-color,#ee0a24)}
================================================
FILE: miniprogram/vant/field/props.d.ts
================================================
export declare const commonProps: {
value: {
type: StringConstructor;
observer(value: string): void;
};
placeholder: StringConstructor;
placeholderStyle: StringConstructor;
placeholderClass: StringConstructor;
disabled: BooleanConstructor;
maxlength: {
type: NumberConstructor;
value: number;
};
cursorSpacing: {
type: NumberConstructor;
value: number;
};
autoFocus: BooleanConstructor;
focus: BooleanConstructor;
cursor: {
type: NumberConstructor;
value: number;
};
selectionStart: {
type: NumberConstructor;
value: number;
};
selectionEnd: {
type: NumberConstructor;
value: number;
};
adjustPosition: {
type: BooleanConstructor;
value: boolean;
};
holdKeyboard: BooleanConstructor;
};
export declare const inputProps: {
type: {
type: StringConstructor;
value: string;
};
password: BooleanConstructor;
confirmType: StringConstructor;
confirmHold: BooleanConstructor;
};
export declare const textareaProps: {
autoHeight: BooleanConstructor;
fixed: BooleanConstructor;
showConfirmBar: {
type: BooleanConstructor;
value: boolean;
};
disableDefaultPadding: {
type: BooleanConstructor;
value: boolean;
};
};
================================================
FILE: miniprogram/vant/field/props.js
================================================
export const commonProps = {
value: {
type: String,
observer(value) {
if (value !== this.value) {
this.setData({ innerValue: value });
this.value = value;
}
},
},
placeholder: String,
placeholderStyle: String,
placeholderClass: String,
disabled: Boolean,
maxlength: {
type: Number,
value: -1,
},
cursorSpacing: {
type: Number,
value: 50,
},
autoFocus: Boolean,
focus: Boolean,
cursor: {
type: Number,
value: -1,
},
selectionStart: {
type: Number,
value: -1,
},
selectionEnd: {
type: Number,
value: -1,
},
adjustPosition: {
type: Boolean,
value: true,
},
holdKeyboard: Boolean,
};
export const inputProps = {
type: {
type: String,
value: 'text',
},
password: Boolean,
confirmType: String,
confirmHold: Boolean,
};
export const textareaProps = {
autoHeight: Boolean,
fixed: Boolean,
showConfirmBar: {
type: Boolean,
value: true,
},
disableDefaultPadding: {
type: Boolean,
value: true,
},
};
================================================
FILE: miniprogram/vant/goods-action/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/goods-action/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
relation: {
type: 'descendant',
name: 'goods-action-button',
current: 'goods-action',
linked() {
this.updateStyle();
},
unlinked() {
this.updateStyle();
},
linkChanged() {
this.updateStyle();
},
},
props: {
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
},
methods: {
updateStyle() {
wx.nextTick(() => {
this.children.forEach((child) => {
child.updateStyle();
});
});
},
},
});
================================================
FILE: miniprogram/vant/goods-action/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/goods-action/index.wxml
================================================
================================================
FILE: miniprogram/vant/goods-action/index.wxss
================================================
@import '../common/index.wxss';.van-goods-action{position:fixed;right:0;bottom:0;left:0;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;background-color:#fff;background-color:var(--goods-action-background-color,#fff)}.van-goods-action--safe{padding-bottom:env(safe-area-inset-bottom)}
================================================
FILE: miniprogram/vant/goods-action-button/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/goods-action-button/index.js
================================================
import { VantComponent } from '../common/component';
import { link } from '../mixins/link';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
mixins: [link, button, openType],
relation: {
type: 'ancestor',
name: 'goods-action',
current: 'goods-action-button',
},
props: {
text: String,
color: String,
loading: Boolean,
disabled: Boolean,
plain: Boolean,
type: {
type: String,
value: 'danger',
},
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
},
updateStyle() {
if (this.parent == null) {
return;
}
const { children = [] } = this.parent;
const { length } = children;
const index = children.indexOf(this);
this.setData({
isFirst: index === 0,
isLast: index === length - 1,
});
},
},
});
================================================
FILE: miniprogram/vant/goods-action-button/index.json
================================================
{
"component": true,
"usingComponents": {
"van-button": "../button/index"
}
}
================================================
FILE: miniprogram/vant/goods-action-button/index.wxml
================================================
{{ text }}
================================================
FILE: miniprogram/vant/goods-action-button/index.wxss
================================================
@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-goods-action-button{--button-warning-background-color:linear-gradient(90deg,#ffd01e,#ff8917);--button-warning-background-color:var(--goods-action-button-warning-color,linear-gradient(90deg,#ffd01e,#ff8917));--button-danger-background-color:linear-gradient(90deg,#ff6034,#ee0a24);--button-danger-background-color:var(--goods-action-button-danger-color,linear-gradient(90deg,#ff6034,#ee0a24));--button-default-height:40px;--button-default-height:var(--goods-action-button-height,40px);--button-line-height:20px;--button-line-height:var(--goods-action-button-line-height,20px);--button-plain-background-color:#fff;--button-plain-background-color:var(--goods-action-button-plain-color,#fff);display:block;--button-border-width:0}.van-goods-action-button--first{margin-left:5px;--button-border-radius:20px 0 0 20px;--button-border-radius:var(--goods-action-button-border-radius,20px) 0 0 var(--goods-action-button-border-radius,20px)}.van-goods-action-button--last{margin-right:5px;--button-border-radius:0 20px 20px 0;--button-border-radius:0 var(--goods-action-button-border-radius,20px) var(--goods-action-button-border-radius,20px) 0}.van-goods-action-button--first.van-goods-action-button--last{--button-border-radius:20px;--button-border-radius:var(--goods-action-button-border-radius,20px)}.van-goods-action-button--plain{--button-border-width:1px}.van-goods-action-button__inner{width:100%;font-weight:500!important;font-weight:var(--font-weight-bold,500)!important}@media (max-width:321px){.van-goods-action-button{font-size:13px}}
================================================
FILE: miniprogram/vant/goods-action-icon/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/goods-action-icon/index.js
================================================
import { VantComponent } from '../common/component';
import { link } from '../mixins/link';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
classes: ['icon-class', 'text-class'],
mixins: [link, button, openType],
props: {
text: String,
dot: Boolean,
info: String,
icon: String,
disabled: Boolean,
loading: Boolean,
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
},
},
});
================================================
FILE: miniprogram/vant/goods-action-icon/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-button": "../button/index"
}
}
================================================
FILE: miniprogram/vant/goods-action-icon/index.wxml
================================================
{{ text }}
================================================
FILE: miniprogram/vant/goods-action-icon/index.wxss
================================================
@import '../common/index.wxss';.van-goods-action-icon{border:none!important;width:50px!important;width:var(--goods-action-icon-height,50px)!important}.van-goods-action-icon__content{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:center;justify-content:center;height:100%;line-height:1;font-size:10px;font-size:var(--goods-action-icon-font-size,10px);color:#646566;color:var(--goods-action-icon-text-color,#646566)}.van-goods-action-icon__icon{margin-bottom:4px}
================================================
FILE: miniprogram/vant/grid/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/grid/index.js
================================================
import { VantComponent } from '../common/component';
import { addUnit } from '../common/utils';
VantComponent({
relation: {
name: 'grid-item',
type: 'descendant',
current: 'grid',
},
props: {
square: {
type: Boolean,
observer: 'updateChildren',
},
gutter: {
type: [Number, String],
value: 0,
observer: 'updateChildren',
},
clickable: {
type: Boolean,
observer: 'updateChildren',
},
columnNum: {
type: Number,
value: 4,
observer: 'updateChildren',
},
center: {
type: Boolean,
value: true,
observer: 'updateChildren',
},
border: {
type: Boolean,
value: true,
observer: 'updateChildren',
},
},
data: {
viewStyle: '',
},
created() {
const { gutter } = this.data;
if (gutter) {
this.setData({
viewStyle: `padding-left: ${addUnit(gutter)}`,
});
}
},
methods: {
updateChildren() {
this.children.forEach((child) => {
child.updateStyle();
});
},
},
});
================================================
FILE: miniprogram/vant/grid/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/grid/index.wxml
================================================
================================================
FILE: miniprogram/vant/grid/index.wxss
================================================
@import '../common/index.wxss';.van-grid{position:relative;box-sizing:border-box;overflow:hidden}
================================================
FILE: miniprogram/vant/grid-item/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/grid-item/index.js
================================================
import { link } from '../mixins/link';
import { VantComponent } from '../common/component';
import { addUnit } from '../common/utils';
VantComponent({
relation: {
name: 'grid',
type: 'ancestor',
current: 'grid-item',
},
classes: ['content-class', 'icon-class', 'text-class'],
mixins: [link],
props: {
icon: String,
dot: Boolean,
info: null,
text: String,
useSlot: Boolean,
},
data: {
viewStyle: '',
},
mounted() {
this.updateStyle();
},
methods: {
updateStyle() {
if (!this.parent) {
return;
}
const { data, children } = this.parent;
const { columnNum, border, square, gutter, clickable, center } = data;
const width = `${100 / columnNum}%`;
const styleWrapper = [];
styleWrapper.push(`width: ${width}`);
if (square) {
styleWrapper.push(`padding-top: ${width}`);
}
if (gutter) {
const gutterValue = addUnit(gutter);
styleWrapper.push(`padding-right: ${gutterValue}`);
const index = children.indexOf(this);
if (index >= columnNum) {
styleWrapper.push(`margin-top: ${gutterValue}`);
}
}
let contentStyle = '';
if (square && gutter) {
const gutterValue = addUnit(gutter);
contentStyle = `
right: ${gutterValue};
bottom: ${gutterValue};
height: auto;
`;
}
this.setData({
viewStyle: styleWrapper.join('; '),
contentStyle,
center,
border,
square,
gutter,
clickable,
});
},
onClick() {
this.$emit('click');
this.jumpLink();
},
},
});
================================================
FILE: miniprogram/vant/grid-item/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/grid-item/index.wxml
================================================
{{ text }}
================================================
FILE: miniprogram/vant/grid-item/index.wxss
================================================
@import '../common/index.wxss';.van-grid-item{position:relative;float:left;box-sizing:border-box}.van-grid-item--square{height:0}.van-grid-item__content{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;box-sizing:border-box;height:100%;padding:16px 8px;padding:var(--grid-item-content-padding,16px 8px);background-color:#fff;background-color:var(--grid-item-content-background-color,#fff)}.van-grid-item__content:after{z-index:1;border-width:0 1px 1px 0;border-bottom-width:var(--border-width-base,1px);border-right-width:var(--border-width-base,1px);border-top-width:0}.van-grid-item__content--surround:after{border-width:1px;border-width:var(--border-width-base,1px)}.van-grid-item__content--center{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-grid-item__content--square{position:absolute;top:0;right:0;left:0}.van-grid-item__content--clickable:active{background-color:#f2f3f5;background-color:var(--grid-item-content-active-color,#f2f3f5)}.van-grid-item__icon{font-size:26px;font-size:var(--grid-item-icon-size,26px)}.van-grid-item__text{word-wrap:break-word;color:#646566;color:var(--grid-item-text-color,#646566);font-size:12px;font-size:var(--grid-item-text-font-size,12px)}
================================================
FILE: miniprogram/vant/icon/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/icon/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
props: {
dot: Boolean,
info: null,
size: null,
color: String,
customStyle: String,
classPrefix: {
type: String,
value: 'van-icon',
},
name: {
type: String,
observer(val) {
this.setData({
isImageName: val.indexOf('/') !== -1,
});
},
},
},
methods: {
onClick() {
this.$emit('click');
},
},
});
================================================
FILE: miniprogram/vant/icon/index.json
================================================
{
"component": true,
"usingComponents": {
"van-info": "../info/index"
}
}
================================================
FILE: miniprogram/vant/icon/index.wxml
================================================
================================================
FILE: miniprogram/vant/icon/index.wxss
================================================
@import '../common/index.wxss';@font-face{font-weight:400;font-family:vant-icon;font-style:normal;font-display:auto;src:url(https://img.yzcdn.cn/vant/vant-icon-d3825a.woff2) format("woff2"),url(https://img.yzcdn.cn/vant/vant-icon-d3825a.woff) format("woff"),url(https://img.yzcdn.cn/vant/vant-icon-d3825a.ttf) format("truetype")}.van-icon{position:relative;font:normal normal normal 14px/1 vant-icon;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased}.van-icon,.van-icon:before{display:inline-block}.van-icon-add-o:before{content:"\F000"}.van-icon-add-square:before{content:"\F001"}.van-icon-add:before{content:"\F002"}.van-icon-after-sale:before{content:"\F003"}.van-icon-aim:before{content:"\F004"}.van-icon-alipay:before{content:"\F005"}.van-icon-apps-o:before{content:"\F006"}.van-icon-arrow-down:before{content:"\F007"}.van-icon-arrow-left:before{content:"\F008"}.van-icon-arrow-up:before{content:"\F009"}.van-icon-arrow:before{content:"\F00A"}.van-icon-ascending:before{content:"\F00B"}.van-icon-audio:before{content:"\F00C"}.van-icon-award-o:before{content:"\F00D"}.van-icon-award:before{content:"\F00E"}.van-icon-bag-o:before{content:"\F00F"}.van-icon-bag:before{content:"\F010"}.van-icon-balance-list-o:before{content:"\F011"}.van-icon-balance-list:before{content:"\F012"}.van-icon-balance-o:before{content:"\F013"}.van-icon-balance-pay:before{content:"\F014"}.van-icon-bar-chart-o:before{content:"\F015"}.van-icon-bars:before{content:"\F016"}.van-icon-bell:before{content:"\F017"}.van-icon-bill-o:before{content:"\F018"}.van-icon-bill:before{content:"\F019"}.van-icon-birthday-cake-o:before{content:"\F01A"}.van-icon-bookmark-o:before{content:"\F01B"}.van-icon-bookmark:before{content:"\F01C"}.van-icon-browsing-history-o:before{content:"\F01D"}.van-icon-browsing-history:before{content:"\F01E"}.van-icon-brush-o:before{content:"\F01F"}.van-icon-bulb-o:before{content:"\F020"}.van-icon-bullhorn-o:before{content:"\F021"}.van-icon-calender-o:before{content:"\F022"}.van-icon-card:before{content:"\F023"}.van-icon-cart-circle-o:before{content:"\F024"}.van-icon-cart-circle:before{content:"\F025"}.van-icon-cart-o:before{content:"\F026"}.van-icon-cart:before{content:"\F027"}.van-icon-cash-back-record:before{content:"\F028"}.van-icon-cash-on-deliver:before{content:"\F029"}.van-icon-cashier-o:before{content:"\F02A"}.van-icon-certificate:before{content:"\F02B"}.van-icon-chart-trending-o:before{content:"\F02C"}.van-icon-chat-o:before{content:"\F02D"}.van-icon-chat:before{content:"\F02E"}.van-icon-checked:before{content:"\F02F"}.van-icon-circle:before{content:"\F030"}.van-icon-clear:before{content:"\F031"}.van-icon-clock-o:before{content:"\F032"}.van-icon-clock:before{content:"\F033"}.van-icon-close:before{content:"\F034"}.van-icon-closed-eye:before{content:"\F035"}.van-icon-cluster-o:before{content:"\F036"}.van-icon-cluster:before{content:"\F037"}.van-icon-column:before{content:"\F038"}.van-icon-comment-circle-o:before{content:"\F039"}.van-icon-comment-circle:before{content:"\F03A"}.van-icon-comment-o:before{content:"\F03B"}.van-icon-comment:before{content:"\F03C"}.van-icon-completed:before{content:"\F03D"}.van-icon-contact:before{content:"\F03E"}.van-icon-coupon-o:before{content:"\F03F"}.van-icon-coupon:before{content:"\F040"}.van-icon-credit-pay:before{content:"\F041"}.van-icon-cross:before{content:"\F042"}.van-icon-debit-pay:before{content:"\F043"}.van-icon-delete:before{content:"\F044"}.van-icon-descending:before{content:"\F045"}.van-icon-description:before{content:"\F046"}.van-icon-desktop-o:before{content:"\F047"}.van-icon-diamond-o:before{content:"\F048"}.van-icon-diamond:before{content:"\F049"}.van-icon-discount:before{content:"\F04A"}.van-icon-down:before{content:"\F04B"}.van-icon-ecard-pay:before{content:"\F04C"}.van-icon-edit:before{content:"\F04D"}.van-icon-ellipsis:before{content:"\F04E"}.van-icon-empty:before{content:"\F04F"}.van-icon-envelop-o:before{content:"\F050"}.van-icon-exchange:before{content:"\F051"}.van-icon-expand-o:before{content:"\F052"}.van-icon-expand:before{content:"\F053"}.van-icon-eye-o:before{content:"\F054"}.van-icon-eye:before{content:"\F055"}.van-icon-fail:before{content:"\F056"}.van-icon-failure:before{content:"\F057"}.van-icon-filter-o:before{content:"\F058"}.van-icon-fire-o:before{content:"\F059"}.van-icon-fire:before{content:"\F05A"}.van-icon-flag-o:before{content:"\F05B"}.van-icon-flower-o:before{content:"\F05C"}.van-icon-free-postage:before{content:"\F05D"}.van-icon-friends-o:before{content:"\F05E"}.van-icon-friends:before{content:"\F05F"}.van-icon-gem-o:before{content:"\F060"}.van-icon-gem:before{content:"\F061"}.van-icon-gift-card-o:before{content:"\F062"}.van-icon-gift-card:before{content:"\F063"}.van-icon-gift-o:before{content:"\F064"}.van-icon-gift:before{content:"\F065"}.van-icon-gold-coin-o:before{content:"\F066"}.van-icon-gold-coin:before{content:"\F067"}.van-icon-good-job-o:before{content:"\F068"}.van-icon-good-job:before{content:"\F069"}.van-icon-goods-collect-o:before{content:"\F06A"}.van-icon-goods-collect:before{content:"\F06B"}.van-icon-graphic:before{content:"\F06C"}.van-icon-home-o:before{content:"\F06D"}.van-icon-hot-o:before{content:"\F06E"}.van-icon-hot-sale-o:before{content:"\F06F"}.van-icon-hot-sale:before{content:"\F070"}.van-icon-hot:before{content:"\F071"}.van-icon-hotel-o:before{content:"\F072"}.van-icon-idcard:before{content:"\F073"}.van-icon-info-o:before{content:"\F074"}.van-icon-info:before{content:"\F075"}.van-icon-invition:before{content:"\F076"}.van-icon-label-o:before{content:"\F077"}.van-icon-label:before{content:"\F078"}.van-icon-like-o:before{content:"\F079"}.van-icon-like:before{content:"\F07A"}.van-icon-live:before{content:"\F07B"}.van-icon-location-o:before{content:"\F07C"}.van-icon-location:before{content:"\F07D"}.van-icon-lock:before{content:"\F07E"}.van-icon-logistics:before{content:"\F07F"}.van-icon-manager-o:before{content:"\F080"}.van-icon-manager:before{content:"\F081"}.van-icon-map-marked:before{content:"\F082"}.van-icon-medal-o:before{content:"\F083"}.van-icon-medal:before{content:"\F084"}.van-icon-more-o:before{content:"\F085"}.van-icon-more:before{content:"\F086"}.van-icon-music-o:before{content:"\F087"}.van-icon-music:before{content:"\F088"}.van-icon-new-arrival-o:before{content:"\F089"}.van-icon-new-arrival:before{content:"\F08A"}.van-icon-new-o:before{content:"\F08B"}.van-icon-new:before{content:"\F08C"}.van-icon-newspaper-o:before{content:"\F08D"}.van-icon-notes-o:before{content:"\F08E"}.van-icon-orders-o:before{content:"\F08F"}.van-icon-other-pay:before{content:"\F090"}.van-icon-paid:before{content:"\F091"}.van-icon-passed:before{content:"\F092"}.van-icon-pause-circle-o:before{content:"\F093"}.van-icon-pause-circle:before{content:"\F094"}.van-icon-pause:before{content:"\F095"}.van-icon-peer-pay:before{content:"\F096"}.van-icon-pending-payment:before{content:"\F097"}.van-icon-phone-circle-o:before{content:"\F098"}.van-icon-phone-circle:before{content:"\F099"}.van-icon-phone-o:before{content:"\F09A"}.van-icon-phone:before{content:"\F09B"}.van-icon-photo-o:before{content:"\F09C"}.van-icon-photo:before{content:"\F09D"}.van-icon-photograph:before{content:"\F09E"}.van-icon-play-circle-o:before{content:"\F09F"}.van-icon-play-circle:before{content:"\F0A0"}.van-icon-play:before{content:"\F0A1"}.van-icon-plus:before{content:"\F0A2"}.van-icon-point-gift-o:before{content:"\F0A3"}.van-icon-point-gift:before{content:"\F0A4"}.van-icon-points:before{content:"\F0A5"}.van-icon-printer:before{content:"\F0A6"}.van-icon-qr-invalid:before{content:"\F0A7"}.van-icon-qr:before{content:"\F0A8"}.van-icon-question-o:before{content:"\F0A9"}.van-icon-question:before{content:"\F0AA"}.van-icon-records:before{content:"\F0AB"}.van-icon-refund-o:before{content:"\F0AC"}.van-icon-replay:before{content:"\F0AD"}.van-icon-scan:before{content:"\F0AE"}.van-icon-search:before{content:"\F0AF"}.van-icon-send-gift-o:before{content:"\F0B0"}.van-icon-send-gift:before{content:"\F0B1"}.van-icon-service-o:before{content:"\F0B2"}.van-icon-service:before{content:"\F0B3"}.van-icon-setting-o:before{content:"\F0B4"}.van-icon-setting:before{content:"\F0B5"}.van-icon-share:before{content:"\F0B6"}.van-icon-shop-collect-o:before{content:"\F0B7"}.van-icon-shop-collect:before{content:"\F0B8"}.van-icon-shop-o:before{content:"\F0B9"}.van-icon-shop:before{content:"\F0BA"}.van-icon-shopping-cart-o:before{content:"\F0BB"}.van-icon-shopping-cart:before{content:"\F0BC"}.van-icon-shrink:before{content:"\F0BD"}.van-icon-sign:before{content:"\F0BE"}.van-icon-smile-comment-o:before{content:"\F0BF"}.van-icon-smile-comment:before{content:"\F0C0"}.van-icon-smile-o:before{content:"\F0C1"}.van-icon-smile:before{content:"\F0C2"}.van-icon-star-o:before{content:"\F0C3"}.van-icon-star:before{content:"\F0C4"}.van-icon-stop-circle-o:before{content:"\F0C5"}.van-icon-stop-circle:before{content:"\F0C6"}.van-icon-stop:before{content:"\F0C7"}.van-icon-success:before{content:"\F0C8"}.van-icon-thumb-circle-o:before{content:"\F0C9"}.van-icon-thumb-circle:before{content:"\F0CA"}.van-icon-todo-list-o:before{content:"\F0CB"}.van-icon-todo-list:before{content:"\F0CC"}.van-icon-tosend:before{content:"\F0CD"}.van-icon-tv-o:before{content:"\F0CE"}.van-icon-umbrella-circle:before{content:"\F0CF"}.van-icon-underway-o:before{content:"\F0D0"}.van-icon-underway:before{content:"\F0D1"}.van-icon-upgrade:before{content:"\F0D2"}.van-icon-user-circle-o:before{content:"\F0D3"}.van-icon-user-o:before{content:"\F0D4"}.van-icon-video-o:before{content:"\F0D5"}.van-icon-video:before{content:"\F0D6"}.van-icon-vip-card-o:before{content:"\F0D7"}.van-icon-vip-card:before{content:"\F0D8"}.van-icon-volume-o:before{content:"\F0D9"}.van-icon-volume:before{content:"\F0DA"}.van-icon-wap-home-o:before{content:"\F0DB"}.van-icon-wap-home:before{content:"\F0DC"}.van-icon-wap-nav:before{content:"\F0DD"}.van-icon-warn-o:before{content:"\F0DE"}.van-icon-warning-o:before{content:"\F0DF"}.van-icon-warning:before{content:"\F0E0"}.van-icon-weapp-nav:before{content:"\F0E1"}.van-icon-wechat:before{content:"\F0E2"}.van-icon-youzan-shield:before{content:"\F0E3"}:host{display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-icon--image{width:1em;height:1em}.van-icon__image{width:100%;height:100%}.van-icon__info{z-index:1}
================================================
FILE: miniprogram/vant/image/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/image/index.js
================================================
import { addUnit, isDef } from '../common/utils';
import { VantComponent } from '../common/component';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
const FIT_MODE_MAP = {
none: 'center',
fill: 'scaleToFill',
cover: 'aspectFill',
contain: 'aspectFit',
widthFix: 'widthFix',
heightFix: 'heightFix',
};
VantComponent({
mixins: [button, openType],
classes: ['custom-class', 'loading-class', 'error-class', 'image-class'],
props: {
src: {
type: String,
observer() {
this.setData({
error: false,
loading: true,
});
},
},
round: Boolean,
width: {
type: null,
observer: 'setStyle',
},
height: {
type: null,
observer: 'setStyle',
},
radius: null,
lazyLoad: Boolean,
useErrorSlot: Boolean,
useLoadingSlot: Boolean,
showMenuByLongpress: Boolean,
fit: {
type: String,
value: 'fill',
observer: 'setMode',
},
showError: {
type: Boolean,
value: true,
},
showLoading: {
type: Boolean,
value: true,
},
},
data: {
error: false,
loading: true,
viewStyle: '',
},
mounted() {
this.setMode();
this.setStyle();
},
methods: {
setMode() {
this.setData({
mode: FIT_MODE_MAP[this.data.fit],
});
},
setStyle() {
const { width, height, radius } = this.data;
let style = '';
if (isDef(width)) {
style += `width: ${addUnit(width)};`;
}
if (isDef(height)) {
style += `height: ${addUnit(height)};`;
}
if (isDef(radius)) {
style += 'overflow: hidden;';
style += `border-radius: ${addUnit(radius)};`;
}
this.setData({ viewStyle: style });
},
onLoad(event) {
this.setData({
loading: false,
});
this.$emit('load', event.detail);
},
onError(event) {
this.setData({
loading: false,
error: true,
});
this.$emit('error', event.detail);
},
onClick(event) {
this.$emit('click', event.detail);
},
},
});
================================================
FILE: miniprogram/vant/image/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-loading": "../loading/index"
}
}
================================================
FILE: miniprogram/vant/image/index.wxml
================================================
================================================
FILE: miniprogram/vant/image/index.wxss
================================================
@import '../common/index.wxss';.van-image{position:relative;display:inline-block}.van-image--round{overflow:hidden;border-radius:50%}.van-image--round .van-image__img{border-radius:inherit}.van-image__error,.van-image__img,.van-image__loading{display:block;width:100%;height:100%}.van-image__error,.van-image__loading{position:absolute;top:0;left:0;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;color:#969799;color:var(--image-placeholder-text-color,#969799);font-size:14px;font-size:var(--image-placeholder-font-size,14px);background-color:#f7f8fa;background-color:var(--image-placeholder-background-color,#f7f8fa)}
================================================
FILE: miniprogram/vant/index-anchor/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/index-anchor/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'index-bar',
type: 'ancestor',
current: 'index-anchor',
},
props: {
useSlot: Boolean,
index: null,
},
data: {
active: false,
wrapperStyle: '',
anchorStyle: '',
},
methods: {
scrollIntoView(scrollTop) {
this.getBoundingClientRect().then((rect) => {
wx.pageScrollTo({
duration: 0,
scrollTop: scrollTop + rect.top - this.parent.data.stickyOffsetTop,
});
});
},
getBoundingClientRect() {
return this.getRect('.van-index-anchor-wrapper');
},
},
});
================================================
FILE: miniprogram/vant/index-anchor/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/index-anchor/index.wxml
================================================
{{ index }}
================================================
FILE: miniprogram/vant/index-anchor/index.wxss
================================================
@import '../common/index.wxss';.van-index-anchor{padding:0 16px;padding:var(--index-anchor-padding,0 16px);color:#323233;color:var(--index-anchor-text-color,#323233);font-weight:500;font-weight:var(--index-anchor-font-weight,500);font-size:14px;font-size:var(--index-anchor-font-size,14px);line-height:32px;line-height:var(--index-anchor-line-height,32px);background-color:initial;background-color:var(--index-anchor-background-color,transparent)}.van-index-anchor--active{right:0;left:0;color:#07c160;color:var(--index-anchor-active-text-color,#07c160);background-color:#fff;background-color:var(--index-anchor-active-background-color,#fff)}
================================================
FILE: miniprogram/vant/index-bar/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/index-bar/index.js
================================================
import { VantComponent } from '../common/component';
import { GREEN } from '../common/color';
import { pageScrollMixin } from '../mixins/page-scroll';
const indexList = () => {
const indexList = [];
const charCodeOfA = 'A'.charCodeAt(0);
for (let i = 0; i < 26; i++) {
indexList.push(String.fromCharCode(charCodeOfA + i));
}
return indexList;
};
VantComponent({
relation: {
name: 'index-anchor',
type: 'descendant',
current: 'index-bar',
linked() {
this.updateData();
},
unlinked() {
this.updateData();
},
},
props: {
sticky: {
type: Boolean,
value: true,
},
zIndex: {
type: Number,
value: 1,
},
highlightColor: {
type: String,
value: GREEN,
},
stickyOffsetTop: {
type: Number,
value: 0,
},
indexList: {
type: Array,
value: indexList(),
},
},
mixins: [
pageScrollMixin(function (event) {
this.scrollTop = event.scrollTop || 0;
this.onScroll();
}),
],
data: {
activeAnchorIndex: null,
showSidebar: false,
},
created() {
this.scrollTop = 0;
},
methods: {
updateData() {
wx.nextTick(() => {
if (this.timer != null) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
this.setData({
showSidebar: !!this.children.length,
});
this.setRect().then(() => {
this.onScroll();
});
}, 0);
});
},
setRect() {
return Promise.all([
this.setAnchorsRect(),
this.setListRect(),
this.setSiderbarRect(),
]);
},
setAnchorsRect() {
return Promise.all(
this.children.map((anchor) =>
anchor.getRect('.van-index-anchor-wrapper').then((rect) => {
Object.assign(anchor, {
height: rect.height,
top: rect.top + this.scrollTop,
});
})
)
);
},
setListRect() {
return this.getRect('.van-index-bar').then((rect) => {
Object.assign(this, {
height: rect.height,
top: rect.top + this.scrollTop,
});
});
},
setSiderbarRect() {
return this.getRect('.van-index-bar__sidebar').then((res) => {
this.sidebar = {
height: res.height,
top: res.top,
};
});
},
setDiffData({ target, data }) {
const diffData = {};
Object.keys(data).forEach((key) => {
if (target.data[key] !== data[key]) {
diffData[key] = data[key];
}
});
if (Object.keys(diffData).length) {
target.setData(diffData);
}
},
getAnchorRect(anchor) {
return anchor.getRect('.van-index-anchor-wrapper').then((rect) => ({
height: rect.height,
top: rect.top,
}));
},
getActiveAnchorIndex() {
const { children, scrollTop } = this;
const { sticky, stickyOffsetTop } = this.data;
for (let i = this.children.length - 1; i >= 0; i--) {
const preAnchorHeight = i > 0 ? children[i - 1].height : 0;
const reachTop = sticky ? preAnchorHeight + stickyOffsetTop : 0;
if (reachTop + scrollTop >= children[i].top) {
return i;
}
}
return -1;
},
onScroll() {
const { children = [], scrollTop } = this;
if (!children.length) {
return;
}
const { sticky, stickyOffsetTop, zIndex, highlightColor } = this.data;
const active = this.getActiveAnchorIndex();
this.setDiffData({
target: this,
data: {
activeAnchorIndex: active,
},
});
if (sticky) {
let isActiveAnchorSticky = false;
if (active !== -1) {
isActiveAnchorSticky =
children[active].top <= stickyOffsetTop + scrollTop;
}
children.forEach((item, index) => {
if (index === active) {
let wrapperStyle = '';
let anchorStyle = `
color: ${highlightColor};
`;
if (isActiveAnchorSticky) {
wrapperStyle = `
height: ${children[index].height}px;
`;
anchorStyle = `
position: fixed;
top: ${stickyOffsetTop}px;
z-index: ${zIndex};
color: ${highlightColor};
`;
}
this.setDiffData({
target: item,
data: {
active: true,
anchorStyle,
wrapperStyle,
},
});
} else if (index === active - 1) {
const currentAnchor = children[index];
const currentOffsetTop = currentAnchor.top;
const targetOffsetTop =
index === children.length - 1
? this.top
: children[index + 1].top;
const parentOffsetHeight = targetOffsetTop - currentOffsetTop;
const translateY = parentOffsetHeight - currentAnchor.height;
const anchorStyle = `
position: relative;
transform: translate3d(0, ${translateY}px, 0);
z-index: ${zIndex};
color: ${highlightColor};
`;
this.setDiffData({
target: item,
data: {
active: true,
anchorStyle,
},
});
} else {
this.setDiffData({
target: item,
data: {
active: false,
anchorStyle: '',
wrapperStyle: '',
},
});
}
});
}
},
onClick(event) {
this.scrollToAnchor(event.target.dataset.index);
},
onTouchMove(event) {
const sidebarLength = this.children.length;
const touch = event.touches[0];
const itemHeight = this.sidebar.height / sidebarLength;
let index = Math.floor((touch.clientY - this.sidebar.top) / itemHeight);
if (index < 0) {
index = 0;
} else if (index > sidebarLength - 1) {
index = sidebarLength - 1;
}
this.scrollToAnchor(index);
},
onTouchStop() {
this.scrollToAnchorIndex = null;
},
scrollToAnchor(index) {
if (typeof index !== 'number' || this.scrollToAnchorIndex === index) {
return;
}
this.scrollToAnchorIndex = index;
const anchor = this.children.find(
(item) => item.data.index === this.data.indexList[index]
);
if (anchor) {
anchor.scrollIntoView(this.scrollTop);
this.$emit('select', anchor.data.index);
}
},
},
});
================================================
FILE: miniprogram/vant/index-bar/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/index-bar/index.wxml
================================================
================================================
FILE: miniprogram/vant/index-bar/index.wxss
================================================
@import '../common/index.wxss';.van-index-bar{position:relative}.van-index-bar__sidebar{position:fixed;top:50%;right:0;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;text-align:center;-webkit-transform:translateY(-50%);transform:translateY(-50%);-webkit-user-select:none;user-select:none}.van-index-bar__index{font-weight:500;padding:0 4px 0 16px;padding:0 var(--padding-base,4px) 0 var(--padding-md,16px);font-size:10px;font-size:var(--index-bar-index-font-size,10px);line-height:14px;line-height:var(--index-bar-index-line-height,14px)}
================================================
FILE: miniprogram/vant/info/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/info/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
props: {
dot: Boolean,
info: null,
customStyle: String,
},
});
================================================
FILE: miniprogram/vant/info/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/info/index.wxml
================================================
{{ dot ? '' : info }}
================================================
FILE: miniprogram/vant/info/index.wxss
================================================
@import '../common/index.wxss';.van-info{position:absolute;top:0;right:0;box-sizing:border-box;white-space:nowrap;text-align:center;-webkit-transform:translate(50%,-50%);transform:translate(50%,-50%);-webkit-transform-origin:100%;transform-origin:100%;min-width:16px;min-width:var(--info-size,16px);padding:0 3px;padding:var(--info-padding,0 3px);color:#fff;color:var(--info-color,#fff);font-weight:500;font-weight:var(--info-font-weight,500);font-size:12px;font-size:var(--info-font-size,12px);font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--info-font-family,Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif);line-height:14px;line-height:calc(var(--info-size, 16px) - var(--info-border-width, 1px)*2);background-color:#ee0a24;background-color:var(--info-background-color,#ee0a24);border:1px solid #fff;border:var(--info-border-width,1px) solid var(--white,#fff);border-radius:16px;border-radius:var(--info-size,16px)}.van-info--dot{min-width:0;border-radius:100%;width:8px;width:var(--info-dot-size,8px);height:8px;height:var(--info-dot-size,8px);background-color:#ee0a24;background-color:var(--info-dot-color,#ee0a24)}
================================================
FILE: miniprogram/vant/loading/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/loading/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
props: {
color: String,
vertical: Boolean,
type: {
type: String,
value: 'circular',
},
size: String,
textSize: String,
},
data: {
array12: Array.from({ length: 12 }),
},
});
================================================
FILE: miniprogram/vant/loading/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/loading/index.wxml
================================================
================================================
FILE: miniprogram/vant/loading/index.wxss
================================================
@import '../common/index.wxss';:host{font-size:0;line-height:1}.van-loading{display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;color:#c8c9cc;color:var(--loading-spinner-color,#c8c9cc)}.van-loading__spinner{position:relative;box-sizing:border-box;width:30px;width:var(--loading-spinner-size,30px);max-width:100%;max-height:100%;height:30px;height:var(--loading-spinner-size,30px);-webkit-animation:van-rotate .8s linear infinite;animation:van-rotate .8s linear infinite;-webkit-animation:van-rotate var(--loading-spinner-animation-duration,.8s) linear infinite;animation:van-rotate var(--loading-spinner-animation-duration,.8s) linear infinite}.van-loading__spinner--spinner{-webkit-animation-timing-function:steps(12);animation-timing-function:steps(12)}.van-loading__spinner--circular{border:1px solid transparent;border-top-color:initial;border-radius:100%}.van-loading__text{margin-left:8px;margin-left:var(--padding-xs,8px);color:#969799;color:var(--loading-text-color,#969799);font-size:14px;font-size:var(--loading-text-font-size,14px);line-height:20px;line-height:var(--loading-text-line-height,20px)}.van-loading__text:empty{display:none}.van-loading--vertical{-webkit-flex-direction:column;flex-direction:column}.van-loading--vertical .van-loading__text{margin:8px 0 0;margin:var(--padding-xs,8px) 0 0}.van-loading__dot{position:absolute;top:0;left:0;width:100%;height:100%}.van-loading__dot:before{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%;content:" "}.van-loading__dot:first-of-type{-webkit-transform:rotate(30deg);transform:rotate(30deg);opacity:1}.van-loading__dot:nth-of-type(2){-webkit-transform:rotate(60deg);transform:rotate(60deg);opacity:.9375}.van-loading__dot:nth-of-type(3){-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:.875}.van-loading__dot:nth-of-type(4){-webkit-transform:rotate(120deg);transform:rotate(120deg);opacity:.8125}.van-loading__dot:nth-of-type(5){-webkit-transform:rotate(150deg);transform:rotate(150deg);opacity:.75}.van-loading__dot:nth-of-type(6){-webkit-transform:rotate(180deg);transform:rotate(180deg);opacity:.6875}.van-loading__dot:nth-of-type(7){-webkit-transform:rotate(210deg);transform:rotate(210deg);opacity:.625}.van-loading__dot:nth-of-type(8){-webkit-transform:rotate(240deg);transform:rotate(240deg);opacity:.5625}.van-loading__dot:nth-of-type(9){-webkit-transform:rotate(270deg);transform:rotate(270deg);opacity:.5}.van-loading__dot:nth-of-type(10){-webkit-transform:rotate(300deg);transform:rotate(300deg);opacity:.4375}.van-loading__dot:nth-of-type(11){-webkit-transform:rotate(330deg);transform:rotate(330deg);opacity:.375}.van-loading__dot:nth-of-type(12){-webkit-transform:rotate(1turn);transform:rotate(1turn);opacity:.3125}@-webkit-keyframes van-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes van-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}
================================================
FILE: miniprogram/vant/mixins/basic.d.ts
================================================
export declare const basic: string;
================================================
FILE: miniprogram/vant/mixins/basic.js
================================================
export const basic = Behavior({
methods: {
$emit(...args) {
this.triggerEvent(...args);
},
set(data, callback) {
this.setData(data, callback);
return new Promise((resolve) => wx.nextTick(resolve));
},
getRect(selector, all) {
return new Promise((resolve) => {
wx.createSelectorQuery()
.in(this)
[all ? 'selectAll' : 'select'](selector)
.boundingClientRect((rect) => {
if (all && Array.isArray(rect) && rect.length) {
resolve(rect);
}
if (!all && rect) {
resolve(rect);
}
})
.exec();
});
},
},
});
================================================
FILE: miniprogram/vant/mixins/button.d.ts
================================================
export declare const button: string;
================================================
FILE: miniprogram/vant/mixins/button.js
================================================
export const button = Behavior({
externalClasses: ['hover-class'],
properties: {
id: String,
lang: String,
businessId: Number,
sessionFrom: String,
sendMessageTitle: String,
sendMessagePath: String,
sendMessageImg: String,
showMessageCard: Boolean,
appParameter: String,
ariaLabel: String,
},
});
================================================
FILE: miniprogram/vant/mixins/link.d.ts
================================================
export declare const link: string;
================================================
FILE: miniprogram/vant/mixins/link.js
================================================
export const link = Behavior({
properties: {
url: String,
linkType: {
type: String,
value: 'navigateTo',
},
},
methods: {
jumpLink(urlKey = 'url') {
const url = this.data[urlKey];
if (url) {
wx[this.data.linkType]({ url });
}
},
},
});
================================================
FILE: miniprogram/vant/mixins/open-type.d.ts
================================================
export declare const openType: string;
================================================
FILE: miniprogram/vant/mixins/open-type.js
================================================
export const openType = Behavior({
properties: {
openType: String,
},
methods: {
bindGetUserInfo(event) {
this.$emit('getuserinfo', event.detail);
},
bindContact(event) {
this.$emit('contact', event.detail);
},
bindGetPhoneNumber(event) {
this.$emit('getphonenumber', event.detail);
},
bindError(event) {
this.$emit('error', event.detail);
},
bindLaunchApp(event) {
this.$emit('launchapp', event.detail);
},
bindOpenSetting(event) {
this.$emit('opensetting', event.detail);
},
},
});
================================================
FILE: miniprogram/vant/mixins/page-scroll.d.ts
================================================
///
declare type IPageScrollOption = WechatMiniprogram.Page.IPageScrollOption;
declare type Scroller = (event: IPageScrollOption) => void;
export declare const pageScrollMixin: (scroller: Scroller) => string;
export {};
================================================
FILE: miniprogram/vant/mixins/page-scroll.js
================================================
function getCurrentPage() {
const pages = getCurrentPages();
return pages[pages.length - 1] || {};
}
function onPageScroll(event) {
const { vanPageScroller = [] } = getCurrentPage();
vanPageScroller.forEach((scroller) => {
if (typeof scroller === 'function') {
scroller(event);
}
});
}
export const pageScrollMixin = (scroller) =>
Behavior({
attached() {
const page = getCurrentPage();
if (Array.isArray(page.vanPageScroller)) {
page.vanPageScroller.push(scroller.bind(this));
} else {
page.vanPageScroller =
typeof page.onPageScroll === 'function'
? [page.onPageScroll.bind(page), scroller.bind(this)]
: [scroller.bind(this)];
}
page.onPageScroll = onPageScroll;
},
detached() {
const page = getCurrentPage();
page.vanPageScroller = (page.vanPageScroller || []).filter(
(item) => item !== scroller
);
},
});
================================================
FILE: miniprogram/vant/mixins/touch.d.ts
================================================
export declare const touch: string;
================================================
FILE: miniprogram/vant/mixins/touch.js
================================================
const MIN_DISTANCE = 10;
function getDirection(x, y) {
if (x > y && x > MIN_DISTANCE) {
return 'horizontal';
}
if (y > x && y > MIN_DISTANCE) {
return 'vertical';
}
return '';
}
export const touch = Behavior({
methods: {
resetTouchStatus() {
this.direction = '';
this.deltaX = 0;
this.deltaY = 0;
this.offsetX = 0;
this.offsetY = 0;
},
touchStart(event) {
this.resetTouchStatus();
const touch = event.touches[0];
this.startX = touch.clientX;
this.startY = touch.clientY;
},
touchMove(event) {
const touch = event.touches[0];
this.deltaX = touch.clientX - this.startX;
this.deltaY = touch.clientY - this.startY;
this.offsetX = Math.abs(this.deltaX);
this.offsetY = Math.abs(this.deltaY);
this.direction =
this.direction || getDirection(this.offsetX, this.offsetY);
},
},
});
================================================
FILE: miniprogram/vant/mixins/transition.d.ts
================================================
export declare const transition: (showDefaultValue: boolean) => string;
================================================
FILE: miniprogram/vant/mixins/transition.js
================================================
import { isObj } from '../common/utils';
const getClassNames = (name) => ({
enter: `van-${name}-enter van-${name}-enter-active enter-class enter-active-class`,
'enter-to': `van-${name}-enter-to van-${name}-enter-active enter-to-class enter-active-class`,
leave: `van-${name}-leave van-${name}-leave-active leave-class leave-active-class`,
'leave-to': `van-${name}-leave-to van-${name}-leave-active leave-to-class leave-active-class`,
});
const nextTick = () => new Promise((resolve) => setTimeout(resolve, 1000 / 30));
export const transition = function (showDefaultValue) {
return Behavior({
properties: {
customStyle: String,
// @ts-ignore
show: {
type: Boolean,
value: showDefaultValue,
observer: 'observeShow',
},
// @ts-ignore
duration: {
type: null,
value: 300,
observer: 'observeDuration',
},
name: {
type: String,
value: 'fade',
},
},
data: {
type: '',
inited: false,
display: false,
},
methods: {
observeShow(value, old) {
if (value === old) {
return;
}
value ? this.enter() : this.leave();
},
enter() {
const { duration, name } = this.data;
const classNames = getClassNames(name);
const currentDuration = isObj(duration) ? duration.enter : duration;
this.status = 'enter';
this.$emit('before-enter');
Promise.resolve()
.then(nextTick)
.then(() => {
this.checkStatus('enter');
this.$emit('enter');
this.setData({
inited: true,
display: true,
classes: classNames.enter,
currentDuration,
});
})
.then(nextTick)
.then(() => {
this.checkStatus('enter');
this.transitionEnded = false;
this.setData({
classes: classNames['enter-to'],
});
})
.catch(() => {});
},
leave() {
if (!this.data.display) {
return;
}
const { duration, name } = this.data;
const classNames = getClassNames(name);
const currentDuration = isObj(duration) ? duration.leave : duration;
this.status = 'leave';
this.$emit('before-leave');
Promise.resolve()
.then(nextTick)
.then(() => {
this.checkStatus('leave');
this.$emit('leave');
this.setData({
classes: classNames.leave,
currentDuration,
});
})
.then(nextTick)
.then(() => {
this.checkStatus('leave');
this.transitionEnded = false;
setTimeout(() => this.onTransitionEnd(), currentDuration);
this.setData({
classes: classNames['leave-to'],
});
})
.catch(() => {});
},
checkStatus(status) {
if (status !== this.status) {
throw new Error(`incongruent status: ${status}`);
}
},
onTransitionEnd() {
if (this.transitionEnded) {
return;
}
this.transitionEnded = true;
this.$emit(`after-${this.status}`);
const { show, display } = this.data;
if (!show && display) {
this.setData({ display: false });
}
},
},
});
};
================================================
FILE: miniprogram/vant/nav-bar/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/nav-bar/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
classes: ['title-class'],
props: {
title: String,
fixed: {
type: Boolean,
observer: 'setHeight',
},
placeholder: {
type: Boolean,
observer: 'setHeight',
},
leftText: String,
rightText: String,
customStyle: String,
leftArrow: Boolean,
border: {
type: Boolean,
value: true,
},
zIndex: {
type: Number,
value: 1,
},
safeAreaInsetTop: {
type: Boolean,
value: true,
},
},
data: {
statusBarHeight: 0,
height: 44,
baseStyle: '',
},
created() {
const { statusBarHeight } = wx.getSystemInfoSync();
const { safeAreaInsetTop, zIndex } = this.data;
const paddingTop = safeAreaInsetTop ? statusBarHeight : 0;
const baseStyle = `z-index: ${zIndex};padding-top: ${paddingTop}px;`;
this.setData({
statusBarHeight,
height: 44 + statusBarHeight,
baseStyle,
});
},
mounted() {
this.setHeight();
},
methods: {
onClickLeft() {
this.$emit('click-left');
},
onClickRight() {
this.$emit('click-right');
},
setHeight() {
if (!this.data.fixed || !this.data.placeholder) {
return;
}
wx.nextTick(() => {
this.getRect('.van-nav-bar').then((res) => {
this.setData({ height: res.height });
});
});
},
},
});
================================================
FILE: miniprogram/vant/nav-bar/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/nav-bar/index.wxml
================================================
{{ leftText }}
{{ title }}
{{ rightText }}
================================================
FILE: miniprogram/vant/nav-bar/index.wxss
================================================
@import '../common/index.wxss';.van-nav-bar{position:relative;text-align:center;-webkit-user-select:none;user-select:none;height:44px;height:var(--nav-bar-height,44px);line-height:44px;line-height:var(--nav-bar-height,44px);background-color:#fff;background-color:var(--nav-bar-background-color,#fff)}.van-nav-bar__text{display:inline-block;vertical-align:middle;margin:0 -16px;margin:0 -var(--padding-md,16px);padding:0 16px;padding:0 var(--padding-md,16px);color:#1989fa;color:var(--nav-bar-text-color,#1989fa)}.van-nav-bar__text--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-nav-bar__arrow{vertical-align:middle;font-size:16px;font-size:var(--nav-bar-arrow-size,16px);color:#1989fa;color:var(--nav-bar-text-color,#1989fa)}.van-nav-bar__arrow+.van-nav-bar__text{margin-left:-20px;padding-left:25px}.van-nav-bar--fixed{position:fixed;top:0;left:0;width:100%}.van-nav-bar__title{max-width:60%;margin:0 auto;color:#323233;color:var(--nav-bar-title-text-color,#323233);font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--nav-bar-title-font-size,16px)}.van-nav-bar__left,.van-nav-bar__right{position:absolute;bottom:0;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;font-size:14px;font-size:var(--font-size-md,14px)}.van-nav-bar__left{left:16px;left:var(--padding-md,16px)}.van-nav-bar__right{right:16px;right:var(--padding-md,16px)}
================================================
FILE: miniprogram/vant/notice-bar/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/notice-bar/index.js
================================================
import { VantComponent } from '../common/component';
const FONT_COLOR = '#ed6a0c';
const BG_COLOR = '#fffbe8';
VantComponent({
props: {
text: {
type: String,
value: '',
observer() {
wx.nextTick(() => {
this.init();
});
},
},
mode: {
type: String,
value: '',
},
url: {
type: String,
value: '',
},
openType: {
type: String,
value: 'navigate',
},
delay: {
type: Number,
value: 1,
},
speed: {
type: Number,
value: 50,
observer() {
wx.nextTick(() => {
this.init();
});
},
},
scrollable: {
type: Boolean,
value: true,
},
leftIcon: {
type: String,
value: '',
},
color: {
type: String,
value: FONT_COLOR,
},
backgroundColor: {
type: String,
value: BG_COLOR,
},
wrapable: Boolean,
},
data: {
show: true,
},
created() {
this.resetAnimation = wx.createAnimation({
duration: 0,
timingFunction: 'linear',
});
},
destroyed() {
this.timer && clearTimeout(this.timer);
},
methods: {
init() {
Promise.all([
this.getRect('.van-notice-bar__content'),
this.getRect('.van-notice-bar__wrap'),
]).then((rects) => {
const [contentRect, wrapRect] = rects;
if (
contentRect == null ||
wrapRect == null ||
!contentRect.width ||
!wrapRect.width
) {
return;
}
const { speed, scrollable, delay } = this.data;
if (scrollable && wrapRect.width < contentRect.width) {
const duration = (contentRect.width / speed) * 1000;
this.wrapWidth = wrapRect.width;
this.contentWidth = contentRect.width;
this.duration = duration;
this.animation = wx.createAnimation({
duration,
timingFunction: 'linear',
delay,
});
this.scroll();
}
});
},
scroll() {
this.timer && clearTimeout(this.timer);
this.timer = null;
this.setData({
animationData: this.resetAnimation
.translateX(this.wrapWidth)
.step()
.export(),
});
setTimeout(() => {
this.setData({
animationData: this.animation
.translateX(-this.contentWidth)
.step()
.export(),
});
}, 20);
this.timer = setTimeout(() => {
this.scroll();
}, this.duration);
},
onClickIcon() {
this.timer && clearTimeout(this.timer);
this.timer = null;
this.setData({ show: false });
},
onClick(event) {
this.$emit('click', event);
},
},
});
================================================
FILE: miniprogram/vant/notice-bar/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/notice-bar/index.wxml
================================================
{{ text }}
================================================
FILE: miniprogram/vant/notice-bar/index.wxss
================================================
@import '../common/index.wxss';.van-notice-bar{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:40px;height:var(--notice-bar-height,40px);padding:0 16px;padding:var(--notice-bar-padding,0 16px);font-size:14px;font-size:var(--notice-bar-font-size,14px);color:#ed6a0c;color:var(--notice-bar-text-color,#ed6a0c);line-height:24px;line-height:var(--notice-bar-line-height,24px);background-color:#fffbe8;background-color:var(--notice-bar-background-color,#fffbe8)}.van-notice-bar--withicon{position:relative;padding-right:40px}.van-notice-bar--wrapable{height:auto;padding:8px 16px;padding:var(--notice-bar-wrapable-padding,8px 16px)}.van-notice-bar--wrapable .van-notice-bar__wrap{height:auto}.van-notice-bar--wrapable .van-notice-bar__content{position:relative;white-space:normal}.van-notice-bar__left-icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;margin-right:4px;vertical-align:middle}.van-notice-bar__left-icon,.van-notice-bar__right-icon{font-size:16px;font-size:var(--notice-bar-icon-size,16px);min-width:22px;min-width:var(--notice-bar-icon-min-width,22px)}.van-notice-bar__right-icon{position:absolute;top:10px;right:15px}.van-notice-bar__wrap{position:relative;-webkit-flex:1;flex:1;overflow:hidden;height:24px;height:var(--notice-bar-line-height,24px)}.van-notice-bar__content{position:absolute;white-space:nowrap}.van-notice-bar__content.van-ellipsis{max-width:100%}
================================================
FILE: miniprogram/vant/notify/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/notify/index.js
================================================
import { VantComponent } from '../common/component';
import { WHITE } from '../common/color';
VantComponent({
props: {
message: String,
background: String,
type: {
type: String,
value: 'danger',
},
color: {
type: String,
value: WHITE,
},
duration: {
type: Number,
value: 3000,
},
zIndex: {
type: Number,
value: 110,
},
safeAreaInsetTop: {
type: Boolean,
value: false,
},
top: null,
},
data: {
show: false,
},
created() {
const { statusBarHeight } = wx.getSystemInfoSync();
this.setData({ statusBarHeight });
},
methods: {
show() {
const { duration, onOpened } = this.data;
clearTimeout(this.timer);
this.setData({ show: true });
wx.nextTick(onOpened);
if (duration > 0 && duration !== Infinity) {
this.timer = setTimeout(() => {
this.hide();
}, duration);
}
},
hide() {
const { onClose } = this.data;
clearTimeout(this.timer);
this.setData({ show: false });
wx.nextTick(onClose);
},
onTap(event) {
const { onClick } = this.data;
if (onClick) {
onClick(event.detail);
}
},
},
});
================================================
FILE: miniprogram/vant/notify/index.json
================================================
{
"component": true,
"usingComponents": {
"van-transition": "../transition/index"
}
}
================================================
FILE: miniprogram/vant/notify/index.wxml
================================================
{{ message }}
================================================
FILE: miniprogram/vant/notify/index.wxss
================================================
@import '../common/index.wxss';.van-notify{text-align:center;word-wrap:break-word;padding:6px 15px;padding:var(--notify-padding,6px 15px);font-size:14px;font-size:var(--notify-font-size,14px);line-height:20px;line-height:var(--notify-line-height,20px)}.van-notify__container{position:fixed;top:0;box-sizing:border-box;width:100%}.van-notify--primary{background-color:#1989fa;background-color:var(--notify-primary-background-color,#1989fa)}.van-notify--success{background-color:#07c160;background-color:var(--notify-success-background-color,#07c160)}.van-notify--danger{background-color:#ee0a24;background-color:var(--notify-danger-background-color,#ee0a24)}.van-notify--warning{background-color:#ff976a;background-color:var(--notify-warning-background-color,#ff976a)}
================================================
FILE: miniprogram/vant/notify/notify.d.ts
================================================
interface NotifyOptions {
type?: 'primary' | 'success' | 'danger' | 'warning';
color?: string;
zIndex?: number;
top?: number;
message: string;
context?: any;
duration?: number;
selector?: string;
background?: string;
safeAreaInsetTop?: boolean;
onClick?: () => void;
onOpened?: () => void;
onClose?: () => void;
}
declare function Notify(options: NotifyOptions | string): any;
declare namespace Notify {
var clear: (options?: NotifyOptions) => void;
}
export default Notify;
================================================
FILE: miniprogram/vant/notify/notify.js
================================================
import { WHITE } from '../common/color';
const defaultOptions = {
selector: '#van-notify',
type: 'danger',
message: '',
background: '',
duration: 3000,
zIndex: 110,
top: 0,
color: WHITE,
safeAreaInsetTop: false,
onClick: () => {},
onOpened: () => {},
onClose: () => {},
};
function parseOptions(message) {
return typeof message === 'string' ? { message } : message;
}
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
export default function Notify(options) {
options = Object.assign(
Object.assign({}, defaultOptions),
parseOptions(options)
);
const context = options.context || getContext();
const notify = context.selectComponent(options.selector);
delete options.context;
delete options.selector;
if (notify) {
notify.setData(options);
notify.show();
return notify;
}
console.warn('未找到 van-notify 节点,请确认 selector 及 context 是否正确');
}
Notify.clear = function (options) {
options = Object.assign(
Object.assign({}, defaultOptions),
parseOptions(options)
);
const context = options.context || getContext();
const notify = context.selectComponent(options.selector);
if (notify) {
notify.hide();
}
};
================================================
FILE: miniprogram/vant/overlay/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/overlay/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
props: {
show: Boolean,
customStyle: String,
duration: {
type: null,
value: 300,
},
zIndex: {
type: Number,
value: 1,
},
},
methods: {
onClick() {
this.$emit('click');
},
// for prevent touchmove
noop() {},
},
});
================================================
FILE: miniprogram/vant/overlay/index.json
================================================
{
"component": true,
"usingComponents": {
"van-transition": "../transition/index"
}
}
================================================
FILE: miniprogram/vant/overlay/index.wxml
================================================
================================================
FILE: miniprogram/vant/overlay/index.wxss
================================================
@import '../common/index.wxss';.van-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.7);background-color:var(--overlay-background-color,rgba(0,0,0,.7))}
================================================
FILE: miniprogram/vant/panel/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/panel/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
classes: ['header-class', 'footer-class'],
props: {
desc: String,
title: String,
status: String,
useFooterSlot: Boolean,
},
});
================================================
FILE: miniprogram/vant/panel/index.json
================================================
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index"
}
}
================================================
FILE: miniprogram/vant/panel/index.wxml
================================================
================================================
FILE: miniprogram/vant/panel/index.wxss
================================================
@import '../common/index.wxss';.van-panel{background:#fff;background:var(--panel-background-color,#fff)}.van-panel__header-value{color:#ee0a24;color:var(--panel-header-value-color,#ee0a24)}.van-panel__footer{padding:8px 16px;padding:var(--panel-footer-padding,8px 16px)}
================================================
FILE: miniprogram/vant/picker/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/picker/index.js
================================================
import { VantComponent } from '../common/component';
import { pickerProps } from './shared';
VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign(Object.assign({}, pickerProps), {
valueKey: {
type: String,
value: 'text',
},
toolbarPosition: {
type: String,
value: 'top',
},
defaultIndex: {
type: Number,
value: 0,
},
columns: {
type: Array,
value: [],
observer(columns = []) {
this.simple = columns.length && !columns[0].values;
this.children = this.selectAllComponents('.van-picker__column');
if (Array.isArray(this.children) && this.children.length) {
this.setColumns().catch(() => {});
}
},
},
}),
beforeCreate() {
this.children = [];
},
methods: {
noop() {},
setColumns() {
const { data } = this;
const columns = this.simple ? [{ values: data.columns }] : data.columns;
const stack = columns.map((column, index) =>
this.setColumnValues(index, column.values)
);
return Promise.all(stack);
},
emit(event) {
const { type } = event.currentTarget.dataset;
if (this.simple) {
this.$emit(type, {
value: this.getColumnValue(0),
index: this.getColumnIndex(0),
});
} else {
this.$emit(type, {
value: this.getValues(),
index: this.getIndexes(),
});
}
},
onChange(event) {
if (this.simple) {
this.$emit('change', {
picker: this,
value: this.getColumnValue(0),
index: this.getColumnIndex(0),
});
} else {
this.$emit('change', {
picker: this,
value: this.getValues(),
index: event.currentTarget.dataset.index,
});
}
},
// get column instance by index
getColumn(index) {
return this.children[index];
},
// get column value by index
getColumnValue(index) {
const column = this.getColumn(index);
return column && column.getValue();
},
// set column value by index
setColumnValue(index, value) {
const column = this.getColumn(index);
if (column == null) {
return Promise.reject(new Error('setColumnValue: 对应列不存在'));
}
return column.setValue(value);
},
// get column option index by column index
getColumnIndex(columnIndex) {
return (this.getColumn(columnIndex) || {}).data.currentIndex;
},
// set column option index by column index
setColumnIndex(columnIndex, optionIndex) {
const column = this.getColumn(columnIndex);
if (column == null) {
return Promise.reject(new Error('setColumnIndex: 对应列不存在'));
}
return column.setIndex(optionIndex);
},
// get options of column by index
getColumnValues(index) {
return (this.children[index] || {}).data.options;
},
// set options of column by index
setColumnValues(index, options, needReset = true) {
const column = this.children[index];
if (column == null) {
return Promise.reject(new Error('setColumnValues: 对应列不存在'));
}
const isSame =
JSON.stringify(column.data.options) === JSON.stringify(options);
if (isSame) {
return Promise.resolve();
}
return column.set({ options }).then(() => {
if (needReset) {
column.setIndex(0);
}
});
},
// get values of all columns
getValues() {
return this.children.map((child) => child.getValue());
},
// set values of all columns
setValues(values) {
const stack = values.map((value, index) =>
this.setColumnValue(index, value)
);
return Promise.all(stack);
},
// get indexes of all columns
getIndexes() {
return this.children.map((child) => child.data.currentIndex);
},
// set indexes of all columns
setIndexes(indexes) {
const stack = indexes.map((optionIndex, columnIndex) =>
this.setColumnIndex(columnIndex, optionIndex)
);
return Promise.all(stack);
},
},
});
================================================
FILE: miniprogram/vant/picker/index.json
================================================
{
"component": true,
"usingComponents": {
"picker-column": "../picker-column/index",
"loading": "../loading/index"
}
}
================================================
FILE: miniprogram/vant/picker/index.wxml
================================================
function isSimple(columns) {
return columns.length && !columns[0].values;
}
module.exports = isSimple;
================================================
FILE: miniprogram/vant/picker/index.wxss
================================================
@import '../common/index.wxss';.van-picker{position:relative;overflow:hidden;-webkit-text-size-adjust:100%;-webkit-user-select:none;user-select:none;background-color:#fff;background-color:var(--picker-background-color,#fff)}.van-picker__toolbar{display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;height:44px;height:var(--picker-toolbar-height,44px);line-height:44px;line-height:var(--picker-toolbar-height,44px)}.van-picker__cancel,.van-picker__confirm{padding:0 16px;padding:var(--picker-action-padding,0 16px);font-size:14px;font-size:var(--picker-action-font-size,14px);color:#1989fa;color:var(--picker-action-text-color,#1989fa)}.van-picker__cancel--hover,.van-picker__confirm--hover{background-color:#f2f3f5;background-color:var(--picker-action-active-color,#f2f3f5)}.van-picker__title{max-width:50%;text-align:center;font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--picker-option-font-size,16px)}.van-picker__columns{position:relative;display:-webkit-flex;display:flex}.van-picker__column{-webkit-flex:1 1;flex:1 1;width:0}.van-picker__loading{position:absolute;top:0;right:0;bottom:0;left:0;z-index:4;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;background-color:hsla(0,0%,100%,.9);background-color:var(--picker-loading-mask-color,hsla(0,0%,100%,.9))}.van-picker__mask{position:absolute;top:0;left:0;z-index:2;width:100%;height:100%;background-image:linear-gradient(180deg,hsla(0,0%,100%,.9),hsla(0,0%,100%,.4)),linear-gradient(0deg,hsla(0,0%,100%,.9),hsla(0,0%,100%,.4));background-repeat:no-repeat;background-position:top,bottom;-webkit-backface-visibility:hidden;backface-visibility:hidden;pointer-events:none}.van-picker__frame,.van-picker__loading .van-loading{position:absolute;top:50%;left:0;z-index:1;width:100%;-webkit-transform:translateY(-50%);transform:translateY(-50%);pointer-events:none}
================================================
FILE: miniprogram/vant/picker/shared.d.ts
================================================
export declare const pickerProps: {
title: StringConstructor;
loading: BooleanConstructor;
showToolbar: BooleanConstructor;
cancelButtonText: {
type: StringConstructor;
value: string;
};
confirmButtonText: {
type: StringConstructor;
value: string;
};
visibleItemCount: {
type: NumberConstructor;
value: number;
};
itemHeight: {
type: NumberConstructor;
value: number;
};
};
================================================
FILE: miniprogram/vant/picker/shared.js
================================================
export const pickerProps = {
title: String,
loading: Boolean,
showToolbar: Boolean,
cancelButtonText: {
type: String,
value: '取消',
},
confirmButtonText: {
type: String,
value: '确认',
},
visibleItemCount: {
type: Number,
value: 5,
},
itemHeight: {
type: Number,
value: 44,
},
};
================================================
FILE: miniprogram/vant/picker/toolbar.wxml
================================================
{{ cancelButtonText }}
{{
title
}}
{{ confirmButtonText }}
================================================
FILE: miniprogram/vant/picker-column/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/picker-column/index.js
================================================
import { VantComponent } from '../common/component';
import { isObj, range } from '../common/utils';
const DEFAULT_DURATION = 200;
VantComponent({
classes: ['active-class'],
props: {
valueKey: String,
className: String,
itemHeight: Number,
visibleItemCount: Number,
initialOptions: {
type: Array,
value: [],
},
defaultIndex: {
type: Number,
value: 0,
observer(value) {
this.setIndex(value);
},
},
},
data: {
startY: 0,
offset: 0,
duration: 0,
startOffset: 0,
options: [],
currentIndex: 0,
},
created() {
const { defaultIndex, initialOptions } = this.data;
this.set({
currentIndex: defaultIndex,
options: initialOptions,
}).then(() => {
this.setIndex(defaultIndex);
});
},
methods: {
getCount() {
return this.data.options.length;
},
onTouchStart(event) {
this.setData({
startY: event.touches[0].clientY,
startOffset: this.data.offset,
duration: 0,
});
},
onTouchMove(event) {
const { data } = this;
const deltaY = event.touches[0].clientY - data.startY;
this.setData({
offset: range(
data.startOffset + deltaY,
-(this.getCount() * data.itemHeight),
data.itemHeight
),
});
},
onTouchEnd() {
const { data } = this;
if (data.offset !== data.startOffset) {
this.setData({ duration: DEFAULT_DURATION });
const index = range(
Math.round(-data.offset / data.itemHeight),
0,
this.getCount() - 1
);
this.setIndex(index, true);
}
},
onClickItem(event) {
const { index } = event.currentTarget.dataset;
this.setIndex(index, true);
},
adjustIndex(index) {
const { data } = this;
const count = this.getCount();
index = range(index, 0, count);
for (let i = index; i < count; i++) {
if (!this.isDisabled(data.options[i])) return i;
}
for (let i = index - 1; i >= 0; i--) {
if (!this.isDisabled(data.options[i])) return i;
}
},
isDisabled(option) {
return isObj(option) && option.disabled;
},
getOptionText(option) {
const { data } = this;
return isObj(option) && data.valueKey in option
? option[data.valueKey]
: option;
},
setIndex(index, userAction) {
const { data } = this;
index = this.adjustIndex(index) || 0;
const offset = -index * data.itemHeight;
if (index !== data.currentIndex) {
return this.set({ offset, currentIndex: index }).then(() => {
userAction && this.$emit('change', index);
});
}
return this.set({ offset });
},
setValue(value) {
const { options } = this.data;
for (let i = 0; i < options.length; i++) {
if (this.getOptionText(options[i]) === value) {
return this.setIndex(i);
}
}
return Promise.resolve();
},
getValue() {
const { data } = this;
return data.options[data.currentIndex];
},
},
});
================================================
FILE: miniprogram/vant/picker-column/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/picker-column/index.wxml
================================================
{{ getOptionText(option, valueKey) }}
================================================
FILE: miniprogram/vant/picker-column/index.wxs
================================================
function isObj(x) {
var type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
module.exports = function (option, valueKey) {
return isObj(option) && option[valueKey] != null ? option[valueKey] : option;
}
================================================
FILE: miniprogram/vant/picker-column/index.wxss
================================================
@import '../common/index.wxss';.van-picker-column{overflow:hidden;text-align:center;color:#000;color:var(--picker-option-text-color,#000);font-size:16px;font-size:var(--picker-option-font-size,16px)}.van-picker-column__item{padding:0 5px}.van-picker-column__item--selected{font-weight:500;font-weight:var(--font-weight-bold,500);color:#323233;color:var(--picker-option-selected-text-color,#323233)}.van-picker-column__item--disabled{opacity:.3;opacity:var(--picker-option-disabled-opacity,.3)}
================================================
FILE: miniprogram/vant/popup/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/popup/index.js
================================================
import { VantComponent } from '../common/component';
import { transition } from '../mixins/transition';
VantComponent({
classes: [
'enter-class',
'enter-active-class',
'enter-to-class',
'leave-class',
'leave-active-class',
'leave-to-class',
'close-icon-class',
],
mixins: [transition(false)],
props: {
round: Boolean,
closeable: Boolean,
customStyle: String,
overlayStyle: String,
transition: {
type: String,
observer: 'observeClass',
},
zIndex: {
type: Number,
value: 100,
},
overlay: {
type: Boolean,
value: true,
},
closeIcon: {
type: String,
value: 'cross',
},
closeIconPosition: {
type: String,
value: 'top-right',
},
closeOnClickOverlay: {
type: Boolean,
value: true,
},
position: {
type: String,
value: 'center',
observer: 'observeClass',
},
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
safeAreaInsetTop: {
type: Boolean,
value: false,
},
},
created() {
this.observeClass();
},
methods: {
onClickCloseIcon() {
this.$emit('close');
},
onClickOverlay() {
this.$emit('click-overlay');
if (this.data.closeOnClickOverlay) {
this.$emit('close');
}
},
observeClass() {
const { transition, position } = this.data;
const updateData = {
name: transition || position,
};
if (transition === 'none') {
updateData.duration = 0;
}
this.setData(updateData);
},
},
});
================================================
FILE: miniprogram/vant/popup/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-overlay": "../overlay/index"
}
}
================================================
FILE: miniprogram/vant/popup/index.wxml
================================================
================================================
FILE: miniprogram/vant/popup/index.wxss
================================================
@import '../common/index.wxss';.van-popup{position:fixed;box-sizing:border-box;max-height:100%;overflow-y:auto;transition-timing-function:ease;-webkit-animation:ease both;animation:ease both;-webkit-overflow-scrolling:touch;background-color:#fff;background-color:var(--popup-background-color,#fff)}.van-popup--center{top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.van-popup--center.van-popup--round{border-radius:20px;border-radius:var(--popup-round-border-radius,20px)}.van-popup--top{top:0;left:0;width:100%}.van-popup--top.van-popup--round{border-radius:0 0 20px 20px;border-radius:0 0 var(--popup-round-border-radius,20px) var(--popup-round-border-radius,20px)}.van-popup--right{top:50%;right:0;-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.van-popup--right.van-popup--round{border-radius:20px 0 0 20px;border-radius:var(--popup-round-border-radius,20px) 0 0 var(--popup-round-border-radius,20px)}.van-popup--bottom{bottom:0;left:0;width:100%}.van-popup--bottom.van-popup--round{border-radius:20px 20px 0 0;border-radius:var(--popup-round-border-radius,20px) var(--popup-round-border-radius,20px) 0 0}.van-popup--left{top:50%;left:0;-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.van-popup--left.van-popup--round{border-radius:0 20px 20px 0;border-radius:0 var(--popup-round-border-radius,20px) var(--popup-round-border-radius,20px) 0}.van-popup--bottom.van-popup--safe{padding-bottom:env(safe-area-inset-bottom)}.van-popup--safeTop{padding-top:env(safe-area-inset-top)}.van-popup__close-icon{position:absolute;z-index:1;z-index:var(--popup-close-icon-z-index,1);color:#969799;color:var(--popup-close-icon-color,#969799);font-size:18px;font-size:var(--popup-close-icon-size,18px)}.van-popup__close-icon--top-left{top:16px;top:var(--popup-close-icon-margin,16px);left:16px;left:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--top-right{top:16px;top:var(--popup-close-icon-margin,16px);right:16px;right:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--bottom-left{bottom:16px;bottom:var(--popup-close-icon-margin,16px);left:16px;left:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--bottom-right{right:16px;right:var(--popup-close-icon-margin,16px);bottom:16px;bottom:var(--popup-close-icon-margin,16px)}.van-popup__close-icon:active{opacity:.6}.van-scale-enter-active,.van-scale-leave-active{transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}.van-scale-enter,.van-scale-leave-to{-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7);opacity:0}.van-fade-enter-active,.van-fade-leave-active{transition-property:opacity}.van-fade-enter,.van-fade-leave-to{opacity:0}.van-center-enter-active,.van-center-leave-active{transition-property:opacity}.van-center-enter,.van-center-leave-to{opacity:0}.van-bottom-enter-active,.van-bottom-leave-active,.van-left-enter-active,.van-left-leave-active,.van-right-enter-active,.van-right-leave-active,.van-top-enter-active,.van-top-leave-active{transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform}.van-bottom-enter,.van-bottom-leave-to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.van-top-enter,.van-top-leave-to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.van-left-enter,.van-left-leave-to{-webkit-transform:translate3d(-100%,-50%,0);transform:translate3d(-100%,-50%,0)}.van-right-enter,.van-right-leave-to{-webkit-transform:translate3d(100%,-50%,0);transform:translate3d(100%,-50%,0)}
================================================
FILE: miniprogram/vant/progress/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/progress/index.js
================================================
import { VantComponent } from '../common/component';
import { BLUE } from '../common/color';
VantComponent({
props: {
inactive: Boolean,
percentage: Number,
pivotText: String,
pivotColor: String,
trackColor: String,
showPivot: {
type: Boolean,
value: true,
},
color: {
type: String,
value: BLUE,
},
textColor: {
type: String,
value: '#fff',
},
strokeWidth: {
type: null,
value: 4,
},
},
});
================================================
FILE: miniprogram/vant/progress/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/progress/index.wxml
================================================
{{ getters.text(pivotText, percentage) }}
================================================
FILE: miniprogram/vant/progress/index.wxs
================================================
module.exports = {
text: function(pivotText, percentage) {
return pivotText || percentage + '%';
}
};
================================================
FILE: miniprogram/vant/progress/index.wxss
================================================
@import '../common/index.wxss';.van-progress{position:relative;height:4px;height:var(--progress-height,4px);border-radius:4px;border-radius:var(--progress-height,4px);background:#ebedf0;background:var(--progress-background-color,#ebedf0)}.van-progress__portion{position:absolute;left:0;height:100%;border-radius:inherit;background:#1989fa;background:var(--progress-color,#1989fa)}.van-progress__pivot{position:absolute;top:50%;right:0;box-sizing:border-box;min-width:2em;text-align:center;word-break:keep-all;border-radius:1em;-webkit-transform:translateY(-50%);transform:translateY(-50%);color:#fff;color:var(--progress-pivot-text-color,#fff);padding:0 5px;padding:var(--progress-pivot-padding,0 5px);font-size:10px;font-size:var(--progress-pivot-font-size,10px);line-height:1.6;line-height:var(--progress-pivot-line-height,1.6);background-color:#1989fa;background-color:var(--progress-pivot-background-color,#1989fa)}
================================================
FILE: miniprogram/vant/radio/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/radio/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'radio-group',
type: 'ancestor',
current: 'radio',
},
classes: ['icon-class', 'label-class'],
props: {
name: null,
value: null,
disabled: Boolean,
useIconSlot: Boolean,
checkedColor: String,
labelPosition: {
type: String,
value: 'right',
},
labelDisabled: Boolean,
shape: {
type: String,
value: 'round',
},
iconSize: {
type: null,
value: 20,
},
},
methods: {
emitChange(value) {
const instance = this.parent || this;
instance.$emit('input', value);
instance.$emit('change', value);
},
onChange() {
if (!this.data.disabled) {
this.emitChange(this.data.name);
}
},
onClickLabel() {
const { disabled, labelDisabled, name } = this.data;
if (!disabled && !labelDisabled) {
this.emitChange(name);
}
},
},
});
================================================
FILE: miniprogram/vant/radio/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/radio/index.wxml
================================================
================================================
FILE: miniprogram/vant/radio/index.wxss
================================================
@import '../common/index.wxss';.van-radio{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;overflow:hidden;-webkit-user-select:none;user-select:none}.van-radio__icon-wrap{-webkit-flex:none;flex:none}.van-radio__icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:1em;height:1em;color:transparent;text-align:center;transition-property:color,border-color,background-color;border:1px solid #c8c9cc;border:1px solid var(--radio-border-color,#c8c9cc);font-size:20px;font-size:var(--radio-size,20px);transition-duration:.2s;transition-duration:var(--radio-transition-duration,.2s)}.van-radio__icon--round{border-radius:100%}.van-radio__icon--checked{color:#fff;color:var(--white,#fff);background-color:#1989fa;background-color:var(--radio-checked-icon-color,#1989fa);border-color:#1989fa;border-color:var(--radio-checked-icon-color,#1989fa)}.van-radio__icon--disabled{background-color:#ebedf0;background-color:var(--radio-disabled-background-color,#ebedf0);border-color:#c8c9cc;border-color:var(--radio-disabled-icon-color,#c8c9cc)}.van-radio__icon--disabled.van-radio__icon--checked{color:#c8c9cc;color:var(--radio-disabled-icon-color,#c8c9cc)}.van-radio__label{word-wrap:break-word;margin-left:10px;margin-left:var(--radio-label-margin,10px);color:#323233;color:var(--radio-label-color,#323233);line-height:20px;line-height:var(--radio-size,20px)}.van-radio__label--left{float:left;margin:0 10px 0 0;margin:0 var(--radio-label-margin,10px) 0 0}.van-radio__label--disabled{color:#c8c9cc;color:var(--radio-disabled-label-color,#c8c9cc)}.van-radio__label:empty{margin:0}
================================================
FILE: miniprogram/vant/radio-group/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/radio-group/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'radio',
type: 'descendant',
current: 'radio-group',
linked(target) {
this.updateChild(target);
},
},
props: {
value: {
type: null,
observer: 'updateChildren',
},
disabled: {
type: Boolean,
observer: 'updateChildren',
},
},
methods: {
updateChildren() {
(this.children || []).forEach((child) => this.updateChild(child));
},
updateChild(child) {
const { value, disabled } = this.data;
child.setData({
value,
disabled: disabled || child.data.disabled,
});
},
},
});
================================================
FILE: miniprogram/vant/radio-group/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/radio-group/index.wxml
================================================
================================================
FILE: miniprogram/vant/radio-group/index.wxss
================================================
@import '../common/index.wxss';
================================================
FILE: miniprogram/vant/rate/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/rate/index.js
================================================
import { VantComponent } from '../common/component';
import { canIUseModel } from '../common/version';
VantComponent({
field: true,
classes: ['icon-class'],
props: {
value: {
type: Number,
observer(value) {
if (value !== this.data.innerValue) {
this.setData({ innerValue: value });
}
},
},
readonly: Boolean,
disabled: Boolean,
allowHalf: Boolean,
size: null,
icon: {
type: String,
value: 'star',
},
voidIcon: {
type: String,
value: 'star-o',
},
color: {
type: String,
value: '#ffd21e',
},
voidColor: {
type: String,
value: '#c7c7c7',
},
disabledColor: {
type: String,
value: '#bdbdbd',
},
count: {
type: Number,
value: 5,
observer(value) {
this.setData({ innerCountArray: Array.from({ length: value }) });
},
},
gutter: null,
touchable: {
type: Boolean,
value: true,
},
},
data: {
innerValue: 0,
innerCountArray: Array.from({ length: 5 }),
},
methods: {
onSelect(event) {
const { data } = this;
const { score } = event.currentTarget.dataset;
if (!data.disabled && !data.readonly) {
this.setData({ innerValue: score + 1 });
if (canIUseModel()) {
this.setData({ value: score + 1 });
}
wx.nextTick(() => {
this.$emit('input', score + 1);
this.$emit('change', score + 1);
});
}
},
onTouchMove(event) {
const { touchable } = this.data;
if (!touchable) return;
const { clientX } = event.touches[0];
this.getRect('.van-rate__icon', true).then((list) => {
const target = list
.sort((item) => item.right - item.left)
.find((item) => clientX >= item.left && clientX <= item.right);
if (target != null) {
this.onSelect(
Object.assign(Object.assign({}, event), { currentTarget: target })
);
}
});
},
},
});
================================================
FILE: miniprogram/vant/rate/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/rate/index.wxml
================================================
================================================
FILE: miniprogram/vant/rate/index.wxss
================================================
@import '../common/index.wxss';.van-rate{display:-webkit-inline-flex;display:inline-flex;-webkit-user-select:none;user-select:none}.van-rate__item{position:relative;padding:0 2px;padding:0 var(--rate-horizontal-padding,2px)}.van-rate__icon{display:block;height:1em;font-size:20px;font-size:var(--rate-icon-size,20px)}.van-rate__icon--half{position:absolute;top:0;width:.5em;overflow:hidden;left:2px;left:var(--rate-horizontal-padding,2px)}
================================================
FILE: miniprogram/vant/row/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/row/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'col',
type: 'descendant',
current: 'row',
linked(target) {
if (this.data.gutter) {
target.setGutter(this.data.gutter);
}
},
},
props: {
gutter: {
type: Number,
observer: 'setGutter',
},
},
data: {
viewStyle: '',
},
mounted() {
if (this.data.gutter) {
this.setGutter();
}
},
methods: {
setGutter() {
const { gutter } = this.data;
const margin = `-${Number(gutter) / 2}px`;
const viewStyle = gutter
? `margin-right: ${margin}; margin-left: ${margin};`
: '';
this.setData({ viewStyle });
this.getRelationNodes('../col/index').forEach((col) => {
col.setGutter(this.data.gutter);
});
},
},
});
================================================
FILE: miniprogram/vant/row/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/row/index.wxml
================================================
================================================
FILE: miniprogram/vant/row/index.wxss
================================================
@import '../common/index.wxss';.van-row:after{display:table;clear:both;content:""}
================================================
FILE: miniprogram/vant/search/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/search/index.js
================================================
import { VantComponent } from '../common/component';
import { canIUseModel } from '../common/version';
VantComponent({
field: true,
classes: ['field-class', 'input-class', 'cancel-class'],
props: {
label: String,
focus: Boolean,
error: Boolean,
disabled: Boolean,
readonly: Boolean,
inputAlign: String,
showAction: Boolean,
useActionSlot: Boolean,
useLeftIconSlot: Boolean,
useRightIconSlot: Boolean,
leftIcon: {
type: String,
value: 'search',
},
rightIcon: String,
placeholder: String,
placeholderStyle: String,
actionText: {
type: String,
value: '取消',
},
background: {
type: String,
value: '#ffffff',
},
maxlength: {
type: Number,
value: -1,
},
shape: {
type: String,
value: 'square',
},
clearable: {
type: Boolean,
value: true,
},
},
methods: {
onChange(event) {
if (canIUseModel()) {
this.setData({ value: event.detail });
}
this.$emit('change', event.detail);
},
onCancel() {
/**
* 修复修改输入框值时,输入框失焦和赋值同时触发,赋值失效
* https://github.com/youzan/@vant/weapp/issues/1768
*/
setTimeout(() => {
if (canIUseModel()) {
this.setData({ value: '' });
}
this.$emit('cancel');
this.$emit('change', '');
}, 200);
},
onSearch(event) {
this.$emit('search', event.detail);
},
onFocus(event) {
this.$emit('focus', event.detail);
},
onBlur(event) {
this.$emit('blur', event.detail);
},
onClear(event) {
this.$emit('clear', event.detail);
},
},
});
================================================
FILE: miniprogram/vant/search/index.json
================================================
{
"component": true,
"usingComponents": {
"van-field": "../field/index"
}
}
================================================
FILE: miniprogram/vant/search/index.wxml
================================================
{{ label }}
{{ actionText }}
================================================
FILE: miniprogram/vant/search/index.wxss
================================================
@import '../common/index.wxss';.van-search{-webkit-align-items:center;align-items:center;box-sizing:border-box;padding:10px 12px;padding:var(--search-padding,10px 12px)}.van-search,.van-search__content{display:-webkit-flex;display:flex}.van-search__content{-webkit-flex:1;flex:1;padding-left:8px;padding-left:var(--padding-xs,8px);border-radius:2px;border-radius:var(--border-radius-sm,2px);background-color:#f7f8fa;background-color:var(--search-background-color,#f7f8fa)}.van-search__content--round{border-radius:17px;border-radius:calc(var(--search-input-height, 34px)/2)}.van-search__label{padding:0 5px;padding:var(--search-label-padding,0 5px);font-size:14px;font-size:var(--search-label-font-size,14px);line-height:34px;line-height:var(--search-input-height,34px);color:#323233;color:var(--search-label-color,#323233)}.van-search__field{-webkit-flex:1;flex:1}.van-search__field__left-icon{color:#969799;color:var(--search-left-icon-color,#969799)}.van-search--withaction{padding-right:0}.van-search__action{padding:0 8px;padding:var(--search-action-padding,0 8px);font-size:14px;font-size:var(--search-action-font-size,14px);line-height:34px;line-height:var(--search-input-height,34px);color:#323233;color:var(--search-action-text-color,#323233)}.van-search__action--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}
================================================
FILE: miniprogram/vant/sidebar/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/sidebar/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'sidebar-item',
type: 'descendant',
current: 'sidebar',
linked() {
this.setActive(this.data.activeKey);
},
unlinked() {
this.setActive(this.data.activeKey);
},
},
props: {
activeKey: {
type: Number,
value: 0,
observer: 'setActive',
},
},
beforeCreate() {
this.currentActive = -1;
},
methods: {
setActive(activeKey) {
const { children, currentActive } = this;
if (!children.length) {
return Promise.resolve();
}
this.currentActive = activeKey;
const stack = [];
if (currentActive !== activeKey && children[currentActive]) {
stack.push(children[currentActive].setActive(false));
}
if (children[activeKey]) {
stack.push(children[activeKey].setActive(true));
}
return Promise.all(stack);
},
},
});
================================================
FILE: miniprogram/vant/sidebar/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/sidebar/index.wxml
================================================
================================================
FILE: miniprogram/vant/sidebar/index.wxss
================================================
@import '../common/index.wxss';.van-sidebar{width:85px;width:var(--sidebar-width,85px)}
================================================
FILE: miniprogram/vant/sidebar-item/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/sidebar-item/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
classes: ['active-class', 'disabled-class'],
relation: {
type: 'ancestor',
name: 'sidebar',
current: 'sidebar-item',
},
props: {
dot: Boolean,
info: null,
title: String,
disabled: Boolean,
},
methods: {
onClick() {
const { parent } = this;
if (!parent || this.data.disabled) {
return;
}
const index = parent.children.indexOf(this);
parent.setActive(index).then(() => {
this.$emit('click', index);
parent.$emit('change', index);
});
},
setActive(selected) {
return this.setData({ selected });
},
},
});
================================================
FILE: miniprogram/vant/sidebar-item/index.json
================================================
{
"component": true,
"usingComponents": {
"van-info": "../info/index"
}
}
================================================
FILE: miniprogram/vant/sidebar-item/index.wxml
================================================
================================================
FILE: miniprogram/vant/sidebar-item/index.wxss
================================================
@import '../common/index.wxss';.van-sidebar-item{display:block;box-sizing:border-box;overflow:hidden;word-wrap:break-word;border-left:3px solid transparent;-webkit-user-select:none;user-select:none;padding:20px 12px 20px 8px;padding:var(--sidebar-padding,20px 12px 20px 8px);font-size:14px;font-size:var(--sidebar-font-size,14px);line-height:20px;line-height:var(--sidebar-line-height,20px);color:#323233;color:var(--sidebar-text-color,#323233);background-color:#f7f8fa;background-color:var(--sidebar-background-color,#f7f8fa)}.van-sidebar-item__text{position:relative;display:inline-block}.van-sidebar-item--hover:not(.van-sidebar-item--disabled){background-color:#f2f3f5;background-color:var(--sidebar-active-color,#f2f3f5)}.van-sidebar-item:after{border-bottom-width:1px}.van-sidebar-item--selected{color:#323233;color:var(--sidebar-selected-text-color,#323233);font-weight:500;font-weight:var(--sidebar-selected-font-weight,500);border-color:#ee0a24;border-color:var(--sidebar-selected-border-color,#ee0a24)}.van-sidebar-item--selected:after{border-right-width:1px}.van-sidebar-item--selected,.van-sidebar-item--selected.van-sidebar-item--hover{background-color:#fff;background-color:var(--sidebar-selected-background-color,#fff)}.van-sidebar-item--disabled{color:#c8c9cc;color:var(--sidebar-disabled-text-color,#c8c9cc)}
================================================
FILE: miniprogram/vant/skeleton/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/skeleton/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
classes: ['avatar-class', 'title-class', 'row-class'],
props: {
row: {
type: Number,
value: 0,
observer(value) {
this.setData({ rowArray: Array.from({ length: value }) });
},
},
title: Boolean,
avatar: Boolean,
loading: {
type: Boolean,
value: true,
},
animate: {
type: Boolean,
value: true,
},
avatarSize: {
type: String,
value: '32px',
},
avatarShape: {
type: String,
value: 'round',
},
titleWidth: {
type: String,
value: '40%',
},
rowWidth: {
type: null,
value: '100%',
observer(val) {
this.setData({ isArray: val instanceof Array });
},
},
},
data: {
isArray: false,
rowArray: [],
},
});
================================================
FILE: miniprogram/vant/skeleton/index.json
================================================
{
"component": true,
"usingComponents": {}
}
================================================
FILE: miniprogram/vant/skeleton/index.wxml
================================================
================================================
FILE: miniprogram/vant/skeleton/index.wxss
================================================
@import '../common/index.wxss';.van-skeleton{display:-webkit-flex;display:flex;box-sizing:border-box;width:100%;padding:0 16px;padding:var(--skeleton-padding,0 16px)}.van-skeleton__avatar{-webkit-flex-shrink:0;flex-shrink:0;margin-right:16px;margin-right:var(--padding-md,16px);background-color:#f2f3f5;background-color:var(--skeleton-avatar-background-color,#f2f3f5)}.van-skeleton__avatar--round{border-radius:100%}.van-skeleton__content{-webkit-flex:1;flex:1}.van-skeleton__avatar+.van-skeleton__content{padding-top:8px;padding-top:var(--padding-xs,8px)}.van-skeleton__row,.van-skeleton__title{height:16px;height:var(--skeleton-row-height,16px);background-color:#f2f3f5;background-color:var(--skeleton-row-background-color,#f2f3f5)}.van-skeleton__title{margin:0}.van-skeleton__row:not(:first-child){margin-top:12px;margin-top:var(--skeleton-row-margin-top,12px)}.van-skeleton__title+.van-skeleton__row{margin-top:20px}.van-skeleton--animate{-webkit-animation:van-skeleton-blink 1.2s ease-in-out infinite;animation:van-skeleton-blink 1.2s ease-in-out infinite}@-webkit-keyframes van-skeleton-blink{50%{opacity:.6}}@keyframes van-skeleton-blink{50%{opacity:.6}}
================================================
FILE: miniprogram/vant/slider/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/slider/index.js
================================================
import { VantComponent } from '../common/component';
import { touch } from '../mixins/touch';
import { canIUseModel } from '../common/version';
VantComponent({
mixins: [touch],
props: {
disabled: Boolean,
useButtonSlot: Boolean,
activeColor: String,
inactiveColor: String,
max: {
type: Number,
value: 100,
},
min: {
type: Number,
value: 0,
},
step: {
type: Number,
value: 1,
},
value: {
type: Number,
value: 0,
observer: 'updateValue',
},
barHeight: {
type: null,
value: '2px',
},
},
created() {
this.updateValue(this.data.value);
},
methods: {
onTouchStart(event) {
if (this.data.disabled) return;
this.touchStart(event);
this.startValue = this.format(this.data.value);
this.dragStatus = 'start';
},
onTouchMove(event) {
if (this.data.disabled) return;
if (this.dragStatus === 'start') {
this.$emit('drag-start');
}
this.touchMove(event);
this.dragStatus = 'draging';
this.getRect('.van-slider').then((rect) => {
const diff = (this.deltaX / rect.width) * 100;
this.newValue = this.startValue + diff;
this.updateValue(this.newValue, false, true);
});
},
onTouchEnd() {
if (this.data.disabled) return;
if (this.dragStatus === 'draging') {
this.updateValue(this.newValue, true);
this.$emit('drag-end');
}
},
onClick(event) {
if (this.data.disabled) return;
const { min } = this.data;
this.getRect('.van-slider').then((rect) => {
const value =
((event.detail.x - rect.left) / rect.width) * this.getRange() + min;
this.updateValue(value, true);
});
},
updateValue(value, end, drag) {
value = this.format(value);
const { min } = this.data;
const width = `${((value - min) * 100) / this.getRange()}%`;
this.setData({
value,
barStyle: `
width: ${width};
${drag ? 'transition: none;' : ''}
`,
});
if (drag) {
this.$emit('drag', { value });
}
if (end) {
this.$emit('change', value);
}
if ((drag || end) && canIUseModel()) {
this.setData({ value });
}
},
getRange() {
const { max, min } = this.data;
return max - min;
},
format(value) {
const { max, min, step } = this.data;
return Math.round(Math.max(min, Math.min(value, max)) / step) * step;
},
},
});
================================================
FILE: miniprogram/vant/slider/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/slider/index.wxml
================================================
================================================
FILE: miniprogram/vant/slider/index.wxs
================================================
/* eslint-disable */
var utils = require('../wxs/utils.wxs');
function barStyle(barHeight, activeColor) {
var styles = [['height', utils.addUnit(barHeight)]];
if (activeColor) {
styles.push(['background', activeColor]);
}
return styles
.map(function (item) {
return item.join(':');
})
.join(';');
}
module.exports = {
barStyle: barStyle,
};
================================================
FILE: miniprogram/vant/slider/index.wxss
================================================
@import '../common/index.wxss';.van-slider{position:relative;border-radius:999px;border-radius:var(--border-radius-max,999px);background-color:#ebedf0;background-color:var(--slider-inactive-background-color,#ebedf0)}.van-slider:before{position:absolute;right:0;left:0;content:"";top:-8px;top:-var(--padding-xs,8px);bottom:-8px;bottom:-var(--padding-xs,8px)}.van-slider__bar{position:relative;border-radius:inherit;transition:width .2s;transition:width var(--animation-duration-fast,.2s);background-color:#1989fa;background-color:var(--slider-active-background-color,#1989fa)}.van-slider__button{width:24px;height:24px;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.5);background-color:#fff;background-color:var(--slider-button-background-color,#fff)}.van-slider__button-wrapper{position:absolute;top:50%;right:0;-webkit-transform:translate3d(50%,-50%,0);transform:translate3d(50%,-50%,0)}.van-slider--disabled{opacity:.5}
================================================
FILE: miniprogram/vant/stepper/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/stepper/index.js
================================================
import { VantComponent } from '../common/component';
import { isDef } from '../common/utils';
const LONG_PRESS_START_TIME = 600;
const LONG_PRESS_INTERVAL = 200;
// add num and avoid float number
function add(num1, num2) {
const cardinal = Math.pow(10, 10);
return Math.round((num1 + num2) * cardinal) / cardinal;
}
function equal(value1, value2) {
return String(value1) === String(value2);
}
VantComponent({
field: true,
classes: ['input-class', 'plus-class', 'minus-class'],
props: {
value: {
type: null,
observer(value) {
if (!equal(value, this.data.currentValue)) {
this.setData({ currentValue: this.format(value) });
}
},
},
integer: {
type: Boolean,
observer: 'check',
},
disabled: Boolean,
inputWidth: null,
buttonSize: null,
asyncChange: Boolean,
disableInput: Boolean,
decimalLength: {
type: Number,
value: null,
observer: 'check',
},
min: {
type: null,
value: 1,
observer: 'check',
},
max: {
type: null,
value: Number.MAX_SAFE_INTEGER,
observer: 'check',
},
step: {
type: null,
value: 1,
},
showPlus: {
type: Boolean,
value: true,
},
showMinus: {
type: Boolean,
value: true,
},
disablePlus: Boolean,
disableMinus: Boolean,
longPress: {
type: Boolean,
value: true,
},
},
data: {
currentValue: '',
},
created() {
this.setData({
currentValue: this.format(this.data.value),
});
},
methods: {
check() {
const val = this.format(this.data.currentValue);
if (!equal(val, this.data.currentValue)) {
this.setData({ currentValue: val });
}
},
isDisabled(type) {
if (type === 'plus') {
return (
this.data.disabled ||
this.data.disablePlus ||
this.data.currentValue >= this.data.max
);
}
return (
this.data.disabled ||
this.data.disableMinus ||
this.data.currentValue <= this.data.min
);
},
onFocus(event) {
this.$emit('focus', event.detail);
},
onBlur(event) {
const value = this.format(event.detail.value);
this.emitChange(value);
this.$emit(
'blur',
Object.assign(Object.assign({}, event.detail), { value })
);
},
// filter illegal characters
filter(value) {
value = String(value).replace(/[^0-9.-]/g, '');
if (this.data.integer && value.indexOf('.') !== -1) {
value = value.split('.')[0];
}
return value;
},
// limit value range
format(value) {
value = this.filter(value);
// format range
value = value === '' ? 0 : +value;
value = Math.max(Math.min(this.data.max, value), this.data.min);
// format decimal
if (isDef(this.data.decimalLength)) {
value = value.toFixed(this.data.decimalLength);
}
return value;
},
onInput(event) {
const { value = '' } = event.detail || {};
// allow input to be empty
if (value === '') {
return;
}
let formatted = this.filter(value);
// limit max decimal length
if (isDef(this.data.decimalLength) && formatted.indexOf('.') !== -1) {
const pair = formatted.split('.');
formatted = `${pair[0]}.${pair[1].slice(0, this.data.decimalLength)}`;
}
this.emitChange(formatted);
},
emitChange(value) {
if (!this.data.asyncChange) {
this.setData({ currentValue: value });
}
this.$emit('change', value);
},
onChange() {
const { type } = this;
if (this.isDisabled(type)) {
this.$emit('overlimit', type);
return;
}
const diff = type === 'minus' ? -this.data.step : +this.data.step;
const value = this.format(add(+this.data.currentValue, diff));
this.emitChange(value);
this.$emit(type);
},
longPressStep() {
this.longPressTimer = setTimeout(() => {
this.onChange();
this.longPressStep();
}, LONG_PRESS_INTERVAL);
},
onTap(event) {
const { type } = event.currentTarget.dataset;
this.type = type;
this.onChange();
},
onTouchStart(event) {
if (!this.data.longPress) {
return;
}
clearTimeout(this.longPressTimer);
const { type } = event.currentTarget.dataset;
this.type = type;
this.isLongPress = false;
this.longPressTimer = setTimeout(() => {
this.isLongPress = true;
this.onChange();
this.longPressStep();
}, LONG_PRESS_START_TIME);
},
onTouchEnd() {
if (!this.data.longPress) {
return;
}
clearTimeout(this.longPressTimer);
},
},
});
================================================
FILE: miniprogram/vant/stepper/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/stepper/index.wxml
================================================
================================================
FILE: miniprogram/vant/stepper/index.wxss
================================================
@import '../common/index.wxss';.van-stepper{font-size:0}.van-stepper__minus,.van-stepper__plus{position:relative;display:inline-block;box-sizing:border-box;margin:1px;vertical-align:middle;border:0;background-color:#f2f3f5;background-color:var(--stepper-background-color,#f2f3f5);color:#323233;color:var(--stepper-button-icon-color,#323233);width:28px;width:var(--stepper-input-height,28px);height:28px;height:var(--stepper-input-height,28px);padding:4px;padding:var(--padding-base,4px)}.van-stepper__minus:before,.van-stepper__plus:before{width:9px;height:1px}.van-stepper__minus:after,.van-stepper__plus:after{width:1px;height:9px}.van-stepper__minus:after,.van-stepper__minus:before,.van-stepper__plus:after,.van-stepper__plus:before{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;background-color:currentColor;content:""}.van-stepper__minus--hover,.van-stepper__plus--hover{background-color:#e8e8e8;background-color:var(--stepper-active-color,#e8e8e8)}.van-stepper__minus--disabled,.van-stepper__plus--disabled{color:#c8c9cc;color:var(--stepper-button-disabled-icon-color,#c8c9cc)}.van-stepper__minus--disabled,.van-stepper__minus--disabled.van-stepper__minus--hover,.van-stepper__minus--disabled.van-stepper__plus--hover,.van-stepper__plus--disabled,.van-stepper__plus--disabled.van-stepper__minus--hover,.van-stepper__plus--disabled.van-stepper__plus--hover{background-color:#f7f8fa;background-color:var(--stepper-button-disabled-color,#f7f8fa)}.van-stepper__minus{border-radius:4px 0 0 4px;border-radius:var(--stepper-border-radius,4px) 0 0 var(--stepper-border-radius,4px)}.van-stepper__minus:after{display:none}.van-stepper__plus{border-radius:0 4px 4px 0;border-radius:0 var(--stepper-border-radius,4px) var(--stepper-border-radius,4px) 0}.van-stepper__input{display:inline-block;box-sizing:border-box;min-height:0;margin:1px;padding:1px;text-align:center;vertical-align:middle;border:0;border-width:1px 0;border-radius:0;-webkit-appearance:none;font-size:14px;font-size:var(--stepper-input-font-size,14px);color:#323233;color:var(--stepper-input-text-color,#323233);background-color:#f2f3f5;background-color:var(--stepper-background-color,#f2f3f5);width:32px;width:var(--stepper-input-width,32px);height:28px;height:var(--stepper-input-height,28px)}.van-stepper__input--disabled{color:#c8c9cc;color:var(--stepper-input-disabled-text-color,#c8c9cc);background-color:#f2f3f5;background-color:var(--stepper-input-disabled-background-color,#f2f3f5)}
================================================
FILE: miniprogram/vant/steps/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/steps/index.js
================================================
import { VantComponent } from '../common/component';
import { GREEN, GRAY_DARK } from '../common/color';
VantComponent({
classes: ['desc-class'],
props: {
icon: String,
steps: Array,
active: Number,
direction: {
type: String,
value: 'horizontal',
},
activeColor: {
type: String,
value: GREEN,
},
inactiveColor: {
type: String,
value: GRAY_DARK,
},
activeIcon: {
type: String,
value: 'checked',
},
inactiveIcon: String,
},
methods: {
onClick(event) {
const { index } = event.currentTarget.dataset;
this.$emit('click-step', index);
},
},
});
================================================
FILE: miniprogram/vant/steps/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/steps/index.wxml
================================================
{{ item.text }}
{{ item.desc }}
function get(index, active) {
if (index < active) {
return 'finish';
} else if (index === active) {
return 'process';
}
return 'inactive';
}
module.exports = get;
================================================
FILE: miniprogram/vant/steps/index.wxss
================================================
@import '../common/index.wxss';.van-steps{overflow:hidden;background-color:#fff;background-color:var(--steps-background-color,#fff)}.van-steps--horizontal{padding:10px}.van-steps--horizontal .van-step__wrapper{position:relative;display:-webkit-flex;display:flex;overflow:hidden}.van-steps--vertical{padding-left:10px}.van-steps--vertical .van-step__wrapper{padding:0 0 0 20px}.van-step{position:relative;-webkit-flex:1;flex:1;font-size:14px;font-size:var(--step-font-size,14px);color:#969799;color:var(--step-text-color,#969799)}.van-step--finish{color:#323233;color:var(--step-finish-text-color,#323233)}.van-step__circle{border-radius:50%;width:5px;width:var(--step-circle-size,5px);height:5px;height:var(--step-circle-size,5px);background-color:#969799;background-color:var(--step-circle-color,#969799)}.van-step--horizontal{padding-bottom:14px}.van-step--horizontal:first-child .van-step__title{-webkit-transform:none;transform:none}.van-step--horizontal:first-child .van-step__circle-container{padding:0 8px 0 0;-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0)}.van-step--horizontal:last-child{position:absolute;right:0;width:auto}.van-step--horizontal:last-child .van-step__title{text-align:right;-webkit-transform:none;transform:none}.van-step--horizontal:last-child .van-step__circle-container{right:0;padding:0 0 0 8px;-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0)}.van-step--horizontal .van-step__circle-container{position:absolute;bottom:6px;z-index:1;-webkit-transform:translate3d(-50%,50%,0);transform:translate3d(-50%,50%,0);background-color:#fff;background-color:var(--white,#fff);padding:0 8px;padding:0 var(--padding-xs,8px)}.van-step--horizontal .van-step__title{display:inline-block;-webkit-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0);font-size:12px;font-size:var(--step-horizontal-title-font-size,12px)}.van-step--horizontal .van-step__line{position:absolute;right:0;bottom:6px;left:0;height:1px;-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0);background-color:#ebedf0;background-color:var(--step-line-color,#ebedf0)}.van-step--horizontal.van-step--process{color:#323233;color:var(--step-process-text-color,#323233)}.van-step--horizontal.van-step--process .van-step__icon{display:block;line-height:1;font-size:12px;font-size:var(--step-icon-size,12px)}.van-step--vertical{padding:10px 10px 10px 0;line-height:18px}.van-step--vertical:after{border-bottom-width:1px}.van-step--vertical:last-child:after{border-bottom-width:none}.van-step--vertical:first-child:before{position:absolute;top:0;left:-15px;z-index:1;width:1px;height:20px;content:"";background-color:#fff;background-color:var(--white,#fff)}.van-step--vertical .van-step__circle,.van-step--vertical .van-step__icon,.van-step--vertical .van-step__line{position:absolute;top:19px;left:-14px;z-index:2;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.van-step--vertical .van-step__icon{line-height:1;font-size:12px;font-size:var(--step-icon-size,12px)}.van-step--vertical .van-step__line{z-index:1;width:1px;height:100%;-webkit-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0);background-color:#ebedf0;background-color:var(--step-line-color,#ebedf0)}
================================================
FILE: miniprogram/vant/sticky/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/sticky/index.js
================================================
import { VantComponent } from '../common/component';
import { pageScrollMixin } from '../mixins/page-scroll';
const ROOT_ELEMENT = '.van-sticky';
VantComponent({
props: {
zIndex: {
type: Number,
value: 99,
},
offsetTop: {
type: Number,
value: 0,
observer: 'onScroll',
},
disabled: {
type: Boolean,
observer: 'onScroll',
},
container: {
type: null,
observer: 'onScroll',
},
scrollTop: {
type: null,
observer(val) {
this.onScroll({ scrollTop: val });
},
},
},
mixins: [
pageScrollMixin(function (event) {
if (this.data.scrollTop != null) {
return;
}
this.onScroll(event);
}),
],
data: {
height: 0,
fixed: false,
transform: 0,
},
mounted() {
this.onScroll();
},
methods: {
onScroll({ scrollTop } = {}) {
const { container, offsetTop, disabled } = this.data;
if (disabled) {
this.setDataAfterDiff({
fixed: false,
transform: 0,
});
return;
}
this.scrollTop = scrollTop || this.scrollTop;
if (typeof container === 'function') {
Promise.all([this.getRect(ROOT_ELEMENT), this.getContainerRect()]).then(
([root, container]) => {
if (offsetTop + root.height > container.height + container.top) {
this.setDataAfterDiff({
fixed: false,
transform: container.height - root.height,
});
} else if (offsetTop >= root.top) {
this.setDataAfterDiff({
fixed: true,
height: root.height,
transform: 0,
});
} else {
this.setDataAfterDiff({ fixed: false, transform: 0 });
}
}
);
return;
}
this.getRect(ROOT_ELEMENT).then((root) => {
if (offsetTop >= root.top) {
this.setDataAfterDiff({ fixed: true, height: root.height });
this.transform = 0;
} else {
this.setDataAfterDiff({ fixed: false });
}
});
},
setDataAfterDiff(data) {
wx.nextTick(() => {
const diff = Object.keys(data).reduce((prev, key) => {
if (data[key] !== this.data[key]) {
prev[key] = data[key];
}
return prev;
}, {});
this.setData(diff);
this.$emit('scroll', {
scrollTop: this.scrollTop,
isFixed: data.fixed || this.data.fixed,
});
});
},
getContainerRect() {
const nodesRef = this.data.container();
return new Promise((resolve) =>
nodesRef.boundingClientRect(resolve).exec()
);
},
},
});
================================================
FILE: miniprogram/vant/sticky/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/sticky/index.wxml
================================================
================================================
FILE: miniprogram/vant/sticky/index.wxs
================================================
/* eslint-disable */
function wrapStyle(data) {
var style = '';
if (data.transform) {
style += 'transform: translate3d(0, ' + data.transform + 'px, 0);';
}
if (data.fixed) {
style += 'top: ' + data.offsetTop + 'px;';
}
if (data.zIndex) {
style += 'z-index: ' + data.zIndex + ';';
}
return style;
}
function containerStyle(data) {
var style = '';
if (data.fixed) {
style += 'height: ' + data.height + 'px;';
}
if (data.zIndex) {
style += 'z-index: ' + data.zIndex + ';';
}
return style;
}
module.exports = {
wrapStyle: wrapStyle,
containerStyle: containerStyle
};
================================================
FILE: miniprogram/vant/sticky/index.wxss
================================================
@import '../common/index.wxss';.van-sticky{position:relative}.van-sticky-wrap--fixed{position:fixed;right:0;left:0}
================================================
FILE: miniprogram/vant/submit-bar/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/submit-bar/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
classes: ['bar-class', 'price-class', 'button-class'],
props: {
tip: {
type: null,
observer: 'updateTip',
},
tipIcon: String,
type: Number,
price: {
type: null,
observer: 'updatePrice',
},
label: String,
loading: Boolean,
disabled: Boolean,
buttonText: String,
currency: {
type: String,
value: '¥',
},
buttonType: {
type: String,
value: 'danger',
},
decimalLength: {
type: Number,
value: 2,
observer: 'updatePrice',
},
suffixLabel: String,
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
},
methods: {
updatePrice() {
const { price, decimalLength } = this.data;
const priceStrArr =
typeof price === 'number' &&
(price / 100).toFixed(decimalLength).split('.');
this.setData({
hasPrice: typeof price === 'number',
integerStr: priceStrArr && priceStrArr[0],
decimalStr: decimalLength && priceStrArr ? `.${priceStrArr[1]}` : '',
});
},
updateTip() {
this.setData({ hasTip: typeof this.data.tip === 'string' });
},
onSubmit(event) {
this.$emit('submit', event.detail);
},
},
});
================================================
FILE: miniprogram/vant/submit-bar/index.json
================================================
{
"component": true,
"usingComponents": {
"van-button": "../button/index",
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/submit-bar/index.wxml
================================================
{{ tip }}
{{ label || '合计:' }}
{{ currency }}
{{ integerStr }} {{decimalStr}}
{{ suffixLabel }}
{{ loading ? '' : buttonText }}
================================================
FILE: miniprogram/vant/submit-bar/index.wxss
================================================
@import '../common/index.wxss';.van-submit-bar{position:fixed;bottom:0;left:0;width:100%;-webkit-user-select:none;user-select:none;z-index:100;z-index:var(--submit-bar-z-index,100);background-color:#fff;background-color:var(--submit-bar-background-color,#fff)}.van-submit-bar__tip{padding:10px;padding:var(--submit-bar-tip-padding,10px);color:#f56723;color:var(--submit-bar-tip-color,#f56723);font-size:12px;font-size:var(--submit-bar-tip-font-size,12px);line-height:1.5;line-height:var(--submit-bar-tip-line-height,1.5);background-color:#fff7cc;background-color:var(--submit-bar-tip-background-color,#fff7cc)}.van-submit-bar__tip:empty{display:none}.van-submit-bar__tip-icon{width:12px;height:12px;margin-right:4px;vertical-align:middle;font-size:12px;font-size:var(--submit-bar-tip-icon-size,12px);min-width:18px;min-width:calc(var(--submit-bar-tip-icon-size, 12px)*1.5)}.van-submit-bar__tip-text{display:inline;vertical-align:middle}.van-submit-bar__bar{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:flex-end;justify-content:flex-end;padding:0 16px;padding:var(--submit-bar-padding,0 16px);height:50px;height:var(--submit-bar-height,50px);font-size:14px;font-size:var(--submit-bar-text-font-size,14px);background-color:#fff;background-color:var(--submit-bar-background-color,#fff)}.van-submit-bar__safe{height:constant(safe-area-inset-bottom);height:env(safe-area-inset-bottom)}.van-submit-bar__text{-webkit-flex:1;flex:1;text-align:right;color:#323233;color:var(--submit-bar-text-color,#323233);padding-right:12px;padding-right:var(--padding-sm,12px)}.van-submit-bar__price,.van-submit-bar__text{font-weight:500;font-weight:var(--font-weight-bold,500)}.van-submit-bar__price{color:#ee0a24;color:var(--submit-bar-price-color,#ee0a24);font-size:12px;font-size:var(--submit-bar-price-font-size,12px)}.van-submit-bar__price-integer{font-size:20px;font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif}.van-submit-bar__currency{font-size:12px;font-size:var(--submit-bar-currency-font-size,12px)}.van-submit-bar__suffix-label{margin-left:5px}.van-submit-bar__button{width:110px;width:var(--submit-bar-button-width,110px);font-weight:500;font-weight:var(--font-weight-bold,500);--button-default-height:40px!important;--button-default-height:var(--submit-bar-button-height,40px)!important;--button-line-height:40px!important;--button-line-height:var(--submit-bar-button-height,40px)!important}
================================================
FILE: miniprogram/vant/swipe-cell/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/swipe-cell/index.js
================================================
import { VantComponent } from '../common/component';
import { touch } from '../mixins/touch';
import { range } from '../common/utils';
const THRESHOLD = 0.3;
let ARRAY = [];
VantComponent({
props: {
disabled: Boolean,
leftWidth: {
type: Number,
value: 0,
observer(leftWidth = 0) {
if (this.offset > 0) {
this.swipeMove(leftWidth);
}
},
},
rightWidth: {
type: Number,
value: 0,
observer(rightWidth = 0) {
if (this.offset < 0) {
this.swipeMove(-rightWidth);
}
},
},
asyncClose: Boolean,
name: {
type: [Number, String],
value: '',
},
},
mixins: [touch],
data: {
catchMove: false,
},
created() {
this.offset = 0;
ARRAY.push(this);
},
destroyed() {
ARRAY = ARRAY.filter((item) => item !== this);
},
methods: {
open(position) {
const { leftWidth, rightWidth } = this.data;
const offset = position === 'left' ? leftWidth : -rightWidth;
this.swipeMove(offset);
this.$emit('open', {
position,
name: this.data.name,
});
},
close() {
this.swipeMove(0);
},
swipeMove(offset = 0) {
this.offset = range(offset, -this.data.rightWidth, this.data.leftWidth);
const transform = `translate3d(${this.offset}px, 0, 0)`;
const transition = this.dragging
? 'none'
: 'transform .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
this.setData({
wrapperStyle: `
-webkit-transform: ${transform};
-webkit-transition: ${transition};
transform: ${transform};
transition: ${transition};
`,
});
},
swipeLeaveTransition() {
const { leftWidth, rightWidth } = this.data;
const { offset } = this;
if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
this.open('right');
} else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
this.open('left');
} else {
this.swipeMove(0);
}
this.setData({ catchMove: false });
},
startDrag(event) {
if (this.data.disabled) {
return;
}
this.startOffset = this.offset;
this.touchStart(event);
},
noop() {},
onDrag(event) {
if (this.data.disabled) {
return;
}
this.touchMove(event);
if (this.direction !== 'horizontal') {
return;
}
this.dragging = true;
ARRAY.filter((item) => item !== this).forEach((item) => item.close());
this.setData({ catchMove: true });
this.swipeMove(this.startOffset + this.deltaX);
},
endDrag() {
if (this.data.disabled) {
return;
}
this.dragging = false;
this.swipeLeaveTransition();
},
onClick(event) {
const { key: position = 'outside' } = event.currentTarget.dataset;
this.$emit('click', position);
if (!this.offset) {
return;
}
if (this.data.asyncClose) {
this.$emit('close', {
position,
instance: this,
name: this.data.name,
});
} else {
this.swipeMove(0);
}
},
},
});
================================================
FILE: miniprogram/vant/swipe-cell/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/swipe-cell/index.wxml
================================================
================================================
FILE: miniprogram/vant/swipe-cell/index.wxss
================================================
@import '../common/index.wxss';.van-swipe-cell{position:relative;overflow:hidden}.van-swipe-cell__left,.van-swipe-cell__right{position:absolute;top:0;height:100%}.van-swipe-cell__left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.van-swipe-cell__right{right:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}
================================================
FILE: miniprogram/vant/switch/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/switch/index.js
================================================
import { VantComponent } from '../common/component';
import { BLUE, GRAY_DARK } from '../common/color';
VantComponent({
field: true,
classes: ['node-class'],
props: {
checked: {
type: null,
observer(value) {
const loadingColor = this.getLoadingColor(value);
this.setData({ value, loadingColor });
},
},
loading: Boolean,
disabled: Boolean,
activeColor: String,
inactiveColor: String,
size: {
type: String,
value: '30px',
},
activeValue: {
type: null,
value: true,
},
inactiveValue: {
type: null,
value: false,
},
},
created() {
const { checked: value } = this.data;
const loadingColor = this.getLoadingColor(value);
this.setData({ value, loadingColor });
},
methods: {
getLoadingColor(checked) {
const { activeColor, inactiveColor } = this.data;
return checked ? activeColor || BLUE : inactiveColor || GRAY_DARK;
},
onClick() {
const { activeValue, inactiveValue } = this.data;
if (!this.data.disabled && !this.data.loading) {
const checked = this.data.checked === activeValue;
const value = checked ? inactiveValue : activeValue;
this.$emit('input', value);
this.$emit('change', value);
}
},
},
});
================================================
FILE: miniprogram/vant/switch/index.json
================================================
{
"component": true,
"usingComponents": {
"van-loading": "../loading/index"
}
}
================================================
FILE: miniprogram/vant/switch/index.wxml
================================================
================================================
FILE: miniprogram/vant/switch/index.wxss
================================================
@import '../common/index.wxss';.van-switch{position:relative;display:inline-block;box-sizing:initial;width:2em;width:var(--switch-width,2em);height:1em;height:var(--switch-height,1em);background-color:#fff;background-color:var(--switch-background-color,#fff);border:1px solid rgba(0,0,0,.1);border:var(--switch-border,1px solid rgba(0,0,0,.1));border-radius:1em;border-radius:var(--switch-node-size,1em);transition:background-color .3s;transition:background-color var(--switch-transition-duration,.3s)}.van-switch__node{position:absolute;top:0;left:0;border-radius:100%;z-index:1;z-index:var(--switch-node-z-index,1);width:1em;width:var(--switch-node-size,1em);height:1em;height:var(--switch-node-size,1em);background-color:#fff;background-color:var(--switch-node-background-color,#fff);box-shadow:0 3px 1px 0 rgba(0,0,0,.05),0 2px 2px 0 rgba(0,0,0,.1),0 3px 3px 0 rgba(0,0,0,.05);box-shadow:var(--switch-node-box-shadow,0 3px 1px 0 rgba(0,0,0,.05),0 2px 2px 0 rgba(0,0,0,.1),0 3px 3px 0 rgba(0,0,0,.05));transition:-webkit-transform .3s cubic-bezier(.3,1.05,.4,1.05);transition:transform .3s cubic-bezier(.3,1.05,.4,1.05);transition:transform .3s cubic-bezier(.3,1.05,.4,1.05),-webkit-transform .3s cubic-bezier(.3,1.05,.4,1.05);transition:-webkit-transform var(--switch-transition-duration,.3s) cubic-bezier(.3,1.05,.4,1.05);transition:transform var(--switch-transition-duration,.3s) cubic-bezier(.3,1.05,.4,1.05);transition:transform var(--switch-transition-duration,.3s) cubic-bezier(.3,1.05,.4,1.05),-webkit-transform var(--switch-transition-duration,.3s) cubic-bezier(.3,1.05,.4,1.05)}.van-switch__loading{position:absolute!important;top:25%;left:25%;width:50%;height:50%}.van-switch--on{background-color:#1989fa;background-color:var(--switch-on-background-color,#1989fa)}.van-switch--on .van-switch__node{-webkit-transform:translateX(1em);transform:translateX(1em);-webkit-transform:translateX(calc(var(--switch-width, 2em) - var(--switch-node-size, 1em)));transform:translateX(calc(var(--switch-width, 2em) - var(--switch-node-size, 1em)))}.van-switch--disabled{opacity:.4;opacity:var(--switch-disabled-opacity,.4)}
================================================
FILE: miniprogram/vant/tab/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/tab/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'tabs',
type: 'ancestor',
current: 'tab',
},
props: {
dot: {
type: Boolean,
observer: 'update',
},
info: {
type: null,
observer: 'update',
},
title: {
type: String,
observer: 'update',
},
disabled: {
type: Boolean,
observer: 'update',
},
titleStyle: {
type: String,
observer: 'update',
},
name: {
type: [Number, String],
value: '',
},
},
data: {
active: false,
},
methods: {
getComputedName() {
if (this.data.name !== '') {
return this.data.name;
}
return this.index;
},
updateRender(active, parent) {
const { data: parentData } = parent;
this.inited = this.inited || active;
this.setData({
active,
shouldRender: this.inited || !parentData.lazyRender,
shouldShow: active || parentData.animated,
});
},
update() {
if (this.parent) {
this.parent.updateTabs();
}
},
},
});
================================================
FILE: miniprogram/vant/tab/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/tab/index.wxml
================================================
================================================
FILE: miniprogram/vant/tab/index.wxss
================================================
@import '../common/index.wxss';:host{-webkit-flex-shrink:0;flex-shrink:0;width:100%}.van-tab__pane,:host{box-sizing:border-box}.van-tab__pane{overflow-y:auto;-webkit-overflow-scrolling:touch}.van-tab__pane--active{height:auto}.van-tab__pane--inactive{height:0;overflow:visible}
================================================
FILE: miniprogram/vant/tabbar/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/tabbar/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'tabbar-item',
type: 'descendant',
current: 'tabbar',
linked(target) {
target.parent = this;
target.updateFromParent();
},
unlinked() {
this.updateChildren();
},
},
props: {
active: {
type: null,
observer: 'updateChildren',
},
activeColor: {
type: String,
observer: 'updateChildren',
},
inactiveColor: {
type: String,
observer: 'updateChildren',
},
fixed: {
type: Boolean,
value: true,
},
border: {
type: Boolean,
value: true,
},
zIndex: {
type: Number,
value: 1,
},
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
},
methods: {
updateChildren() {
const { children } = this;
if (!Array.isArray(children) || !children.length) {
return Promise.resolve();
}
return Promise.all(children.map((child) => child.updateFromParent()));
},
onChange(child) {
const index = this.children.indexOf(child);
const active = child.data.name || index;
if (active !== this.data.active) {
this.$emit('change', active);
}
},
},
});
================================================
FILE: miniprogram/vant/tabbar/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/tabbar/index.wxml
================================================
================================================
FILE: miniprogram/vant/tabbar/index.wxss
================================================
@import '../common/index.wxss';.van-tabbar{display:-webkit-flex;display:flex;width:100%;height:50px;height:var(--tabbar-height,50px);background-color:#fff;background-color:var(--tabbar-background-color,#fff)}.van-tabbar--fixed{position:fixed;bottom:0;left:0}.van-tabbar--safe{padding-bottom:env(safe-area-inset-bottom)}
================================================
FILE: miniprogram/vant/tabbar-item/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/tabbar-item/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
props: {
info: null,
name: null,
icon: String,
dot: Boolean,
},
relation: {
name: 'tabbar',
type: 'ancestor',
current: 'tabbar-item',
},
data: {
active: false,
},
methods: {
onClick() {
if (this.parent) {
this.parent.onChange(this);
}
this.$emit('click');
},
updateFromParent() {
const { parent } = this;
if (!parent) {
return;
}
const index = parent.children.indexOf(this);
const parentData = parent.data;
const { data } = this;
const active = (data.name || index) === parentData.active;
const patch = {};
if (active !== data.active) {
patch.active = active;
}
if (parentData.activeColor !== data.activeColor) {
patch.activeColor = parentData.activeColor;
}
if (parentData.inactiveColor !== data.inactiveColor) {
patch.inactiveColor = parentData.inactiveColor;
}
return Object.keys(patch).length > 0
? this.set(patch)
: Promise.resolve();
},
},
});
================================================
FILE: miniprogram/vant/tabbar-item/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-info": "../info/index"
}
}
================================================
FILE: miniprogram/vant/tabbar-item/index.wxml
================================================
================================================
FILE: miniprogram/vant/tabbar-item/index.wxss
================================================
@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-tabbar-item{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;height:100%;color:#646566;color:var(--tabbar-item-text-color,#646566);font-size:12px;font-size:var(--tabbar-item-font-size,12px);line-height:1;line-height:var(--tabbar-item-line-height,1)}.van-tabbar-item__icon{position:relative;margin-bottom:5px;margin-bottom:var(--tabbar-item-margin-bottom,5px);font-size:18px;font-size:var(--tabbar-item-icon-size,18px)}.van-tabbar-item__icon__inner{display:block;min-width:1em}.van-tabbar-item--active{color:#1989fa;color:var(--tabbar-item-active-color,#1989fa)}.van-tabbar-item__info{margin-top:2px}
================================================
FILE: miniprogram/vant/tabs/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/tabs/index.js
================================================
import { VantComponent } from '../common/component';
import { touch } from '../mixins/touch';
import { isDef, addUnit } from '../common/utils';
VantComponent({
mixins: [touch],
classes: ['nav-class', 'tab-class', 'tab-active-class', 'line-class'],
relation: {
name: 'tab',
type: 'descendant',
current: 'tabs',
linked(target) {
target.index = this.children.length - 1;
this.updateTabs();
},
unlinked() {
this.children = this.children.map((child, index) => {
child.index = index;
return child;
});
this.updateTabs();
},
},
props: {
color: {
type: String,
observer: 'setLine',
},
sticky: Boolean,
animated: {
type: Boolean,
observer() {
this.children.forEach((child, index) =>
child.updateRender(index === this.data.currentIndex, this)
);
},
},
swipeable: Boolean,
lineWidth: {
type: [String, Number],
value: -1,
observer: 'setLine',
},
lineHeight: {
type: [String, Number],
value: -1,
observer: 'setLine',
},
titleActiveColor: String,
titleInactiveColor: String,
active: {
type: [String, Number],
value: 0,
observer(name) {
if (name !== this.getCurrentName()) {
this.setCurrentIndexByName(name);
}
},
},
type: {
type: String,
value: 'line',
},
border: {
type: Boolean,
value: true,
},
ellipsis: {
type: Boolean,
value: true,
},
duration: {
type: Number,
value: 0.3,
},
zIndex: {
type: Number,
value: 1,
},
swipeThreshold: {
type: Number,
value: 4,
observer(value) {
this.setData({
scrollable: this.children.length > value || !this.data.ellipsis,
});
},
},
offsetTop: {
type: Number,
value: 0,
},
lazyRender: {
type: Boolean,
value: true,
},
},
data: {
tabs: [],
lineStyle: '',
scrollLeft: 0,
scrollable: false,
trackStyle: '',
currentIndex: null,
container: null,
},
mounted() {
wx.nextTick(() => {
this.setLine(true);
this.scrollIntoView();
});
},
methods: {
updateContainer() {
this.setData({
container: () => this.createSelectorQuery().select('.van-tabs'),
});
},
updateTabs() {
const { children = [], data } = this;
this.setData({
tabs: children.map((child) => child.data),
scrollable:
this.children.length > data.swipeThreshold || !data.ellipsis,
});
this.setCurrentIndexByName(this.getCurrentName() || data.active);
},
trigger(eventName, child) {
const { currentIndex } = this.data;
const currentChild = child || this.children[currentIndex];
if (!isDef(currentChild)) {
return;
}
this.$emit(eventName, {
index: currentChild.index,
name: currentChild.getComputedName(),
title: currentChild.data.title,
});
},
onTap(event) {
const { index } = event.currentTarget.dataset;
const child = this.children[index];
if (child.data.disabled) {
this.trigger('disabled', child);
} else {
this.setCurrentIndex(index);
wx.nextTick(() => {
this.trigger('click');
});
}
},
// correct the index of active tab
setCurrentIndexByName(name) {
const { children = [] } = this;
const matched = children.filter(
(child) => child.getComputedName() === name
);
if (matched.length) {
this.setCurrentIndex(matched[0].index);
}
},
setCurrentIndex(currentIndex) {
const { data, children = [] } = this;
if (
!isDef(currentIndex) ||
currentIndex >= children.length ||
currentIndex < 0
) {
return;
}
children.forEach((item, index) => {
const active = index === currentIndex;
if (active !== item.data.active || !item.inited) {
item.updateRender(active, this);
}
});
if (currentIndex === data.currentIndex) {
return;
}
const shouldEmitChange = data.currentIndex !== null;
this.setData({ currentIndex });
wx.nextTick(() => {
this.setLine();
this.scrollIntoView();
this.updateContainer();
this.trigger('input');
if (shouldEmitChange) {
this.trigger('change');
}
});
},
getCurrentName() {
const activeTab = this.children[this.data.currentIndex];
if (activeTab) {
return activeTab.getComputedName();
}
},
setLine(skipTransition) {
if (this.data.type !== 'line') {
return;
}
const {
color,
duration,
currentIndex,
lineWidth,
lineHeight,
} = this.data;
this.getRect('.van-tab', true).then((rects = []) => {
const rect = rects[currentIndex];
if (rect == null) {
return;
}
const width = lineWidth !== -1 ? lineWidth : rect.width / 2;
const height =
lineHeight !== -1
? `height: ${addUnit(lineHeight)}; border-radius: ${addUnit(
lineHeight
)};`
: '';
let left = rects
.slice(0, currentIndex)
.reduce((prev, curr) => prev + curr.width, 0);
left += (rect.width - width) / 2;
const transition = skipTransition
? ''
: `transition-duration: ${duration}s; -webkit-transition-duration: ${duration}s;`;
this.setData({
lineStyle: `
${height}
width: ${addUnit(width)};
background-color: ${color};
-webkit-transform: translateX(${left}px);
transform: translateX(${left}px);
${transition}
`,
});
});
},
// scroll active tab into view
scrollIntoView() {
const { currentIndex, scrollable } = this.data;
if (!scrollable) {
return;
}
Promise.all([
this.getRect('.van-tab', true),
this.getRect('.van-tabs__nav'),
]).then(([tabRects, navRect]) => {
const tabRect = tabRects[currentIndex];
const offsetLeft = tabRects
.slice(0, currentIndex)
.reduce((prev, curr) => prev + curr.width, 0);
this.setData({
scrollLeft: offsetLeft - (navRect.width - tabRect.width) / 2,
});
});
},
onTouchScroll(event) {
this.$emit('scroll', event.detail);
},
onTouchStart(event) {
if (!this.data.swipeable) return;
this.touchStart(event);
},
onTouchMove(event) {
if (!this.data.swipeable) return;
this.touchMove(event);
},
// watch swipe touch end
onTouchEnd() {
if (!this.data.swipeable) return;
const { tabs, currentIndex } = this.data;
const { direction, deltaX, offsetX } = this;
const minSwipeDistance = 50;
if (direction === 'horizontal' && offsetX >= minSwipeDistance) {
if (deltaX > 0 && currentIndex !== 0) {
this.setCurrentIndex(currentIndex - 1);
} else if (deltaX < 0 && currentIndex !== tabs.length - 1) {
this.setCurrentIndex(currentIndex + 1);
}
}
},
},
});
================================================
FILE: miniprogram/vant/tabs/index.json
================================================
{
"component": true,
"usingComponents": {
"van-info": "../info/index",
"van-sticky": "../sticky/index"
}
}
================================================
FILE: miniprogram/vant/tabs/index.wxml
================================================
{{ item.title }}
================================================
FILE: miniprogram/vant/tabs/index.wxs
================================================
/* eslint-disable */
function tabClass(active, ellipsis) {
var classes = ['tab-class'];
if (active) {
classes.push('tab-active-class');
}
if (ellipsis) {
classes.push('van-ellipsis');
}
return classes.join(' ');
}
function tabStyle(
active,
ellipsis,
color,
type,
disabled,
activeColor,
inactiveColor,
swipeThreshold,
scrollable
) {
var styles = [];
var isCard = type === 'card';
// card theme color
if (color && isCard) {
styles.push('border-color:' + color);
if (!disabled) {
if (active) {
styles.push('background-color:' + color);
} else {
styles.push('color:' + color);
}
}
}
var titleColor = active ? activeColor : inactiveColor;
if (titleColor) {
styles.push('color:' + titleColor);
}
if (scrollable && ellipsis) {
styles.push('flex-basis:' + 88 / swipeThreshold + '%');
}
return styles.join(';');
}
function tabCardTypeBorderStyle(color, type) {
var isCard = type === 'card';
var styles = [];
if (isCard && color) {
styles.push('border-color:' + color);
}
return styles.join(';');
}
function trackStyle(data) {
if (!data.animated) {
return '';
}
return [
'transform: translate3d(' + -100 * data.currentIndex + '%, 0, 0)',
'-webkit-transition-duration: ' + data.duration + 's',
'transition-duration: ' + data.duration + 's'
].join(';');
}
module.exports.tabClass = tabClass;
module.exports.tabStyle = tabStyle;
module.exports.trackStyle = trackStyle;
module.exports.tabCardTypeBorderStyle = tabCardTypeBorderStyle;
================================================
FILE: miniprogram/vant/tabs/index.wxss
================================================
@import '../common/index.wxss';.van-tabs{position:relative;-webkit-tap-highlight-color:transparent}.van-tabs__wrap{display:-webkit-flex;display:flex;overflow:hidden}.van-tabs__wrap--scrollable .van-tab{-webkit-flex:0 0 22%;flex:0 0 22%}.van-tabs__scroll{background-color:#fff;background-color:var(--tabs-nav-background-color,#fff)}.van-tabs__scroll--line{box-sizing:initial;height:calc(100% + 15px)}.van-tabs__scroll--card{margin:0 16px;margin:0 var(--padding-md,16px)}.van-tabs__scroll::-webkit-scrollbar{display:none}.van-tabs__nav{position:relative;display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none}.van-tabs__nav--card{box-sizing:border-box;height:30px;height:var(--tabs-card-height,30px);border:1px solid #ee0a24;border:var(--border-width-base,1px) solid var(--tabs-default-color,#ee0a24);border-radius:2px;border-radius:var(--border-radius-sm,2px)}.van-tabs__nav--card .van-tab{color:#ee0a24;color:var(--tabs-default-color,#ee0a24);line-height:28px;line-height:calc(var(--tabs-card-height, 30px) - 2*var(--border-width-base, 1px));border-right:1px solid #ee0a24;border-right:var(--border-width-base,1px) solid var(--tabs-default-color,#ee0a24)}.van-tabs__nav--card .van-tab:last-child{border-right:none}.van-tabs__nav--card .van-tab.van-tab--active{color:#fff;color:var(--white,#fff);background-color:#ee0a24;background-color:var(--tabs-default-color,#ee0a24)}.van-tabs__nav--card .van-tab--disabled{color:#c8c9cc;color:var(--tab-disabled-text-color,#c8c9cc)}.van-tabs__line{position:absolute;bottom:0;left:0;z-index:1;height:3px;height:var(--tabs-bottom-bar-height,3px);border-radius:3px;border-radius:var(--tabs-bottom-bar-height,3px);background-color:#ee0a24;background-color:var(--tabs-bottom-bar-color,#ee0a24)}.van-tabs__track{position:relative;width:100%;height:100%}.van-tabs__track--animated{display:-webkit-flex;display:flex;transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform}.van-tabs__content{overflow:hidden}.van-tabs--line .van-tabs__wrap{height:44px;height:var(--tabs-line-height,44px)}.van-tabs--card .van-tabs__wrap{height:30px;height:var(--tabs-card-height,30px)}.van-tab{position:relative;-webkit-flex:1;flex:1;box-sizing:border-box;min-width:0;padding:0 5px;text-align:center;cursor:pointer;color:#646566;color:var(--tab-text-color,#646566);font-size:14px;font-size:var(--tab-font-size,14px);line-height:44px;line-height:var(--tabs-line-height,44px)}.van-tab--active{font-weight:500;font-weight:var(--font-weight-bold,500);color:#323233;color:var(--tab-active-text-color,#323233)}.van-tab--disabled{color:#c8c9cc;color:var(--tab-disabled-text-color,#c8c9cc)}.van-tab--complete{-webkit-flex:1 0 auto!important;flex:1 0 auto!important}.van-tab__title__info{position:relative!important;top:-1px!important;display:inline-block;-webkit-transform:translateX(0)!important;transform:translateX(0)!important}
================================================
FILE: miniprogram/vant/tag/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/tag/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
props: {
size: String,
mark: Boolean,
color: String,
plain: Boolean,
round: Boolean,
textColor: String,
type: {
type: String,
value: 'default',
},
closeable: Boolean,
},
methods: {
onClose() {
this.$emit('close');
},
},
});
================================================
FILE: miniprogram/vant/tag/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
================================================
FILE: miniprogram/vant/tag/index.wxml
================================================
================================================
FILE: miniprogram/vant/tag/index.wxss
================================================
@import '../common/index.wxss';.van-tag{display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;line-height:normal;padding:.2em .5em;padding:var(--tag-padding,.2em .5em);color:#fff;color:var(--tag-text-color,#fff);font-size:10px;font-size:var(--tag-font-size,10px);border-radius:.2em;border-radius:var(--tag-border-radius,.2em)}.van-tag:after{border-color:currentColor;border-radius:.2em * 2;border-radius:var(--tag-border-radius,.2em) * 2}.van-tag--default{background-color:#969799;background-color:var(--tag-default-color,#969799)}.van-tag--default.van-tag--plain{color:#969799;color:var(--tag-default-color,#969799)}.van-tag--danger{background-color:#ee0a24;background-color:var(--tag-dander-color,#ee0a24)}.van-tag--danger.van-tag--plain{color:#ee0a24;color:var(--tag-dander-color,#ee0a24)}.van-tag--primary{background-color:#1989fa;background-color:var(--tag-primary-color,#1989fa)}.van-tag--primary.van-tag--plain{color:#1989fa;color:var(--tag-primary-color,#1989fa)}.van-tag--success{background-color:#07c160;background-color:var(--tag-success-color,#07c160)}.van-tag--success.van-tag--plain{color:#07c160;color:var(--tag-success-color,#07c160)}.van-tag--warning{background-color:#ff976a;background-color:var(--tag-warning-color,#ff976a)}.van-tag--warning.van-tag--plain{color:#ff976a;color:var(--tag-warning-color,#ff976a)}.van-tag--plain{background-color:#fff;background-color:var(--tag-plain-background-color,#fff)}.van-tag--mark{padding-right:.7em}.van-tag--mark,.van-tag--mark:after{border-radius:0 999px 999px 0;border-radius:0 var(--tag-round-border-radius,999px) var(--tag-round-border-radius,999px) 0}.van-tag--round,.van-tag--round:after{border-radius:999px;border-radius:var(--tag-round-border-radius,999px)}.van-tag--medium{font-size:12px;font-size:var(--tag-medium-font-size,12px)}.van-tag--large{font-size:14px;font-size:var(--tag-large-font-size,14px)}.van-tag__close{margin-left:2px}
================================================
FILE: miniprogram/vant/toast/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/toast/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
props: {
show: Boolean,
mask: Boolean,
message: String,
forbidClick: Boolean,
zIndex: {
type: Number,
value: 1000,
},
type: {
type: String,
value: 'text',
},
loadingType: {
type: String,
value: 'circular',
},
position: {
type: String,
value: 'middle',
},
},
methods: {
// for prevent touchmove
noop() {},
},
});
================================================
FILE: miniprogram/vant/toast/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-loading": "../loading/index",
"van-overlay": "../overlay/index",
"van-transition": "../transition/index"
}
}
================================================
FILE: miniprogram/vant/toast/index.wxml
================================================
{{ message }}
{{ message }}
================================================
FILE: miniprogram/vant/toast/index.wxss
================================================
@import '../common/index.wxss';.van-toast{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:initial;color:#fff;color:var(--toast-text-color,#fff);font-size:14px;font-size:var(--toast-font-size,14px);line-height:20px;line-height:var(--toast-line-height,20px);white-space:pre-wrap;word-wrap:break-word;background-color:rgba(50,50,51,.88);background-color:var(--toast-background-color,rgba(50,50,51,.88));border-radius:4px;border-radius:var(--toast-border-radius,4px)}.van-toast__container{position:fixed;top:50%;left:50%;width:-webkit-fit-content;width:fit-content;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);max-width:70%;max-width:var(--toast-max-width,70%)}.van-toast--text{min-width:96px;min-width:var(--toast-text-min-width,96px);padding:8px 12px;padding:var(--toast-text-padding,8px 12px)}.van-toast--icon{width:90px;width:var(--toast-default-width,90px);min-height:90px;min-height:var(--toast-default-min-height,90px);padding:16px;padding:var(--toast-default-padding,16px)}.van-toast--icon .van-toast__icon{font-size:48px;font-size:var(--toast-icon-size,48px)}.van-toast--icon .van-toast__text{padding-top:8px}.van-toast__loading{margin:10px 0}.van-toast--top{-webkit-transform:translateY(-30vh);transform:translateY(-30vh)}.van-toast--bottom{-webkit-transform:translateY(30vh);transform:translateY(30vh)}
================================================
FILE: miniprogram/vant/toast/toast.d.ts
================================================
///
declare type ToastMessage = string | number;
interface ToastOptions {
show?: boolean;
type?: string;
mask?: boolean;
zIndex?: number;
context?: WechatMiniprogram.Component.TrivialInstance | WechatMiniprogram.Page.TrivialInstance;
position?: string;
duration?: number;
selector?: string;
forbidClick?: boolean;
loadingType?: string;
message?: ToastMessage;
onClose?: () => void;
}
declare function Toast(toastOptions: ToastOptions | ToastMessage): WechatMiniprogram.Component.TrivialInstance;
declare namespace Toast {
var loading: (options: string | number | ToastOptions) => WechatMiniprogram.Component.Instance, Record, Record>;
var success: (options: string | number | ToastOptions) => WechatMiniprogram.Component.Instance, Record, Record>;
var fail: (options: string | number | ToastOptions) => WechatMiniprogram.Component.Instance, Record, Record>;
var clear: () => void;
var setDefaultOptions: (options: ToastOptions) => void;
var resetDefaultOptions: () => void;
}
export default Toast;
================================================
FILE: miniprogram/vant/toast/toast.js
================================================
import { isObj } from '../common/utils';
const defaultOptions = {
type: 'text',
mask: false,
message: '',
show: true,
zIndex: 1000,
duration: 2000,
position: 'middle',
forbidClick: false,
loadingType: 'circular',
selector: '#van-toast',
};
let queue = [];
let currentOptions = Object.assign({}, defaultOptions);
function parseOptions(message) {
return isObj(message) ? message : { message };
}
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
function Toast(toastOptions) {
const options = Object.assign(
Object.assign({}, currentOptions),
parseOptions(toastOptions)
);
const context = options.context || getContext();
const toast = context.selectComponent(options.selector);
if (!toast) {
console.warn('未找到 van-toast 节点,请确认 selector 及 context 是否正确');
return;
}
delete options.context;
delete options.selector;
toast.clear = () => {
toast.setData({ show: false });
if (options.onClose) {
options.onClose();
}
};
queue.push(toast);
toast.setData(options);
clearTimeout(toast.timer);
if (options.duration > 0) {
toast.timer = setTimeout(() => {
toast.clear();
queue = queue.filter((item) => item !== toast);
}, options.duration);
}
return toast;
}
const createMethod = (type) => (options) =>
Toast(Object.assign({ type }, parseOptions(options)));
Toast.loading = createMethod('loading');
Toast.success = createMethod('success');
Toast.fail = createMethod('fail');
Toast.clear = () => {
queue.forEach((toast) => {
toast.clear();
});
queue = [];
};
Toast.setDefaultOptions = (options) => {
Object.assign(currentOptions, options);
};
Toast.resetDefaultOptions = () => {
currentOptions = Object.assign({}, defaultOptions);
};
export default Toast;
================================================
FILE: miniprogram/vant/transition/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/transition/index.js
================================================
import { VantComponent } from '../common/component';
import { transition } from '../mixins/transition';
VantComponent({
classes: [
'enter-class',
'enter-active-class',
'enter-to-class',
'leave-class',
'leave-active-class',
'leave-to-class',
],
mixins: [transition(true)],
});
================================================
FILE: miniprogram/vant/transition/index.json
================================================
{
"component": true
}
================================================
FILE: miniprogram/vant/transition/index.wxml
================================================
================================================
FILE: miniprogram/vant/transition/index.wxss
================================================
@import '../common/index.wxss';.van-transition{transition-timing-function:ease}.van-fade-enter-active,.van-fade-leave-active{transition-property:opacity}.van-fade-enter,.van-fade-leave-to{opacity:0}.van-fade-down-enter-active,.van-fade-down-leave-active,.van-fade-left-enter-active,.van-fade-left-leave-active,.van-fade-right-enter-active,.van-fade-right-leave-active,.van-fade-up-enter-active,.van-fade-up-leave-active{transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}.van-fade-up-enter,.van-fade-up-leave-to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);opacity:0}.van-fade-down-enter,.van-fade-down-leave-to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);opacity:0}.van-fade-left-enter,.van-fade-left-leave-to{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);opacity:0}.van-fade-right-enter,.van-fade-right-leave-to{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);opacity:0}.van-slide-down-enter-active,.van-slide-down-leave-active,.van-slide-left-enter-active,.van-slide-left-leave-active,.van-slide-right-enter-active,.van-slide-right-leave-active,.van-slide-up-enter-active,.van-slide-up-leave-active{transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform}.van-slide-up-enter,.van-slide-up-leave-to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.van-slide-down-enter,.van-slide-down-leave-to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.van-slide-left-enter,.van-slide-left-leave-to{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.van-slide-right-enter,.van-slide-right-leave-to{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}
================================================
FILE: miniprogram/vant/tree-select/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/tree-select/index.js
================================================
import { VantComponent } from '../common/component';
VantComponent({
classes: [
'main-item-class',
'content-item-class',
'main-active-class',
'content-active-class',
'main-disabled-class',
'content-disabled-class',
],
props: {
items: {
type: Array,
observer: 'updateSubItems',
},
activeId: null,
mainActiveIndex: {
type: Number,
value: 0,
observer: 'updateSubItems',
},
height: {
type: [Number, String],
value: 300,
},
max: {
type: Number,
value: Infinity,
},
},
data: {
subItems: [],
},
methods: {
// 当一个子项被选择时
onSelectItem(event) {
const { item } = event.currentTarget.dataset;
const isArray = Array.isArray(this.data.activeId);
// 判断有没有超出右侧选择的最大数
const isOverMax = isArray && this.data.activeId.length >= this.data.max;
// 判断该项有没有被选中, 如果有被选中,则忽视是否超出的条件
const isSelected = isArray
? this.data.activeId.indexOf(item.id) > -1
: this.data.activeId === item.id;
if (!item.disabled && (!isOverMax || isSelected)) {
this.$emit('click-item', item);
}
},
// 当一个导航被点击时
onClickNav(event) {
const index = event.detail;
const item = this.data.items[index];
if (!item.disabled) {
this.$emit('click-nav', { index });
}
},
// 更新子项列表
updateSubItems() {
const { items, mainActiveIndex } = this.data;
const { children = [] } = items[mainActiveIndex] || {};
return this.set({ subItems: children });
},
},
});
================================================
FILE: miniprogram/vant/tree-select/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-sidebar": "../sidebar/index",
"van-sidebar-item": "../sidebar-item/index"
}
}
================================================
FILE: miniprogram/vant/tree-select/index.wxml
================================================
{{ item.text }}
================================================
FILE: miniprogram/vant/tree-select/index.wxs
================================================
/* eslint-disable */
var array = require('../wxs/array.wxs');
function isActive (activeList, itemId) {
if (array.isArray(activeList)) {
return activeList.indexOf(itemId) > -1;
}
return activeList === itemId;
}
module.exports.isActive = isActive;
================================================
FILE: miniprogram/vant/tree-select/index.wxss
================================================
@import '../common/index.wxss';.van-tree-select{position:relative;display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none;font-size:14px;font-size:var(--tree-select-font-size,14px)}.van-tree-select__nav{-webkit-flex:1;flex:1;background-color:#f7f8fa;background-color:var(--tree-select-nav-background-color,#f7f8fa);--sidebar-padding:12px 8px 12px 12px}.van-tree-select__nav__inner{width:100%!important;height:100%}.van-tree-select__content{-webkit-flex:2;flex:2;background-color:#fff;background-color:var(--tree-select-content-background-color,#fff)}.van-tree-select__item{position:relative;font-weight:700;padding:0 32px 0 16px;padding:0 32px 0 var(--padding-md,16px);line-height:44px;line-height:var(--tree-select-item-height,44px)}.van-tree-select__item--active{color:#ee0a24;color:var(--tree-select-item-active-color,#ee0a24)}.van-tree-select__item--disabled{color:#c8c9cc;color:var(--tree-select-item-disabled-color,#c8c9cc)}.van-tree-select__selected{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);right:16px;right:var(--padding-md,16px)}
================================================
FILE: miniprogram/vant/uploader/index.d.ts
================================================
export {};
================================================
FILE: miniprogram/vant/uploader/index.js
================================================
import { VantComponent } from '../common/component';
import { isImageFile, isVideo, chooseFile, isPromise } from './utils';
import { chooseImageProps, chooseVideoProps } from './shared';
VantComponent({
props: Object.assign(
Object.assign(
{
disabled: Boolean,
multiple: Boolean,
uploadText: String,
useBeforeRead: Boolean,
afterRead: null,
beforeRead: null,
previewSize: {
type: null,
value: 90,
},
name: {
type: [Number, String],
value: '',
},
accept: {
type: String,
value: 'image',
},
fileList: {
type: Array,
value: [],
observer: 'formatFileList',
},
maxSize: {
type: Number,
value: Number.MAX_VALUE,
},
maxCount: {
type: Number,
value: 100,
},
deletable: {
type: Boolean,
value: true,
},
showUpload: {
type: Boolean,
value: true,
},
previewImage: {
type: Boolean,
value: true,
},
previewFullImage: {
type: Boolean,
value: true,
},
imageFit: {
type: String,
value: 'scaleToFill',
},
uploadIcon: {
type: String,
value: 'photograph',
},
},
chooseImageProps
),
chooseVideoProps
),
data: {
lists: [],
isInCount: true,
},
methods: {
formatFileList() {
const { fileList = [], maxCount } = this.data;
const lists = fileList.map((item) =>
Object.assign(Object.assign({}, item), {
isImage:
typeof item.isImage === 'undefined'
? isImageFile(item)
: item.isImage,
})
);
this.setData({ lists, isInCount: lists.length < maxCount });
},
getDetail(index) {
return {
name: this.data.name,
index: index == null ? this.data.fileList.length : index,
};
},
startUpload() {
const { maxCount, multiple, accept, lists, disabled } = this.data;
if (disabled) return;
chooseFile(
Object.assign(Object.assign({}, this.data), {
maxCount: maxCount - lists.length,
})
)
.then((res) => {
let file = null;
if (isVideo(res, accept)) {
file = Object.assign({ path: res.tempFilePath }, res);
} else {
file = multiple ? res.tempFiles : res.tempFiles[0];
}
this.onBeforeRead(file);
})
.catch((error) => {
this.$emit('error', error);
});
},
onBeforeRead(file) {
const { beforeRead, useBeforeRead } = this.data;
let res = true;
if (typeof beforeRead === 'function') {
res = beforeRead(file, this.getDetail());
}
if (useBeforeRead) {
res = new Promise((resolve, reject) => {
this.$emit(
'before-read',
Object.assign(Object.assign({ file }, this.getDetail()), {
callback: (ok) => {
ok ? resolve() : reject();
},
})
);
});
}
if (!res) {
return;
}
if (isPromise(res)) {
res.then((data) => this.onAfterRead(data || file));
} else {
this.onAfterRead(file);
}
},
onAfterRead(file) {
const { maxSize } = this.data;
const oversize = Array.isArray(file)
? file.some((item) => item.size > maxSize)
: file.size > maxSize;
if (oversize) {
this.$emit('oversize', Object.assign({ file }, this.getDetail()));
return;
}
if (typeof this.data.afterRead === 'function') {
this.data.afterRead(file, this.getDetail());
}
this.$emit('after-read', Object.assign({ file }, this.getDetail()));
},
deleteItem(event) {
const { index } = event.currentTarget.dataset;
this.$emit(
'delete',
Object.assign(Object.assign({}, this.getDetail(index)), {
file: this.data.fileList[index],
})
);
},
onPreviewImage(event) {
if (!this.data.previewFullImage) return;
const { index } = event.currentTarget.dataset;
const { lists } = this.data;
const item = lists[index];
wx.previewImage({
urls: lists
.filter((item) => item.isImage)
.map((item) => item.url || item.path),
current: item.url || item.path,
fail() {
wx.showToast({ title: '预览图片失败', icon: 'none' });
},
});
},
onClickPreview(event) {
const { index } = event.currentTarget.dataset;
const item = this.data.lists[index];
this.$emit(
'click-preview',
Object.assign(Object.assign({}, item), this.getDetail(index))
);
},
},
});
================================================
FILE: miniprogram/vant/uploader/index.json
================================================
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-loading": "../loading/index"
}
}
================================================
FILE: miniprogram/vant/uploader/index.wxml
================================================
{{ item.name || item.url || item.path }}
{{ item.message }}
{{ uploadText }}
================================================
FILE: miniprogram/vant/uploader/index.wxss
================================================
@import '../common/index.wxss';.van-uploader{position:relative;display:inline-block}.van-uploader__wrapper{display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap}.van-uploader__slot:empty{display:none}.van-uploader__slot:not(:empty)+.van-uploader__upload{display:none!important}.van-uploader__upload{position:relative;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:80px;height:80px;margin:0 8px 8px 0;background-color:#f7f8fa;border-radius:8px}.van-uploader__upload:active{background-color:#f2f3f5}.van-uploader__upload-icon{color:#dcdee0;font-size:24px}.van-uploader__upload-text{margin-top:8px;color:#969799;font-size:12px}.van-uploader__upload--disabled{opacity:.5;opacity:var(--uploader-disabled-opacity,.5)}.van-uploader__preview{position:relative;margin:0 8px 8px 0;cursor:pointer}.van-uploader__preview-image{display:block;width:80px;height:80px;overflow:hidden;border-radius:8px}.van-uploader__preview-delete{position:absolute;top:-8px;right:-8px;color:#969799;font-size:18px;background-color:#fff;border-radius:100%}.van-uploader__file{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;width:80px;height:80px;background-color:#f7f8fa;border-radius:8px}.van-uploader__file-icon{color:#646566;font-size:20px}.van-uploader__file-name{box-sizing:border-box;width:100%;margin-top:8px;padding:0 4px;color:#646566;font-size:12px;text-align:center}.van-uploader__mask{position:absolute;top:0;right:0;bottom:0;left:0;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;color:#fff;background-color:rgba(50,50,51,.88);border-radius:8px}.van-uploader__mask-icon{font-size:22px}.van-uploader__mask-message{margin-top:6px;padding:0 4px;font-size:12px;line-height:14px}.van-uploader__loading{width:22px;height:22px;color:#fff}
================================================
FILE: miniprogram/vant/uploader/shared.d.ts
================================================
export declare const chooseImageProps: {
sizeType: {
type: ArrayConstructor;
value: string[];
};
capture: {
type: ArrayConstructor;
value: string[];
};
};
export declare const chooseVideoProps: {
capture: {
type: ArrayConstructor;
value: string[];
};
compressed: {
type: BooleanConstructor;
value: boolean;
};
maxDuration: {
type: NumberConstructor;
value: number;
};
camera: {
type: StringConstructor;
value: string;
};
};
================================================
FILE: miniprogram/vant/uploader/shared.js
================================================
// props for choose image
export const chooseImageProps = {
sizeType: {
type: Array,
value: ['original', 'compressed'],
},
capture: {
type: Array,
value: ['album', 'camera'],
},
};
// props for choose video
export const chooseVideoProps = {
capture: {
type: Array,
value: ['album', 'camera'],
},
compressed: {
type: Boolean,
value: true,
},
maxDuration: {
type: Number,
value: 60,
},
camera: {
type: String,
value: 'back',
},
};
================================================
FILE: miniprogram/vant/uploader/utils.d.ts
================================================
///
interface File {
path: string;
url: string;
size: number;
name: string;
type: string;
time: number;
image: boolean;
}
export declare function isImageFile(item: File): boolean;
export declare function isVideo(
res: any,
accept: string
): res is WechatMiniprogram.ChooseVideoSuccessCallbackResult;
export declare function chooseFile({
accept,
multiple,
capture,
compressed,
maxDuration,
sizeType,
camera,
maxCount,
}: {
accept: any;
multiple: any;
capture: any;
compressed: any;
maxDuration: any;
sizeType: any;
camera: any;
maxCount: any;
}): Promise<
| WechatMiniprogram.ChooseImageSuccessCallbackResult
| WechatMiniprogram.ChooseMediaSuccessCallbackResult
| WechatMiniprogram.ChooseVideoSuccessCallbackResult
| WechatMiniprogram.ChooseMessageFileSuccessCallbackResult
>;
export declare function isFunction(val: unknown): val is Function;
export declare function isObject(val: any): val is Record;
export declare function isPromise(val: unknown): val is Promise;
export {};
================================================
FILE: miniprogram/vant/uploader/utils.js
================================================
const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i;
function isImageUrl(url) {
return IMAGE_REGEXP.test(url);
}
export function isImageFile(item) {
if (item.type) {
return item.type.indexOf('image') === 0;
}
if (item.path) {
return isImageUrl(item.path);
}
if (item.url) {
return isImageUrl(item.url);
}
return false;
}
export function isVideo(res, accept) {
return accept === 'video';
}
export function chooseFile({
accept,
multiple,
capture,
compressed,
maxDuration,
sizeType,
camera,
maxCount,
}) {
switch (accept) {
case 'image':
return new Promise((resolve, reject) => {
wx.chooseImage({
count: multiple ? Math.min(maxCount, 9) : 1,
sourceType: capture,
sizeType,
success: resolve,
fail: reject,
});
});
case 'media':
return new Promise((resolve, reject) => {
wx.chooseMedia({
count: multiple ? Math.min(maxCount, 9) : 1,
sourceType: capture,
maxDuration,
sizeType,
camera,
success: resolve,
fail: reject,
});
});
case 'video':
return new Promise((resolve, reject) => {
wx.chooseVideo({
sourceType: capture,
compressed,
maxDuration,
camera,
success: resolve,
fail: reject,
});
});
default:
return new Promise((resolve, reject) => {
wx.chooseMessageFile({
count: multiple ? maxCount : 1,
type: 'file',
success: resolve,
fail: reject,
});
});
}
}
export function isFunction(val) {
return typeof val === 'function';
}
export function isObject(val) {
return val !== null && typeof val === 'object';
}
export function isPromise(val) {
return isObject(val) && isFunction(val.then) && isFunction(val.catch);
}
================================================
FILE: miniprogram/vant/wxs/add-unit.wxs
================================================
/* eslint-disable */
var REGEXP = getRegExp('^\d+(\.\d+)?$');
function addUnit(value) {
if (value == null) {
return undefined;
}
return REGEXP.test('' + value) ? value + 'px' : value;
}
module.exports = {
addUnit: addUnit
};
================================================
FILE: miniprogram/vant/wxs/array.wxs
================================================
function isArray(array) {
return array && array.constructor === 'Array';
}
module.exports.isArray = isArray;
================================================
FILE: miniprogram/vant/wxs/bem.wxs
================================================
var array = require('./array.wxs');
var object = require('./object.wxs');
var PREFIX = 'van-';
function join(name, mods) {
name = PREFIX + name;
mods = mods.map(function(mod) {
return name + '--' + mod;
});
mods.unshift(name);
return mods.join(' ');
}
function traversing(mods, conf) {
if (!conf) {
return;
}
if (typeof conf === 'string' || typeof conf === 'number') {
mods.push(conf);
} else if (array.isArray(conf)) {
conf.forEach(function(item) {
traversing(mods, item);
});
} else if (typeof conf === 'object') {
object.keys(conf).forEach(function(key) {
conf[key] && mods.push(key);
});
}
}
function bem(name, conf) {
var mods = [];
traversing(mods, conf);
return join(name, mods);
}
module.exports.bem = bem;
================================================
FILE: miniprogram/vant/wxs/memoize.wxs
================================================
/**
* Simple memoize
* wxs doesn't support fn.apply, so this memoize only support up to 2 args
*/
function isPrimitive(value) {
var type = typeof value;
return (
type === 'boolean' ||
type === 'number' ||
type === 'string' ||
type === 'undefined' ||
value === null
);
}
// mock simple fn.call in wxs
function call(fn, args) {
if (args.length === 2) {
return fn(args[0], args[1]);
}
if (args.length === 1) {
return fn(args[0]);
}
return fn();
}
function serializer(args) {
if (args.length === 1 && isPrimitive(args[0])) {
return args[0];
}
var obj = {};
for (var i = 0; i < args.length; i++) {
obj['key' + i] = args[i];
}
return JSON.stringify(obj);
}
function memoize(fn) {
var cache = {};
return function() {
var key = serializer(arguments);
if (cache[key] === undefined) {
cache[key] = call(fn, arguments);
}
return cache[key];
};
}
module.exports.memoize = memoize;
================================================
FILE: miniprogram/vant/wxs/object.wxs
================================================
/* eslint-disable */
var REGEXP = getRegExp('{|}|"', 'g');
function keys(obj) {
return JSON.stringify(obj)
.replace(REGEXP, '')
.split(',')
.map(function(item) {
return item.split(':')[0];
});
}
module.exports.keys = keys;
================================================
FILE: miniprogram/vant/wxs/utils.wxs
================================================
/* eslint-disable */
var bem = require('./bem.wxs').bem;
var memoize = require('./memoize.wxs').memoize;
var addUnit = require('./add-unit.wxs').addUnit;
module.exports = {
bem: memoize(bem),
memoize: memoize,
addUnit: addUnit
};
================================================
FILE: project.config.json
================================================
{
"miniprogramRoot": "miniprogram/",
"cloudfunctionRoot": "cloudfunctions/",
"setting": {
"urlCheck": true,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": true,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"useMultiFrameRuntime": false,
"useApiHook": false,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"useIsolateContext": true,
"useCompilerModule": true,
"userConfirmedUseCompilerModuleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": []
},
"appid": "wxd6beb52c8602bff4",
"projectname": "%E6%A0%A1%E5%9B%AD%E4%BA%8C%E6%89%8B%E4%B9%A6",
"libVersion": "2.12.0",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"cloudfunctionTemplateRoot": "cloudfunctionTemplate",
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"plugin": {
"current": -1,
"list": []
},
"game": {
"list": []
},
"gamePlugin": {
"current": -1,
"list": []
},
"miniprogram": {
"current": 17,
"list": [
{
"id": -1,
"name": "db guide",
"pathName": "pages/databaseGuide/databaseGuide",
"query": ""
},
{
"id": -1,
"name": "注册",
"pathName": "pages/login/login",
"query": "",
"scene": null
},
{
"id": -1,
"name": "发布",
"pathName": "pages/publish/publish",
"query": "",
"scene": null
},
{
"id": 3,
"name": "详情页",
"pathName": "pages/detail/detail",
"query": "scene=3c4c6d855d70f8b6124543920c2934e6",
"scene": null
},
{
"id": 4,
"name": "支付成功",
"pathName": "pages/success/success",
"query": "id=efdeb2615d72487b1319b22650cd56cb",
"scene": null
},
{
"id": -1,
"name": "【订单】详情",
"pathName": "pages/order/detail/detail",
"query": "id=5d262bd45d7264f5134049797256c6f9",
"scene": null
},
{
"id": -1,
"name": "【订单】列表",
"pathName": "pages/order/list/list",
"query": "",
"scene": null
},
{
"id": -1,
"name": "个人中心",
"pathName": "pages/my/my",
"query": "",
"scene": null
},
{
"id": -1,
"name": "关于我们",
"pathName": "pages/about/about",
"query": "",
"scene": null
},
{
"id": -1,
"name": "钱包",
"pathName": "pages/parse/parse",
"query": "",
"scene": null
},
{
"id": -1,
"name": "充值",
"pathName": "pages/recharge/recharge",
"query": "",
"scene": null
},
{
"id": -1,
"name": "提现",
"pathName": "pages/reflect/reflect",
"query": "",
"scene": null
},
{
"id": 12,
"name": "我的发布【列表】",
"pathName": "pages/sell/list/list",
"query": "",
"scene": null
},
{
"id": 13,
"name": "我的发布【详情】",
"pathName": "pages/sell/detail/detail",
"query": "id=efdeb2615d70eb6012393ac94afadcf6",
"scene": null
},
{
"id": -1,
"name": "搜索",
"pathName": "pages/search/search",
"query": "",
"scene": null
},
{
"id": -1,
"name": "首页",
"pathName": "pages/index/index",
"query": "",
"scene": null
},
{
"id": -1,
"name": "【编辑资料】",
"pathName": "pages/edit/edit",
"query": "",
"scene": null
},
{
"id": -1,
"name": "帮助中心",
"pathName": "pages/help/help",
"query": "",
"scene": null
},
{
"id": -1,
"name": "pages/about/about",
"pathName": "pages/about/about",
"query": "",
"scene": null
},
{
"id": -1,
"name": "pages/message/message",
"pathName": "pages/message/message",
"scene": null
}
]
}
}
}