提交 29ac9218 编写于 作者: D devil

小程序会员开发

上级 e995cae3
......@@ -7,5 +7,4 @@
.idea
.htaccess
*payment_*_respond.php
*payment_*_notify.php
.swan
*payment_*_notify.php
\ No newline at end of file
......@@ -15,7 +15,7 @@
return [
// 开发模式
'is_develop' => false,
'is_develop' => true,
// 默认编码
'default_charset' => 'utf-8',
......
......@@ -302,7 +302,7 @@ class Alipay
{
return DataReturn('签名错误', -1);
}
return DataReturn('获取成功', 0, $result[$key]);
return DataReturn('获取成功', 0, $result[$key]['qr_code_url']);
}
$msg = isset($res['sub_msg']) ? $res['sub_msg'] : '获取二维码失败';
......
project.config.json
project.swan.json
\ No newline at end of file
project.swan.json
.swan
\ No newline at end of file
......@@ -29,10 +29,10 @@ App({
// tabbar页面
tabbar_pages: [
"index",
"goods-category",
"cart",
"user",
"/pages/index/index",
"/pages/goods-category/goods-category",
"/pages/cart/cart",
"/pages/user/user",
],
// 页面标题
......@@ -200,7 +200,7 @@ App({
var token = (user == false) ? '' : user.token || '';
return this.data.request_url +
"index.php?s=/api/" + c + "/" + a + plugins_params+
"&application=app&application_client_type=weixin" +
"&application=app&application_client_type=alipay" +
"&token=" +
token +
"&ajax=ajax" +
......@@ -545,12 +545,12 @@ App({
is_tabbar_pages(url) {
if (url.indexOf("?") == -1)
{
var all = url.split("/");
var value = url;
} else {
var temp_str = url.split("?");
var all = temp_str[0].split("/");
var value = temp_str[0];
}
if (all.length <= 0)
if ((value || null) == null)
{
return false;
}
......@@ -558,7 +558,7 @@ App({
var temp_tabbar_pages = this.data.tabbar_pages;
for (var i in temp_tabbar_pages)
{
if (temp_tabbar_pages[i] == all[all.length-1])
if (temp_tabbar_pages[i] == value)
{
return true;
}
......@@ -718,10 +718,16 @@ App({
},
// 窗口背景色设置
set_nav_bg_color_main() {
set_nav_bg_color_main(color) {
// 默认主色
if((color || null) == null)
{
color = '#d2364c';
}
// 窗口和下拉顶部背景色
my.setBackgroundColor({
backgroundColorTop: '#d2364c',
backgroundColorTop: color,
backgroundColorBottom: '#f5f5f5',
});
......
......@@ -26,9 +26,19 @@
"pages/user-goods-browse/user-goods-browse",
"pages/user-orderaftersale/user-orderaftersale",
"pages/user-orderaftersale-detail/user-orderaftersale-detail",
"pages/coupon/coupon",
"pages/user-coupon/user-coupon",
"pages/extraction-address/extraction-address"
"pages/extraction-address/extraction-address",
"pages/plugins/coupon/index/index",
"pages/plugins/coupon/user/user",
"pages/plugins/membershiplevelvip/index/index",
"pages/plugins/membershiplevelvip/buy/buy",
"pages/plugins/membershiplevelvip/user/user",
"pages/plugins/membershiplevelvip/order/order",
"pages/plugins/membershiplevelvip/order-detail/order-detail",
"pages/plugins/membershiplevelvip/shouyi-detail/shouyi-detail",
"pages/plugins/membershiplevelvip/shouyi/shouyi",
"pages/plugins/membershiplevelvip/tongji/tongji",
"pages/plugins/membershiplevelvip/tuiguang/tuiguang",
"pages/plugins/membershiplevelvip/tuandui/tuandui"
],
"window": {
"defaultTitle": "shopxo",
......
......@@ -2,7 +2,6 @@
display: inline-block;
position: relative;
vertical-align: middle;
line-height: 1;
}
.am-badge-text {
......@@ -20,22 +19,8 @@
border-radius: 16px;
color: #fff;
font-size: 10px;
padding: 1px 1px;
}
.am-badge-text.am-badge-double {
padding: 0 4px;
}
.am-badge-not-a-wrapper .am-badge-text {
position: relative;
top: auto;
right: auto;
transform: translateX(0);
}
.am-badge-text.is-dot {
padding: 0;
width: 10px;
min-width: 10px;
height: 10px;
}
.am-badge-text-max {
padding: 1px 2px;
}
\ No newline at end of file
<view a:if="{{propNumber > 0}}" class="am-badge">
<view class="am-badge-text {{(propNumber > 99) ? 'am-badge-text-max' : ''}}">
<text>{{(propNumber > 99) ? '99+' : propNumber}}</text>
</view>
</view>
\ No newline at end of file
// components/badge.js
Component({
/**
* 组件的属性列表
*/
properties: {
propNumber: Number,
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
\ No newline at end of file
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<view class="am-popup {{propClassname || ''}} {{(propShow || false) ? 'am-popup-show' : ''}} {{ (propAnimation || true) ? 'animation': '' }}" disable-scroll="{{propDisablescroll || true}}">
<view class="am-popup-mask" a:if="{{propMask || true}}" onTap="onMaskTap"></view>
<view class="am-popup-content am-popup-{{propPosition || 'bottom'}}">
<slot></slot>
</view>
</view>
\ No newline at end of file
// components/popup.js
Component({
/**
* 组件的属性列表
*/
props: {
className: '',
show: false,
position: 'bottom',
mask: true,
animation: true,
disableScroll: true
propClassname: String,
propShow: Boolean,
propPosition: String,
propMask: Boolean,
propAnimation: Boolean,
propDisablescroll: Boolean
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
onMaskTap: function onMaskTap() {
var onClose = this.props.onClose;
if (onClose) {
onClose();
}
}
}
});
\ No newline at end of file
})
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
## 0.4.3
`2018-11-07`
- **Enhancement**
- `tabs`新增`tabBarCls`tabBar自定义样式class
- `tabs`新增`duration`控制滑动动画时长
- `calendar`date参数兼容IOS格式要求
## 0.4.2
`2018-10-31`
- **Enhancement**
- `amount-input`组件type属性新增`digit`类型
- `vtabs`新增`activeTab``onTabClick``onChange`属性([#125](https://github.com/ant-mini-program/mini-antui/issues/125))
## 0.4.1
`2018-10-29`
- **Enhancement**
- `notice`新增`enableMarquee``marqueeProps`属性([#140](https://github.com/ant-mini-program/mini-antui/issues/140))
- **Bug Fix**
- 修复`message`type为`fail`时的白屏问题([#152](https://github.com/ant-mini-program/mini-antui/issues/152))
## 0.4.0
`2018-10-23`
- **Feature**
- 新增`am-checkbox`组件
- 新增`badge`组件
- **Enhancement**
- `calendar`组件`tabs`属性新增`disable`字段,新增`onSelectHasDisableDat`属性([#108](https://github.com/ant-mini-program/mini-antui/issues/108))
- **Bug Fix**
- 修复`vtabs`在安卓下出现滚动误差的问题
- 修复`tabs``tabs`属性变化时没有重新计算宽度导致的滚动不正常问题
## 0.3.13
`2018-10-18`
- **Bug Fix**
- 修复`swipe-action`在didUpdate时陷入死循环的问题
- 修复`vtabs`tabs数据变化没有响应的问题
## 0.3.12
`2018-10-12`
- **Enhancement**
- `vtabs`新增`badgeType``badgeText`属性([#92](https://github.com/ant-mini-program/mini-antui/issues/92))
## 0.3.11
`2018-10-10`
- **Bug Fix**
- 修复`search-bar`在IPhone X下面出现滚动的问题([#113](https://github.com/ant-mini-program/mini-antui/issues/113))
- 修复`stepper`在重置初始值时操作按钮状态不改变的bug([#111](https://github.com/ant-mini-program/mini-antui/issues/111))
- **Enhancement**
- `page-result`图标升级到最新版本
- `input-item`增大清除icon点击响应范围
## 0.3.10
`2018-10-08`
- **Enhancement**
- 解决`list``input-item`在安卓下线条较粗的问题
## 0.3.9
`2018-09-27`
- **Bug Fix**
- 修复`input-item`在失去焦点时清除按钮仍旧显示的问题
## 0.3.8
`2018-09-26`
- **Bug Fix**
- 修复`filter`组件单选时需要反选取消选择的问题
- **Feature**
- 新增`picker-item`组件
- **Enhancement**
- `tabs`新增`activeCls`属性,用来表示激活tabbar的自定义class([#87](https://github.com/ant-mini-program/mini-antui/issues/87))
- `input-item`新增`clear``onClear`属性,组件内支持清除输入功能([#84](https://github.com/ant-mini-program/mini-antui/issues/84))
- `list-item` onClick回调新增target参数,用来支持自定义dataset([#85](https://github.com/ant-mini-program/mini-antui/issues/85))
## 0.3.7
`2018-09-25`
- **Bug Fix**
- 修复了`input-item`组件在失去焦点等事件中无dataset的问题([#66](https://github.com/ant-mini-program/mini-antui/issues/66))
- 修复`popup`组件mask定位为absolut导致的页面滚动时mask跟着滚动的bug
- **Enhancement**
- `popup`新增disableScroll属性以适应不同业务场景
- 完善`swipe-action`的示例代码
- 文档更新,添加体验二维码
## 0.3.6
`2018-09-13`
- **Enhancement**
- 新增tips组件的类型
## 0.3.5
`2018-08-29`
- **Bug Fix**
- 修复`search-bar`点击icon无效的bug
- 修复`search-bar`苹果输入法中间态无法清除placeholder的bug
- **Enhancement**
- 优化`list`组件样式
## 0.3.4
`2018-08-16`
- **Enhancement**
- 优化`tabs`组件闪烁问题
- `face-detection`组件增加最小旋转角度属性
## 0.3.3
`2018-08-10`
- **Feature**
- `tabs`组件新增`activeTab`属性,用来指定当前激活tab
## 0.3.2
`2018-08-07`
- **Feature**
- 新增`popup`弹出菜单组件
- `face-detection`组件新增活体检测功能
## 0.3.1
`2018-07-27`
- **Feature**
- `face-detection`组件新增`appName``serviceName`字段
## 0.3.0
`2018-07-26`
- **Feature**
- 新增`face-detection`组件
- 新增`footer`组件
- `page-result`组件增加slot,方便开发者个性化定制区域内容
- **Enhancement**
- 优化`calendar`组件在初次渲染时的闪烁问题
- 优化`swipe-action`右侧按钮宽度自适应文本内容
## 0.2.0
`2018-07-11`
- **Feature**
- 新增`vtab组件`
- **Enhancement**
- 优化`swipe-action`组件性能
- 解决`tabs`组件在初次渲染时的页面闪烁问题
## 0.1.0
`2018-06-21`
- **Feature**
- 新增`steps``popover``amount-input``calendar`组件;
- `tabs`组件`tabs`属性新增`badgeType`属性、新增`showPlus``onPlusClick`属性
- `modal`组件新增`closeType`属性,以适应不同的背景颜色
- **Bug Fix**
- 修复`grid``modal``input-item`组件样式问题
## 0.0.13
`2018-05-09`
首次发布小程序版antui组件库
MIT LICENSE
Copyright (c) 2018-present Alipay.com, https://www.alipay.com/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<p align="center">
<img width="320" src="https://gw.alipayobjects.com/zos/rmsportal/CsCzHzlOkLDKyyRadsdD.png">
</p>
# mini-antui
## 链接
- [mini-antui官网文档](https://docs.alipay.com/mini/component-ext/overview-ext-common)
- [支付宝小程序](https://mini.open.alipay.com/channel/miniIndex.htm)
- [开发工具](https://docs.alipay.com/mini/ide/overview)
## 特性
- 基于`Advance Design`设计规范
- 使用[支付宝小程序](https://mini.open.alipay.com/channel/miniIndex.htm)开发
## 预览
[小程序开发者工具](https://docs.alipay.com/mini/ide/overview)打开项目
## 安装
```bash
$ npm install mini-antui --save
```
## 使用
在页面json中文件中进行注册,如card组件的注册如下所示:
```json
{
"usingComponents": {
"card": "mini-antui/es/card/index",
}
}
```
在axml文件中进行调用:
```html
<card
thumb="{{thumb}}"
title="卡片标题2"
subTitle="副标题非必填2"
onClick="onCardClick"
info="点击了第二个card"
/>
```
## 贡献
如果你有好的意见或建议,欢迎给我们提[issue](https://github.com/ant-mini-program/mini-antui/issues)
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
export default function fmtEvent(props, e) {
var dataset = {};
for (var key in props) {
if (/data-/gi.test(key)) {
dataset[key.replace(/data-/gi, '')] = props[key];
}
}
return _extends({}, e, {
currentTarget: { dataset: dataset },
target: { dataset: dataset, targetDataset: dataset }
});
}
\ No newline at end of file
.am-checkbox {
position: relative;
height: 22px;
width: 22px;
display: inline-block;
}
.am-checkbox-value {
position: absolute;
z-index: 1;
border-radius: 50%;
opacity: 0;
}
.am-checkbox-synthetic {
position: absolute;
z-index: 2;
pointer-events: none;
top: 0;
left: 0;
border-radius: 50%;
height: 100%;
width: 100%;
}
.am-checkbox-synthetic::before {
position: absolute;
left: 0;
top: 0;
height: 200%;
width: 200%;
display: block;
box-sizing: border-box;
border-radius: 50%;
content: '';
transform-origin: 0 0;
transform: scale(0.5);
border: 1px solid #c9c9c9;
}
.am-checkbox-value.a-checkbox-checked + .am-checkbox-synthetic::before {
background-color: #108ee9;
border-color: #108ee9;
border-width: 0;
}
.am-checkbox-value.a-checkbox-checked + .am-checkbox-synthetic::after {
position: absolute;
display: block;
z-index: 999;
content: '';
top: 4px;
right: 8px;
width: 5px;
height: 10px;
border: 2px solid #fff;
border-width: 0 1px 1px 0;
transform: rotate(45deg);
}
.am-checkbox-value.a-checkbox-disabled + .am-checkbox-synthetic::before {
border: 1px solid #ccc;
background-color: #e1e1e1;
}
.am-checkbox-value.a-checkbox-disabled + .am-checkbox-synthetic::after {
border-color: #adadad;
}
\ No newline at end of file
<view class="am-checkbox">
<checkbox
class="am-checkbox-value"
value="{{value}}"
checked="{{checked}}"
disabled="{{disabled}}"
onChange="onChange"
id="{{id}}"
/>
<view class="am-checkbox-synthetic"></view>
</view>
\ No newline at end of file
import fmtEvent from '../_util/fmtEvent';
Component({
props: {
value: '',
checked: false,
disabled: false,
onChange: function onChange() {},
id: ''
},
methods: {
onChange: function onChange(e) {
var event = fmtEvent(this.props, e);
this.props.onChange(event);
}
}
});
\ No newline at end of file
.am-amount {
box-sizing: border-box;
height: 173px;
width: 100%;
padding: 16px;
background: #fff;
}
.am-amount-title {
height: 24px;
line-height: 24px;
color: #333;
font-size: 17px;
}
.am-amount-synthetic {
position: absolute;
top: 0;
left: 0;
display: flex;
}
.am-amount-input {
margin-top: 16px;
padding-bottom: 16px;
display: flex;
align-items: center;
width: 100%;
height: 48px;
position: relative;
line-height: 48px;
border-bottom: 1rpx solid #eee;
}
.am-amount-symbol {
width: 18px;
font-family: PingFang SC;
font-size: 30px;
color: #333;
}
.am-amount-placeholder {
margin-left: 6px;
color: #ccc;
font-size: 24px;
}
.am-amount-value {
padding: 0 0 0 24px;
box-sizing: border-box;
z-index: 2;
height: 48px;
line-height: 48px;
vertical-align: middle;
background-color: transparent;
font-size: 48px;
font-weight: 500;
}
.am-amount-clear {
visibility: hidden;
width: 28px;
height: 28px;
}
.am-amount-clear icon {
display: flex;
height: 100%;
justify-content: center;
align-items: center;
}
.am-amount-clear-show {
visibility: visible;
}
.am-amount-footer {
padding: 16px 0;
display: flex;
}
.am-amount-extra {
flex: 1;
height: 20px;
line-height: 20px;
color: #999;
font-size: 14px;
}
.am-amount-btn {
width: 120px;
text-align: right;
color: #108ee9;
font-size: 14px;
}
\ No newline at end of file
<view class="am-amount {{className}}">
<view class="am-amount-title">{{title}}</view>
<view class="am-amount-input">
<view class="am-amount-synthetic">
<text class="am-amount-symbol">¥</text>
<text class="am-amount-placeholder" style="{{ visibility: value.length == 0 ? 'visible': 'hidden'}}">{{placeholder}}</text>
</view>
<input
type="{{type === 'digit' ? 'digit' : 'number'}}"
maxlength="{{maxLength}}"
class="am-amount-value"
value="{{value}}"
focus="{{focus}}"
onInput="onInput"
onConfirm="onConfirm"
onFocus="onFocus"
onBlur="onBlur" />
<view class="am-amount-clear {{ value.length > 0 && _focus ? 'am-amount-clear-show' : '' }}" onTap="onClearTap">
<icon type="clear" size="22" />
</view>
</view>
<view class="am-amount-footer">
<text class="am-amount-extra">{{extra}}</text>
<view class="am-amount-btn" onTap="onButtonClick">{{btnText}}</view>
</view>
</view>
\ No newline at end of file
import fmtEvent from '../_util/fmtEvent';
Component({
props: {
type: 'number',
className: '',
focus: false,
placeholder: '',
value: ''
},
data: {
_focus: false
},
methods: {
onInput: function onInput(e) {
var event = fmtEvent(this.props, e);
if (this.props.onInput) {
this.props.onInput(event);
}
},
onConfirm: function onConfirm(e) {
var event = fmtEvent(this.props, e);
if (this.props.onConfirm) {
this.props.onConfirm(event);
}
},
onButtonClick: function onButtonClick() {
if (this.onButtonClick) {
this.props.onButtonClick();
}
},
onFocus: function onFocus(e) {
this.setData({
_focus: true
});
var event = fmtEvent(this.props, e);
if (this.props.onFocus) {
this.props.onFocus(event);
}
},
onBlur: function onBlur(e) {
this.setData({
_focus: false
});
var event = fmtEvent(this.props, e);
if (this.props.onBlur) {
this.props.onBlur(event);
}
},
onClearTap: function onClearTap() {
if (this.props.onClear) {
this.props.onClear('');
}
}
}
});
\ No newline at end of file
<view class="am-badge {{className}} {{!$slots.inner ? 'am-badge-not-a-wrapper' : ''}}">
<view
class="am-badge-text
{{ text.toString().length > 1 ? 'am-badge-double' : ''}}"
a:if="{{!dot}}">
<text>{{typeof text === 'number' && text > overflowCount ? overflowCount + '+' : text }}</text>
</view>
<view class="am-badge-text is-dot" a:if="{{dot}}"></view>
<slot name="inner" />
</view>
\ No newline at end of file
Component({
props: {
className: '',
overflowCount: 99,
text: '',
dot: false
}
});
\ No newline at end of file
.am-calendar {
background-color: #fff;
padding-top: 10px;
}
.am-calendar-months {
display: flex;
box-sizing: border-box;
padding: 0 26px;
align-items: center;
height: 28px;
}
.am-calendar-prev-month,
.am-calendar-next-month {
display: flex;
width: 40px;
font-size: 20px;
}
.am-calendar-prev-month {
justify-content: flex-start;
}
.am-calendar-next-month {
justify-content: flex-end;
}
.am-calendar-arrow {
height: 28px;
width: 12px;
background-image: url('https://gw.alipayobjects.com/zos/rmsportal/vYcMhkfyHRIOeVXWdcPe.png');
background-size: 8px 14px;
background-position: left center;
background-repeat: no-repeat;
}
.am-calendar-arrow.next {
transform: rotate(180deg);
}
.am-calendar-selected-month {
flex: 1;
text-align: center;
font-size: 20px;
font-weight: 600;
color: #333;
}
.am-calendar-days {
display: flex;
padding: 14px 10px 9px;
border-bottom: 1rpx solid #eee;
height: 20px;
line-height: 20px;
}
.am-calendar-day {
flex: 1;
text-align: center;
color: #333;
font-size: 14px;
}
.am-calendar-dates {
display: flex;
flex-direction: column;
}
.am-calendar-week {
margin-bottom: 17px;
display: flex;
flex-direction: row;
padding: 0 10px;
}
.am-calendar-week:first-child {
margin-top: 12px;
}
.am-calendar-date-wrap {
position: relative;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
height: 42px;
flex: 1;
}
.am-calendar-date {
text-align: center;
height: 23px;
line-height: 23px;
font-size: 19px;
font-family: 'Helvetica';
color: #333;
}
.am-calendar-tag {
position: absolute;
top: 21px;
width: 42px;
overflow: hidden;
text-overflow: hidden;
white-space: nowrap;
color: #f5a623;
font-size: 10px;
font-weight: 500;
}
.am-calendar-today {
color: #108ee9;
}
.am-calendar-gray {
color: #ccc;
}
.am-calendar-selected .am-calendar-block {
position: absolute;
left: calc(50% - 21px);
top: calc(50% - 10px);
transform: translateY(-50%);
width: 42px;
height: 42px;
background: #309EF2;
border-radius: 2px;
}
.am-calendar-middle.is-range .am-calendar-block {
position: absolute;
left: 0;
top: calc(50% - 10px);
transform: translateY(-50%);
height: 42px;
background: #309EF2;
width: 100%;
border-radius: 0;
}
.am-calendar-start.is-range .am-calendar-block {
position: absolute;
left: calc(50% - 21px);
top: calc(50% - 10px);
transform: translateY(-50%);
width: 100%;
height: 42px;
background: #309EF2;
border-radius: 2px 0 0 2px;
}
.am-calendar-end.is-range .am-calendar-block {
position: absolute;
left: 0;
top: calc(50% - 10px);
transform: translateY(-50%);
width: calc(50% + 21px);
height: 42px;
background: #309EF2;
border-radius: 0 2px 2px 0;
}
.am-calendar-selected .am-calendar-block.has-tag,
.am-calendar-start .am-calendar-block.has-tag,
.am-calendar-middle .am-calendar-block.has-tag,
.am-calendar-end .am-calendar-block.has-tag {
top: calc(50% - 7px);
}
.am-calendar-selected .am-calendar-date,
.am-calendar-start .am-calendar-date,
.am-calendar-middle .am-calendar-date,
.am-calendar-end .am-calendar-date {
position: relative;
color: #fff;
}
.am-calendar-selected .am-calendar-tag,
.am-calendar-start .am-calendar-tag,
.am-calendar-middle .am-calendar-tag,
.am-calendar-end .am-calendar-tag {
color: #fff;
}
.am-calendar-disable .am-calendar-date {
color: #999;
}
\ No newline at end of file
<view class="am-calendar {{className}}" a:if="{{dates.length > 0}}">
<view class="am-calendar-months">
<view class="am-calendar-prev-month" onTap="onPrevMonthTap">
<view class="am-calendar-arrow"></view>
</view>
<view class="am-calendar-selected-month">{{selectedYear}}年{{selectedMonth + 1}}月</view>
<view class="am-calendar-next-month" onTap="onNextMonthTap">
<view class="am-calendar-arrow next"></view>
</view>
</view>
<view class="am-calendar-days">
<block a:for="{{['日', '一', '二', '三', '四', '五', '六']}}">
<view class="am-calendar-day">{{item}}</view>
</block>
</view>
<view class="am-calendar-dates">
<block a:for="{{dates}}">
<view class="am-calendar-week">
<block a:for="{{item}}">
<view
class="am-calendar-date-wrap
{{ item.isSelected ? 'am-calendar-selected': '' }}
{{ item.isStart ? 'am-calendar-start': '' }}
{{ item.isMiddle ? 'am-calendar-middle': '' }}
{{ item.isEnd ? 'am-calendar-end': '' }}
{{ item.disable ? 'am-calendar-disable': '' }}
{{ type === 'range' ? 'is-range' : '' }}"
data-year="{{item.year}}"
data-month="{{item.month}}"
data-date="{{item.date}}"
onTap="onDateTap"
>
<view
class="am-calendar-block {{ blockType === 2 ? 'has-tag': '' }}"
></view>
<view
class="am-calendar-date {{ item.isGray ? 'am-calendar-gray': '' }} {{ item.isToday ? 'am-calendar-today': ''}}"
>{{item.date}}</view>
<view class="am-calendar-tag" style="{{
color: item.isSelected || item.isMiddle || item.isStart || item.isEnd ? '#fff' : (item.disable ? '#999' : item.color)
}}">{{item.disable ? 'disable' : item.tag}}</view>
</view>
</block>
</view>
</block>
</view>
</view>
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
/* eslint-disable complexity, no-param-reassign */
/* eslint max-depth: [2, 7] */
var leapYear = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var commonYear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var FIRST_MONTH = 0;
var LAST_MONTH = 11;
var DAYS_PER_ROW = 7;
var COLOR_MAP = {
1: '#f5a911',
2: '#e8541e',
3: '#07a89b',
4: '#108ee9',
5: 'rgba(51, 51, 51, 0.4)'
};
// 获取某月第某天是星期几
function getDay(month, year, index) {
return new Date(year, month, index).getDay();
}
// 获取某月有几天
function getMonthLength(month, year) {
if (year % 400 === 0 || year % 100 !== 0 && year % 4 === 0) {
return leapYear[month];
} else {
return commonYear[month];
}
}
// 数字补位 1 -> 01
function prefixNum(num) {
if (num < 10) {
return '0' + num;
} else {
return '' + num;
}
}
Component({
data: {
selectedYear: 0,
selectedMonth: 0,
currentDate: null,
dates: [],
blockType: 1 // 1.没有待办纯数字 2.有待办 用于区分不同类型日期块的样式。
},
props: {
className: '',
tagData: [],
type: 'single'
},
didMount: function didMount() {
this.tapTimes = 1;
var date = new Date();
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);
var year = date.getFullYear();
var month = date.getMonth();
this.setData({
selectedYear: year,
selectedMonth: month,
currentDate: date
});
this.refreshdates(month, year);
},
didUpdate: function didUpdate() {
var dates = this.data.dates;
var blockType = 1;
for (var i = 0; i < dates.length; i++) {
for (var j = 0; j < dates[i].length; j++) {
if (this.hasTag(dates[i][j])) {
blockType = 2;
}
}
}
this.setData({
dates: dates,
blockType: blockType
});
},
methods: {
onPrevMonthTap: function onPrevMonthTap() {
var _data = this.data,
selectedMonth = _data.selectedMonth,
selectedYear = _data.selectedYear;
var year = selectedYear;
var month = selectedMonth;
// 如果当前选中是一月份,前一月是去年的12月
if (selectedMonth === FIRST_MONTH) {
year = selectedYear - 1;
month = LAST_MONTH;
} else {
month = selectedMonth - 1;
}
if (this.props.onMonthChange) {
this.props.onMonthChange(month, selectedMonth);
}
this.setData({
selectedYear: year,
selectedMonth: month
});
this.refreshdates(month, year);
},
onNextMonthTap: function onNextMonthTap() {
var _data2 = this.data,
selectedMonth = _data2.selectedMonth,
selectedYear = _data2.selectedYear;
var year = selectedYear;
var month = selectedMonth;
// 如果当前选中是十二月份,下一月是去年的12月
if (selectedMonth === LAST_MONTH) {
year = selectedYear + 1;
month = FIRST_MONTH;
} else {
month = selectedMonth + 1;
}
if (this.props.onMonthChange) {
this.props.onMonthChange(month, selectedMonth);
}
this.setData({
selectedYear: year,
selectedMonth: month
});
this.refreshdates(month, year);
},
refreshdates: function refreshdates(month, year) {
this.tapTimes = 1;
var _data3 = this.data,
selectedYear = _data3.selectedYear,
selectedMonth = _data3.selectedMonth,
currentDate = _data3.currentDate;
var firstDay = getDay(month, year, 1);
var days = getMonthLength(month, year);
var datesArray = [];
var currentDateTimeStamp = +currentDate;
var num = 0;
for (var i = 0; i < firstDay; i++) {
num += 1;
// 如果当前选中的是一月份,前一个月是去年的12月
var _year = selectedYear;
var _month = selectedMonth;
if (selectedMonth === 0) {
_year = selectedYear - 1;
_month = LAST_MONTH;
} else {
_year = selectedYear;
_month = selectedMonth - 1;
}
var date = getMonthLength(_month, _year) - i;
datesArray.unshift({
year: _year,
month: _month,
date: date,
isToday: false,
isGray: true,
isSelected: false,
tag: ''
});
}
for (var _i = 0; _i < days; _i++) {
num += 1;
var _date = _i + 1;
var dateTimeStamp = +new Date(selectedYear, selectedMonth, _date);
datesArray.push({
year: selectedYear,
month: selectedMonth,
date: _date,
isToday: dateTimeStamp === currentDateTimeStamp,
isGray: false,
isSelected: dateTimeStamp === currentDateTimeStamp,
tag: ''
});
}
var nextDate = 0;
var daysPerPage = 35;
if (num > 35) {
daysPerPage = 42;
}
for (var _i2 = 0; _i2 < daysPerPage - days - firstDay; _i2++) {
// 如果是12月,下月是第二年的1月份
nextDate += 1;
var _year2 = selectedYear;
var _month2 = selectedMonth;
if (selectedMonth === LAST_MONTH) {
_year2 = selectedYear + 1;
_month2 = FIRST_MONTH;
} else {
_year2 = selectedYear;
_month2 = selectedMonth + 1;
}
datesArray.push({
year: _year2,
month: _month2,
date: nextDate,
isToday: false,
isGray: true,
isSelected: false,
tag: ''
});
}
var blockType = 1;
for (var _i3 = 0; _i3 < datesArray.length; _i3++) {
if (this.hasTag(datesArray[_i3])) {
blockType = 2;
}
}
var dates = [];
var weekDates = [];
for (var _i4 = 0; _i4 < datesArray.length; _i4++) {
weekDates.push(datesArray[_i4]);
if ((_i4 + 1) % DAYS_PER_ROW === 0) {
dates.push([].concat(_toConsumableArray(weekDates)));
weekDates = [];
}
}
this.setData({
dates: dates,
blockType: blockType
});
},
hasTag: function hasTag(dateObj) {
var tagData = this.props.tagData;
// 去重由调用者处理
if (tagData.length === 0) {
dateObj.tag = '';
return false;
}
return tagData.some(function (item) {
var dateArr = item.date.split('-');
var dateStr = [];
// 兼容ios下new Date('2018-1-1')格式返回invalid Date的问题
for (var i = 0; i < dateArr.length; i++) {
dateStr.push(dateArr[i].length > 1 ? dateArr[i] : '0' + dateArr[i]);
}
var date = new Date(dateStr.join('-'));
if (dateObj.year === date.getFullYear() && dateObj.month === date.getMonth() && dateObj.date === date.getDate()) {
dateObj.tag = item.tag;
dateObj.color = COLOR_MAP[item.tagColor];
dateObj.disable = item.disable;
return true;
} else {
dateObj.tag = '';
return false;
}
});
},
getDateGap: function getDateGap(day1, day2) {
var date1 = +new Date(day1.year, prefixNum(day1.month), prefixNum(day1.date));
var date2 = +new Date(day2.year, prefixNum(day2.month), prefixNum(day2.date));
return (date1 - date2) / (24 * 3600 * 1000);
},
makeDate: function makeDate(dateObj) {
return new Date(dateObj.year + '-' + prefixNum(dateObj.month + 1) + '-' + prefixNum(dateObj.date));
},
onDateTap: function onDateTap(event) {
var dates = this.data.dates;
var _event$currentTarget$ = event.currentTarget.dataset,
year = _event$currentTarget$.year,
month = _event$currentTarget$.month,
date = _event$currentTarget$.date;
var type = this.props.type;
if (type === 'range') {
if (this.tapTimes % 2 === 0) {
this.tapTimes += 1;
this.endDate = { year: year, month: month, date: date };
var dateGap = this.getDateGap(this.startDate, this.endDate);
if (dateGap > 0) {
var _ref = [this.endDate, this.startDate];
this.startDate = _ref[0];
this.endDate = _ref[1];
}
var hasDisable = false;
for (var i = 0; i < dates.length; i++) {
for (var j = 0; j < dates[i].length; j++) {
var dateObj = dates[i][j];
dateObj.isStart = false;
dateObj.isMiddle = false;
dateObj.isEnd = false;
var startDateGap = this.getDateGap(dateObj, this.startDate);
var endDateGap = this.getDateGap(dateObj, this.endDate);
if (dateObj.year === year && dateObj.month === month && dateObj.date === date && dateObj.disable) {
hasDisable = true;
}
if (startDateGap > 0 && endDateGap < 0) {
if (dateObj.disable) {
hasDisable = true;
}
if (dateGap !== 0) {
if (j === 0) {
dateObj.isStart = true;
} else if (j === 6) {
dateObj.isEnd = true;
} else {
dateObj.isMiddle = true;
}
} else {
dateObj.isSelected = true;
}
}
if (this.startDate.year === dateObj.year && this.startDate.month === dateObj.month && this.startDate.date === dateObj.date && dateGap !== 0) {
if (j === 6) {
dateObj.isSelected = true;
} else {
dateObj.isStart = true;
}
}
if (this.endDate.year === dateObj.year && this.endDate.month === dateObj.month && this.endDate.date === dateObj.date && dateGap !== 0) {
if (j === 0) {
dateObj.isSelected = true;
} else {
dateObj.isEnd = true;
}
}
}
}
if (hasDisable) {
this.props.onSelectHasDisableDate([this.makeDate(this.startDate), this.makeDate(this.endDate)]);
return;
}
if (this.props.onSelect) {
this.props.onSelect([this.makeDate(this.startDate), this.makeDate(this.endDate)]);
}
} else {
var isDisable = false;
for (var _i5 = 0; _i5 < dates.length; _i5++) {
for (var _j = 0; _j < dates[_i5].length; _j++) {
var _dateObj = dates[_i5][_j];
if (_dateObj.year === year && _dateObj.month === month && _dateObj.date === date) {
if (_dateObj.disable) {
console.log(1111);
isDisable = true;
_dateObj.isSelected = false;
} else {
_dateObj.isSelected = true;
}
_dateObj.isStart = false;
_dateObj.isMiddle = false;
_dateObj.isEnd = false;
} else {
_dateObj.isSelected = false;
_dateObj.isStart = false;
_dateObj.isMiddle = false;
_dateObj.isEnd = false;
}
}
}
if (!isDisable) {
this.tapTimes += 1;
}
this.startDate = { year: year, month: month, date: date };
}
this.setData({
dates: dates
});
} else {
var _isDisable = false;
for (var _i6 = 0; _i6 < dates.length; _i6++) {
for (var _j2 = 0; _j2 < dates[_i6].length; _j2++) {
var _dateObj2 = dates[_i6][_j2];
if (_dateObj2.year === year && _dateObj2.month === month && _dateObj2.date === date) {
_dateObj2.isSelected = true;
if (_dateObj2.disable) {
_isDisable = true;
}
} else {
_dateObj2.isSelected = false;
}
}
}
if (_isDisable) {
return;
}
this.setData({
dates: dates
});
if (this.props.onSelect) {
this.props.onSelect([this.makeDate({ year: year, month: month, date: date }), undefined]);
}
}
}
}
});
\ No newline at end of file
.am-card {
display: flex;
background-color: #fff;
border-radius: 4px;
margin: 6px 10px;
align-items: center;
min-height: 81px;
flex-direction: column;
padding: 0 16px;
}
.am-card.am-card-active {
background: #D9D9D9;
}
.am-card-body {
display: flex;
align-items: center;
width: 100%;
padding: 16px 0;
}
.am-card-content {
flex: 1;
min-width: 100px;
}
.am-card-title {
font-size: 18px;
line-height: 25px;
color: #333;
margin-bottom: 4px;
}
.am-card-subtitle {
font-size: 14px;
line-height: 20px;
color: #999;
margin-bottom: 2px;
}
.am-card-thumb {
margin-right: 10px;
width: 48px;
height: 48px;
border-radius: 2px;
}
.am-card-arrow {
width: 13px;
height: 13px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAaCAYAAAC+aNwHAAAAkElEQVR4AWJwL/BhAJRWByYAgkAUhmdpkDZxlJZqD9UpXCPyBUTEga9+4IkI94F1XaWUTdH+a67inPOhjP2OgD+IFoTcm1GY3khrbfGAGFG6kBmAkPCw1rq6iBYb0VkEzJD+hHQWAz6iJBtQdP8YiQEbUQNiAF0BP0T+Gnkj8VbmHxMq5gOFjzQ+VPlYxz+WEyrVzhdMcxADAAAAAElFTkSuQmCC") center center no-repeat;
background-size: 8px 13px;
}
.am-card-footer {
display: flex;
width: 100%;
align-items: center;
border-top: 1rpx solid #eee;
padding: 10px 0;
margin: -4px 0 0;
font-size: 14px;
line-height: 20px;
color: #999;
}
.am-card-footer image {
width: 14px;
height: 14px;
margin-right: 4px;
}
<view
class="am-card"
hover-class="am-card-active"
onTap="onCardClick"
>
<view class="am-card-body">
<image a:if="{{thumb}}" src="{{thumb}}" class="am-card-thumb" />
<view class="am-card-content">
<view a:if="{{!thumb || (thumb && footer)}}" class="am-card-title">{{title}}</view>
<view class="am-card-subtitle">{{subTitle}}</view>
<view a:if="{{!footer && thumb}}" class="am-card-title">{{title}}</view>
</view>
<view class="am-card-arrow" aria-hidden="true" />
</view>
<view a:if="{{footer}}" class="am-card-footer">
<image a:if="{{footerImg}}" src="{{footerImg}}" />
{{footer}}
</view>
</view>
Component({
props: {
title: '',
onClick: function onClick() {},
info: ''
},
methods: {
onCardClick: function onCardClick() {
var _props = this.props,
info = _props.info,
onClick = _props.onClick;
onClick({ info: info });
}
}
});
\ No newline at end of file
<web-view
a:if="{{appName && serviceName}}"
src="https://render.alipay.com/p/s/tiny-webar-online/www/faceDetect.html?facing={{facing}}&appName={{appName}}&serviceName={{serviceName}}&useLiveFaceCheck={{useLiveFaceCheck}}&resignSuccessBtnText={{btnText}}"
id="am-face-detection"
onMessage="onMessage"
enableWK="{{false}}"
/>
<view a:else style="color: red; text-align: center; font-size: 14px; padding: 10px">appName and serviceName is required</view>
\ No newline at end of file
Component({
props: {
facing: 'front',
appName: '',
serviceName: '',
useLiveFaceCheck: false,
minRotate: -1
},
didMount: function didMount() {
this.webViewContext = my.createWebViewContext('am-face-detection');
this.doFaceLeftResolve = null;
this.isDidFaceLeftResolve = false;
this.doFaceRightResolve = null;
this.isDidFaceRightResolve = false;
},
didUnMount: function didUnMount() {
this.webViewContext.postMessage({ action: 'releaseCamera' });
},
methods: {
doLeftFaceCheck: function doLeftFaceCheck() {
var _this = this;
return new Promise(function (resolve, reject) {
_this.isDidFaceLeftResolve = false;
_this.webViewContext.postMessage({ action: 'doFaceLeft', data: { minRotate: _this.props.minRotate } });
_this.doFaceLeftResolve = resolve;
setTimeout(function () {
if (!_this.isDidFaceLeftResolve) {
reject();
}
}, 30000);
});
},
doRightFaceCheck: function doRightFaceCheck() {
var _this2 = this;
return new Promise(function (resolve, reject) {
_this2.isDidFaceRightResolve = false;
_this2.webViewContext.postMessage({ action: 'doFaceRight', data: { minRotate: _this2.props.minRotate } });
_this2.doFaceRightResolve = resolve;
setTimeout(function () {
if (!_this2.isDidFaceRightResolve) {
reject();
}
}, 30000);
});
},
onMessage: function onMessage(e) {
var _this3 = this;
var _props = this.props,
onFaceStatusChange = _props.onFaceStatusChange,
onFail = _props.onFail,
onSuccessBtnTap = _props.onSuccessBtnTap;
var _e$detail = e.detail,
action = _e$detail.action,
data = _e$detail.data;
if (action === 'resignSuccessBtnClick') {
if (onSuccessBtnTap) {
onSuccessBtnTap();
}
}
if (action === 'faceRotated' && data.forward === 'left') {
this.isDidFaceLeftResolve = true;
this.doFaceLeftResolve(data.imageBase64);
return;
}
if (action === 'faceRotated' && data.forward === 'right') {
this.isDidFaceRightResolve = true;
this.doFaceRightResolve(data.imageBase64);
return;
}
if (action === 'captureImage') {
if (onFaceStatusChange) {
var promise = onFaceStatusChange({
imageBase64: data.imageBase64,
faceRect: data.faceRect
}, {
doLeftFaceCheck: this.doLeftFaceCheck.bind(this),
doRightFaceCheck: this.doRightFaceCheck.bind(this)
});
if (promise instanceof Promise) {
promise.then(function () {
_this3.webViewContext.postMessage({ action: 'requestSuccess' });
})['catch'](function () {
_this3.webViewContext.postMessage({ action: 'requestFailure' });
});
} else {
this.webViewContext.postMessage({ action: 'requestSuccess' });
}
}
} else {
/* eslint-disable */
if (onFail) {
onFail({ code: data.code, message: data.message });
}
}
}
}
});
\ No newline at end of file
.am-filter-item-wrap {
padding: 7px 6px;
min-width: 33.3%;
max-width: 180px;
overflow: hidden;
float: left;
display: list-item;
box-sizing: border-box;
}
.am-filter-item {
font-size: 14px;
height: 36px;
line-height: 36px;
background: #f5f5f5;
border-radius: 2px;
text-align: center;
padding: 0 20px;
box-sizing: border-box;
}
.am-filter-click {
color: #108EE9;
background: #e1f2fe url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAfCAYAAACLSL/LAAAEgElEQVRYhc2Xa0wcVRTH/2cXdi2F0pe29RWMNbHBpLWf2qQmWqma4Ftj1ZBqfcQYjUmlobESP2hDfTT9ILGaaEEECQ0qjy5uNgUDRGiatsG0JNpStaAujy6wsO+d2Xv8MDN3ZhekSHndZLObe+fO/Oac//nfs8TMWEyj3SvS3jnuLU5baBDrqL+kZO1p8JZf9sWeWjRgpWeit773o7fJH1HvAoBFAbbHM7rlSOeoK64kVhlzCwp2sl9QSYtvl+vXQBnANuvagoGd6FMdha7Bg+e90bdBABgAEUAABIMWoioru2PLi9xDNQPjyoMAAIOBWf6e94h90BFa/1Grzx2KifU6TfIFRADmGezFRv99VV3jjQnBmRKCoaXPGHrU5gWsY1DQfrfv9fbLkc/kpKErKxCg64zmHqz+kurc6/GV/u6Lv6pFyALALFOn0+mwcyz+I13R1cXNI3WjEXWb8dwkoUseAYD0b8xtKvf+FNxQemrsRFwVN0kRUWoQjAhKv5ArcwL2eK0/v/Fi+HtmdspUTZZCZg3IWgT6dbbJbjzT0dInbHcf9e1ruBh2MeBM0g+R/uSJn5wVaViXaTevI5o9sOrflIxdx4erfhlSPpQZMTJHeqpInySzJDetc+Dky2uxeqk96X6zksqDp6JrSzrGm4IxsTkZRE8RA6bOIFN5/21O1O28HllOm/kC+to1g73iCW/6+lzQk0iIG7SHUnLFGSPFKp7PXYLyx1bBYScMBBIYDCd0drr2qry3xv9MW2+sGiC7WVl6ytgSIcOf9AgWbsnEJ3nZICL0janI+2YIQyHTw2asMdefqv2Oo/4DbX8px0BklzoGmYZpzFm6BgLj8APZOLRjOYgIPcMK7ikfRM+IKkU/47Pyi24ls7gt+O1wWH1UEsgUWUAAXS/aT4edUPHICjybmwEA6B6KY0flFQyEdFOVkdbf7/84f9HP0Vs+PRPyxFTeICf1/SXbMlCQex0AoOJ8BO93BKEktLVl6UDd0yuxPccJADjtjeOh6isYiZhtjqlLbW7aYE82BLfW98TcDM5OhtJe08ZARX4mCnKXAADODigoaPRjLCrg3rkSG9ekAwDa+2J4uGYYgbgw9yfBaVqbFtjmqrHdXQPKV5jMkOVNARsYFfnLZOQiCmM0KnBjluZRnj+ieKJ2GBHVstey31rNU4Idu6CmF7YGDv0TSLx1VXrjKGFGRX6WjJwxfrgQwXN1o4iLVAhLNcr5Kezi47Ox7AOdoe8CMZF3VSgJBwgivNAUAAAJV9kdwW6XHwlhORKsp4O1N5uqKl9rjtxedi7crArOmTaU4fYMCEDCBeKMNzzjYCbT07QNgEhpX4nl8oRU5tWOb2/pUxrBvHTaUMZIqTCbDmn2WfiPFBpFIK2jX4rZ3SvozrKxN1t6480zggKSTZIIwnpoG3/NpBnD7DisZysRQLZWYmZ82a049rcHPveFxUszAkodk3apk3gWW6Jlin8ETtqY9m5nfM3h04G6qMJbZwUKmNgMSj6yCD2130c/QK1woAj7bv77X8e4TyVCc9zHAAAAAElFTkSuQmCC') right bottom no-repeat;
background-size: 17px 13px;
}
<view class="am-filter-item-wrap {{className}}" onTap="handleClick">
<view class="am-filter-item {{confirmStyle !=='' ? 'am-filter-click':''}}">{{value}}</view>
</view>
import lifecycle from '../mixins/lifecycle';
Component({
mixins: [lifecycle],
data: {
confirmStyle: ''
},
props: {
className: '',
item: '',
id: '',
value: '',
selected: false,
onChange: function onChange() {}
},
didMount: function didMount() {
var _data = this.data,
results = _data.results,
items = _data.items;
var _props = this.props,
selected = _props.selected,
id = _props.id,
value = _props.value;
if (selected) {
results.push({ id: id, value: value });
items.push(this);
this.setData({
confirmStyle: true
});
}
},
methods: {
handleClick: function handleClick() {
var _props2 = this.props,
id = _props2.id,
value = _props2.value,
onChange = _props2.onChange;
var confirmStyle = this.data.confirmStyle;
var _data2 = this.data,
results = _data2.results,
items = _data2.items,
commonProps = _data2.commonProps;
if (commonProps.max === 1) {
if (confirmStyle === '') {
items.forEach(function (element) {
element.setData({
confirmStyle: ''
});
});
results.splice(0, results.length);
confirmStyle = true;
results.push({ id: id, value: value });
items.push(this);
onChange(results);
}
this.setData({
confirmStyle: confirmStyle
});
return;
}
if (confirmStyle === '' && results.length < commonProps.max) {
confirmStyle = true;
results.push({ id: id, value: value });
items.push(this);
} else {
confirmStyle = '';
results.some(function (key, index) {
if (JSON.stringify(key) === JSON.stringify({ id: id, value: value })) {
results.splice(index, 1);
return true;
} else {
return false;
}
});
}
this.setData({
confirmStyle: confirmStyle
});
}
}
});
\ No newline at end of file
.am-filter-show {
height: 100vh;
display: block;
position: relative;
}
.am-filter-hide {
display: none;
}
.am-filter-mask, .am-filter-document {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.am-filter-mask {
background: rgba(0, 0, 0, 0.65);
}
.am-filter-content {
background: #ffffff;
display: flex;
flex-direction: column;
overflow-x: hidden;
overflow-y: scroll;
}
.am-filter-list {
flex: 1;
padding: 10px 5px 23px;
overflow-x: hidden;
min-height: 200px;
overflow-y: scroll;
max-height: 515px;
box-sizing: border-box;
}
.am-filter-btn {
width: 100%;
display: flex;
}
.am-filter-default, .am-filter-primary {
flex: 1;
height: 48px;
font-size: 18px;
box-sizing: border-box;
width: 50%;
border: 0;
border-radius: 0;
}
.am-filter-default {
border-top: 1px solid #eeeeee;
border-right: none;
}
<view class="am-filter-{{show ? 'show' : 'hide'}} {{className}}" disable-scroll="{{false}}">
<view class="am-filter-mask" />
<view class="am-filter-document">
<view class="am-filter-content" onChange="{{callBackFn}}">
<view class="am-filter-list">
<slot/>
</view>
<view class="am-filter-btn" a:if="{{max !== 1}}">
<button type="default" class="am-filter-default" onTap="resetFn">重置</button>
<button type="primary" class="am-filter-primary" onTap="confirmFn">确定</button>
</view>
</view>
</view>
</view>
import lifecycle from './mixins/lifecycle';
Component({
mixins: [lifecycle],
data: {
maxHeight: 0
},
props: {
className: '',
onChange: function onChange() {},
max: 10000
},
didMount: function didMount() {
var commonProps = this.data.commonProps;
var max = this.props.max;
commonProps.max = max;
},
methods: {
resetFn: function resetFn() {
var _data = this.data,
items = _data.items,
results = _data.results;
items.forEach(function (element) {
element.setData({
confirmStyle: ''
});
});
results.splice(0, results.length);
},
confirmFn: function confirmFn() {
var onChange = this.props.onChange;
var results = this.data.results;
onChange(results);
}
}
});
\ No newline at end of file
export default {
data: {
results: [],
items: [],
commonProps: {
max: 10000
}
},
didUnmount: function didUnmount() {
var _data = this.data,
items = _data.items,
results = _data.results;
results.splice(0, results.length);
items.splice(0, items.length);
}
};
\ No newline at end of file
.am-footer-links {
display: flex;
justify-content: center;
}
.am-footer-link {
height: 17px;
line-height: 17px;
color: #108ee9;
font-size: 12px;
}
.am-footer-link::after {
content: '|';
padding: 0 5px;
height: 17px;
color: #ccc;
}
.am-footer-link:last-child::after {
display: none;
}
.am-footer-copyright {
margin-top: 3px;
height: 17px;
line-height: 17px;
color: #ccc;
font-size: 14px;
text-align: center;
}
\ No newline at end of file
<view class="am-footer {{className}}">
<view class="am-footer-links" a:if="{{links && links.length > 0}}">
<block a:for="{{links}}">
<navigator class="am-footer-link" url="{{item.url}}">{{item.text}}</navigator>
</block>
</view>
<view class="am-footer-copyright" a:if="{{copyright}}">{{copyright}}</view>
</view>
\ No newline at end of file
Component({
props: {
className: ''
}
});
\ No newline at end of file
.am-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
background-color: white;
}
.am-grid-4 {
padding-top: 7px;
padding-bottom: 7px;
}
.am-grid-5 {
padding-top: 6px;
padding-bottom: 7px;
}
.am-grid-item {
text-align: center;
position: relative;
}
.am-grid-3 .am-grid-border {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
border-bottom: 1rpx solid #eee;
border-right: 1rpx solid #eee;
box-sizing: border-box;
}
.am-grid-3 .am-grid-right {
border-right: none;
}
.am-grid-3 .am-grid-bottom {
border-bottom: none;
}
.am-grid-3 .am-grid-top {
height: calc(100% - 15px);
}
.am-grid-item-wrapper {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.am-grid-2 .am-grid-item-wrapper {
flex-direction: row;
justify-content: flex-start;
}
.am-grid-icon-container {
display: flex;
justify-content: center;
align-items: center;
}
.am-grid-icon {
flex: 1;
width: 36px;
height: 36px;
}
.am-grid-text-wrapper {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.am-grid-3 .am-grid-text-wrapper {
align-items: center;
}
.am-grid-3 .am-grid-text {
height: 20px;
line-height: 20px;
}
.am-grid-3 .am-grid-desc {
height: 17px;
line-height: 17px;
}
.am-grid-text {
color: #333;
font-size: 14px;
line-height: 1;
margin-top: 14px;
}
.am-grid-desc {
color: #999;
font-size: 12px;
}
.am-grid-2 .am-grid-item.has-desc {
padding-top: 70px;
}
.am-grid-3 .am-grid-item {
padding-top: 125px;
}
.am-grid-3.am-grid-no-line {
padding: 8px 16px 0 16px;
}
.am-grid-no-line .am-grid-item {
padding-top: 110px;
}
.am-grid-2 .am-grid-item {
padding-top: 64px;
}
.am-grid-4 .am-grid-item {
padding-top: 68px;
}
.am-grid-4.circular .am-grid-item {
padding-top: 82px;
}
.am-grid-3 {
padding: 0 16px;
}
.am-grid-3 .am-grid-text {
margin-top: 12px;
}
.am-grid-no-line .am-grid-border {
border-right: none;
border-bottom: none;
}
.am-grid-4.circular {
padding-top: 3px;
}
.am-grid-4.circular .am-grid-icon-container {
margin-top: 13px;
padding: 8px;
border-radius: 50%;
background-color: #D8D8D8;
}
.am-grid-2 .am-grid-icon-container {
margin-left: 16px;
}
.am-grid-2 .am-grid-icon {
width: 28px;
height: 28px;
}
.am-grid-4 .am-grid-icon-container {
margin-top: 7px;
}
.am-grid-4 .am-grid-icon {
height: 28px;
width: 28px;
}
.am-grid-4.circular .am-grid-icon {
width: 26px;
height: 26px;
flex: 1;
}
.am-grid-4.circular .am-grid-text {
height: 16px;
line-height: 16px;
}
.am-grid-5 .am-grid-item {
padding-top: 75px;
}
.am-grid-5 .am-grid-icon {
border-radius: 50%;
width: 43px;
height: 43px;
}
.am-grid-2 .am-grid-text {
margin-top: 0;
margin-left: 12px;
height: 24px;
line-height: 24px;
font-size: 17px;
}
.am-grid-2 .am-grid-desc {
margin-left: 12px;
height: 16px;
line-height: 16px;
}
.am-grid-4 .am-grid-text {
font-size: 13px;
height: 13px;
line-height: 13px;
margin-top: 7px;
}
.am-grid-5 .am-grid-text {
font-size: 12px;
margin-top: 7px;
}
<view class="am-grid am-grid-{{columnNum}} {{circular && columnNum === 4 ? 'circular' : ''}} {{hasLine ? '' : 'am-grid-no-line'}}" >
<block a:for="{{list}}">
<view
style="width:{{100/(columnNum)}}%;"
class="am-grid-item {{list.some(item => item.desc && item.desc) ? 'has-desc' : ''}}"
onTap="onGridItemClick"
data-index={{index}}
key="grid-item-{{index}}"
>
<view class="am-grid-border {{index < 2 ? 'am-grid-top' : ''}} {{index >= bottomIndex ? 'am-grid-bottom' : ''}} {{(index + 1) % columnNum === 0 ? 'am-grid-right' : ''}}" />
<view class="am-grid-item-wrapper">
<view class="am-grid-icon-container">
<image src="{{item.icon}}" class="am-grid-icon" mode="aspectFit" />
</view>
<view class="am-grid-text-wrapper">
<text class="am-grid-text">{{item.text}}</text>
<text class="am-grid-desc" a:if="{{(columnNum === 2 || columnNum === 3) && item.desc && item.desc !== ''}}">{{item.desc}}</text>
</view>
</view>
</view>
</block>
</view>
\ No newline at end of file
Component({
data: {
bottomIndex: 0
},
props: {
columnNum: 3,
circular: false,
list: [],
onGridItemClick: function onGridItemClick() {},
hasLine: true
},
didMount: function didMount() {
var _props = this.props,
list = _props.list,
columnNum = _props.columnNum;
var rows = list.length / columnNum;
this.setData({
bottomIndex: Math.floor(rows) === rows ? (rows - 1) * columnNum : Math.floor(rows) * columnNum
});
},
methods: {
onGridItemClick: function onGridItemClick(e) {
this.props.onGridItemClick({
detail: {
index: e.target.dataset.index
}
});
}
}
});
\ No newline at end of file
.am-input-item {
display: flex;
align-items: center;
background: #fff;
padding-left: 15px;
}
.am-input-item .a-input-content {
padding-left: 2px;
}
.am-input-line {
position: relative;
flex: 1;
display: flex;
align-items: center;
padding-right: 15px;
min-height: 47px;
overflow: hidden;
}
.am-input-label {
min-width: 80px;
margin-right: 2px;
color: #333;
}
.am-input-content {
flex: 1;
display: flex;
height: 33px;
color: #000;
text-align: left;
}
.am-input-content .a-input-wrap {
flex: 1;
}
.am-input-clear {
display: flex;
height: 33px;
width: 33px;
justify-content: center;
align-items: center;
}
.am-input-clear.show {
visibility: visible;
}
.am-input-clear.hidden {
visibility: hidden;
pointer-events: none;
}
.am-input-line-bottom::after {
content: '';
display: block;
position: absolute;
width: 100%;
height: 1px;
transform: scaleY(0.5);
left: 0;
bottom: 0;
right: auto;
top: auto;
background-color: #eee;
}
/* 最后一行 */
.am-input-item.last .am-input-line-bottom::after {
display: none;
}
\ No newline at end of file
<view
class="am-input-item {{last ? 'last': ''}} {{className}}"
>
<view class="am-input-line">
<view a:if="{{$slots.$default}}" class="am-input-label {{labelCls}}">
<slot />
</view>
<input
enableNative="{{enableNative}}"
sync-input="{{syncInput}}"
class="am-input-content {{inputCls}}"
value="{{value}}"
name="{{name}}"
type="{{type}}"
password="{{password}}"
placeholder="{{placeholder}}"
placeholderClass="{{placeholderClass}}"
placeholderStyle="{{placeholderStyle}}"
disabled="{{disabled}}"
maxlength="{{maxlength}}"
focus="{{focus}}"
onInput="onInput"
onConfirm="onConfirm"
onFocus="onFocus"
onBlur="onBlur"
/>
<view class="am-input-clear {{clear && value.length > 0 && !disabled && _focus ? 'show' : 'hidden'}}" onTap="onClear">
<icon size="18" type="clear" />
</view>
<slot name="extra" />
<view class="am-input-line-bottom" />
</view>
</view>
import fmtEvent from '../_util/fmtEvent';
Component({
props: {
className: '',
labelCls: '',
inputCls: '',
last: false,
value: '',
name: '',
type: 'text',
password: false,
placeholder: '',
placeholderClass: '',
placeholderStyle: '',
disabled: false,
maxlength: 140,
focus: false,
clear: false, // 是否带清除功能
syncInput: false,
enableNative: false, // 兼容安卓input的输入bug
onInput: function onInput() {},
onConfirm: function onConfirm() {},
onFocus: function onFocus() {},
onBlur: function onBlur() {},
onClear: function onClear() {}
},
data: {
_focus: false
},
methods: {
onBlur: function onBlur(e) {
this.setData({
_focus: false
});
var event = fmtEvent(this.props, e);
this.props.onBlur(event);
},
onConfirm: function onConfirm(e) {
var event = fmtEvent(this.props, e);
this.props.onConfirm(event);
},
onFocus: function onFocus(e) {
this.setData({
_focus: true
});
var event = fmtEvent(this.props, e);
this.props.onFocus(event);
},
onInput: function onInput(e) {
var event = fmtEvent(this.props, e);
this.props.onInput(event);
},
onClear: function onClear(e) {
var event = fmtEvent(this.props, e);
this.props.onClear(event);
}
}
});
\ No newline at end of file
.am-list-header,
.am-list-footer {
font-size: 14px;
color: #888;
}
.am-list-header {
padding: 16px 16px 8px;
}
.am-list-body {
position: relative;
}
.am-list-body::before {
position: absolute;
content: '';
top: 0;
left: 0;
right: 0;
height: 1px;
transform: scaleY(0.5);
background-color: #eee;
}
.am-list-body::after {
position: absolute;
content: '';
bottom: 0;
left: 0;
right: 0;
height: 1px;
transform: scaleY(0.5);
background-color: #eee;
}
.am-list-footer {
padding: 8px 16px 16px 16px;
}
<view class="am-list {{className}}">
<view class="am-list-header" a:if="{{$slots.header}}">
<slot name="header" />
</view>
<view class="am-list-body">
<slot />
</view>
<view class="am-list-footer" a:if="{{$slots.footer}}">
<slot name="footer" />
</view>
</view>
Component({
props: {
className: ''
}
});
\ No newline at end of file
.am-list-item {
display: flex;
align-items: center;
background: #fff;
padding-left: 16px;
font-size: 15px;
line-height: 1.4;
color: #333;
}
/* hover 样式 */
.am-list-item-hover {
background-color: #f8f8f8;
}
.am-list-prefix {
margin-right: 16px;
}
.am-list-thumb {
width: 30px;
height: 30px;
margin-right: 16px;
}
.am-list-line {
position: relative;
flex: 1;
display: flex;
align-items: center;
align-self: stretch;
padding-right: 15px;
min-height: 52px;
overflow: hidden;
}
.am-list-content,
.am-list-extra {
line-height: 1.5;
width: auto;
padding-top: 7px;
padding-bottom: 7px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.am-list-content {
flex: 1;
color: #000;
font-size: 17px;
text-align: left;
}
.am-list-extra {
flex-basis: 36%;
color: #888;
font-size: 16px;
text-align: right;
}
.am-list-brief {
color: #888;
font-size: 14px;
}
.am-list-wrap .am-list-content,
.am-list-wrap .am-list-extra {
white-space: normal;
}
.am-list-arrow {
display: block;
width: 15px;
height: 15px;
margin-left: 8px;
background-image: url('https://gw.alipayobjects.com/zos/rmsportal/nGMpTwTjtKMbOeeQIucS.png');
background-size: contain;
background-repeat: no-repeat;
background-position: 50% 50%;
}
.am-list-arrow-empty {
visibility: hidden;
}
.am-list-line-bottom::after {
content: '';
display: block;
position: absolute;
width: 100%;
height: 1px;
background: #eee;
transform: scaleY(0.5);
left: 0;
bottom: 0;
right: auto;
top: auto;
}
/* 子元素垂直对齐 */
.am-list-top .am-list-line {
align-items: flex-start;
}
.am-list-middle .am-list-line {
align-items: center;
}
.am-list-bottom .am-list-line {
align-items: flex-end;
}
/* 多行 */
.am-list-multiple .am-list-line {
padding: 6px 15px 6px 0;
}
.am-list-multiple .am-list-thumb {
width: 36px;
height: 36px;
}
/* 最后一行 */
.am-list-item.last .am-list-line-bottom::after {
display: none;
}
<view
class="am-list-item am-list-{{align}} {{multipleLine ? 'am-list-multiple' : ''}} {{last ? 'last': ''}} {{className}}"
hover-class="{{disabled ? '' : 'am-list-item-hover'}}"
onTap="onItemTap"
data-index="{{index}}"
>
<view a:if={{$slots.prefix}} class="am-list-prefix">
<slot name="prefix">
</view>
<image a:if={{thumb}} class="am-list-thumb" src="{{thumb}}" mode="scaleToFill" />
<view class="am-list-line {{wrap ? 'am-list-wrap' : ''}}">
<view class="am-list-content">
<slot />
</view>
<view a:if={{$slots.extra}} class="am-list-extra" >
<slot name="extra" />
</view>
<view a:if={{arrow}} class="am-list-arrow" />
<view class="am-list-line-bottom" />
</view>
</view>
Component({
props: {
className: '',
align: false,
disabled: false,
multipleLine: false,
wrap: false
},
didMount: function didMount() {
this.dataset = {};
for (var key in this.props) {
if (/data-/gi.test(key)) {
this.dataset[key.replace(/data-/gi, '')] = this.props[key];
}
}
},
methods: {
onItemTap: function onItemTap(ev) {
var _props = this.props,
onClick = _props.onClick,
disabled = _props.disabled;
if (onClick && !disabled) {
onClick({
index: ev.target.dataset.index,
target: { dataset: this.dataset }
});
}
}
}
});
\ No newline at end of file
.am-message {
background-color: #fff;
border-bottom: 1rpx solid #eeeeee;
margin-bottom: 30px;
padding: 30px 15px;
text-align: center;
height: 199px;
box-sizing: border-box;
}
.am-message .am-icon {
display: block;
}
.am-message-main {
font-size: 20px;
margin: 16px 0 9px;
line-height: 28px;
}
.am-message-sub {
padding: 0 30px;
font-size: 14px;
line-height: 19px;
margin-top: 6px;
color: #999;
}
.am-button-wrap{
padding: 0 15px;
}
.am-button-wrap .a-button {
margin-bottom: 15px;
}
.am-button-wrap .a-button:last-child {
margin-bottom: 0;
}
<view class="am-message {{className}}">
<icon class="am-icon" size="64" type="{{type === 'fail' ? 'cancel' : type}}" />
<view class="am-message-main">
{{title}}
</view>
<view a:if="{{subTitle}}" class="am-message-sub">
{{subTitle}}
</view>
</view>
<view class="am-button-wrap" a:if="{{mainButton || subButton}}">
<button
a:if="{{mainButton}}"
type="primary"
disabled="{{mainButton.disabled}}"
onTap="tapMain"
>
{{mainButton.buttonText}}
</button>
<button
a:if="{{subButton}}"
type="default"
disabled="{{subButton.disabled}}"
onTap="tapSub"
>
{{subButton.buttonText}}
</button>
</view>
Component({
props: {
className: "",
type: "success",
title: "",
onTapMain: function onTapMain() {},
onTapSub: function onTapSub() {}
},
methods: {
tapMain: function tapMain() {
this.props.onTapMain();
},
tapSub: function tapSub() {
this.props.onTapSub();
}
}
});
\ No newline at end of file
.am-modal-show {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.am-modal-hide {
display: none;
}
.am-modal-mask,
.am-modal-document {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.am-modal-mask {
background-color: rgba(0, 0, 0, 0.75);
}
.am-modal-document {
display: flex;
align-items: center;
justify-content: center;
}
.am-modal {
background-color: #fff;
border-radius: 2px;
width: 270px;
position: relative;
}
.am-modal-image {
display: flex;
justify-content: center;
}
.am-modal-image-md,
.am-modal-image-sm {
margin-top: 24px;
}
.am-modal-image-lg image {
width: 270px;
height: 156px;
}
.am-modal-image-md image {
width: 134px;
height: 134px;
}
.am-modal-image-sm image {
width: 65px;
height: 65px;
}
.am-modal-header {
font-size: 18px;
line-height: 21px;
text-align: center;
color: #333;
font-weight: 600;
padding-top: 22px;
}
.am-modal-body {
margin-top: 8px;
overflow: hidden;
max-width: 270px;
padding: 0 16px;
line-height: 20px;
text-align: center;
color: #333;
font-size: 14px;
}
.am-modal-footer {
margin-top: 12px;
height: 50px;
line-height: 50px;
border-top: 1rpx solid #ddd;
font-size: 18px;
color: #108ee9;
text-align: center;
}
.am-modal-close {
position: absolute;
display: block;
right: 0;
top: 0;
height: 48px;
width: 48px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAANlBMVEVMaXGIiIiJiYmJiYn///+IiIiIiIiRkZGJiYmJiYmIiIiZmZmIiIiIiIiLi4uJiYmIiIiIiIif033nAAAAEXRSTlMA3vWjAZv1FdRBcAq0vhZmK7msGmgAAABnSURBVHhe7dEpFoAwEATRTliysIS5/2VReS16xiEp+2XhuQqC2nngshp4262j1Omq2wq6q3Rf6arionRVdaq4qjpVneo71fOUqerJbAkVLRv/eBcW/nEvfPD3/4szPHhXGzj6VPWBF66vCbNK4YfYAAAAAElFTkSuQmCC") center no-repeat;
background-size: 16px 16px;
}
.am-close-white {
background: url("https://gw.alipayobjects.com/zos/rmsportal/fdmdsySxNBrpcVBVGEUM.png") center no-repeat;;
background-size: 16px 16px;
}
.am-modal-close-active,
.am-modal-footer-active {
background-color: rgba(37,39,40,.05);
}
.am-modal-document-advice .am-modal {
padding-top: 0;
width: auto;
}
.am-modal-document-advice .am-modal-body {
padding: 0;
max-width: 319px;
}
.am-modal-document-advice .am-modal-close {
top: -50px;
height: 27px;
width: 27px;
background-size: 27px 27px;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAAEMElEQVR4AWKgJvj//z8roFl7cJJdiaM4/mbtvbZt27Zt27ZtrvLfvu8iVWe77tSmJ/lNMlWfQtLICXo6wARswRk8wUf8RAt+4TOe4wJ2YAaqkujfIsx8XEMTggK04j5WojbtQBXYhF8I8viCh7iJy7iBB3iPtjx1mnEQdcUOVIKl+IzA8QEHMBFVEY70SGzHcwSO39iCimKEGoeXCMRP7MDwmG33wzp8gHvU51uGWoYW55TZi5qE+ynrCvjDCbgXJUmfegedTs6gj/HZUY3dzs68huqkGr8pDbdgaZGv6YnO0XuFfnGPlIb6hnEpjcD98Uq25W3BfwvO6fcKfVP+e6lydvQtlPgPFHqkNFS64Sqdv4ZDvkN6i1xT4zI20+mDbxJuWdTr6oVU0oEiS+HGys7/hbqeKizRIV3XZTDcRtnWAz1NcT7Ln2+fjAcrx0e5ZPrlK7gJQZd9KW1sNeajX8Tyi2Sbz+ZL/1PmfrUeM/zT+IaxCRyBw/iLu1HCUSbnjJID3QLzZOUOj43Zh78I8BoT4oaSie+6iHXnyrbvcldek5XDPTaoN24h0HAxQ33DeuSi/rfJDe5Hdzb9110RP5x9KGnnqvQ/JFw4QRYelPLxwxmHkraWSt9rwoWbZeFEKZ9sOINQ0l699Hs+XHhaFnbd6xiEMwilP7nzfh4ueBSORFIubrjbbjiLUPqTmf9f5DTpIy1ocOQmGoTSPo93O/Pk7vS2FjQI9xF/DEKF/e2Xvnq3L2hGgCta0CKcQSjta0e3GYhMpW4aTVT3oFk6fYnRBn3tlT76/Ccz5IcGofSa+ukOKAn3d1Tar2lf8Mxj1hFnmrTJf4bi1ecVuYUpaV9wXjqrMAq1Hjn0tgrX3lbYZrhgu3Q02ipUjOlX1IlwCwJcDhdOk052WoayCkfd2dLWpnBhlaR9aR3KIpwzLRylK+7Jiv5moTymXx79l8iI+wMlunK5NL7eIpTVkaPsRKl72F1ZjWaZ+pRHbHQWHvmGihDuIaYVcJM56l8FDkiBDZ5Pjr9hFXIJ3BX8wCaURKgzXrb5dr5Ctfjl86TKYFrUiIEeZ8wjCTZCVhk+W7TfCXPdZ4pRnwa3YnJGQ/XGV30K7LsnfmJAxkJVyPy23Q6fyrud4bc6I6FyuOi8ky7x/dPTYfQ2qjIQap/zlrWq0FejL6WhF+iX4umnR+oH+sdpsC9eS4PfMT6FN5jPnVBjk3q1c8P5JGITyos0pH/z/xTC75o7gEB8wmKUGH3b8djp76rFda6vcn86Hb7AfFTFbLsUk3AdgWjBDpRYnx612BdOmkUzrmEZGjwGqLk4oztMnEW/ND5LOON+dyg+4hZO4AB2YR+O4SreojVP3dsYkfaf5gDswAcEMXzHYYzK4hxuEFbhLJ7KI21XM17hEjZilM01ZP8NVCP6ozeqkbPu93+pG3nJRlqdHgAAAABJRU5ErkJggg==");
}
\ No newline at end of file
<view class="am-modal-{{show ? 'show' : 'hide'}}" disable-scroll="{{true}}">
<view class="am-modal-mask" />
<view class="am-modal-document {{advice === true ? 'am-modal-document-advice' : '' }}">
<view class="am-modal {{className}}">
<view a:if="{{topImage}}" class="am-modal-image am-modal-image-{{topImageSize}}">
<image src="{{topImage}}" />
</view>
<view class="am-modal-header" a:if="{{$slots.header}}">
<slot name="header" />
</view>
<view class="am-modal-body">
<slot />
</view>
<view class="am-modal-footer" hover-class="am-modal-footer-active" a:if="{{$slots.footer}}" onTap="onModalClick">
<slot name="footer" />
</view>
<view class="am-modal-close {{closeType === '1' ? 'am-close-white' : ''}}" hover-class="am-modal-close-active" a:if="{{showClose}}" onTap="onModalClose" />
</view>
</view>
</view>
Component({
props: {
className: '',
topImageSize: 'md',
showClose: true,
closeType: '0'
},
methods: {
onModalClick: function onModalClick() {
var onModalClick = this.props.onModalClick;
if (onModalClick) {
onModalClick();
}
},
onModalClose: function onModalClose() {
var onModalClose = this.props.onModalClose;
if (onModalClose) {
onModalClose();
}
}
}
});
\ No newline at end of file
.am-notice {
width: 100%;
height: 36px;
box-sizing: border-box;
line-height: 36px;
display: flex;
background-color: #fefceb;
overflow: hidden;
font-size: 13px;
color: #f76a24;
}
.am-notice-thumb {
padding-left: 16px;
width: 19px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAYFBMVEVMaXH4biD/dSn3biD2cib/dDj3biD3biD4biD4byP/lUD3biD4biH4biH3biD5byH4biD4cCH3biH3bST2byT4biH3biD3cSP3biD0bSH6cCL4biH3biL3biH4biL4biGKhhI5AAAAIHRSTlMA4A3wGAj3+rRQBJOsn+o/zUtcKBzH1TKILzZvU796aUQsa54AAAEeSURBVHgBfdNVlt0wFETRElhlZvaD+c+yta7SSYznewstY99aqwkPNYbMcd/XUTHGbTOZvTzQlcZFaUF+kHhQ0OUVjumYroWAZCQZ99hla5YVAgC6zLGcEEqtb1JUC/4CTwaqLpyspFT3+B8gyjla+EpKucYeIBrClZC7MwmYXimAznEVEJ3AyLcGULC4AUkpsy800TVAZ9gAUFxvAGaZPWZ7ByrWsontDjQcnkHG7HGJJFxByeUafCgTVCzTazAwSwHkwq6A7cJJXC/rOOdYZqePZRVn+FpHqbZ7YEfWYW7d972tjg+mUVS7R9fXNM0v0O2bHOz50X4D+DrSbOnp2WfkLGBm/bG4aCPzVpZ4+DWNBw9NiizwVF/kPXb9AFr1D7ArYO8yAAAAAElFTkSuQmCC") center no-repeat;
background-size: 18px auto;
background-position: center right;
}
.am-notice-content {
flex: 1;
width: 100%;
margin-left: 9px;
margin-right: 10px;
overflow: hidden;
}
.am-notice-marquee {
position: relative;
height: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
.am-notice-operation {
padding-right: 16px;
}
.am-notice-link {
display: block;
height: 100%;
color: #f85800;
}
.am-notice-link::after {
content: "";
display: inline-block;
width: 6px;
height: 6px;
border: 1px solid #f76a24;
border-top: 0 none;
border-left: 0 none;
margin-left: 6px;
margin-right: 2px;
margin-bottom: 1px;
transform: rotate(315deg)
}
.am-notice-closable {
width: 10px;
height: 100%;
background-image: url('https://gw.alipayobjects.com/zos/rmsportal/mLiemrUlPGVwIGXQdWDx.png');
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.am-notice-operation-text {
display: block;
height: 100%;
color: #e14f00
;
}
\ No newline at end of file
<view class="am-notice {{className}}" a:if="{{show}}" onTap="onNoticeTap">
<view class="am-notice-thumb"></view>
<view class="am-notice-content am-notice-content-{{$id}}">
<view class="am-notice-marquee am-notice-marquee-{{$id}}" style="right: {{animatedWidth}}px; display: {{enableMarquee ? 'inline-block' : 'block'}}">
<slot></slot>
</view>
</view>
<view class="am-notice-operation" onTap="onOperationTap">
<view a:if="{{action !== ''}}" class="am-notice-operation-text {{actionCls}}" >{{action}}</view>
<view a:else class="am-notice-{{mode}}"></view>
</view>
</view>
\ No newline at end of file
Component({
props: {
className: '',
mode: '', // closable,link
action: '', // 文本按钮
show: true, // 是否显示
enableMarquee: false, // 是否开启marquee
onClick: function onClick() {},
marqueeProps: {
loop: false,
leading: 500,
trailing: 800,
fps: 40
}
},
data: {
animatedWidth: 0,
overflowWidth: 0
},
didMount: function didMount() {
if (this.props.enableMarquee) {
this._measureText();
this._startAnimation();
}
},
didUpdate: function didUpdate() {
this._measureText();
if (this.props.enableMarquee && !this._marqueeTimer) {
this._measureText();
this._startAnimation();
}
},
didUnmount: function didUnmount() {
if (this._marqueeTimer) {
clearTimeout(this._marqueeTimer);
this._marqueeTimer = null;
}
},
methods: {
_measureText: function _measureText() {
var _this = this;
// 计算文本所占据的宽度,计算需要滚动的宽度
my.createSelectorQuery().select('.am-notice-marquee-' + this.$id).boundingClientRect().select('.am-notice-content-' + this.$id).boundingClientRect().exec(function (ret) {
var overflowWidth = ret && ret[0] && ret[1] && ret[0].width - ret[1].width || 0;
_this.setData({
overflowWidth: overflowWidth
});
});
},
_startAnimation: function _startAnimation() {
var _this2 = this;
if (this._marqueeTimer) {
clearTimeout(this._marqueeTimer);
}
var _props$marqueeProps = this.props.marqueeProps,
loop = _props$marqueeProps.loop,
fps = _props$marqueeProps.fps,
trailing = _props$marqueeProps.trailing,
leading = _props$marqueeProps.leading;
var TIMEOUT = 1 / fps * 1000;
var isLeading = this.data.animatedWidth === 0;
var timeout = isLeading ? leading : TIMEOUT;
var animate = function animate() {
var overflowWidth = _this2.data.overflowWidth;
var animatedWidth = _this2.data.animatedWidth + 1;
var isRoundOver = animatedWidth > overflowWidth;
if (isRoundOver) {
if (loop) {
animatedWidth = 0;
} else {
return;
}
}
if (isRoundOver && trailing) {
_this2._marqueeTimer = setTimeout(function () {
_this2.setData({
animatedWidth: animatedWidth
});
_this2._marqueeTimer = setTimeout(animate, TIMEOUT);
}, trailing);
} else {
_this2.setData({
animatedWidth: animatedWidth
});
_this2._marqueeTimer = setTimeout(animate, TIMEOUT);
}
};
if (this.data.overflowWidth !== 0) {
this._marqueeTimer = setTimeout(animate, timeout);
}
},
onNoticeTap: function onNoticeTap() {
var _props = this.props,
mode = _props.mode,
onClick = _props.onClick;
if (mode === 'link' && typeof onClick === 'function') {
onClick();
}
},
onOperationTap: function onOperationTap() {
var _props2 = this.props,
mode = _props2.mode,
onClick = _props2.onClick;
if (mode === 'closable' && typeof onClick === 'function') {
onClick();
}
}
}
});
\ No newline at end of file
.am-page-result {
background: #fff;
height: 100vh;
overflow: hidden;
}
.am-page-result-pic {
width: 220px;
height: 220px;
margin: 22px auto 0;
background-position: center bottom;
background-repeat: no-repeat;
background-size: contain;
}
.page-network {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-network.png");
}
.page-error {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-busy.png");
}
.page-busy {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-excption.png");
}
.page-empty {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-not-found.png");
}
.page-logoff {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-logout.png");
}
.am-page-result-title {
margin: 25px auto 0;
text-align: center;
font-size: 20px;
color: #333;
}
.am-page-result-brief {
margin: 16px auto;
font-size: 14px;
color: #888;
max-width: 266px;
text-align: center;
}
.am-local-page {
height: 100%;
}
.am-local-page .am-page-result-pic {
width: 90px;
height: 90px;
margin: 24px auto 0;
background-size: contain;
}
.am-local-page .am-page-result-brief {
margin-bottom: 30px;
font-size: 14px;
color: #999;
max-width: 266px;
text-align: center;
}
.am-local-page .page-empty {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-not-found-sm.png");
}
.am-local-page .page-error {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-busy-sm.png");
}
.am-local-page .page-network {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-network-sm.png");
}
.am-local-page .page-busy {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-excption-sm.png");
}
.am-local-page .page-logoff {
background-image: url("https://gw.alipayobjects.com/as/g/antui/antui-static/1.0.3/i/error-logout-sm.png");
}
<view class="am-page-result {{className}} {{local ? 'am-local-page': ''}}">
<view class="am-page-result-pic page-{{type}}" />
<view class="am-page-result-title" a:if="{{!local && title}}">{{title}}</view>
<view class="am-page-result-brief" a:if="{{brief}}">{{brief}}</view>
<slot></slot>
</view>
Component({
props: {
className: '',
type: 'network',
local: false
}
});
\ No newline at end of file
.am-picker-item {
display: flex;
align-items: center;
background: #fff;
padding-left: 15px;
}
.am-picker-line {
position: relative;
flex: 1;
display: flex;
align-items: center;
padding-right: 15px;
min-height: 47px;
overflow: hidden;
}
.am-picker-label {
min-width: 80px;
margin-right: 2px;
color: #333;
}
.am-picker-wrapper {
display: flex;
flex: 1;
height: 33px;
align-items: center;
}
.am-picker-content {
flex: 1;
display: flex;
align-items: center;
height: 33px;
color: #000;
text-align: left;
}
.am-picker-clear {
display: flex;
}
.am-picker-line-bottom::after {
content: '';
display: block;
position: absolute;
width: 100%;
height: 1px;
transform: scaleY(0.5);
left: 0;
bottom: 0;
right: auto;
top: auto;
background-color: #eee;
}
/* 最后一行 */
.am-picker-item.last .am-picker-line-bottom::after {
display: none;
}
.am-picker-text {
padding-left: 8px;
}
.am-picker-content-placeholder {
color: #ccc;
}
.am-picker-content-value {
color: #333;
}
.am-picker-arrow {
display: block;
width: 13px;
height: 13px;
margin-left: 8px;
background-image: url('https://gw.alipayobjects.com/zos/rmsportal/nGMpTwTjtKMbOeeQIucS.png');
background-size: contain;
background-repeat: no-repeat;
background-position: 50% 50%;
}
\ No newline at end of file
<view
class="am-picker-item {{last ? 'last': ''}} {{className}}"
>
<view class="am-picker-line">
<view a:if="{{$slots.$default}}" class="am-picker-label {{labelCls}}">
<slot />
</view>
<view class="am-picker-wrapper" onTap="onPickerTap">
<input type="text" name="{{name}}" value="{{value}}" style="display: none" />
<text class="am-picker-content am-picker-text {{pickerCls}} {{ value.length > 0 ? 'am-picker-content-value': 'am-picker-content-placeholder' }}">
{{value.length > 0 ? value : placeholder}}
</text>
<view class="am-picker-arrow"></view>
</view>
<slot name="extra" />
<view class="am-picker-line-bottom" />
</view>
</view>
\ No newline at end of file
import fmtEvent from '../_util/fmtEvent';
Component({
props: {
className: '',
value: '',
placeholder: '',
onSelect: function onSelect() {}
},
methods: {
onPickerTap: function onPickerTap(e) {
var event = fmtEvent(this.props, e);
this.props.onPickerTap(event);
}
}
});
\ No newline at end of file
.am-popover {
position: relative;
}
.am-popover-mask {
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.3);
height: 100%;
z-index: 99;
}
.am-popover-content {
position: absolute;
z-index: 100;
border-radius: 4px;
font-size: 14px;
color: #333;
}
.border-true {
border: 1px solid #ddd;
}
.am-popover-inner {
position: relative;
color: #000;
background-color: #fff;
border-radius: 3px;
}
/* popover position: top */
.am-popover-placement-top {
top: -7px;
left: 50%;
transform: translate(-50%, -100%);
}
.am-popover-placement-topLeft {
top: -7px;
left: 0;
transform: translate(0, -100%);
}
.am-popover-placement-topRight {
top: -7px;
right: 0;
transform: translate(0, -100%);
}
/* popover position: right */
.am-popover-placement-right {
top: 50%;
right: -7px;
transform: translate(100%, -50%);
}
.am-popover-placement-rightTop {
top: 0;
right: -7px;
transform: translateX(100%);
}
.am-popover-placement-rightBottom {
bottom: 0;
right: -7px;
transform: translateX(100%);
}
/* popover position: bottom */
.am-popover-placement-bottom {
bottom: -7px;
left: 50%;
transform: translate(-50%, 100%);
}
.am-popover-placement-bottomRight {
bottom: -7px;
right: 0;
transform: translateY(100%);
}
.am-popover-placement-bottomLeft {
bottom: -7px;
left: 0;
transform: translateY(100%);
}
/* popover position: left */
.am-popover-placement-left {
top: 50%;
left: -7px;
transform: translate(-100%, -50%);
}
.am-popover-placement-leftTop {
top: 0;
left: -7px;
transform: translateX(-100%);
}
.am-popover-placement-leftBottom {
bottom: 0;
left: -7px;
transform: translateX(-100%);
}
/* arrow style start */
.am-popover-arrow {
position: absolute;
width: 7px;
height: 7px;
background-color: #fff;
z-index: 0;
/* box-shadow: 0 0 2px rgba(0, 0, 0, 0.21); */
}
/* arrow position: top */
.am-popover-placement-top .am-popover-arrow,
.am-popover-placement-topLeft .am-popover-arrow,
.am-popover-placement-topRight .am-popover-arrow {
transform: translateY(50%) rotate(45deg);
bottom: 0;
}
.am-popover-placement-top .am-popover-arrow {
transform: translate(-50%, 50%) rotate(45deg);
left: 50%;
}
.am-popover-placement-topRight .am-popover-arrow {
right: 16px;
}
.am-popover-placement-topLeft .am-popover-arrow {
left: 16px;
}
/* arrow position: right */
.am-popover-placement-right .am-popover-arrow,
.am-popover-placement-rightTop .am-popover-arrow,
.am-popover-placement-rightBottom .am-popover-arrow {
transform: translateX(-50%) rotate(45deg);
left: 0;
}
.am-popover-placement-right .am-popover-arrow {
transform: translate(-50%, -50%) rotate(45deg);
top: 50%;
}
.am-popover-placement-rightBottom .am-popover-arrow {
bottom: 16px;
}
.am-popover-placement-rightTop .am-popover-arrow {
top: 16px;
}
/* arrow position: bottom */
.am-popover-placement-bottom .am-popover-arrow,
.am-popover-placement-bottomLeft .am-popover-arrow,
.am-popover-placement-bottomRight .am-popover-arrow {
transform: translateY(-50%) rotate(45deg);
top: 0;
}
.am-popover-placement-bottom .am-popover-arrow {
transform: translate(-50%, -50%) rotate(45deg);
left: 50%;
}
.am-popover-placement-bottomLeft .am-popover-arrow {
left: 16px;
}
.am-popover-placement-bottomRight .am-popover-arrow {
right: 16px;
}
/* arrow position: left */
.am-popover-placement-left .am-popover-arrow,
.am-popover-placement-leftTop .am-popover-arrow,
.am-popover-placement-leftBottom .am-popover-arrow {
transform: translateX(50%) rotate(45deg);
right: 0;
}
.am-popover-placement-left .am-popover-arrow {
transform: translate(50%, -50%) rotate(45deg);
top: 50%;
}
.am-popover-placement-leftTop .am-popover-arrow {
top: 16px;
}
.am-popover-placement-leftBottom .am-popover-arrow {
bottom: 16px;
}
/* arrow style end */
<view class="am-popover {{className}}">
<!-- 点击元素 -->
<slot/>
<!-- 弹窗层 -->
<view class="am-popover-container" a:if="{{show}}">
<!-- 蒙层 -->
<view class="am-popover-mask" a:if="{{showMask}}" onTap="onMaskClick"></view>
<!-- 弹窗内容 -->
<view class="am-popover-content am-popover-placement-{{position}} border-{{!showMask}}">
<!-- 箭头 -->
<view class="am-popover-arrow border-{{!showMask}}"></view>
<!-- 文案 -->
<view class="am-popover-inner">
<slot name="items"></slot>
</view>
</view>
</view>
</view>
\ No newline at end of file
Component({
props: {
show: false,
className: '',
showMask: true,
position: 'bottomRight'
},
methods: {
onMaskClick: function onMaskClick() {
if (this.props.onMaskClick && typeof this.props.onMaskClick === 'function') {
this.props.onMaskClick();
}
}
}
});
\ No newline at end of file
.am-popover-item {
min-width: 80px;
max-width: 170px;
height: 39px;
margin: 0 10px;
line-height: 39px;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #333;
text-align: center;
}
.am-popover-item:not(:last-child) {
border-bottom: 1px solid #eee;
}
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册