石广澎
2025-11-17 8771da2ccf6f7c3fd2a8c89a1a0e230c6386db7f
feat(api): 新增多个API接口并优化配置

- 新增获取商铺信息、积分价值、用户银行卡等接口
- 新增微信授权登录、支付宝授权登录相关接口
- 新增支付相关接口,包括微信支付、通联快捷支付等
- 新增银行卡校验、RSA加密等工具函数
- 更新config配置文件,新增多个环境配置项
- 修改http拦截器,优化token处理逻辑
- 新增多种工具函数,包括日期格式化、时间计算等
- 优化响应拦截器,增加授权过期处理逻辑
66个文件已添加
1 文件已重命名
7个文件已删除
15个文件已修改
12570 ■■■■ 已修改文件
App.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/api/index.js 125 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/api/shuaka.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/bankName.js 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/config.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/http.interceptor.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/jsencrypt.js 5371 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/jweixin-1.6.0.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/math.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/util.js 894 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/bind-card-activity/bind-card-activity.vue 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/card-agreement/card-agreement.vue 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/input-number/input-number.vue 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/key-bord/key-bord.vue 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/user-agreement/user-agreement.vue 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
index.html 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manifest.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages.json 127 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/addCardCode.vue 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/addCardFirst.vue 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/addCardSecond.vue 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/bindCard/bindCard.vue 392 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/discountpay.vue 616 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/login.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/paySuccess.vue 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/register.vue 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/scanRes.vue 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/scanpay.vue 876 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/shuaKa/introduce.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/shuaKa/shuaKa.vue 673 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pay/wxpay.vue 292 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pay/index.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pay/scanpay.vue 1022 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/act-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
static/bangka.png 补丁 | 查看 | 原始文档 | blame | 历史
static/bank-card-ad1.png 补丁 | 查看 | 原始文档 | blame | 历史
static/bank-card-ad2.png 补丁 | 查看 | 原始文档 | blame | 历史
static/bind-card-modal.png 补丁 | 查看 | 原始文档 | blame | 历史
static/bind-card-title.png 补丁 | 查看 | 原始文档 | blame | 历史
static/cart/icon_add.png 补丁 | 查看 | 原始文档 | blame | 历史
static/cart/icon_addLight.png 补丁 | 查看 | 原始文档 | blame | 历史
static/cart/icon_less.png 补丁 | 查看 | 原始文档 | blame | 历史
static/cart/icon_lessLight.png 补丁 | 查看 | 原始文档 | blame | 历史
static/check-type.png 补丁 | 查看 | 原始文档 | blame | 历史
static/close-icon.png 补丁 | 查看 | 原始文档 | blame | 历史
static/coupon-bg2.png 补丁 | 查看 | 原始文档 | blame | 历史
static/coupon-icon.png 补丁 | 查看 | 原始文档 | blame | 历史
static/del-icon.png 补丁 | 查看 | 原始文档 | blame | 历史
static/empty.png 补丁 | 查看 | 原始文档 | blame | 历史
static/imgs/del-icon.png 补丁 | 查看 | 原始文档 | blame | 历史
static/imgs/pay-jyk.png 补丁 | 查看 | 原始文档 | blame | 历史
static/imgs/pay-union.png 补丁 | 查看 | 原始文档 | blame | 历史
static/imgs/pay-wx.png 补丁 | 查看 | 原始文档 | blame | 历史
static/imgs/pay-zfb.png 补丁 | 查看 | 原始文档 | blame | 历史
static/imgs/store-logo.png 补丁 | 查看 | 原始文档 | blame | 历史
static/integral.png 补丁 | 查看 | 原始文档 | blame | 历史
static/no_coupon.png 补丁 | 查看 | 原始文档 | blame | 历史
static/pay-btn.jpeg 补丁 | 查看 | 原始文档 | blame | 历史
static/pay-btn.png 补丁 | 查看 | 原始文档 | blame | 历史
static/pay-by-card-coupon.png 补丁 | 查看 | 原始文档 | blame | 历史
static/paySuccess.png 补丁 | 查看 | 原始文档 | blame | 历史
static/register-btn.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/coupon-title-left.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/coupon-title-right.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/notice-check.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-bg-top.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-btn.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-coupon-get.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-coupon-lock.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-coupon.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-dto-ttitle-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-lock.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-modal-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-step-act.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/pay-by-card-step.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/popup-close.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/shuaka.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/title-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/title-icon1.png 补丁 | 查看 | 原始文档 | blame | 历史
static/shuaka/title-icon2.png 补丁 | 查看 | 原始文档 | blame | 历史
static/store-logo.png 补丁 | 查看 | 原始文档 | blame | 历史
static/title-left.png 补丁 | 查看 | 原始文档 | blame | 历史
static/title-right.png 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-input/u-input.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-parse/u-parse.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-textarea/u-textarea.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
App.vue
@@ -1,13 +1,7 @@
<script>
import Vconsole from 'vconsole';
    export default {
        onLaunch: function(opt) {
      if(opt.query?.debug){
        uni.setStorageSync('DEBUG', opt.query?.debug == 'true');
      }
      if (uni.getStorageSync('DEBUG')) {
        new Vconsole();
      }
        onLaunch: function() {
            console.log('App Launch')
        },
        onShow: function() {
            console.log('App Show')
@@ -51,10 +45,6 @@
    .color-red {
        color: #DE2D35;
    }
    .color-green {
        color: #3fde2d;
    }
    .font-bold {
common/api/index.js
@@ -1,60 +1,123 @@
import {
    config
} from '@/common/config.js';
const http = uni.$u.http;
const URL = config.baseURL;
/* 根据cid获取商铺信息 */
export const queryShopByCid = (params, config = {}) => http.get(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/queryShopById', params, config)
/* 获取商铺信息 */
export const queryShop = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/aggregatePayAllin/queryShopById', params, config)
/* 根据动态码id获取商铺信息 */
export const queryShopByActQrId = (params, config = {}) => http.get(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/getPayInfo', params, config)
/* 获取成功页面配置 */
export const getPayCompleteUrl = (params, config = {}) => http.get(URL +
    '/service-base/v1/base/pc/global/config/getPayCompleteUrl', params, config)
/* 根据订单id获取商铺信息 */
export const queryShopByOnlineId = (params, config = {}) => http.get(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/getOnlineId', params, config)
/* 获取积分价值 */
export const getScoreWorth = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/aggregatePayAllin/getScoreWorth', params, config)
/* 根据shopId获取商铺信息 */
export const queryShopByShopId = (params, config = {}) => http.get(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/queryShopByShopId', params, config)
/* 获取用户银行卡 */
export const myBankCard = (params, config = {}) => http.get(URL +
    '/service-shop/v1/shop/wechat/h5/bankCard/myBankCard', params, config)
/*统一授权*/
/* 获取商铺微信配置 */
export const getWechatInfo = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/aggregatePayAllin/getWechatInfo', params, config = {});
/* 静默授权登录 */
export const getOpenIdBase = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/aggregatePayAllin/getOpenIdBase', params, config = {});
/* 微信普通授权登录 */
export const getOpenId = (params, config = {}) => http.get(URL + '/service-merchant/v1/web/aggregatePayAllin/getOpenId',
    params, config = {});
/* 支付宝普通授权登录 */
export const getUserId = (params, config = {}) => http.get(URL + '/service-merchant/v1/web/h5PayAli/getUserIdByCode',
    params, config = {});
export const userLogin = (params, config = {}) => {
    let path = '/payfour-merchant/v1/web/aggregatePayAllin/getOpenId' //微信授权
    if (params.platform == 5) { //支付宝授权
        path = '/payfour-merchant/v1/web/h5PayAli/getUserIdByCode'
    let path = '/service-merchant/v1/web/aggregatePayAllin/getOpenId'
    if (params.platform == 5) {
        path = '/service-merchant/v1/web/h5PayAli/getUserIdByCode'
    }
    if (params.platform == 15) { //云闪付授权
        path = '/payfour-merchant/v1/web/h5PayUnionPay/getUserIdByCode'
    if (params.platform == 15) {
        path = '/service-merchant/v1/web/h5PayUnionPay/getUserIdByCode'
    }
    return http.get(URL + path,
        params, config = {})
};
/* 获取用户积分 */
export const queryScore = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/aggregatePayAllin/queryScore', params, config = {});
/* 获取用户可用优惠券 面值最大的*/
export const queryMyUseSweepPayMaxCoupon = (params, config = {}) => http.get(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/queryMyUseSweepPayMaxCoupon', params, config = {});
    '/service-merchant/v1/web/aggregatePayAllin/queryMyUseSweepPayMaxCoupon', params, config = {});
/* 获取用户可用优惠券 */
export const queryUseSweepPayCoupon = (params, config = {}) => http.get(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/queryUseSweepPayCoupon', params, config = {});
    '/service-merchant/v1/web/aggregatePayAllin/queryUseSweepPayCoupon', params, config = {});
/* 获取微信js sdk配置 */
export const getWechatConfigInfo = (params, config = {}) => http.post(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/getWechatConfigInfo', params, config = {});
    '/service-merchant/v1/web/aggregatePayAllin/getWechatConfigInfo', params, config = {});
/*统一支付*/
export const saveOrder = (params, config = {}) => http.post(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/saveOrder', params, config = {});
/* 微信支付 */
export const saveWxOrder = (params, config = {}) => http.post(URL +
    '/service-merchant/v1/web/aggregatePayAllin/saveWxOrder', params, config = {});
/*取消订单*/
export const closeOrder = (params, config = {}) => http.get(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/scanPayOrderClose', params, config = {});
/* 图形验证吗 */
export const getVerify = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/aggregatePayAllin/getVerify', params, config = {});
/* 短信验证码 */
export const getH5PayCheckVerifyCode = (params, config = {}) => http.post(URL +
    '/service-merchant/v1/web/aggregatePayAllin/getH5PayCheckVerifyCode', params, config = {});
/* 微信支付 */
export const h5PayLogin = (params, config = {}) => http.post(URL + '/service-shop/v1/shop/web/wechat/h5PayLogin',
    params, config = {});
/* 通联快捷支付 */
export const tlPay = (params, config = {}) => http.post(URL +
    '/service-merchant/v1/web/aggregatePayAllin/payagreeconfirm',
    params, config = {});
/* 微信支付结果 */
export const getWxOrderInfo = (params, config = {}) => http.post(URL +
    '/payfour-merchant/v1/web/aggregatePayAllin/getWxOrderInfo',
    '/service-merchant/v1/web/aggregatePayAllin/getWxOrderInfo',
    params, config = {});
/* 判断是否在卡段内 */
export const isContain = (params, config = {}) => http.get(URL +
    '/service-base/v1/base/pc/bankCardPeriod/isContain',
    params, config = {});
/* 获取银行卡配置 */
export const bankCardStyle = (params, config = {}) => http.get(URL +
    '/service-base/v1/base/pc/global/config/bankCardStyle',
    params, config = {});
/* 获取用户信息 */
export const getUserInfo = (params, config = {}) => http.post(URL +
    '/service-shop/v1/shop/wechat/h5/bankCard/noEnc',
    params, config = {});
/* 获取店铺优惠信息 */
export const queryMyDiscount = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/aggregatePayAllin/queryMyDiscount',
    params, config = {});
/* 签约申请绑卡 */
export const signUpToApply = (params, config = {}) => http.post(URL +
    '/service-shop/v1/shop/wechat/h5/bankCard/signUpToApply',
    params, config = {});
/* 签约申请确认 */
export const bindCard = (params, config = {}) => http.post(URL +
    '/service-shop/v1/shop/wechat/h5/bankCard/bindCard',
    params, config = {});
/* 获取绑卡活动赠送的优惠券 */
export const getMyCoupUseDetail = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/aggregatePayAllin/headBand/getMyCoupUseDetail',
    params, config = {});
/* 获取首绑有礼 */
export const headBand = (params, config = {}) => http.get(URL +
    '/service-shop/v1/shop/wechat/activity/headBand/detail',
    params, config = {});
common/api/shuaka.js
New file
@@ -0,0 +1,18 @@
import {
    config
} from '@/common/config.js';
const http = uni.$u.http;
const URL = config.baseURL;
/* 获取刷卡活动信息 */
export const activityInfo = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/monthBrush/info', params, config)
/* 参与活动 */
export const signActivity = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/monthBrush/sign', params, config)
/* 获取用户参与信息 */
export const myBrushDetail = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/monthBrush/myBrushDetail', params, config)
/* 查询优惠券 */
export const orderRefBrushNode = (params, config = {}) => http.get(URL +
    '/service-merchant/v1/web/monthBrush/orderRefBrushNode', params, config)
common/bankName.js
New file
@@ -0,0 +1,209 @@
const list = {
  "CDB": "国家开发银行",
  "ICBC": "中国工商银行",
  "ABC": "中国农业银行",
  "BOC": "中国银行",
  "CCB": "中国建设银行",
  "PSBC": "中国邮政储蓄银行",
  "COMM": "交通银行",
  "CMB": "招商银行",
  "SPDB": "上海浦东发展银行",
  "CIB": "兴业银行",
  "HXBANK": "华夏银行",
  "GDB": "广东发展银行",
  "CMBC": "中国民生银行",
  "CITIC": "中信银行",
  "CEB": "中国光大银行",
  "EGBANK": "恒丰银行",
  "CZBANK": "浙商银行",
  "BOHAIB": "渤海银行",
  "SPABANK": "平安银行",
  "SHRCB": "上海农村商业银行",
  "YXCCB": "玉溪市商业银行",
  "YDRCB": "尧都农商行",
  "BJBANK": "北京银行",
  "SHBANK": "上海银行",
  "JSBANK": "江苏银行",
  "HZCB": "杭州银行",
  "NJCB": "南京银行",
  "NBBANK": "宁波银行",
  "HSBANK": "徽商银行",
  "CSCB": "长沙银行",
  "CDCB": "成都银行",
  "CQBANK": "重庆银行",
  "DLB": "大连银行",
  "NCB": "南昌银行",
  "FJHXBC": "福建海峡银行",
  "HKB": "汉口银行",
  "WZCB": "温州银行",
  "QDCCB": "青岛银行",
  "TZCB": "台州银行",
  "JXBANK": "嘉兴银行",
  "CSRCB": "常熟农村商业银行",
  "NHB": "南海农村信用联社",
  "CZRCB": "常州农村信用联社",
  "H3CB": "内蒙古银行",
  "SXCB": "绍兴银行",
  "SDEB": "顺德农商银行",
  "WJRCB": "吴江农商银行",
  "ZBCB": "齐商银行",
  "GYCB": "贵阳市商业银行",
  "ZYCBANK": "遵义市商业银行",
  "HZCCB": "湖州市商业银行",
  "DAQINGB": "龙江银行",
  "JINCHB": "晋城银行JCBANK",
  "ZJTLCB": "浙江泰隆商业银行",
  "GDRCC": "广东省农村信用社联合社",
  "DRCBCL": "东莞农村商业银行",
  "MTBANK": "浙江民泰商业银行",
  "GCB": "广州银行",
  "LYCB": "辽阳市商业银行",
  "JSRCU": "江苏省农村信用联合社",
  "LANGFB": "廊坊银行",
  "CZCB": "浙江稠州商业银行",
  "DYCB": "德阳商业银行",
  "JZBANK": "晋中市商业银行",
  "BOSZ": "苏州银行",
  "GLBANK": "桂林银行",
  "URMQCCB": "乌鲁木齐市商业银行",
  "CDRCB": "成都农商银行",
  "ZRCBANK": "张家港农村商业银行",
  "BOD": "东莞银行",
  "LSBANK": "莱商银行",
  "BJRCB": "北京农村商业银行",
  "TRCB": "天津农商银行",
  "SRBANK": "上饶银行",
  "FDB": "富滇银行",
  "CRCBANK": "重庆农村商业银行",
  "ASCB": "鞍山银行",
  "NXBANK": "宁夏银行",
  "BHB": "河北银行",
  "HRXJB": "华融湘江银行",
  "ZGCCB": "自贡市商业银行",
  "YNRCC": "云南省农村信用社",
  "JLBANK": "吉林银行",
  "DYCCB": "东营市商业银行",
  "KLB": "昆仑银行",
  "ORBANK": "鄂尔多斯银行",
  "XTB": "邢台银行",
  "JSB": "晋商银行",
  "TCCB": "天津银行",
  "BOYK": "营口银行",
  "JLRCU": "吉林农信",
  "SDRCU": "山东农信",
  "XABANK": "西安银行",
  "HBRCU": "河北省农村信用社",
  "NXRCU": "宁夏黄河农村商业银行",
  "GZRCU": "贵州省农村信用社",
  "FXCB": "阜新银行",
  "HBHSBANK": "湖北银行黄石分行",
  "ZJNX": "浙江省农村信用社联合社",
  "XXBANK": "新乡银行",
  "HBYCBANK": "湖北银行宜昌分行",
  "LSCCB": "乐山市商业银行",
  "TCRCB": "江苏太仓农村商业银行",
  "BZMD": "驻马店银行",
  "GZB": "赣州银行",
  "WRCB": "无锡农村商业银行",
  "BGB": "广西北部湾银行",
  "GRCB": "广州农商银行",
  "JRCB": "江苏江阴农村商业银行",
  "BOP": "平顶山银行",
  "TACCB": "泰安市商业银行",
  "CGNB": "南充市商业银行",
  "CCQTGB": "重庆三峡银行",
  "XLBANK": "中山小榄村镇银行",
  "HDBANK": "邯郸银行",
  "KORLABANK": "库尔勒市商业银行",
  "BOJZ": "锦州银行",
  "QLBANK": "齐鲁银行",
  "BOQH": "青海银行",
  "YQCCB": "阳泉银行",
  "SJBANK": "盛京银行",
  "FSCB": "抚顺银行",
  "ZZBANK": "郑州银行",
  "SRCB": "深圳农村商业银行",
  "BANKWF": "潍坊银行",
  "JJBANK": "九江银行",
  "JXRCU": "江西省农村信用",
  "HNRCU": "河南省农村信用",
  "GSRCU": "甘肃省农村信用",
  "SCRCU": "四川省农村信用",
  "GXRCU": "广西省农村信用",
  "SXRCCU": "陕西信合",
  "WHRCB": "武汉农村商业银行",
  "YBCCB": "宜宾市商业银行",
  "KSRB": "昆山农村商业银行",
  "SZSBK": "石嘴山银行",
  "HSBK": "衡水银行",
  "XYBANK": "信阳银行",
  "NBYZ": "鄞州银行",
  "ZJKCCB": "张家口市商业银行",
  "XCYH": "许昌银行",
  "JNBANK": "济宁银行",
  "CBKF": "开封市商业银行",
  "WHCCB": "威海市商业银行",
  "HBC": "湖北银行",
  "BOCD": "承德银行",
  "BODD": "丹东银行",
  "JHBANK": "金华银行",
  "BOCY": "朝阳银行",
  "LSBC": "临商银行",
  "BSB": "包商银行",
  "LZYH": "兰州银行",
  "BOZK": "周口银行",
  "DZBANK": "德州银行",
  "SCCB": "三门峡银行",
  "AYCB": "安阳银行",
  "ARCU": "安徽省农村信用社",
  "HURCB": "湖北省农村信用社",
  "HNRCC": "湖南省农村信用社",
  "NYNB": "广东南粤银行",
  "LYBANK": "洛阳银行",
  "NHQS": "农信银清算中心",
  "CBBQS": "城市商业银行资金清算中心"
}
module.exports = {
  bankName: list,
};
common/config.js
@@ -2,32 +2,50 @@
// 开发
const dev = {
    webURL: 'https://sfzf.cpbtsoft.cn',
    baseURL: 'https://sfzf.cpbtsoft.cn/dev-api',
    // baseURL: 'http://172.16.2.117:8080',
    wx_appid: 'wx4c146dba764dcb05',
    ali_appid: '2021004193639959'
    webURL: 'https://zhxx.jinmingyuan.com/pay',
    baseURL: 'http://1.14.252.104:7101',
    sftpURL: 'https://zhkj.jinmingyuan.com:8443/sftp',
    imgUrl: 'https://zhkj.jinmingyuan.com:8443/sftp/platform/app/',
    wx_appid: 'wxad8cc511da676bd4',
    ali_appid: '2021003199690698'
}
// 测试
const test = {
    webURL: 'https://sfzf.cpbtsoft.cn',
    baseURL: 'https://sfzf.cpbtsoft.cn/prod-api',
    wx_appid: 'wx4c146dba764dcb05',
    ali_appid: '2021004193639959'
// 翼支付测试
const yPayTest = {
    webURL: 'https://zhxx.jinmingyuan.com/yPayTest',
    baseURL: 'http://1.14.252.104:7101',
    sftpURL: 'https://zhkj.jinmingyuan.com:8443/sftp',
    imgUrl: 'https://zhkj.jinmingyuan.com:8443/sftp/platform/app/',
    wx_appid: 'wxd163440fc91fd9af',
    ali_appid: '2021003199690698'
}
// 正式
const prod = {
    webURL: 'https://uif.hepost.com',
    baseURL: 'https://uif.hepost.com/prod-api',
    wx_appid: 'wx4c146dba764dcb05',
    ali_appid: '2021004149689887'
// 生态圈
const stq = {
    webURL: 'https://zhxx.jinmingyuan.com/pay',
    baseURL: 'https://zhxx.jinmingyuan.com',
    sftpURL: 'https://zhkj.jinmingyuan.com:8443/sftp',
    imgUrl: 'https://zhkj.jinmingyuan.com:8443/sftp/platform/app/',
    wx_appid: 'wxad8cc511da676bd4',
    ali_appid: '2021003199690698'
}
// 人才码
const rcm = {
    webURL: 'https://zhxx.jinmingyuan.com/rcmpay',
    baseURL: 'https://zhxx.jinmingyuan.com/rcmapi',
    sftpURL: 'https://zhkj.jinmingyuan.com:8443/sftp',
    imgUrl: 'https://zhkj.jinmingyuan.com:8443/sftp/platform/app/',
    wx_appid: 'wxad8cc511da676bd4',
    ali_appid: '2021003199690698'
}
const cardType = {
    '00': '储蓄卡',
    '02': '信用卡'
}
module.exports = {
    config: process.env.NODE_ENV === 'development' ? dev : prod,
    ACCESSTOKEN: "Authorization",
    config: stq,
    ACCESSTOKEN: "SCAN-WECHAT-TOKEN-HEADER",
    /* 是否打印请求日志 */
    DEBUG: false,
    /* 是否校验位置经纬度 */
    CHECK_LOCATION: true
    cardType: cardType
}
common/http.interceptor.js
@@ -3,10 +3,6 @@
    config,
    DEBUG
} from '@/common/config.js';
import {
    getPlat
} from 'common/util.js';
module.exports = (vm) => {
    uni.$u.http.setConfig((x) => {
        return x = {
@@ -17,7 +13,6 @@
            timer: null,
            loadingTime: 800, //多少秒无返回再显示loading
            header: {
                'Clientid': '944c6aade52ebbffc015478e6ce51b5a',
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
                'Access-Control-Allow-Origin': '*'
            }
@@ -29,30 +24,9 @@
        // 引用token
        const TOKEN = uni.getStorageSync(ACCESSTOKEN);
        if (TOKEN) {
            x.header[ACCESSTOKEN] = 'Bearer ' + TOKEN;
        }
        const plat = getPlat()
        if (plat == 2) { //微信
            const OPENID = uni.getStorageSync('OPENID') || null
            const UNIONID = uni.getStorageSync('UNIONID') || null
            if (OPENID) {
                x.header['Openid'] = OPENID;
            }
            if (UNIONID) {
                x.header['Unionid'] = UNIONID;
            }
        }
        if (plat == 5) { //支付宝
            const ALIUSERID = uni.getStorageSync('ALIUSERID') || null
            if (ALIUSERID) {
                x.header['Aliuserid'] = ALIUSERID;
            }
        }
        if (plat == 15) { //云闪付
            const UNIONPAYID = uni.getStorageSync('UNIONPAYID') || null
            if (UNIONPAYID) {
                x.header['Unionpayid '] = UNIONPAYID;
            }
            x.header[ACCESSTOKEN] = TOKEN;
        } else {
            delete x.header[ACCESSTOKEN]
        }
        return x;
    }, x => {
@@ -64,10 +38,20 @@
        let res = x.data
        if (res.code == 10000) {
            return res.data;
        } else if (res.code == 20002) {
            const cid = uni.getStorageSync('CID')
            uni.removeStorageSync(ACCESSTOKEN)
            vm.$u.toast("授权过期,请重新登录");
            setTimeout(() => {
                uni.reLaunch({
                    url: "/pages/pay/scanpay?cid=" + cid
                })
            }, 800);
            return Promise.reject(res)
        } else if (res.code == 10002) {
            return Promise.reject(res)
        } else {
            vm.$u.toast(res.description || res.msg || res.info || "请求异常!"); //错误提示信息
            vm.$u.toast(res.description || "请求异常!"); //错误提示信息
            return Promise.reject(res)
        }
    }, (response) => {
common/jsencrypt.js
New file
Diff too large
common/jweixin-1.6.0.js
New file
@@ -0,0 +1 @@
!function(e,n){"function"==typeof define&&(define.amd||define.cmd)?define(function(){return n(e)}):n(e,!0)}(this,function(o,e){if(!o.jWeixin){var n,c={config:"preVerifyJSAPI",onMenuShareTimeline:"menu:share:timeline",onMenuShareAppMessage:"menu:share:appmessage",onMenuShareQQ:"menu:share:qq",onMenuShareWeibo:"menu:share:weiboApp",onMenuShareQZone:"menu:share:QZone",previewImage:"imagePreview",getLocation:"geoLocation",openProductSpecificView:"openProductViewWithPid",addCard:"batchAddCard",openCard:"batchViewCard",chooseWXPay:"getBrandWCPayRequest",openEnterpriseRedPacket:"getRecevieBizHongBaoRequest",startSearchBeacons:"startMonitoringBeacons",stopSearchBeacons:"stopMonitoringBeacons",onSearchBeacons:"onBeaconsInRange",consumeAndShareCard:"consumedShareCard",openAddress:"editAddress"},a=function(){var e={};for(var n in c)e[c[n]]=n;return e}(),i=o.document,t=i.title,r=navigator.userAgent.toLowerCase(),s=navigator.platform.toLowerCase(),d=!(!s.match("mac")&&!s.match("win")),u=-1!=r.indexOf("wxdebugger"),l=-1!=r.indexOf("micromessenger"),p=-1!=r.indexOf("android"),f=-1!=r.indexOf("iphone")||-1!=r.indexOf("ipad"),m=(n=r.match(/micromessenger\/(\d+\.\d+\.\d+)/)||r.match(/micromessenger\/(\d+\.\d+)/))?n[1]:"",g={initStartTime:L(),initEndTime:0,preVerifyStartTime:0,preVerifyEndTime:0},h={version:1,appId:"",initTime:0,preVerifyTime:0,networkType:"",isPreVerifyOk:1,systemType:f?1:p?2:-1,clientVersion:m,url:encodeURIComponent(location.href)},v={},S={_completes:[]},y={state:0,data:{}};O(function(){g.initEndTime=L()});var I=!1,_=[],w={config:function(e){B("config",v=e);var t=!1!==v.check;O(function(){if(t)M(c.config,{verifyJsApiList:C(v.jsApiList),verifyOpenTagList:C(v.openTagList)},function(){S._complete=function(e){g.preVerifyEndTime=L(),y.state=1,y.data=e},S.success=function(e){h.isPreVerifyOk=0},S.fail=function(e){S._fail?S._fail(e):y.state=-1};var t=S._completes;return t.push(function(){!function(){if(!(d||u||v.debug||m<"6.0.2"||h.systemType<0)){var i=new Image;h.appId=v.appId,h.initTime=g.initEndTime-g.initStartTime,h.preVerifyTime=g.preVerifyEndTime-g.preVerifyStartTime,w.getNetworkType({isInnerInvoke:!0,success:function(e){h.networkType=e.networkType;var n="https://open.weixin.qq.com/sdk/report?v="+h.version+"&o="+h.isPreVerifyOk+"&s="+h.systemType+"&c="+h.clientVersion+"&a="+h.appId+"&n="+h.networkType+"&i="+h.initTime+"&p="+h.preVerifyTime+"&u="+h.url;i.src=n}})}}()}),S.complete=function(e){for(var n=0,i=t.length;n<i;++n)t[n]();S._completes=[]},S}()),g.preVerifyStartTime=L();else{y.state=1;for(var e=S._completes,n=0,i=e.length;n<i;++n)e[n]();S._completes=[]}}),w.invoke||(w.invoke=function(e,n,i){o.WeixinJSBridge&&WeixinJSBridge.invoke(e,x(n),i)},w.on=function(e,n){o.WeixinJSBridge&&WeixinJSBridge.on(e,n)})},ready:function(e){0!=y.state?e():(S._completes.push(e),!l&&v.debug&&e())},error:function(e){m<"6.0.2"||(-1==y.state?e(y.data):S._fail=e)},checkJsApi:function(e){M("checkJsApi",{jsApiList:C(e.jsApiList)},(e._complete=function(e){if(p){var n=e.checkResult;n&&(e.checkResult=JSON.parse(n))}e=function(e){var n=e.checkResult;for(var i in n){var t=a[i];t&&(n[t]=n[i],delete n[i])}return e}(e)},e))},onMenuShareTimeline:function(e){P(c.onMenuShareTimeline,{complete:function(){M("shareTimeline",{title:e.title||t,desc:e.title||t,img_url:e.imgUrl||"",link:e.link||location.href,type:e.type||"link",data_url:e.dataUrl||""},e)}},e)},onMenuShareAppMessage:function(n){P(c.onMenuShareAppMessage,{complete:function(e){"favorite"===e.scene?M("sendAppMessage",{title:n.title||t,desc:n.desc||"",link:n.link||location.href,img_url:n.imgUrl||"",type:n.type||"link",data_url:n.dataUrl||""}):M("sendAppMessage",{title:n.title||t,desc:n.desc||"",link:n.link||location.href,img_url:n.imgUrl||"",type:n.type||"link",data_url:n.dataUrl||""},n)}},n)},onMenuShareQQ:function(e){P(c.onMenuShareQQ,{complete:function(){M("shareQQ",{title:e.title||t,desc:e.desc||"",img_url:e.imgUrl||"",link:e.link||location.href},e)}},e)},onMenuShareWeibo:function(e){P(c.onMenuShareWeibo,{complete:function(){M("shareWeiboApp",{title:e.title||t,desc:e.desc||"",img_url:e.imgUrl||"",link:e.link||location.href},e)}},e)},onMenuShareQZone:function(e){P(c.onMenuShareQZone,{complete:function(){M("shareQZone",{title:e.title||t,desc:e.desc||"",img_url:e.imgUrl||"",link:e.link||location.href},e)}},e)},updateTimelineShareData:function(e){M("updateTimelineShareData",{title:e.title,link:e.link,imgUrl:e.imgUrl},e)},updateAppMessageShareData:function(e){M("updateAppMessageShareData",{title:e.title,desc:e.desc,link:e.link,imgUrl:e.imgUrl},e)},startRecord:function(e){M("startRecord",{},e)},stopRecord:function(e){M("stopRecord",{},e)},onVoiceRecordEnd:function(e){P("onVoiceRecordEnd",e)},playVoice:function(e){M("playVoice",{localId:e.localId},e)},pauseVoice:function(e){M("pauseVoice",{localId:e.localId},e)},stopVoice:function(e){M("stopVoice",{localId:e.localId},e)},onVoicePlayEnd:function(e){P("onVoicePlayEnd",e)},uploadVoice:function(e){M("uploadVoice",{localId:e.localId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},downloadVoice:function(e){M("downloadVoice",{serverId:e.serverId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},translateVoice:function(e){M("translateVoice",{localId:e.localId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},chooseImage:function(e){M("chooseImage",{scene:"1|2",count:e.count||9,sizeType:e.sizeType||["original","compressed"],sourceType:e.sourceType||["album","camera"]},(e._complete=function(e){if(p){var n=e.localIds;try{n&&(e.localIds=JSON.parse(n))}catch(e){}}},e))},getLocation:function(e){},previewImage:function(e){M(c.previewImage,{current:e.current,urls:e.urls},e)},uploadImage:function(e){M("uploadImage",{localId:e.localId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},downloadImage:function(e){M("downloadImage",{serverId:e.serverId,isShowProgressTips:0==e.isShowProgressTips?0:1},e)},getLocalImgData:function(e){!1===I?(I=!0,M("getLocalImgData",{localId:e.localId},(e._complete=function(e){if(I=!1,0<_.length){var n=_.shift();wx.getLocalImgData(n)}},e))):_.push(e)},getNetworkType:function(e){M("getNetworkType",{},(e._complete=function(e){e=function(e){var n=e.errMsg;e.errMsg="getNetworkType:ok";var i=e.subtype;if(delete e.subtype,i)e.networkType=i;else{var t=n.indexOf(":"),o=n.substring(t+1);switch(o){case"wifi":case"edge":case"wwan":e.networkType=o;break;default:e.errMsg="getNetworkType:fail"}}return e}(e)},e))},openLocation:function(e){M("openLocation",{latitude:e.latitude,longitude:e.longitude,name:e.name||"",address:e.address||"",scale:e.scale||28,infoUrl:e.infoUrl||""},e)},getLocation:function(e){M(c.getLocation,{type:(e=e||{}).type||"wgs84"},(e._complete=function(e){delete e.type},e))},hideOptionMenu:function(e){M("hideOptionMenu",{},e)},showOptionMenu:function(e){M("showOptionMenu",{},e)},closeWindow:function(e){M("closeWindow",{},e=e||{})},hideMenuItems:function(e){M("hideMenuItems",{menuList:e.menuList},e)},showMenuItems:function(e){M("showMenuItems",{menuList:e.menuList},e)},hideAllNonBaseMenuItem:function(e){M("hideAllNonBaseMenuItem",{},e)},showAllNonBaseMenuItem:function(e){M("showAllNonBaseMenuItem",{},e)},scanQRCode:function(e){M("scanQRCode",{needResult:(e=e||{}).needResult||0,scanType:e.scanType||["qrCode","barCode"]},(e._complete=function(e){if(f){var n=e.resultStr;if(n){var i=JSON.parse(n);e.resultStr=i&&i.scan_code&&i.scan_code.scan_result}}},e))},openAddress:function(e){M(c.openAddress,{},(e._complete=function(e){e=function(e){return e.postalCode=e.addressPostalCode,delete e.addressPostalCode,e.provinceName=e.proviceFirstStageName,delete e.proviceFirstStageName,e.cityName=e.addressCitySecondStageName,delete e.addressCitySecondStageName,e.countryName=e.addressCountiesThirdStageName,delete e.addressCountiesThirdStageName,e.detailInfo=e.addressDetailInfo,delete e.addressDetailInfo,e}(e)},e))},openProductSpecificView:function(e){M(c.openProductSpecificView,{pid:e.productId,view_type:e.viewType||0,ext_info:e.extInfo},e)},addCard:function(e){for(var n=e.cardList,i=[],t=0,o=n.length;t<o;++t){var r=n[t],a={card_id:r.cardId,card_ext:r.cardExt};i.push(a)}M(c.addCard,{card_list:i},(e._complete=function(e){var n=e.card_list;if(n){for(var i=0,t=(n=JSON.parse(n)).length;i<t;++i){var o=n[i];o.cardId=o.card_id,o.cardExt=o.card_ext,o.isSuccess=!!o.is_succ,delete o.card_id,delete o.card_ext,delete o.is_succ}e.cardList=n,delete e.card_list}},e))},chooseCard:function(e){M("chooseCard",{app_id:v.appId,location_id:e.shopId||"",sign_type:e.signType||"SHA1",card_id:e.cardId||"",card_type:e.cardType||"",card_sign:e.cardSign,time_stamp:e.timestamp+"",nonce_str:e.nonceStr},(e._complete=function(e){e.cardList=e.choose_card_info,delete e.choose_card_info},e))},openCard:function(e){for(var n=e.cardList,i=[],t=0,o=n.length;t<o;++t){var r=n[t],a={card_id:r.cardId,code:r.code};i.push(a)}M(c.openCard,{card_list:i},e)},consumeAndShareCard:function(e){M(c.consumeAndShareCard,{consumedCardId:e.cardId,consumedCode:e.code},e)},chooseWXPay:function(e){M(c.chooseWXPay,V(e),e)},openEnterpriseRedPacket:function(e){M(c.openEnterpriseRedPacket,V(e),e)},startSearchBeacons:function(e){M(c.startSearchBeacons,{ticket:e.ticket},e)},stopSearchBeacons:function(e){M(c.stopSearchBeacons,{},e)},onSearchBeacons:function(e){P(c.onSearchBeacons,e)},openEnterpriseChat:function(e){M("openEnterpriseChat",{useridlist:e.userIds,chatname:e.groupName},e)},launchMiniProgram:function(e){M("launchMiniProgram",{targetAppId:e.targetAppId,path:function(e){if("string"==typeof e&&0<e.length){var n=e.split("?")[0],i=e.split("?")[1];return n+=".html",void 0!==i?n+"?"+i:n}}(e.path),envVersion:e.envVersion},e)},openBusinessView:function(e){M("openBusinessView",{businessType:e.businessType,queryString:e.queryString||"",envVersion:e.envVersion},(e._complete=function(n){if(p){var e=n.extraData;if(e)try{n.extraData=JSON.parse(e)}catch(e){n.extraData={}}}},e))},miniProgram:{navigateBack:function(e){e=e||{},O(function(){M("invokeMiniProgramAPI",{name:"navigateBack",arg:{delta:e.delta||1}},e)})},navigateTo:function(e){O(function(){M("invokeMiniProgramAPI",{name:"navigateTo",arg:{url:e.url}},e)})},redirectTo:function(e){O(function(){M("invokeMiniProgramAPI",{name:"redirectTo",arg:{url:e.url}},e)})},switchTab:function(e){O(function(){M("invokeMiniProgramAPI",{name:"switchTab",arg:{url:e.url}},e)})},reLaunch:function(e){O(function(){M("invokeMiniProgramAPI",{name:"reLaunch",arg:{url:e.url}},e)})},postMessage:function(e){O(function(){M("invokeMiniProgramAPI",{name:"postMessage",arg:e.data||{}},e)})},getEnv:function(e){O(function(){e({miniprogram:"miniprogram"===o.__wxjs_environment})})}}},T=1,k={};return i.addEventListener("error",function(e){if(!p){var n=e.target,i=n.tagName,t=n.src;if("IMG"==i||"VIDEO"==i||"AUDIO"==i||"SOURCE"==i)if(-1!=t.indexOf("wxlocalresource://")){e.preventDefault(),e.stopPropagation();var o=n["wx-id"];if(o||(o=T++,n["wx-id"]=o),k[o])return;k[o]=!0,wx.ready(function(){wx.getLocalImgData({localId:t,success:function(e){n.src=e.localData}})})}}},!0),i.addEventListener("load",function(e){if(!p){var n=e.target,i=n.tagName;n.src;if("IMG"==i||"VIDEO"==i||"AUDIO"==i||"SOURCE"==i){var t=n["wx-id"];t&&(k[t]=!1)}}},!0),e&&(o.wx=o.jWeixin=w),w}function M(n,e,i){o.WeixinJSBridge?WeixinJSBridge.invoke(n,x(e),function(e){A(n,e,i)}):B(n,i)}function P(n,i,t){o.WeixinJSBridge?WeixinJSBridge.on(n,function(e){t&&t.trigger&&t.trigger(e),A(n,e,i)}):B(n,t||i)}function x(e){return(e=e||{}).appId=v.appId,e.verifyAppId=v.appId,e.verifySignType="sha1",e.verifyTimestamp=v.timestamp+"",e.verifyNonceStr=v.nonceStr,e.verifySignature=v.signature,e}function V(e){return{timeStamp:e.timestamp+"",nonceStr:e.nonceStr,package:e.package,paySign:e.paySign,signType:e.signType||"SHA1"}}function A(e,n,i){"openEnterpriseChat"!=e&&"openBusinessView"!==e||(n.errCode=n.err_code),delete n.err_code,delete n.err_desc,delete n.err_detail;var t=n.errMsg;t||(t=n.err_msg,delete n.err_msg,t=function(e,n){var i=e,t=a[i];t&&(i=t);var o="ok";if(n){var r=n.indexOf(":");"confirm"==(o=n.substring(r+1))&&(o="ok"),"failed"==o&&(o="fail"),-1!=o.indexOf("failed_")&&(o=o.substring(7)),-1!=o.indexOf("fail_")&&(o=o.substring(5)),"access denied"!=(o=(o=o.replace(/_/g," ")).toLowerCase())&&"no permission to execute"!=o||(o="permission denied"),"config"==i&&"function not exist"==o&&(o="ok"),""==o&&(o="fail")}return n=i+":"+o}(e,t),n.errMsg=t),(i=i||{})._complete&&(i._complete(n),delete i._complete),t=n.errMsg||"",v.debug&&!i.isInnerInvoke&&alert(JSON.stringify(n));var o=t.indexOf(":");switch(t.substring(o+1)){case"ok":i.success&&i.success(n);break;case"cancel":i.cancel&&i.cancel(n);break;default:i.fail&&i.fail(n)}i.complete&&i.complete(n)}function C(e){if(e){for(var n=0,i=e.length;n<i;++n){var t=e[n],o=c[t];o&&(e[n]=o)}return e}}function B(e,n){if(!(!v.debug||n&&n.isInnerInvoke)){var i=a[e];i&&(e=i),n&&n._complete&&delete n._complete,console.log('"'+e+'",',n||"")}}function L(){return(new Date).getTime()}function O(e){l&&(o.WeixinJSBridge?e():i.addEventListener&&i.addEventListener("WeixinJSBridgeReady",e,!1))}});
common/math.js
New file
@@ -0,0 +1,24 @@
const $math = require('mathjs')
export const math = {
  add () {
    return comp('add', arguments)
  },
  subtract () {
    return comp('subtract', arguments)
  },
  multiply () {
    return comp('multiply', arguments)
  },
  divide () {
    return comp('divide', arguments)
  }
}
function comp (_func, args) {
  let t = $math.chain($math.bignumber(args[0]))
  for (let i = 1; i < args.length; i++) {
    t = t[_func]($math.bignumber(args[i]))
  }
  // 防止超过6位使用科学计数法
  return parseFloat(t.done())
}
common/util.js
@@ -1,3 +1,121 @@
import {
    log
} from 'mathjs';
import JSEncrypt from './jsencrypt';
import {
    ACCESSTOKEN,
    config
} from '@/common/config.js'
let publicKey =
    'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTREknOkrusbeH7kBe3mSw4AwVT438IWmX/jKmcvYxaAWRrBJiMl7gk37L78HBG/ZstLLcdKBYYdj/5cvVWDQfv+uxbv/piZhOmQej98jWIXEA8aFEk724nFRJ7nfcEhHSWfzbTfgZw0KDO1mWdjWHnHIx/MtD0HIFFIyzg3aO7wIDAQAB';
//校验银行卡号
export function verifyBankCard(str) {
    //银行卡号长度在16到19之间
    if (str.length < 16 || str.length > 19) {
        return false;
    }
    var num = /^\d*$/;
    if (!num.exec(str)) {
        //银行卡号必须全为数字;
        return false;
    }
    //开头6位
    var strBin =
        "10,18,30,35,37,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,60,62,65,68,69,84,87,88,94,95,98,99";
    if (strBin.indexOf(str.substring(0, 2)) == -1) { //银行卡号开头6位不符合规范
        return false;
    }
    var lastNum = str.substr(str.length - 1, 1); //取出最后一位(与luhm进行比较)
    var first15Num = str.substr(0, str.length - 1); //前15或18位
    var newArr = new Array();
    for (var i = first15Num.length - 1; i > -1; i--) { //前15或18位倒序存进数组
        newArr.push(first15Num.substr(i, 1));
    }
    var arrJiShu = new Array(); //奇数位*2的积 <9
    var arrJiShu2 = new Array(); //奇数位*2的积 >9
    var arrOuShu = new Array(); //偶数位数组
    for (var j = 0; j < newArr.length; j++) {
        if ((j + 1) % 2 == 1) { //奇数位
            if (parseInt(newArr[j]) * 2 < 9)
                arrJiShu.push(parseInt(newArr[j]) * 2);
            else
                arrJiShu2.push(parseInt(newArr[j]) * 2);
        } else //偶数位
            arrOuShu.push(newArr[j]);
    }
    var jishu_child1 = new Array(); //奇数位*2 >9 的分割之后的数组个位数
    var jishu_child2 = new Array(); //奇数位*2 >9 的分割之后的数组十位数
    for (var h = 0; h < arrJiShu2.length; h++) {
        jishu_child1.push(parseInt(arrJiShu2[h]) % 10);
        jishu_child2.push(parseInt(arrJiShu2[h]) / 10);
    }
    var sumJiShu = 0; //奇数位*2 < 9 的数组之和
    var sumOuShu = 0; //偶数位数组之和
    var sumJiShuChild1 = 0; //奇数位*2 >9 的分割之后的数组个位数之和
    var sumJiShuChild2 = 0; //奇数位*2 >9 的分割之后的数组十位数之和
    var sumTotal = 0;
    for (var m = 0; m < arrJiShu.length; m++) {
        sumJiShu = sumJiShu + parseInt(arrJiShu[m]);
    }
    for (var n = 0; n < arrOuShu.length; n++) {
        sumOuShu = sumOuShu + parseInt(arrOuShu[n]);
    }
    for (var p = 0; p < jishu_child1.length; p++) {
        sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p]);
        sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p]);
    }
    //计算总和
    sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2);
    //计算Luhm值
    var k = parseInt(sumTotal) % 10 == 0 ? 10 : parseInt(sumTotal) % 10;
    var luhm = 10 - k;
    if (lastNum == luhm) {
        return true;
    } else {
        return false;
    }
}
/**
 * 加密
 * @param {Object} pas
 */
export function RSAencrypt(pas) {
    //实例化jsEncrypt对象
    let jse = new JSEncrypt();
    //设置公钥
    jse.setPublicKey(publicKey);
    return jse.encrypt(pas);
}
/**
 * 拼接ftp图片路径
 * @param {Object} item
 * @param {Object} src
 */
export function getImgPath(item, src) {
    if (isBlank(item)) {
        return src
    }
    var ftp = config.sftpURL
    if (typeof item === 'string') {
        const arr = JSON.parse(item)
        return ftp + arr[0].path
    } else if (typeof item === 'object') {
        return ftp + item.path
    } else {
        return ftp + item
    }
}
/**
 * 判断字符串空
@@ -10,49 +128,528 @@
        return false
    }
}
/**
 * 两数相乘 arg1 * arg2
 * @Date 2020/5/9 13:19
 **/
export function accMul(arg1, arg2) {
    let t = 0
    arg1 = arg1 ? arg1.toString() : '0'
    arg2 = arg2 ? arg2.toString() : '0'
    if (arg1.includes('.')) {
        t += arg1.split('.')[1].length
    }
    if (arg2.includes('.')) {
        t += arg2.split('.')[1].length
    }
    const r1 = Number(arg1.replace('.', ''))
    const r2 = Number(arg2.replace('.', ''))
    return (r1 * r2) / Math.pow(10, t)
}
/**
 * 两数相除 arg1 / arg2
 * @Date 2020/5/9 13:18
 **/
export function accDiv(arg1, arg2) {
    let t = 0
    arg1 = arg1 ? arg1.toString() : '0'
    arg2 = arg2 ? arg2.toString() : '0'
    if (arg2.includes('.')) {
        t = arg2.split('.')[1].length
    }
    if (arg1.includes('.')) {
        t -= arg1.split('.')[1].length
    }
    const r1 = Number(arg1.replace('.', ''))
    const r2 = Number(arg2.replace('.', ''))
    return accMul((r1 / r2), Math.pow(10, t))
}
/**
 * 判断非空
 * @param {Object} str
 */
export function isNotBlank(str) {
    return !isBlank(str)
}
/**
 * 判断token是否存在
 */
export function getToken() {
    return uni.getStorageSync(ACCESSTOKEN);
}
/**
 * 判断token是否存在
 */
export function hasToken() {
    return !isBlank(getToken());
}
/**
 * 获取用户信息
 */
export function getUserInfo() {
    return JSON.parse(uni.getStorageSync('userInfo'))
}
/**
 * 判断两个数组的内容是否相同
 */
export function arrEquals(arr1, arr2) {
    // if the other arr2 is a falsy value, return
    if (!arr2)
        return false;
    // compare lengths - can save a lot of time
    if (arr1.length != arr2.length)
        return false;
    for (var i = 0, l = arr1.length; i < l; i++) {
        // Check if we have nested arr2s
        if (arr1[i] instanceof Array && arr2[i] instanceof Array) {
            // recurse into the nested arr2s
            if (!arr1[i].equals(arr2[i]))
                return false;
        } else if (arr1[i] != arr2[i]) {
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;
        }
    }
    return true;
}
/**
 * 获取当前时间
 */
export function getDate(type) {
    const date = new Date();
    let year = date.getFullYear();
    let month = date.getMonth() + 1;
    let day = date.getDate();
    if (type === 'start') {
        year = year - 60;
    } else if (type === 'end') {
        year = year + 2;
    }
    month = month > 9 ? month : '0' + month;;
    day = day > 9 ? day : '0' + day;
    return `${year}-${month}-${day}`;
}
/**
 * 判断是否为整数,为整数则拼接'.0'
 */
export function rateMark(num) {
    if (Number.isInteger(num)) {
        return num + '.0'
    } else {
        return num
    }
}
/**
 * 秒转分钟
 * @param {Object} value
 */
export function formatSeconds(value) {
    var secondTime = parseInt(value); // 秒
    var minuteTime = 0; // 分
    var hourTime = 0; // 小时
    if (secondTime > 60) { //如果秒数大于60,将秒数转换成整数
        //获取分钟,除以60取整数,得到整数分钟
        minuteTime = parseInt(secondTime / 60);
        //获取秒数,秒数取佘,得到整数秒数
        secondTime = parseInt(secondTime % 60);
        //如果分钟大于60,将分钟转换成小时
        if (minuteTime > 60) {
            //获取小时,获取分钟除以60,得到整数小时
            hourTime = parseInt(minuteTime / 60);
            //获取小时后取佘的分,获取分钟除以60取佘的分
            minuteTime = parseInt(minuteTime % 60);
        }
    }
    var result = "" + parseInt(secondTime) + "秒";
    if (minuteTime > 0) {
        result = "" + parseInt(minuteTime) + "分" + result;
    }
    if (hourTime > 0) {
        result = "" + parseInt(hourTime) + "小时" + result;
    }
    return result;
}
/**
 * 日期格式化
 * @param {Object} date
 * @param {Object} fmt
 */
export function dateFormat(date, fmt) {
    if (!date) {
        return
    }
    if (!fmt) {
        fmt = 'yyyy-MM-dd hh:mm'
    }
    if (!(date instanceof Date)) {
        date = new Date(date.replace(/-/g, '/'))
    }
    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    let o = {
        'M+': date.getMonth() + 1,
        'd+': date.getDate(),
        'h+': date.getHours(),
        'm+': date.getMinutes(),
        's+': date.getSeconds()
    };
    for (let k in o) {
        if (new RegExp(`(${k})`).test(fmt)) {
            let str = o[k] + '';
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : ('00' + str).substr(str.length));
        }
    }
    return fmt;
}
/**
 * 传入时间格式的时间,以当前时间为标准,返回距离当前时间之前
 */
export function timeago(date) { //dateTimeStamp是一个时间毫秒,注意时间戳是秒的形式,在这个毫秒的基础上除以1000,就是十位数的时间戳。13位数的都是时间毫秒。
    if (!date) {
        return
    }
    if (!(date instanceof Date)) {
        date = new Date(date.replace(/-/g, '/'))
    }
    var dateTimeStamp = date.getTime()
    var minute = 1000 * 60; //把分,时,天,周,半个月,一个月用毫秒表示
    var hour = minute * 60;
    var day = hour * 24;
    var week = day * 7;
    var halfamonth = day * 15;
    var month = day * 30;
    var now = new Date().getTime(); //获取当前时间毫秒
    var diffValue = now - dateTimeStamp; //时间差
    if (diffValue < 0) {
        return;
    }
    var minC = diffValue / minute; //计算时间差的分,时,天,周,月
    var hourC = diffValue / hour;
    var dayC = diffValue / day;
    var weekC = diffValue / week;
    var monthC = diffValue / month;
    var result = '';
    if (monthC >= 1 && monthC <= 3) {
        result = " " + parseInt(monthC) + "月前"
    } else if (weekC >= 1 && weekC <= 3) {
        result = " " + parseInt(weekC) + "周前"
    } else if (dayC >= 1 && dayC <= 6) {
        result = " " + parseInt(dayC) + "天前"
    } else if (hourC >= 1 && hourC <= 23) {
        result = " " + parseInt(hourC) + "小时前"
    } else if (minC >= 1 && minC <= 59) {
        result = " " + parseInt(minC) + "分钟前"
    } else if (diffValue >= 0 && diffValue <= minute) {
        result = "刚刚"
    } else {
        var datetime = new Date();
        datetime.setTime(dateTimeStamp);
        var Nyear = datetime.getFullYear();
        var Nmonth = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
        var Ndate = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
        var Nhour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours();
        var Nminute = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes();
        var Nsecond = datetime.getSeconds() < 10 ? "0" + datetime.getSeconds() : datetime.getSeconds();
        result = Nyear + "-" + Nmonth + "-" + Ndate
    }
    return result;
}
/**
 * 数组截取
 * @param {Object} data
 * @param {Object} index
 * @param {Object} num
 */
export function subArray(data, index, num) {
    return data.slice(index * num, (index * num) + num)
}
// 根据索引替换字符串中的元素,常用语字符串加密
export function stringReplace(content, start, num, str) {
    var content = content.split("");
    content.splice(start, num, str)
    return content.join("");
}
export function getByteLength(str) {
    //先把中文替换成两个字节的英文,在计算长度
    var aa = str.replace(/[\u0391-\uFFE5]/g, "@@")
    return aa.length;
}
export function getDiffDay(date_1, date_2) {
    // 计算两个日期之间的差值
    let totalDays, diffDate
    let myDate_1 = new Date(date_1.replace(/-/g, '/'))
    let myDate_2 = new Date(date_2.replace(/-/g, '/'))
    // 将两个日期都转换为毫秒格式,然后做差
    diffDate = Math.abs(myDate_1 - myDate_2) // 取相差毫秒数的绝对值
    totalDays = Math.floor(diffDate / (1000 * 3600 * 24)) // 向下取整
    // console.log(totalDays)
    return totalDays // 相差的天数
}
/**
 * 获取两个日期相差的月日时分
 * @param {Object} start
 * @param {Object} end
 * @param {Object} cha
 * @param {Object} flag
 */
export function timeFn(start, end, cha, flag) {
    if (!!!cha) {
        cha = 0
    }
    if (!(start instanceof Date)) {
        start = new Date(start.replace(/-/g, '/'))
    }
    start.setSeconds(start.getSeconds() - 1)
    if (!(end instanceof Date)) {
        end = new Date(end.replace(/-/g, '/'))
    }
    var dateDiff = end.getTime() - start + cha; //时间差的毫秒数
    if (dateDiff == 0) {
        return null
    }
    var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000)); //计算出相差天数
    var leave1 = dateDiff % (24 * 3600 * 1000) //计算天数后剩余的毫秒数
    var hours = Math.floor(leave1 / (3600 * 1000)) //计算出小时数
    //计算相差分钟数
    var leave2 = leave1 % (3600 * 1000) //计算小时数后剩余的毫秒数
    var minutes = Math.floor(leave2 / (60 * 1000)) //计算相差分钟数
    //计算相差秒数
    var leave3 = leave2 % (60 * 1000) //计算分钟数后剩余的毫秒数
    var seconds = Math.round(leave3 / 1000)
    var leave4 = leave3 % (60 * 1000) //计算分钟数后剩余的毫秒数
    var minseconds = Math.round(leave4 / 1000)
    if (seconds * 1 < 10) {
        seconds = '0' + seconds
    }
    if (minutes * 1 < 10) {
        minutes = '0' + minutes
    }
    if (hours * 1 < 10) {
        hours = '0' + hours
    }
    if (flag) {
        var timeFn = (dayDiff ? dayDiff + "天" : '') + hours + "时" + minutes + "分" + seconds + "秒";
        return timeFn;
    }
    var timeFn = (dayDiff ? dayDiff + "天" : '') + hours + ":" + minutes + ":" + seconds;
    return timeFn;
}
/**
 * 简单的uuid
 */
export function guid() {
    return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0,
            v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}
/**
 * 获取long型数据
 */
export function glong() {
    return 'xxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.floor((Math.random() * 10)) | 0,
            v = c == 'x' ? r : (r & 0x3);
        return v.toString();
    });
}
/**
 * 页面跳转
 * @param {Object} url
 * @param {Object} param
 */
export function go(url, param) {
    var pm = '';
    if (param != undefined) {
        if (typeof param === 'string') {
            param = JSON.parse(param)
        }
        for (var p in param) {
            //遍历json对象的每个key/value对,p为key
            pm += '&' + p + '=' + param[p];
        }
    }
    pm = pm.substr(1);
    uni.navigateTo({
        url: url + '?' + pm
    });
}
/**
 * 页面跳转
 * @param {Object} url
 * @param {Object} param
 */
export function redirect(url, param) {
    var pm = '';
    if (param != undefined) {
        if (typeof param === 'string') {
            param = JSON.parse(param)
        }
        for (var p in param) {
            //遍历json对象的每个key/value对,p为key
            pm += '&' + p + '=' + param[p];
        }
    }
    pm = pm.substr(1);
    uni.redirectTo({
        url: url + '?' + pm
    });
}
/**
 * 跳转首页
 */
export function goIndex() {
    uni.reLaunch({
        url: '/pages/index/index'
    });
}
/**
 * 跳转登录页
 */
export function goLogin(callbackUrl) {
    if (callbackUrl) {
        uni.redirectTo({
            url: `/pages/user/login/index?callbackUrl=/${callbackUrl}`
        });
    } else {
        uni.redirectTo({
            url: `/pages/user/login/index`
        });
    }
}
/**
 * 返回
 */
export function goBack() {
    uni.navigateBack()
}
/**
 * 颜色16进制转RGB方法
 * @param {Object} c
 */
export function colorRgb(c) {
    var sColor = c.toLowerCase();
    //十六进制颜色值的正则表达式
    var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
    // 如果是16进制颜色
    if (sColor && reg.test(sColor)) {
        if (sColor.length === 4) {
            var sColorNew = "#";
            for (var i = 1; i < 4; i += 1) {
                sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
            }
            sColor = sColorNew;
        }
        //处理六位的颜色值
        var sColorChange = [];
        for (var i = 1; i < 7; i += 2) {
            sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
        }
        return "(" + sColorChange.join(",") + ",.08)";
    }
    return sColor;
};
/**
 * 验证手机号
 * @param {Object} mobile
 */
export function checkMobile(mobile) {
    return /^1[3456789]\d{9}$/.test(mobile);
}
/**
 * 验证身份证号
 * @param {Object} cardNo
 */
export function checkCardNo(cardNo) {
    return /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/
        .test(cardNo);
}
/**
 * 验证邮箱
 * @param {Object} email
 */
export function checkEmail(email) {
    return /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(email);
}
/**
 * 阿拉伯数字转中文数字
 * @param {Object} num
 */
export function NoToChinese(num) {
    var AA = new Array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九");
    var BB = new Array("", "十", "百", "千", "万", "亿", "点", "");
    var a = ("" + num).replace(/(^0*)/g, "").split("."),
        k = 0,
        re = "";
    for (var i = a[0].length - 1; i >= 0; i--) {
        switch (k) {
            case 0:
                re = BB[7] + re;
                break;
            case 4:
                if (!new RegExp("0{4}\\d{" + (a[0].length - i - 1) + "}$").test(a[0]))
                    re = BB[4] + re;
                break;
            case 8:
                re = BB[5] + re;
                BB[7] = BB[5];
                k = 0;
                break;
        }
        if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0) re = AA[0] + re;
        if (a[0].charAt(i) != 0) re = AA[a[0].charAt(i)] + BB[k % 4] + re;
        k++;
    }
    if (a.length > 1) //加上小数部分(如果有小数部分)
    {
        re += BB[6];
        for (var i = 0; i < a[1].length; i++) re += AA[a[1].charAt(i)];
    }
    return re;
};
/**
 * 合并对象相同属性
 * chenlong
 * @param obj1 目标对象
 * @param obj2 源对象
 */
export function mergeObj(obj1, obj2) {
    const res = {}
    Object.keys(obj2).map(key => {
        if (key in obj1) {
            res[key] = obj2[key]
        }
    })
    return res
}
/**
 * 获取返回值
 * @param {Object} res
 * @param {Object} fun
 */
export function getContent(res, fun) {
    if (res.code === 10000) {
        fun(res.data)
    } else {
        uni.showToast({
            title: res.msg,
            duration: 1500,
            icon: 'none'
        });
    }
}
/* 正整数 */
@@ -106,31 +703,218 @@
    }
    return parseFloat(val) / 100
}
/* 元转分 */
export function yuanToFen(amount) {
    let fen = 0
    if (!amount) {
        return fen;
/**
 * 提示错误信息
 */
export function showErrorMsg(msg) {
    uni.showToast({
        title: msg,
        icon: 'none'
    });
    return false;
    }
    fen = accMul(amount,100)
    console.log(amount,fen);
    return fen
/**
 * 提示成功信息
 */
export function showSuccessMsg(msg) {
    uni.showToast({
        title: msg,
        icon: 'none'
    });
}
/* 分转元 */
export function fenToYuan(amount) {
    if (!amount) {
        return "0";
/**
 * 计算时间差
 */
export function timeDiff(startTime, endTime) {
    // 计算相差的时间
    const timeDiff = endTime.getTime() - startTime.getTime();
    if (timeDiff <= 0) return false;
    const totalSeconds = Math.floor(timeDiff / 1000);
    const hours = Math.floor(totalSeconds / 60 / 60);
    const minutes = Math.floor((totalSeconds - hours * 60 * 60) / 60);
    const seconds = Math.floor(totalSeconds - hours * 60 * 60 - minutes * 60);
    const timeDiffArray = [hours, minutes, seconds].map(e => {
        return e < 10 ? '0' + e : e;
    });
    return timeDiffArray;
    }
    amount = amount.toString();
    if (amount.length == 1) {
        return parseFloat("0.0" + amount);
    } else if (amount.length == 2) {
        return parseFloat("0." + amount);
/**
 * 两数相加 arg1 + arg2
 * @param arg1
 * @param arg2
 * @returns {number}
 */
export function add(arg1, arg2) {
    var t = 0
    arg1 = arg1 ? arg1.toString() : '0'
    arg2 = arg2 ? arg2.toString() : '0'
    if (arg1.includes('.')) {
        t = arg1.split('.')[1].length
    }
    if (arg2.includes('.')) {
        t = Math.max(arg2.split('.')[1].length, t)
    }
    var m = Math.pow(10, t)
    return Number(((this.mul(arg1, m) + this.mul(arg2, m)) / m))
}
/**
 * 两数相减 arg1 - arg2
 * @param arg1
 * @param arg2
 * @returns {number}
 */
export function sub(arg1, arg2) {
    var t = 0
    arg1 = arg1 ? arg1.toString() : '0'
    arg2 = arg2 ? arg2.toString() : '0'
    if (arg1.includes('.')) {
        t = arg1.split('.')[1].length
    }
    if (arg2.includes('.')) {
        t = Math.max(arg2.split('.')[1].length, t)
    }
    var m = Math.pow(10, t)
    return Number(((this.mul(arg1, m) - this.mul(arg2, m)) / m))
}
/**
 * 两数相乘 arg1 * arg2
 * @param arg1
 * @param arg2
 * @returns {number}
 */
export function mul(arg1, arg2) {
    var t = 0
    arg1 = arg1 ? arg1.toString() : '0'
    arg2 = arg2 ? arg2.toString() : '0'
    if (arg1.includes('.')) {
        t += arg1.split('.')[1].length
    }
    if (arg2.includes('.')) {
        t += arg2.split('.')[1].length
    }
    var r1 = Number(arg1.replace('.', ''))
    var r2 = Number(arg2.replace('.', ''))
    return (r1 * r2) / Math.pow(10, t)
}
/**
 * 两数相除 arg1 / arg2
 * @param arg1
 * @param arg2
 * @returns {number}
 */
export function abs(arg1, arg2) {
    var t = 0
    arg1 = arg1 ? arg1.toString() : '0'
    arg2 = arg2 ? arg2.toString() : '0'
    if (arg2.includes('.')) {
        t = arg2.split('.')[1].length
    }
    if (arg1.includes('.')) {
        t -= arg1.split('.')[1].length
    }
    var r1 = Number(arg1.replace('.', ''))
    var r2 = Number(arg2.replace('.', ''))
    return this.mul((r1 / r2), Math.pow(10, t))
}
/**
 * arg1*100/(arg1+arg2)
 * @param {Object} arg2
 * @param {Object} arg1
 */
export function percentage(arg1, arg2) {
    var add = this.add(arg1, arg2)
    return this.mul(this.abs(arg1, add), 100)
}
/**
 * 查看网络状态
 * false 没有网络  true 有网络
 */
export function getNetworkStatus() {
    var result = ''
    uni.getNetworkType({
        success: (res) => {
            if (res.networkType == 'none') {
                // this.$u.toast("没有网络");
                result = false
    } else {
        return parseFloat(amount.substring(0, amount.length - 2) + "." + amount.substring(amount.length - 2));
                // this.$u.toast("有网络");
                result = true
    }
}
// 判断微信、支付宝  2微信 5支付宝 3其他
    })
    return result
}
/**
 * @param {Object} key 缓存的key
 * @param {Object} param 要缓存的对象
 * 将param push到缓存数组中
 */
export function setArrayStorageSync(key, param) {
    const data = uni.getStorageSync(key) || []
    data.push(param)
    uni.setStorageSync(key, data)
}
// 获取轮播图列表
export function getBannerImg(val, state) {
    let list = []
    if (!isBlank(val) && state === '2') {
        let arr = JSON.parse(val)
        arr.map(x => {
            list.push(config.sftpURL + x.path)
        })
    } else {
        list = [config.imgUrl + 'no-book.png']
    }
    return list
}
// 商品图片路径
export function getGoodsImg(val, state) {
    let headImg = ""
    if (!isBlank(val) && state === '2') {
        headImg = config.sftpURL + JSON.parse(val)[0].path
    } else {
        headImg = config.imgUrl + 'no-book.png'
    }
    return headImg
}
// 图片路径
export function GoodsImg(val) {
    let headImg = ""
    if (!isBlank(val)) {
        headImg = config.sftpURL + val
    } else {
        headImg = config.imgUrl + 'no-book.png'
    }
    return headImg
}
// 保留三位小数 末尾超过向上进1
export function getDiscountPrice(price, discount) {
    let newPrice = ""
    let a = Number(price) * Number(discount) / 100
    let b = a.toFixed(4)
    let c = b[b.length - 1]
    newPrice = c != 0 ? Number(b) + 0.01 : b.slice(0, -1)
    return newPrice
}
// 判断微信、支付宝  2微信 5支付宝 15云闪付 3其他
export function getPlat() {
    // #ifdef H5
    var ua = window.navigator.userAgent.toLowerCase();
components/bind-card-activity/bind-card-activity.vue
New file
@@ -0,0 +1,161 @@
<template>
    <view>
        <view class="bg-fff u-br-20 box">
            <image src="/static/bind-card-modal.png" class="top-bg"></image>
            <view class="title">绑卡成功</view>
            <view class="u-flex u-row-center u-m-t-40 u-m-b-30">
                <image class="title-bg" src="/static/title-left.png" mode=""></image>
                <view class="title-txt">已获<text>{{couponList.length}}</text>张优惠券</view>
                <image class="title-bg" src="/static/title-right.png" mode=""></image>
            </view>
            <view v-for="(item,i) in couponList" :key="i" class="coupon">
                <view class="num-box">
                    <view v-if="item.discount_type==1"><text class="unit">¥</text><text class="money">{{item.discount / 100}}</text></view>
                    <view v-else><text class="money">{{item.item.discount}}</text><text class="unit">折</text></view>
                    <view v-if="item.threshold == 0" class="cont">无门槛</view>
                    <view v-else class="cont">满{{item.threshold_value / 100}}元使用</view>
                </view>
                <view class="info-box">
                    <view class="coupon-name">{{item.name}}</view>
                    <view class="coupon-date">有效期至:{{$u.timeFormat(item.out_time, 'yyyy-mm-dd hh:MM')}}</view>
                </view>
            </view>
            <navigator open-type="navigateBack" class="btn">去使用</navigator>
        </view>
        <!-- <image @click="$emit('close')" class="close" src="/static/close-icon.png" mode=""></image> -->
    </view>
</template>
<script>
    export default {
        name: "bind-card-activity",
        props:{
            couponList:{
                type:Array,
                default: []
            }
        },
        data() {
            return {
            };
        }
    }
</script>
<style lang="scss" scoped>
    .box {
        background-image: linear-gradient(180deg, rgba(254, 254, 252, 1) 0%, rgba(253, 242, 225, 1) 100%);
        width: 600rpx;
        padding-bottom: 35rpx;
    }
    .top-bg {
        width: 628rpx;
        height: 385rpx;
        position: absolute;
        top: -225rpx;
        left: -16rpx;
    }
    .title {
        font-size: 36rpx;
        color: #C6774B;
        font-weight: bold;
        width: 337rpx;
        height: 76rpx;
        background-image: url(~@/static/bind-card-title.png);
        background-size: contain;
        text-align: center;
        line-height: 76rpx;
        position: relative;
        left: 141.5rpx;
    }
    .title-bg {
        width: 131rpx;
        height: 21rpx;
    }
    .title-txt {
        font-size: 28rpx;
        color: #B36C44;
    }
    .title-txt text {
        color: #D31F28;
    }
    .coupon {
        width: 508rpx;
        height: 145rpx;
        background-image: url(~@/static/coupon-bg2.png);
        background-size: 100% 100%;
        margin: 0 auto 10rpx;
        display: flex;
    }
    .num-box {
        width: 140rpx;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }
    .unit {
        font-size: 24rpx;
        font-weight: bold;
        color: #D31F28;
    }
    .money {
        font-size: 50rpx;
        font-weight: bold;
        color: #D31F28;
    }
    .cont {
        font-size: 20rpx;
        color: #D31F28;
    }
    .info-box {
        flex: 1;
        padding: 0 15rpx;
        display: flex;
        flex-direction: column;
        justify-content: center;
    }
    .coupon-name {
        font-size: 24rpx;
        color: #333333;
    }
    .coupon-date {
        margin-top: 10rpx;
        font-size: 20rpx;
        color: #999;
    }
    .btn {
        width: 476rpx;
        height: 88rpx;
        border-radius: 44rpx;
        background-color: rgba(238, 68, 82, 1);
        margin: 30rpx auto 0;
        font-size: 36rpx;
        color: #fff;
        font-weight: bold;
        line-height: 88rpx;
        text-align: center;
    }
    .close{
        display: block;
        width: 64rpx;
        height: 64rpx;
        margin: 30rpx auto 0;
    }
</style>
components/card-agreement/card-agreement.vue
New file
@@ -0,0 +1,106 @@
<template>
    <view class="agreement-main">
        <h1>协议详情</h1>
        <scroll-view class="con" scroll-y>
            <p>
                XXXXX有限公司(以下均简称“XXX”)在此提醒您(以下称“您”或称“用户”)认真阅读理解本协议,包括免除或者限制XXX责任的免责条款及对您的权利限制条款;您确认,在您使用XXX的各项服务之前,您已充分阅读、理解并接受本协议的全部内容,一旦您在“我已阅读并同意”前勾选,或点击“我已阅读并同意”按钮,即表示您同意遵循本协议之所有约定,一旦您使用XXX的全部或部分服务,亦表示您同意遵循本协议之所有约定。本协议在您和XXX之间具有合同上的法律效力
            </p>
            <p>甲方:全体XXX注册用户(以上以下简称“你”或称“用户”)</p>
            <p>乙方:XXXXX有限公司(以上以下均简称“XXX”)</p>
            <p><strong>一、</strong>
                您同意通过本协议选定的您银行卡(以下简称“银行卡”)在XXX平台与您在第三方支付机构的托管账户上进行绑定、开通快捷支付业务,即本协议所述的“绑定”为扣款银行卡的确定,一旦绑定成功,第三方支付机构每次扣款前无需输入您绑定的银行卡账号、密码等信息,也无需您提交绑定的银行卡进行刷卡
            </p>
            <p></p>
            <p><strong>二、</strong> 您承诺上述选定的银行卡的开户证件信息与您身份证件信息完全一致。</p>
            <p></p>
            <p><strong>三、</strong> 您允许XXX向快捷支付第三方支付机构发送您的信息(包括但不限于您的身份信息、银行信息、XXX注册信息等涉及您个人的各项信息)以便完成快捷支付业务。</p>
            <p></p>
            <p><strong>四、</strong>
                XXX向第三方支付机构发送的您的一切信息是依据您自己主动填写的信息,XXX有权利但无义务审查您的银行卡信息与身份证件信息。XXX不对是否进行审查核实做出任何承诺,一切以您填写的信息为准。</p>
            <p></p>
            <p><strong>五、</strong>您必须按照第三方支付机构的快捷支付协议的要求绑定符合第三方支付机构要求的银行卡,并且您承诺是绑定的银行卡的合法持卡人(指银行卡账户的开户主体,下同)。</p>
            <p></p>
            <p><strong>六、</strong> 其他有关绑定银行卡、开通快捷支付的权利义务详见您与第三方支付机构达成的快捷支付协议的各项约定。</p>
            <p></p>
            <p><strong>七、</strong> 您与第三方支付机构因快捷支付相关事宜发生的争议与纠纷,请您按照您与第三方支付机构之间的快捷支付协议的约定解决,XXX不对您与第三方支付机构之间的争议承担任何责任。</p>
            <p></p>
            <p><strong>八、</strong>
                您的个人资料受到严格保护,不接受XXX、第三方支付机构、您银行卡开户行及您之外的任何个人或单位的查询请求。但法律法规(含行政规章、民族自治地方的自治条例和单行条例,下同)、司法机关、监管机构、你与第三方支付机构之前的快捷支付协议另有规定或要求,或为开通快捷支付之需要确有必要披露的除外。
            </p>
            <p></p>
            <p><strong>九、</strong> 您承诺如果因您违反本协议或者与第三方支付机构之间的协议造成XXX损失的,XXX有权向你追究法律责任。</p>
            <p></p>
            <p>本协议版本于2023年6月30日更新,于2023年7月1日生效。</p>
        </scroll-view>
        <div @click="$emit('confirm')">我已阅读并同意</div>
    </view>
</template>
<script>
    export default {
        name: "card-agreement",
        data() {
            return {
            };
        }
    }
</script>
<style lang="scss" scoped>
    .agreement-main {
        padding: 30rpx;
        background: #fff;
        border-radius: 30rpx;
    }
    .agreement-main h1 {
        text-align: center;
        font-size: 32rpx;
        color: #333333;
    }
    .agreement-main i {
        position: absolute;
        right: 30rpx;
        top: 30rpx;
        background: url('https://zhkj.jinmingyuan.com:8443/sftpxcx/jrstq/icon-close.png') no-repeat;
        background-size: 100% 100%;
        width: 42rpx;
        height: 42rpx;
    }
    .agreement-main .con {
        color: #545454;
        font-size: 26rpx;
        margin: 30rpx 0;
        height: 630rpx;
        width: 550rpx;
    }
    .agreement-main .con p {
        line-height: 1.65;
        margin-bottom: 5rpx;
    }
    .agreement-main>div {
        height: 66rpx;
        text-align: center;
        line-height: 66rpx;
        color: #fff;
        font-size: 30rpx;
        margin: 0 auto;
        background: #e93b3d;
        border-radius: 33rpx;
    }
    strong {
        margin-right: 5rpx;
    }
    .mask {
        position: fixed;
        z-index: 9
    }
</style>
components/input-number/input-number.vue
New file
@@ -0,0 +1,171 @@
<template>
    <view class="count-box" :class="status ? 'count-box-light' : 'count-box-gray'">
        <view class="count-less count-pub" :class="[myValue <= min ? 'light' : '']" @tap.stop="less"></view>
        <view class="u-rela u-flex u-col-center">
            <view class="plc">{{myValue}}</view>
            <input type="number" v-model="myValue" @focus="onFocus" @blur="onBlue" class="count-input" />
        </view>
        <view class="count-add count-pub" :class="[myValue >= max ? 'light' : '']" @tap.stop="add"></view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                myValue: 0,
                status: false
            }
        },
        props: {
            // 计数器中的值
            value: {
                type: Number,
                default: 0
            },
            max: {
                type: Number,
                default: 10000
            },
            min: {
                type: Number,
                default: 0
            },
            type: {
                type: String,
                default: 'small'
            }
        },
        created() {
            this.myValue = this.value
        },
        watch: {
            value(val) {
                this.myValue = val
            }
        },
        methods: {
            onBlue() {
                if (+this.myValue >= this.max) {
                    this.myValue = this.max
                    this.status = false
                } else if (+this.myValue <= this.min) {
                    this.myValue = this.min
                    this.status = false
                } else {
                    this.status = true
                    this.myValue = +this.myValue
                }
                if (!isNaN(this.myValue)) {
                    this.$emit('handleCount', this.myValue)
                } else {
                    this.$emit('handleCount', 0)
                }
            },
            onFocus() {
                this.status = true
            },
            add() {
                if (this.myValue >= this.max) {
                    this.status = false
                    this.myValue = this.max
                    uni.showToast({
                        title: "已超过最大积分",
                        icon: "none"
                    })
                    this.myValue = this.max
                } else {
                    this.status = true
                    this.myValue++
                }
                this.$emit('handleCount', this.myValue)
            },
            less() {
                if (this.myValue <= this.min) {
                    this.status = false
                    this.myValue = this.min
                    uni.showToast({
                        title: "不能再少了",
                        icon: "none"
                    })
                    this.myValue = this.min
                } else {
                    this.status = true
                    this.myValue--
                }
                this.$emit('handleCount', this.myValue)
            }
        }
    }
</script>
<style lang="less" scoped>
    .gray {
        color: #555555;
    }
    .light {
        color: #C8C7CC;
    }
    .count-box {
        display: flex;
        align-items: center;
        height: 60rpx;
    }
    .count-pub {
        width: 42rpx;
        height: 42rpx;
    }
    .count-less {
        left: 0;
        width: 42rpx;
        height: 42rpx;
        background: url(../../static/cart/icon_less.png) no-repeat;
        background-size: 42rpx;
    }
    .count-add {
        right: 0;
        width: 42rpx;
        height: 42rpx;
        background: url(../../static/cart/icon_add.png) no-repeat;
        background-size: 42rpx;
    }
    .count-less.light {
        background: url(../../static/cart/icon_lessLight.png) no-repeat;
        background-size: 42rpx;
    }
    .count-add.light {
        background: url(../../static/cart/icon_addLight.png) no-repeat;
        background-size: 42rpx;
    }
    .count-input {
        position: absolute;
        width: 100%;
        height: 42rpx;
        line-height: 42rpx;
        padding: 0 10rpx;
        box-sizing: border-box;
        color: #333;
        font-size: 30rpx;
        text-align: center;
    }
    .plc {
        height: 42rpx;
        line-height: 1;
        text-align: center;
        min-width: 70rpx;
        font-size: 30rpx;
        padding: 0 12rpx;
        visibility: hidden;
    }
</style>
components/key-bord/key-bord.vue
@@ -1,19 +1,20 @@
<template>
  <view class="box">
    <view class="u-text-right u-font-30 color-666 u-p-h-20 u-p-t-10" @click="close">关闭</view>
    <view class="u-p-10 u-flex u-row-between">
    <view>
        <view class="u-text-right u-font-30 color-666 u-p-20" @click="close">关闭</view>
        <view class="u-p-10 bord-box u-flex u-row-between">
      <view class="u-flex u-flex-wrap">
        <view v-for="(num,index) in numList" :key="index" class="num-item" hover-class="num-hover" @click="inputStr(num)">{{num}}</view>
                <view v-for="(num,index) in numList" :key="index" class="num-item" hover-class="num-hover"
                    @click="inputStr(num)">{{num}}</view>
      </view>
      <view class="flex-1 u-flex-col">
        <view hover-class="num-hover" class="del-item u-flex u-row-center" @click="delStr">
          <image src="@/static/del-icon.png" class="del-btn"></image>
                    <image src="@/static/imgs/del-icon.png" class="del-btn"></image>
        </view>
        <view hover-class="num-hover" class="flex-1 pay-btn u-font-30 color-fff font-bold" @click="pay">付款</view>
                <view hover-class="num-hover" class="flex-1 pay-btn u-font-30 color-fff font-bold" @click="pay">付款
      </view>
    </view>
  </view>
    </view>
</template>
<script>
@@ -48,10 +49,6 @@
          //小数点后面最多两位
          return;
        }
        if (this.emitNum == '0.0' && num == '0') {
          //小数点后面最多两位
          return;
        }
      } else if (num == '0' && this.emitNum == '0') {
        // 首位的0最多1个
        return;
@@ -61,9 +58,9 @@
          return;
        }
      }
      if (this.emitNum == '' && num == '.') {
                if (num == '.' && this.emitNum == '') {
        this.emitNum = '0.';
      } else if (this.emitNum == '0' && num != '.') {
                } else if (num != '.' && this.emitNum == '0') {
        this.emitNum = num;
      } else {
        this.emitNum += num;
@@ -87,20 +84,17 @@
}
</script>
<style lang="scss" scoped>
.box {
<style lang="scss">
    .bord-box {
  background-color: #F5F5F5;
  transition: all 0.3s;
  padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/
  padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/
}
.num-item {
  width: 175rpx;
  height: 90rpx;
  line-height: 90rpx;
        height: 80rpx;
        line-height: 80rpx;
  color: #333333;
  font-size: 36rpx;
        font-size: 32rpx;
  font-weight: bold;
  text-align: center;
  margin: 0 10rpx 10rpx 0;
@@ -123,16 +117,14 @@
  background-color: #D45159;
  border-radius: 16rpx;
  text-align: center;
  height: 290rpx;
  line-height: 290rpx;
        height: 270rpx;
        line-height: 270rpx;
  vertical-align: middle;
  color: white;
  margin-bottom: 10rpx;
}
.del-item {
  width: 175rpx;
  height: 90rpx;
        height: 80rpx;
  margin-bottom: 10rpx;
  background-color: #FFFFFF;
}
components/user-agreement/user-agreement.vue
New file
@@ -0,0 +1,261 @@
<template>
    <view class="con">
        <p>欢迎您与中邮邮政集团公司四川省分公司(以下简称“本公司”或“四川邮政”)共同签署《用户协议》。本协议详述您在金融生态圈平台使用邮政服务享受的权益和所须遵守的条款和条件。</p>
        <p></p>
        <p>
            <strong>1</strong>
            <strong>、服务条款的确认和接纳</strong>
        </p>
        <p>
            <strong>1.1</strong>您成为金融生态圈平台用户前,必须阅读、同意并接受本协议中所含的所有条款和条件。本协议在用户接受注册时生效。金融生态圈平台规则、说明、公告和隐私权政策也是本协议不可分割的一部分,如您继续使用金融生态圈平台服务,视为您同意,并受其约束。四川邮政建议您阅读本协议时,也应阅读本文件所提及的其他网页中所包含的资料,因为其可能包含对作为金融生态圈平台用户的您适用的进一步条款和条件。
        </p>
        <p>
            <strong>1.2</strong>
            <strong>四川邮政可能根据实际情况随时通过在金融生态圈平台站上公布经修订的条款以对本协议和规则进行修订。所有经修订的条款自其于网站公布起自动生效。如您不同意该等修订,您必须终止您与金融生态圈平台的用户关系。</strong>
            <strong>如您继续使用金融生态圈平台,即视为知悉变动内容并同意接受。</strong>
        </p>
        <p>
            <strong>1.3</strong>金融生态圈平台的服务仅向适用法律下能够签订具有法律约束力的合同的个人提供并仅由其使用。在不限制前述规定的前提下,
            <strong>金融生态圈平台的服务不向18周岁以下或被临时或无限期中止使用金融生态圈平台服务的用户提供。</strong>在电子商务活动中我们推定你具有相应的民事行为能力,如您不合资格,请勿使用金融生态圈平台的服务。
        </p>
        <p>
            <strong>1.4</strong>
            <strong>当您完成注册后,您可获得金融生态圈平台账户,您的账户密码由您自行设置并由您保管,请务必保管好您的账户。账户因您主动泄露或因您遭受他人攻击、诈骗等行为导致的损失及后果,四川邮政并不承担责任。</strong>
        </p>
        <p>
            <strong>1.5</strong>为了提升用户体验、增加服务内容,金融生态圈平台将不断推出新的服务,金融生态圈平台有权主动对软件进行更新或版本升级,更新或版本升级后,用户在下次登录使用时需要下载、安装并使用最新版本。
        </p>
        <p></p>
        <p>
            <strong>2</strong>
            <strong>、订单、价格和数量</strong>
        </p>
        <p>
            <strong>2.1</strong>使用金融生态圈平台下订单,您应具备购买相关商品的权利能力和行为能力,在下订单的同时,即视为您满足前述条件,并对您在订单中提供的所有信息的真实性负责。
        </p>
        <p>
            <strong>2.2</strong>金融生态圈平台上销售商展示的商品和价格等信息仅仅是要约邀请,您下单时须填写您希望购买的商品数量、价款及支付方式、收货人、联系方式、收货地址等内容;系统生成的订单信息是计算机信息系统根据您填写的内容自动生成的数据,仅是您向销售商发出的合同要约。在您付款完毕且销售商确认后,您与销售商之间就前述订单建立了合同关系。如您与销售商有特殊约定的,以特殊约定为准。
        </p>
        <h4>2.3在您下订单时,请您仔细确认所购商品的名称、价格、数量、型号、规格、尺寸、联系地址、电话、收货人等信息。收货人与您本人不一致的,收货人的行为和意思表示视为您的行为和意思表示,您应对收货人的行为及意思表示的法律后果承担连带责任。
        </h4>
        <p>
            <strong>2.4</strong>金融生态圈平台将尽最大努力保证您所购商品与网站上公布的价格一致,但价目表和声明并不构成要约。同时,金融生态圈平台保留对产品订购的数量等的限制权。本网站无法完全避免您提交的订单信息中的商品出现缺货、价格标示错误等情况;如您下单所购买的商品出现该等情况,您有权取消订单。
        </p>
        <p>
            <strong>2.5</strong>产品的价格和可获性都在金融生态圈平台上指明。这类信息将随时更改且不发任何通知。如无特殊说明,商品的价格是含税价。
            <strong>如果发生了意外情况,在确认了您的订单后,由于税额变化引起的价格变化,或是由于网站的错误或重大误解等造成商品价格变化,您有权取消您的订单,销售商或金融生态圈平台亦有权取消订单并通知您。</strong>
        </p>
        <p></p>
        <p>
            <strong>3</strong>
            <strong>、送货、费用</strong>
        </p>
        <p>
            <strong>3.1</strong>金融生态圈平台将会把产品送到您所指定的送货地址。所有在金融生态圈平台上列出的送货时间为参考时间,参考时间的计算是根据库存状况、正常的处理过程和送货时间、送货地点的基础上估计得出的。送货费用根据您选择的配送方式或金融生态圈平台的规定不同而异。
        </p>
        <p>
            <strong>3.2</strong>请清楚准确地填写您的真实姓名、送货地址、联系人及联系方式。因如下情况造成订单延迟、错误交付或无法配送等,金融生态圈平台将不承担责任:
        <div></div>
        <strong>3.2.1</strong>客户提供错误信息和不详细的地址;
        <div></div>
        <strong>3.2.2</strong>货物送达无人签收,由此造成的重复配送所产生的费用及相关的后果。
        <div></div>
        <strong>3.2.3</strong>不可抗力,例如:自然灾害、恶劣天气、交通戒严、罢工、恐怖事件、突发战争等。
        </p>
        <p></p>
        <p>
            <strong>5</strong>
            <strong>、拒绝提供担保</strong>
        </p>
        <p>
            <strong>用户个人对网络服务的使用承担风险。金融生态圈平台对此不作任何类型的担保,不论是明确的或隐含的。</strong>金融生态圈平台不担保服务一定能满足用户的要求,也不担保服务不会受中断,对服务的及时性、安全性、出错发生都不作担保。四川邮政对在金融生态圈平台上得到的任何商品购物服务或交易进程不作担保。
        </p>
        <p></p>
        <p>
            <strong>6</strong>
            <strong>、有限责任</strong>
        </p>
        <p>
            <strong>6.1</strong>金融生态圈平台对任何非四川邮政故意或重大过失直接、间接、偶然、特殊及继起给您带来的损害不负责任,这些损害可能来自:不正当使用网络服务,在网上购买商品或进行同类型服务,在网上进行交易,非法使用网络服务或用户传送的信息有所变动。上述情况可能会导致金融生态圈平台的形象受损,所以金融生态圈平台事先告知用户此种损害存在的可能性。
        </p>
        <p>
            <strong>6.2</strong>四川邮政将致力于不断提升金融生态圈平台的购物体验,但鉴于网络环境下信息与实物相分离等特点,
            <strong>四川邮政无法逐一审查和核实商家上载或发布的商品及</strong>
            <strong>/</strong>
            <strong>或服务的信息,无法逐一审查交易所涉及的商品及</strong>
            <strong>/</strong>
            <strong>或服务的质量、安全以及合法性、真实性、准确性,因此,如您对选购商品或服务有任何疑问,请您谨慎判断并与商家及时沟通解决,四川邮政将提供协助支持。</strong>
        </p>
        <p></p>
        <p>
            <strong>7</strong>
            <strong>、对用户信息的存储和限制</strong>
        </p>
        <p>金融生态圈平台不对用户所发布信息的删除或储存失败负责。金融生态圈平台有判定用户的行为是否符合金融生态圈平台服务条款的要求和精神的保留权利,如果用户违背了服务条款的规定,金融生态圈平台有中断对其提供网络服务的权利。
        </p>
        <p></p>
        <p>
            <strong>8</strong>
            <strong>、用户管理</strong>
        </p>
        <p>
            <strong>8.1</strong>用户单独承担发布内容的责任。用户对服务的使用是根据所有适用于金融生态圈平台的国家法律、地方法律和国际法律标准。用户必须遵循:
        <div></div>
        <strong>8.1.1</strong>从中国境内向外传输技术性资料时必须符合中国有关法规。
        <div></div>
        <strong>8.1.2</strong>使用网络服务不作非法用途。
        <div></div>
        <strong>8.1.3</strong>不干扰或混乱网络服务。不对金融生态圈平台相关软件进行反向工程、反向汇编、反向编译,或者以其他方式尝试发现源代码或采取黑客、木马等方式侵害软件正常运营或后台数据。
        </p>
        <p>
            <strong>8.1.4</strong>遵守所有使用网络服务的网络协议、规定、程序和惯例。
        <div></div>
        <strong>8.2</strong>用户须承诺不传输任何非法的、骚扰性的、中伤他人的、辱骂性的、恐吓性的、伤害性的、庸俗的,淫秽等信息资料。另外,用户也不能传输何教唆他人构成犯罪行为的资料;不能传输助长国内不利条件和涉及国家安全的资料;不能传输任何不符合当地法规、国家法律和国际法律的资料。未经许可而非法进入其它电脑系统是禁止的。
        <div></div>
        <strong>8.3</strong>若用户的行为不符合以上提到的服务条款,金融生态圈平台将作出独立判断立即取消用户服务账号。用户需对自己在网上的行为承担法律责任。用户若在金融生态圈平台上散布和传播反动、色情或其他违反国家法律的信息,金融生态圈平台的系统记录有可能作为用户违反法律的证据。
        </p>
        <p>
            <strong>8.4</strong>您可在金融生态圈平台上对与您达成交易的商家商品或服务进行评价。您的评价行为应遵守金融生态圈平台相关规则,评价内容不应含有法律禁止和本协议禁止信息。四川邮政可自行判断并对该等评价信息进行删除或屏蔽等。
        </p>
        <p></p>
        <p>
            <strong>9</strong>
            <strong>、结束服务</strong>
        </p>
        <p>
            <strong>9.1</strong>用户或金融生态圈平台可随时根据实际情况中断一项或多项网络服务。金融生态圈平台不需对任何个人或第三方负责而随时中断服务。用户对后来的条款修改有异议,或对金融生态圈平台的服务不满,可以行使如下权利:
        <div></div>
        <strong>9.1.1</strong>停止使用金融生态圈平台的网络服务。
        <div></div>
        <strong>9.1.2</strong>通告金融生态圈平台停止对该用户的服务。
        </p>
        <p>
            <strong>9.1.3</strong>在满足金融生态圈平台账户注销条件时注销您的账户。
        <div></div>
        <strong>9.2</strong>
        <strong style='display:inline'>结束用户服务后,用户使用网络服务的权利马上中止。从那时起,金融生态圈平台也没有义务传送任何未处理的信息或未完成的服务给用户或第三方。</strong>
        </p>
        <p>
            <strong>9.3</strong>如您违反本协议、金融生态圈平台公示的平台规则、发布违禁信息、骗取勒索他人财物、采取不正当手段牟利、侵犯他人合法权益等行为的,金融生态圈平台有权不经通知及时删除、屏蔽相关内容,并对您的账户进行限制部分或全部功能,或予以账户冻结。
        </p>
        <p>
            <strong>9.4</strong>如您的账户存在被盗用、黑客攻击、干扰或经四川邮政分析存在其他异常的,为保护您的权益和四川邮政的利益,金融生态圈平台有权对您的账户进行限制部分或全部功能,或予以暂时账户冻结。
        </p>
        <p>
            <strong>9.5</strong>因您违反本协议或相关服务条款的规定,导致或产生第三方主张的任何索赔、主张或损失,您应当独立承担责任;四川邮政因此遭受损失的,您也应当一并赔偿。
        </p>
        <p></p>
        <p>
            <strong>10</strong>
            <strong>、通知</strong>
        </p>
        <p>
            除非另行明示载明,任何通知将发往您在注册过程中向金融生态圈平台提供的电邮地址或者通过短信、彩信等方式发送至您在注册过程中向四川邮政提供的手机号码上。或者,金融生态圈平台可通过已预付邮资和要求回执的保证航空信,将通知发往您在注册过程中向金融生态圈平台提供或您作出相关更新的地址。您确认接受以上金融生态圈平台使用的通知方式。任何通知应视为于以下时间发出:
        <div> </div>
        <strong>(a)</strong>如通过电邮或者短信、彩信等方式发送,则电邮或者短信、彩信等发送后24个小时,但发送方被告知电邮地址或者手机号码无效的,则属例外;
        <div></div>
        <strong>(b)</strong>如以预付邮资的信件发送,则投邮之日后叁个营业日。
        </p>
        <p></p>
        <p>
            <strong>11</strong>
            <strong>、广告</strong>
        </p>
        <p>用户在他们发表的信息中加入宣传资料或参与广告策划,在金融生态圈平台的免费服务上展示他们的产品,任何这类促销方法,包括运输货物、付款、服务、商业条件、担保及与广告有关的描述都只是在相应的用户和广告发布者之间发生。金融生态圈平台不承担任何责任,金融生态圈平台没有义务为这类广告销售承担任何责任。
        </p>
        <p></p>
        <p>
            <strong>12</strong>
            <strong>、版权声明</strong>
        </p>
        <p>金融生态圈平台定义的网络服务内容包括:文字、软件、声音、图片、录像、图表、广告中的全部内容;电子邮件的全部内容;金融生态圈平台为用户提供的其他信息。所有这些内容受版权、商标、标签和其它财产所有权法律的保护。所以,用户只能在金融生态圈平台和原作者授权下才能使用这些内容,而不能擅自复制、再造这些内容、或创造与内容有关的派生产品。金融生态圈平台所有的内容版权归原文作者和金融生态圈平台共同所有,任何人需要转载金融生态圈平台的文章,必须征得原文作者或金融生态圈平台授权。
        </p>
        <p></p>
        <p>
            <strong>13</strong>
            <strong>、许可</strong>
        </p>
        <p>
            <strong>您为使金融生态圈平台能够使用您向金融生态圈平台提交的资料,使金融生态圈平台不违反您可能在该资料中拥有的任何权利之目的,同意向金融生态圈平台授予非独占、全球性、永久、不可撤消、免使用费、可分许可</strong>
            <strong>(通过多层许可的方式)</strong>
            <strong>的权利,以行使您在您的资料</strong>
            <strong>(在任何已知或目前为未知媒体中)</strong>
            <strong>享有的与您的资料有关的著作权、发表权和数据权(但无其它权利)。</strong>金融生态圈平台将根据隐私权保护规则使用您的资料。
        </p>
        <p>
            <strong>14</strong>
            <strong>、责任限制</strong>
        </p>
        <p>
            <strong>14.1</strong>如因不可抗力或其他金融生态圈平台无法控制的原因使金融生态圈平台系统崩溃或无法正常使用导致网上交易无法完成或丢失有关的信息、记录等,金融生态圈平台不承担责任。但是金融生态圈平台会尽可能合理地协助处理善后事宜,并努力使客户免受经济损失。
        <div></div>
        <strong>14.2</strong>除了金融生态圈平台的使用条件中规定的其它限制和除外情况之外,在中国法律法规所允许的限度内,对于因交易而引起的或与之有关的任何直接的、间接的、特殊的、附带的、后果性的或惩罚性的损害,或任何其它性质的损害,金融生态圈平台、金融生态圈平台的董事、管理人员、雇员、代理或其它代表在任何情况下都不承担责任。金融生态圈平台的全部责任,不论是合同、保证、侵权(包括过失)项下的还是其它的责任,均不超过您所购买的商品或与该索赔有关商品的金额。
        </p>
        <p>
            <strong>15</strong>
            <strong>、用户隐私制度</strong>
        </p>
        <p>金融生态圈平台设有适用于所有用户并纳入用户协议的隐私权保护规则。您在作为金融生态圈平台用户期间将受其规定(及金融生态圈平台对隐私权保护规则作出的任何修订)的约束。</p>
        <p></p>
        <p>
            <strong>16</strong>
            <strong>、一般规定</strong>
        </p>
        <p>
            <strong>16.1</strong>
            <strong>本协议在所有方面均受中华人民共和国法律管辖。任何争议,如协商不能解决,均应提交上海市浦东新区有管辖权的法院诉讼解决。</strong>
        <div></div>
        <strong>16.2</strong>本协议的规定是可分割的,如本协议任何规定被裁定为无效或不可执行,该规定可被删除而其余条款应予以执行。
        <div></div>
        <strong>16.3</strong>您同意,在发生并购时,本协议和所有纳入协议的条款和规则可由金融生态圈平台自行酌情决定向第叁方自动转让。
        <div></div>
        <strong>16.4</strong>标题仅为参考之用,在任何方面均不界定、限制、解释或描述该条的范围或限度。
        <div></div>
        <strong>16.5</strong>金融生态圈平台未就您或其他方的违约采取行动并不等于金融生态圈平台放弃就随后或类似的违约采取行动的权利。您同意,本协议不得仅由于系金融生态圈平台制订而以对金融生态圈平台不利的方式予以解释。本协议和本协议所含条款和条件载明我们双方之间就本协议标的之全部谅解和协议。
        </p>
        <p></p>
        <p>
            <strong>17</strong>
            <strong>、提供平台服务</strong>
        </p>
        <p>金融生态圈平台及其关联企业之外的其他人可能在金融生态圈平台上经营店铺、提供服务或者销售产品。另外,我们提供与关联公司和其他企业的链接。我们不负责审查和评估也不担保任何这些企业或个人的待售商品及它们网站的内容。我们对所有这些企业或任何其他第三人或其网站的行为、产品和内容不承担责任。您应仔细阅读它们自己的隐私政策及使用条件。
        </p>
        <p></p>
        <p>本协议版本于2019年2月19日更新,于2019年3月1日生效。</p>
    </view>
</template>
<script>
    export default {
        name: "user-agreement",
        data() {
            return {
            };
        }
    }
</script>
<style lang="scss" scoped>
    .con {
        color: #333;
        font-size: 26rpx;
        margin: 30rpx 0;
        height: 630rpx;
        width: 550rpx;
    }
    .con p {
        line-height: 1.65;
        margin-bottom: 5rpx;
        text-indent: 2em;
    }
    strong {
        margin-right: 5rpx;
    }
</style>
index.html
@@ -4,13 +4,18 @@
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta http-equiv="Content-Security-Policy" content="frame-src https://*.qq.com webcompt:;">
    <title>
        <%= htmlWebpackPlugin.options.title %>
    </title>
        <!-- Open Graph data -->
        <!-- <meta property="og:title" content="Title Here" /> -->
        <!-- <meta property="og:url" content="http://www.example.com/" /> -->
        <!-- <meta property="og:image" content="http://example.com/image.jpg" /> -->
        <!-- <meta property="og:description" content="Description Here" /> -->
    <link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css"/>
    <script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js"></script>
<!--    <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>-->
        <!-- <script src="<%= BASE_URL %>common/jweixin-1.6.0.js"></script> -->
        <!-- <script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script> -->
</head>
<body>
<noscript>
main.js
@@ -1,8 +1,7 @@
import App from './App'
import Vue from 'vue'
/*import Vconsole from 'vconsole';
/*import Vconsole from 'vconsole'
new Vconsole();*/
import uView from '@/uni_modules/uview-ui'
Vue.use(uView)
@@ -13,6 +12,8 @@
App.mpType = 'app'
uni.$u.props.text.color = '#333333'
// import store from '@/store/index.js'
// Vue.prototype.$store = store
Vue.config.ignoredElements.push('wx-open-launch-weapp')
manifest.json
@@ -1,7 +1,7 @@
{
    "name" : "冀驿付",
    "appid" : "__UNI__3E21AAD",
    "description" : "冀驿付",
    "name" : "支付",
    "appid" : "__UNI__895EB4F",
    "description" : "支付",
    "versionName" : "1.0.0",
    "versionCode" : "100",
    "transformPx" : false,
@@ -50,6 +50,11 @@
    "quickapp" : {},
    /* 小程序特有相关 */
    "mp-weixin" : {
        "appid" : "wxfc579973fbdde096",
        "setting" : {
            "urlCheck" : false,
            "minified" : true
        },
        "usingComponents" : true
    },
    "mp-alipay" : {
@@ -66,23 +71,14 @@
    },
    "vueVersion" : "2",
    "h5" : {
        "title" : "冀驿付",
        "title" : "支付",
        "router" : {
            "base" : "/",
            "base" : "/pay/",
            "mode" : "history"
        },
        "devServer" : {
            "proxy" : {
                "/dev-api" : {
                    "target" : "http://172.16.2.121:8080",
                    "changeOrigin" : true,
                    "secure" : false,
                    "pathRewrite" : {
                        "^/dev-api" : ""
                    }
                }
            },
            "port" : ""
            "https" : false,
            "disableHostCheck" : true
        },
        "optimization" : {
            "treeShaking" : {
package.json
@@ -9,6 +9,7 @@
  "author": "",
  "license": "ISC",
  "dependencies": {
    "mathjs": "^11.5.0",
    "vconsole": "^3.14.7",
    "weixin-js-sdk": "^1.6.0"
  },
pages.json
@@ -2,31 +2,47 @@
    "easycom": {
        "^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
    },
    "pages": [
        {
            "path": "pay/index",
    "pages": [{
            "path": "pages/pay/scanpay",
            "style": {
                "navigationBarTitleText": "冀驿付",
                "navigationBarTitleText": "支付",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        },
        {
            "path": "pay/scanpay",
        }, {
            "path": "pages/pay/discountpay",
            "style": {
                "navigationBarTitleText": "向商家付款",
                "navigationBarTitleText": "优惠",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        },
        {
            "path": "pay/paySuccess",
        },{
            "path": "pages/pay/wxpay",
            "style": {
                // #ifdef H5
                "navigationStyle": "custom"
                // #endif
            }
        }, {
            "path": "pages/pay/register",
            "style": {
                "navigationBarTitleText": "注册",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        }, {
            "path": "pages/pay/paySuccess",
            "style": {
                "navigationBarTitleText": "支付成功",
                "enablePullDownRefresh": false
@@ -35,13 +51,96 @@
                "navigationStyle": "custom"
                // #endif
            }
        }, {
            "path": "pages/pay/scanRes",
            "style": {
                "navigationStyle": "custom"
            }
        }, {
            "path": "pages/pay/login",
            "style": {
                "navigationBarTitleText": "登录",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        }, {
            "path": "pages/pay/addCardFirst",
            "style": {
                "navigationBarTitleText": "添加银行卡",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        }, {
            "path": "pages/pay/addCardSecond",
            "style": {
                "navigationBarTitleText": "添加银行卡",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        }, {
            "path": "pages/pay/addCardCode",
            "style": {
                "navigationBarTitleText": "银行卡验证码",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        }, {
            "path": "pages/pay/bindCard/bindCard",
            "style": {
                "navigationBarTitleText": "绑定银行卡",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        }, {
            "path": "pages/pay/shuaKa/shuaKa",
            "style": {
                "navigationBarTitleText": "刷卡活动",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        }, {
            "path": "pages/pay/shuaKa/introduce",
            "style": {
                "navigationBarTitleText": "活动详情",
                "enablePullDownRefresh": false
                // #ifdef H5
                ,
                "navigationStyle": "custom"
                // #endif
            }
        }
    ],
    "globalStyle": {
        "navigationBarTextStyle": "black",
        "navigationBarTitleText": "冀驿付",
        "navigationBarBackgroundColor": "#EDEDED",
        "backgroundColor": "#EDEDED"
        "navigationBarTitleText": "支付",
        "navigationBarBackgroundColor": "#FFFFFF",
        "backgroundColor": "#FFFFFF"
    },
    "uniIdRouter": {}
}
pages/pay/addCardCode.vue
New file
@@ -0,0 +1,141 @@
<template>
    <view>
        <view class="u-p-30 color-666">已发送至手机号{{form.mobile|mobile_asterisk}}</view>
        <u--form class="bg-fff u-p-h-30" labelWidth="80" :model="form" :rules="rules" ref="uForm">
            <u-form-item label="验证码" prop="code">
                <u--input v-model="form.code" border="none" placeholder="请输入手机验证码"></u--input>
                <u-button slot="right" @click="getCode" type="error" size="mini" plain :text="tips"></u-button>
            </u-form-item>
        </u--form>
        <view class="u-p-40">
            <u-button @click="doBind" :loading="loading" :disabled="loading" type="error" text="确认绑卡"></u-button>
        </view>
        <u-toast ref="uToast"></u-toast>
        <u-code :seconds="seconds" ref="uCode" @change="codeChange"></u-code>
    </view>
</template>
<script>
    import {
        signUpToApply,
        bindCard
    } from '@/common/api/index'
    const bankName = require("@/common/bankName.js");
    export default {
        data() {
            return {
                tips: '',
                seconds: 60,
                loading: false,
                form: {
                    acctName: '',
                    cardNo: '',
                    bankName: '',
                    cardType: 'DC',
                    validdate: '',
                    cvv2: '',
                    idNo: '',
                    mobile: '18737516907',
                    thpinfo: '',
                    code: ''
                },
                rules: {
                    code: [{
                        required: true,
                        message: '验证码不能为空',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        validator: (rule, value, callback) => {
                            // 上面有说,返回true表示校验通过,返回false表示不通过
                            // uni.$u.test.mobile()就是返回true或者false的
                            return uni.$u.test.code(value, 6);
                        },
                        message: '验证码格式不正确',
                        trigger: 'change'
                    }]
                }
            };
        },
        filters: {
            mobile_asterisk(mobile) {
                if (uni.$u.test.isEmpty(mobile)) {
                    return ''
                }
                return mobile.substr(0, 4) +
                    "****" + mobile.substr(8, 3);
            }
        },
        onLoad(opt) {
            opt.acctName = decodeURIComponent(opt.acctName || '')
            opt.bankName = decodeURIComponent(opt.bankName || '')
            this.form = opt
        },
        onReady() {
            //如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则。
            this.$refs.uForm.setRules(this.rules)
            this.$refs.uCode.start();
        },
        methods: {
            codeChange(text) {
                this.tips = text;
            },
            getCode() {
                if (this.$refs.uCode.canGetCode) {
                    // 模拟向后端请求验证码
                    uni.showLoading({
                        title: '正在获取验证码'
                    })
                    const params = uni.$u.deepClone(this.form);
                    delete params.thpinfo
                    delete params.code
                    delete params.bankName
                    delete params.cardType
                    signUpToApply(params).then(res => {
                        this.form.thpinfo = res
                        uni.hideLoading();
                        uni.$u.toast('验证码已发送');
                        // 通知验证码组件内部开始倒计时
                        this.$refs.uCode.start();
                    }).catch(() => {
                        uni.$u.toast('验证码发送失败');
                        uni.hideLoading();
                    })
                } else {
                    uni.$u.toast('倒计时结束后再发送');
                }
            },
            doBind() {
                this.$refs.uForm.validate().then(res => {
                    this.loading = true
                    const params = uni.$u.deepClone(this.form);
                    delete params.bankName
                    delete params.cardType
                    bindCard(params).then(res => {
                        this.loading = false
                        this.$refs.uToast.show({
                            type: 'success',
                            title: '成功',
                            message: "绑卡成功",
                            iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png',
                            complete: () => {
                                uni.navigateBack({
                                    delta: 3
                                })
                            }
                        })
                    }).catch(() => {
                        this.loading = false
                    })
                }).catch(errors => {
                })
            }
        }
    }
</script>
<style lang="scss">
</style>
pages/pay/addCardFirst.vue
New file
@@ -0,0 +1,113 @@
<template>
    <view>
        <view class="u-p-30 color-666">请绑定持卡人本人的银行卡</view>
        <u--form class="bg-fff u-p-h-30" labelWidth="80" :model="form" :rules="rules" ref="uForm">
            <u-form-item label="持卡人" prop="acctName" borderBottom>
                <u--input v-model="form.acctName" border="none" placeholder="请输入持卡人姓名"></u--input>
            </u-form-item>
            <u-form-item label="卡号" prop="cardNo">
                <u--input v-model="form.cardNo" border="none" placeholder="请输入卡号"></u--input>
            </u-form-item>
        </u--form>
        <view class="u-p-40">
            <u-button @click="doNext" :loading="loading" :disabled="loading" type="error" text="下一步"></u-button>
        </view>
    </view>
</template>
<script>
    import {
        isContain,
    } from '@/common/api/index'
    const bankName = require("@/common/bankName.js");
    export default {
        data() {
            return {
                loading: false,
                form: {
                    acctName: '',
                    cardNo: ''
                },
                rules: {
                    acctName: [{
                        required: true,
                        message: '持卡人姓名不能为空',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        validator: (rule, value, callback) => {
                            // 上面有说,返回true表示校验通过,返回false表示不通过
                            // uni.$u.test.mobile()就是返回true或者false的
                            return uni.$u.test.rangeLength(value, [2, 6]) && uni.$u.test.chinese(value);
                        },
                        message: '持卡人姓名不正确',
                        trigger: 'change'
                    }],
                    cardNo: [{
                        required: true,
                        message: '卡号不能为空',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        validator: (rule, value, callback) => {
                            // 上面有说,返回true表示校验通过,返回false表示不通过
                            // uni.$u.test.mobile()就是返回true或者false的
                            return this.$utils.verifyBankCard(value);
                        },
                        message: '卡号不正确',
                        trigger: 'change'
                    }]
                }
            };
        },
        onReady() {
            //如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则。
            this.$refs.uForm.setRules(this.rules)
        },
        methods: {
            doNext() {
                this.$refs.uForm.validate().then(res => {
                    this.loading = true
                    isContain({
                        cardNum: this.form.cardNo
                    }).then(res => {
                        uni.request({
                            url: 'https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardBinCheck=true&cardNo=' +
                                this.form.cardNo,
                            method: "GET",
                            complete: (res) => {
                                this.loading = false
                                if (res.statusCode == 200) {
                                    if (res.data.validated) {
                                        const bank = bankName.bankName[res.data.bank]
                                        const params = uni.$u.deepClone(this.form);
                                        params.cardType = res.data.cardType
                                        params.bankName = bank
                                        uni.$u.route({
                                            url: '/pages/pay/addCardSecond',
                                            params: params
                                        })
                                    } else {
                                        uni.$u.toast("卡号不正确!");
                                    }
                                } else {
                                    uni.$u.toast("卡类型获取失败!");
                                }
                            }
                        })
                    }).catch(() => {
                        this.loading = false
                    })
                }).catch(errors => {
                })
            }
        }
    }
</script>
<style lang="scss">
</style>
pages/pay/addCardSecond.vue
New file
@@ -0,0 +1,151 @@
<template>
    <view>
        <u--form class="" labelWidth="80" :model="form" :rules="rules" ref="uForm">
            <view class="u-p-h-30">
                <u-form-item label="持卡人">
                    <u--input v-model="form.acctName" readonly border="none"></u--input>
                </u-form-item>
                <u-form-item label="银行卡号">
                    <u--input v-model="form.cardNo" readonly border="none"></u--input>
                </u-form-item>
                <u-form-item label="所属银行">
                    <u--input v-model="form.bankName" readonly border="none"></u--input>
                </u-form-item>
            </view>
            <view class="bg-fff u-p-h-30 u-m-t-30">
                <block v-if="form.cardType=='CC'">
                    <u-form-item label="有效期" borderBottom prop="validdate">
                        <u--input v-model="form.validdate" border="none" placeholder="请输入信用卡有效期">
                        </u--input>
                    </u-form-item>
                    <u-form-item label="安全码" borderBottom prop="cvv2">
                        <u--input v-model="form.cvv2" border="none" placeholder="请输入信用卡安全码"></u--input>
                    </u-form-item>
                </block>
                <u-form-item label="身份证号" borderBottom prop="idNo">
                    <u--input v-model="form.idNo" border="none" placeholder="请输入持卡人身份证号"></u--input>
                </u-form-item>
                <u-form-item label="手机号" prop="mobile">
                    <u--input v-model="form.mobile" border="none" placeholder="请输入持卡人手机号"></u--input>
                </u-form-item>
            </view>
        </u--form>
        <label @click="checked=!checked" class="u-flex u-font-24 color-999 u-m-h-30 u-m-t-30">
            <radio style="transform: scale(0.7);" color="#e93b3d" @change="radioChange" :checked="checked" />我已阅读并同意
            <view @click.stop="showAgreement=true" class="" style="color: #e93b3d;">《用户协议》</view>
        </label>
        <view class="u-p-40">
            <u-button @click="doNext" :loading="loading" :disabled="loading" type="error" text="下一步"></u-button>
        </view>
        <u-popup :show="showAgreement" mode="center" :round="30">
            <card-agreement @confirm="checked=true;showAgreement=false;doNext()"></card-agreement>
        </u-popup>
    </view>
</template>
<script>
    import {
        signUpToApply,
    } from '@/common/api/index'
    export default {
        data() {
            return {
                showAgreement: false,
                checked: true,
                loading: false,
                form: {
                    acctName: '',
                    cardNo: '',
                    bankName: '',
                    cardType: 'DC',
                    validdate: '',
                    cvv2: '',
                    idNo: '',
                    mobile: ''
                },
                rules: {
                    validdate: [{
                        required: true,
                        message: '有效期不能为空',
                        trigger: 'blur'
                    }],
                    cvv2: [{
                        required: true,
                        message: '安全码不能为空',
                        trigger: 'blur'
                    }],
                    idNo: [{
                        required: true,
                        message: '身份证号不能为空',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        validator: (rule, value, callback) => {
                            // 上面有说,返回true表示校验通过,返回false表示不通过
                            // uni.$u.test.mobile()就是返回true或者false的
                            return uni.$u.test.idCard(value);
                        },
                        message: '身份证号不正确',
                        trigger: 'change'
                    }],
                    mobile: [{
                        required: true,
                        message: '手机号不能为空',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        validator: (rule, value, callback) => {
                            // 上面有说,返回true表示校验通过,返回false表示不通过
                            // uni.$u.test.mobile()就是返回true或者false的
                            return uni.$u.test.mobile(value);
                        },
                        message: '手机号不正确',
                        trigger: 'change'
                    }],
                }
            };
        },
        onLoad(opt) {
            opt.acctName = decodeURIComponent(opt.acctName || '')
            opt.bankName = decodeURIComponent(opt.bankName || '')
            this.form = opt
        },
        onReady() {
            //如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则。
            this.$refs.uForm.setRules(this.rules)
        },
        methods: {
            doNext() {
                this.$refs.uForm.validate().then(res => {
                    if (!this.checked) {
                        this.showAgreement = true
                        return
                    }
                    this.loading = true
                    const param = uni.$u.deepClone(this.form);
                    delete param.bankName
                    delete param.cardType
                    signUpToApply(param).then(res => {
                        const params = uni.$u.deepClone(this.form);
                        params.thpinfo = res
                        uni.$u.route({
                            url: '/pages/pay/addCardCode',
                            params: params
                        })
                    }).catch(() => {
                        this.loading = false
                    })
                }).catch(errors => {
                })
            }
        }
    }
</script>
<style lang="scss" scoped>
</style>
pages/pay/bindCard/bindCard.vue
New file
@@ -0,0 +1,392 @@
<template>
    <view>
        <view class="u-font-42 font-bold u-text-center u-m-t-30">添加银行卡</view>
        <view class="u-font-28 u-text-center u-m-t-10 u-m-b-60">填写以下信息进行绑卡</view>
        <u--form class="" labelWidth="80" :model="form" :rules="rules" ref="uForm">
            <u-form-item class="form-item u-m-b-24" label="持卡人" prop="acctName">
                <u--input v-model="form.acctName" inputAlign="right" border="none" :readonly="userInfo.tlAuthName" placeholder="请输入持卡人姓名"></u--input>
            </u-form-item>
            <u-form-item class="form-item u-m-b-24" label="身份证号" prop="idNo">
                <u--input v-model="form.idNo" inputAlign="right" border="none" :readonly="userInfo.tlAuthIdentityNo" placeholder="请输入持卡人身份证号"></u--input>
            </u-form-item>
            <u-form-item class="form-item u-m-b-24" label="手机号" prop="mobile">
                <u--input v-model="form.mobile" inputAlign="right" border="none" placeholder="请输入手机号"></u--input>
            </u-form-item>
            <view class="u-font-30 color-333 u-m-t-60 u-m-b-24">银行卡类别</view>
            <view class="u-flex u-row-between u-m-b-24">
                <view @click="chooseType('DC')" :class="['type-btn',{'type-act':cardType=='DC'}]">储蓄卡
                </view>
                <view @click="chooseType('CC')" :class="['type-btn',{'type-act':cardType=='CC'}]">信用卡
                </view>
            </view>
            <u-form-item class="form-item u-m-b-24" label="卡号" prop="cardNo">
                <u--input v-model="form.cardNo" inputAlign="right" border="none" placeholder="请输入持卡人本人银行卡号"></u--input>
            </u-form-item>
            <block v-if="cardType=='CC'">
                <u-form-item class="form-item u-m-b-24" label="有效期" prop="validdate">
                    <u--input v-model="form.validdate" inputAlign="right" border="none" placeholder="请输入信用卡有效期">
                    </u--input>
                </u-form-item>
                <u-form-item class="form-item u-m-b-24" label="安全码" prop="cvv2">
                    <u--input v-model="form.cvv2" inputAlign="right" border="none" placeholder="请输入信用卡安全码"></u--input>
                </u-form-item>
            </block>
            <view class="u-flex u-m-b-24">
                <u-form-item class="form-item" label="验证码" prop="code">
                    <u--input v-model="form.code" maxlength="6" inputAlign="right" border="none" placeholder="请输入验证码">
                    </u--input>
                </u-form-item>
                <view @click="getCode" class="code-btn" :class="codeAct?'code-act':''">{{tips}}</view>
            </view>
        </u--form>
        <label @click="checked=!checked" class="u-flex u-font-24 color-999 u-m-t-30">
            <radio style="transform: scale(0.7);" color="#e93b3d" @change="radioChange" :checked="checked" />我已阅读并同意
            <view @click.stop="showAgreement=true" class="" style="color: #e93b3d;">《用户协议》</view>
        </label>
        <view class="u-m-b-60" style="opacity: 0;">
            <button class="bind-btn">立即绑卡</button>
        </view>
        <view class="btn-box">
            <button @click="doBind" :loading="loading" :disabled="loading" class="bind-btn">立即绑卡</button>
        </view>
        <!-- 用户协议 -->
        <u-popup @close="showAgreement=false" :show="showAgreement" mode="center" :round="30" closeable
            :safeAreaInsetBottom="false">
            <card-agreement @confirm="checked=true;showAgreement=false;doBind()"></card-agreement>
        </u-popup>
        <!-- 首绑有礼活动 -->
        <u-popup bgColor="transparent" @close="showAct=false" :show="showAct" mode="center" :round="30"
            :safeAreaInsetBottom="false">
            <bind-card-activity :couponList="couponList" @close="showAct = false"></bind-card-activity>
        </u-popup>
        <u-toast ref="uToast"></u-toast>
        <u-code :seconds="seconds" @end="end" @start="start" ref="uCode" keepRunning changeText="已发送(x)"
            @change="codeChange"></u-code>
    </view>
</template>
<script>
    import {
        isContain,
        signUpToApply,
        bindCard,
        getMyCoupUseDetail,
        getUserInfo
    } from '@/common/api/index'
    export default {
        data() {
            return {
                showAct: false,
                couponList: [],
                bankName: '',
                cardType: 'DC',
                tips: '',
                seconds: 60,
                codeAct: true,
                showAgreement: false,
                checked: true,
                loading: false,
                userInfo: {
                    tlAuthIdentityNo: '',
                    tlAuthName: ''
                },
                form: {
                    acctName: '',
                    idNo: '',
                    cardNo: '',
                    validdate: '',
                    cvv2: '',
                    mobile: '',
                    code: ''
                },
                rules: {
                    acctName: [{
                        required: true,
                        message: '持卡人姓名不能为空',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        validator: (rule, value, callback) => {
                            // 上面有说,返回true表示校验通过,返回false表示不通过
                            // uni.$u.test.mobile()就是返回true或者false的
                            return uni.$u.test.rangeLength(value, [2, 6]) && uni.$u.test.chinese(value);
                        },
                        message: '持卡人姓名不正确',
                        trigger: 'change'
                    }],
                    idNo: [{
                        required: true,
                        message: '身份证号不能为空',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        validator: (rule, value, callback) => {
                            // 上面有说,返回true表示校验通过,返回false表示不通过
                            // uni.$u.test.mobile()就是返回true或者false的
                            return uni.$u.test.idCard(value);
                        },
                        message: '身份证号不正确',
                        trigger: 'blur'
                    }],
                    mobile: [{
                        required: true,
                        message: '手机号不能为空',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        validator: (rule, value, callback) => {
                            // 上面有说,返回true表示校验通过,返回false表示不通过
                            // uni.$u.test.mobile()就是返回true或者false的
                            return uni.$u.test.mobile(value);
                        },
                        message: '手机号不正确',
                        trigger: 'blur'
                    }],
                    cardNo: [{
                        required: true,
                        message: '卡号不能为空',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        validator: (rule, value, callback) => {
                            // 上面有说,返回true表示校验通过,返回false表示不通过
                            // uni.$u.test.mobile()就是返回true或者false的
                            return this.$utils.verifyBankCard(value);
                        },
                        message: '卡号不正确',
                        trigger: 'blur'
                    }, {
                        // 自定义验证函数,见上说明
                        asyncValidator: (rule, value, callback) => {
                            isContain({
                                params: {
                                    cardNum: value
                                }
                            }).then(res => {
                                if (res) {
                                    callback();
                                } else {
                                    callback(new Error('卡号不在卡段内'));
                                }
                            }).catch(() => {
                                callback(new Error('卡号不在卡段内'));
                            })
                        },
                        trigger: 'blur'
                    }],
                    validdate: [{
                        required: true,
                        message: '有效期不能为空',
                        trigger: 'blur'
                    }, {
                        len: 4,
                        message: '有效期不正确',
                        trigger: 'blur'
                    }],
                    cvv2: [{
                        required: true,
                        message: '安全码不能为空',
                        trigger: ['blur']
                    }, {
                        min: 3,
                        max: 4,
                        message: '安全码长度为3-4',
                        trigger: 'blur'
                    }]
                }
            };
        },
        onLoad() {
            const IS_NEW = uni.getStorageSync('IS_NEW')
            if(!IS_NEW){
                getUserInfo().then(res=>{
                    if(res){
                        this.userInfo = res
                        this.form.mobile = res.mobile
                        this.form.acctName = res.tlAuthName||res.memberName
                        this.form.idNo = res.tlAuthIdentityNo||res.idcard
                    }
                })
            }
        },
        onReady() {
            //如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则。
            this.$refs.uForm.setRules(this.rules)
        },
        methods: {
            codeChange(text) {
                this.tips = text;
            },
            end() {
                this.codeAct = true
            },
            start() {
                this.codeAct = false
            },
            // 发送验证码
            getCode() {
                if (this.$refs.uCode.canGetCode) {
                    delete this.rules.code
                    this.$refs.uForm.clearValidate();
                    this.$refs.uForm.setRules(this.rules);
                    this.$nextTick(() => {
                        this.$refs.uForm.validate().then(() => {
                            uni.showLoading({
                                title: '正在获取验证码'
                            })
                            const params = uni.$u.deepClone(this.form);
                            delete params.thpinfo
                            delete params.code
                            signUpToApply(params).then(res => {
                                this.form.thpinfo = JSON.stringify(res.thpinfo)
                                uni.hideLoading();
                                uni.$u.toast('验证码已发送');
                                // 通知验证码组件内部开始倒计时
                                this.$refs.uCode.start();
                            }).catch(() => {
                                uni.hideLoading();
                            })
                        })
                    })
                } else {
                    uni.$u.toast('倒计时结束后再发送');
                }
            },
            //选择银行卡类型
            chooseType(type) {
                this.cardType = type
            },
            //绑定银行卡
            doBind() {
                if (!this.checked) {
                    this.showAgreement = true
                    return
                }
                this.rules.code = [{
                    required: true,
                    message: '验证码不能为空',
                    trigger: 'blur'
                }, {
                    // 自定义验证函数,见上说明
                    validator: (rule, value, callback) => {
                        // 上面有说,返回true表示校验通过,返回false表示不通过
                        // uni.$u.test.mobile()就是返回true或者false的
                        return uni.$u.test.code(value, 6);
                    },
                    message: '验证码格式不正确',
                    trigger: 'blur'
                }]
                this.$refs.uForm.setRules(this.rules)
                this.$nextTick(() => {
                    this.$refs.uForm.validate().then(() => {
                        this.loading = true
                        const params = uni.$u.deepClone(this.form);
                        if (this.cardType == 'DC') {
                            delete params.validdate
                            delete params.cvv2
                        }
                        bindCard(params).then(res => {
                            getMyCoupUseDetail().then(res => {
                                this.loading = false
                                if (res && res.length > 0) {
                                    this.showAct = true
                                    this.couponList = res
                                } else {
                                    uni.showToast({
                                        icon: 'success',
                                        title: '绑卡成功',
                                        mask: true
                                    })
                                    setTimeout(() => {
                                        uni.navigateBack()
                                    }, 1000)
                                }
                            }).catch(() => {
                                this.loading = false
                            })
                        }).catch(() => {
                            this.loading = false
                        })
                    }).catch(errors => {
                    })
                })
            }
        },
    }
</script>
<style>
    page {
        background-color: #fff;
        padding: 32rpx;
        color: #333;
    }
</style>
<style lang="scss" scoped>
    .form-item {
        border: 1px solid #D9D9D9;
        border-radius: 10rpx;
        padding: 4rpx 32rpx;
    }
    ::v-deep .u-form-item__body__right__message {
        text-align: right;
    }
    .btn-box {
        width: 686rpx;
        position: fixed;
        bottom: 30rpx;
    }
    .bind-btn {
        width: 686rpx;
        height: 98rpx;
        border-radius: 10rpx;
        background: #d31f28;
        color: #fff;
        font-size: 34rpx;
    }
    .code-btn {
        background-color: #F2F2F2;
        border-radius: 10rpx;
        color: #999;
        width: 290rpx;
        height: 88rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-left: 20rpx;
    }
    .code-act {
        background-color: #D31F28;
        color: #fff;
    }
    .type-btn {
        width: 333rpx;
        height: 88rpx;
        border-radius: 10rpx;
        border: 1px solid #d9d9d9;
        background-color: #ffffff;
        font-size: 30rpx;
        color: #333;
        text-align: center;
        line-height: 88rpx;
    }
    .type-act {
        font-weight: bold;
        border-color: #D31F28;
        color: #D31F28;
        background-image: url('~@/static/check-type.png');
        background-position: right bottom;
        background-repeat: no-repeat;
        background-size: 42rpx 38rpx;
    }
</style>
pages/pay/discountpay.vue
New file
@@ -0,0 +1,616 @@
<!-- 扫码支付 -->
<template>
    <view class="page">
        <u-alert type="warning" closable description="安全提醒:请谨慎核对商家、订单信息,保护自己资金安全!"></u-alert>
        <view class="pay-box">
            <view class="u-font-26 color-666">应付金额</view>
            <view class="u-m-t-14">
                <text class="u-font-36 color-333 u-m-r-8">¥</text>
                <text class="money">{{money.split(".")[0]}}</text>
                <text class="u-font-40">.{{money.split(".")[1]}}</text>
            </view>
        </view>
        <view v-if="discountInfo.shopDiscount!=1&&money*(1-discountInfo.shopDiscount)>=0.01" class="bg-fff u-m-h-32 u-m-t-20 u-p-h-32 u-br-10">
            <view class="u-p-v-32 u-flex u-row-between u-border-bottom u-font-30 color-333">
                <view>{{discountInfo.memberGradeName}}专属折扣</view>
                <view>-{{ money*(1-discountInfo.shopDiscount).toFixed(2) }}</view>
            </view>
        </view>
        <view v-if="canUseIntegral||canUseCoupon" class="u-p-h-32 bg-fff u-m-h-32 u-br-10">
            <view class="u-font-28 u-m-t-32">选择优惠方式</view>
            <view v-if="canUseIntegral" class="u-p-v-24 u-border-bottom u-flex u-m-t-10">
                <image class="item-icon" style="align-self: flex-start;position: relative;top: -3rpx;" src="/static/integral.png" mode=""></image>
                <view class="u-flex-1 u-m-h-16">
                    <view class="u-font-30">积分抵扣</view>
                    <view class="u-font-24 color-999 u-m-t-20">可用<text style="color: #D31F28;">{{integral}}</text>积分
                    </view>
                </view>
                <input-number @handleCount="changeInt" :value="canUseInt" :min="0" :max="maxIntegral">
                </input-number>
            </view>
            <view v-if="canUseCoupon" class="u-flex u-p-v-32">
                <image class="item-icon" src="/static/coupon-icon.png" mode=""></image>
                <view class="u-font-30 u-flex-1 u-m-h-16">优惠券</view>
                <view @click="showCoupon" class="u-flex">
                    <view v-if="couponInfo.id" class="tag-pain">
                        满{{parseFloat((couponInfo.thresholdValue/100).toFixed(2))}}元减{{parseFloat((couponInfo.discount/100).toFixed(2))}}元
                    </view>
                    <text v-else class="u-font-26">请选择</text>
                    <u-icon class="u-m-l-10" name="arrow-right" color="#333" size="13"></u-icon>
                </view>
            </view>
        </view>
        <view class="bg-fff u-m-h-32 u-m-t-20 u-p-h-32 u-br-10">
            <view v-if="discount" class="u-p-v-32 u-flex u-row-between u-border-bottom u-font-30 color-333">
                <view>实际抵扣</view>
                <view>-{{ discount }}</view>
            </view>
            <view class="u-p-v-32 u-flex u-row-between">
                <view class="u-font-30 color-333">实付金额</view>
                <view class="color-red">
                    <text class="u-font-26 u-m-r-6">¥</text>
                    <text class="u-font-34">{{ price }}</text>
                </view>
            </view>
        </view>
        <button class="pay-it" @click="pay">确定支付</button>
        <!-- 优惠券弹窗 -->
        <u-popup mode="bottom" :closeable="true" :show="couponShow" @close="couponShow = false" :round="10">
            <view class="u-font-32 color-333 u-text-center u-p-t-30">优惠券</view>
            <view v-if="checkCoupon.id" class="choose-coupon">
                已选择优惠券1张,共抵扣¥{{parseFloat((checkCoupon.discount/100).toFixed(2))}}</view>
            <!-- <view class="choose-coupon">选择优惠券</view> -->
            <scroll-view scroll-y class="u-p-30 coupon-list">
                <view @click="clickCoupon(item)" class="u-m-b-24 u-flex coupon" v-for="(item, index) in couponList" :key="index">
                    <view style="color: #D31F28;" class="u-p-h-28">
                        <view class="font-bold">
                            <text class="u-font-36">¥</text>
                            <text class="money">{{parseFloat(item.discount/100)}}</text>
                        </view>
                        <view class="u-font-24 u-m-t-20">满{{parseFloat(item.thresholdValue/100)}}元使用</view>
                    </view>
                    <view class="butt"></view>
                    <view class="u-p-30 u-flex-1 u-flex">
                        <view class="u-flex-1">
                            <view class="u-font-28 color-333 u-line-2">{{item.name}}</view>
                            <view class="u-font-22 color-999 u-m-t-20">
                                有效期至:{{$u.timeFormat(item.outTime, 'yyyy-mm-dd hh:MM')}}
                            </view>
                        </view>
                        <u-icon v-if="item.id==checkCoupon.id" name="checkmark-circle-fill" color="#D31F28" size="20">
                        </u-icon>
                    </view>
                </view>
            </scroll-view>
            <view @click="getCoupon" class="coupon-btn">确定</view>
        </u-popup>
        <!-- 数字键盘 -->
        <u-popup :show="bordShow" :overlay="false" @close="bordShow = false">
            <key-bord @changeMoney="changeMoney" :num.sync="money" @close="bordShow = false" @pay="pay"></key-bord>
        </u-popup>
        <!-- 支付验证码 -->
        <u-popup :show="codeShow" closeable mode="center" @close="codeShow = false">
            <view class="u-p-h-40 u-p-b-40">
                <view class="u-text-center u-p-t-20 u-m-b-30 u-font-34">请输入手机验证码</view>
                <view class="u-text-center u-m-b-20 color-666">{{ shopInfo.shop_name }}</view>
                <view class="u-flex u-row-center font-bold u-m-b-40"><text class="u-font-42">¥</text><text class="u-font-money">{{ price }}</text>
                </view>
                <u-code-input @finish="bankPay" v-model="smscode" mode="box" :focus="true"></u-code-input>
            </view>
        </u-popup>
    </view>
</template>
<script>
    import {
        ACCESSTOKEN
    } from '@/common/config.js';
    import {
        queryMyUseSweepPayMaxCoupon,
        queryUseSweepPayCoupon,
        getWechatConfigInfo,
        saveWxOrder,
        tlPay
    } from '@/common/api/index'
    import wx from 'weixin-js-sdk'; // 使用js-sdk
    export default {
        data() {
            return {
                cid: null,
                bordShow: false, // 显示键盘
                scoreWorth: 0,
                shopInfo: {
                    shop_name: '',
                    scan_flag: '',
                    use_score_flag: 0, //商铺是否可用积分 0否 1是
                    user_coupon_flag: 0, //商铺是否可用优惠券 0否 1是
                    app_pay_use_score_flag: 0, //微信/支付宝是否可用积分 0否 1是
                    app_pay_use_coupon_flag: 0, //微信/支付宝是否可用优惠券 0否 1是
                    bank_pay_use_score_flag: 0, //银行卡支付是否可用积分 0否 1是
                    bank_pay_use_coupon_flag: 0, //银行卡支付是否可用优惠券 0否 1是
                },
                money: 0.00, // 金额
                integral: 0, // 使用积分
                canUseInt: 0, // 可用积分
                couponList: [], // 优惠券
                couponShow: false, // 优惠券弹窗
                couponInfo: {
                    id: '',
                    discount: 0,
                    thresholdValue: 0
                }, // 优惠券内容
                payWay: 3, // 5支付宝 2微信 3银行卡
                isNew: false,
                codeShow: false,
                smscode: '',
                thpinfo: null,
                canReset: false,
                checkCoupon: {
                    id: null,
                    discount: 0,
                    thresholdValue: 0
                },
                discountInfo: {
                    memberGradeName: '',
                    shopDiscount: 10
                }
            };
        },
        watch: {
            integralDiscount(val) {
                if (this.couponInfo.id && val < this.couponInfo.thresholdValue) {
                    this.couponInfo = {
                        id: '',
                        discount: 0,
                        thresholdValue: 0
                    }
                    this.checkCoupon = {
                        id: '',
                        discount: 0,
                        thresholdValue: 0
                    }
                }
            }
        },
        computed: {
            canUseIntegral() {
                if (this.payWay == 3) { //银行卡
                    return this.shopInfo.use_score_flag && this.shopInfo.bank_pay_use_score_flag
                } else {
                    return this.shopInfo.use_score_flag && this.shopInfo.app_pay_use_score_flag
                }
            },
            canUseCoupon() {
                if (this.payWay == 3) { //银行卡
                    return this.shopInfo.user_coupon_flag && this.shopInfo.bank_pay_use_coupon_flag
                } else {
                    return this.shopInfo.user_coupon_flag && this.shopInfo.app_pay_use_coupon_flag
                }
            },
            maxIntegral() {
                if (this.couponInfo.id) {
                    const num = Math.ceil((this.money * this.discountInfo.shopDiscount - this.couponInfo.thresholdValue / 100) / (
                        this.scoreWorth / 100))
                    if (num < 0) {
                        return 0
                    }
                    return num
                } else {
                    const num = Math.ceil((this.money * this.discountInfo.shopDiscount - this.couponInfo.thresholdValue / 100) / (
                        this.scoreWorth / 100))
                    if (num < 0) {
                        return 0
                    }
                    return num
                }
            },
            integralDiscount() {
                let num = 0;
                num = parseInt(parseFloat((this.money * this.discountInfo.shopDiscount * 100).toPrecision(12)) - this.canUseInt *
                    this.scoreWorth);
                return num;
            },
            discount() {
                let num = 0;
                num = ((this.canUseInt * this.scoreWorth + parseFloat(this.couponInfo.discount)) / 100).toFixed(2);
                if (parseFloat(num) > parseFloat(this.money * this.discountInfo.shopDiscount)) {
                    return this.money * this.discountInfo.shopDiscount
                }
                return num;
            },
            price() {
                let num = 0;
                num = parseFloat((this.money * this.discountInfo.shopDiscount * 100).toPrecision(12)) - this.canUseInt * this
                    .scoreWorth - this.couponInfo
                    .discount;
                num = num > 0 ? (num / 100).toFixed(2) : '0.00';
                return num;
            }
        },
        onLoad(opt) {
            this.isNew = uni.getStorageSync('IS_NEW')
            this.cid = uni.getStorageSync('CID')
            this.discountInfo = uni.getStorageSync('DISCOUNT_INFO') || {
                shopDiscount: 1
            }
            const token = uni.getStorageSync(ACCESSTOKEN) || null
            this.shopInfo = uni.getStorageSync('SHOP_INFO')
            if (opt.scoreWorth) {
                this.scoreWorth = Number(opt.scoreWorth)
            }
            if (opt.integral) {
                this.integral = Number(opt.integral)
            }
            if (opt.money) {
                this.money = parseFloat(opt.money).toFixed(2)
                let ds = parseFloat(this.discountInfo.shopDiscount)
                let dis = this.money * 100 * (1 - ds)
                let money = parseInt((this.money * 100 * ds))
                if (dis < 1) {
                    money = parseInt((this.money * 100))
                }
                queryMyUseSweepPayMaxCoupon({
                    params: {
                        shopId: this.shopInfo.id,
                        money: money < 1 ? 1 : money
                    }
                }).then(res => {
                    if (res && this.canUseCoupon) {
                        this.couponInfo = res
                        this.checkCoupon = res
                    }
                })
            }
            if (opt.payWay) {
                this.payWay = opt.payWay
            }
            if (opt.bankCardId) {
                this.bankCardId = opt.bankCardId
            }
            this.init()
        },
        methods: {
            // 更新金额
            changeMoney(str) {
                this.money = str;
            },
            // 展示键盘
            showBord() {
                this.bordShow = true;
            },
            init() {
                uni.showLoading()
                if (this.payWay == 2) {
                    const uri = encodeURIComponent(window.location)
                    getWechatConfigInfo({
                        url: uri
                    }).then(res => {
                        uni.hideLoading()
                        wx.config({
                            debug: false, // 开启调试模式
                            appId: res.appId, // 必填,公众号的唯一标识
                            timestamp: res.timestamp, // 必填,生成签名的时间戳
                            nonceStr: res.nonceStr, // 必填,生成签名的随机串
                            signature: res.signature, // 必填,签名
                            jsApiList: ['chooseWXPay'], // 必填,需要使用的 JS 接口列表
                            // openTagList: ['wx-open-launch-weapp'] //可选,需要使用的开放标签列表
                        });
                    }).catch(() => {
                        uni.hideLoading()
                    })
                }
            },
            // 更改积分
            changeInt(num) {
                this.canUseInt = num;
            },
            pay() {
                this.bordShow = false
                uni.showLoading()
                const params = {
                    money: parseFloat((this.money * 100).toPrecision(12)),
                    shopId: this.shopInfo.id,
                    cid: this.cid,
                    payWay: this.payWay,
                    score: this.canUseInt,
                    couponDetailId: this.couponInfo.id
                }
                if (this.payWay == 3) {
                    params.bankCardId = this.bankCardId
                }
                saveWxOrder(params).then(res => {
                    uni.hideLoading()
                    try {
                        this.orderId = res.orderId
                        res.youHuiInfo.shopName = this.shopInfo.shop_name
                        this.youHuiInfo = res.youHuiInfo
                        if (res.isOk == 1) {
                            uni.navigateTo({
                                url: `/pages/pay/paySuccess?orderId=${this.orderId}&youHuiInfo=${JSON
                                    .stringify(this.youHuiInfo)}`
                            })
                        } else {
                            if (res.toPayMethod == 1) {
                                if (this.payWay == 3) {
                                    this.smscode = ''
                                    this.codeShow = true
                                }
                            } else if (res.toPayMethod == 2) {
                                if (this.payWay == 2) {
                                    this.wxPay(res.paymentData)
                                }
                                if (this.payWay == 5) {
                                    this.aliPay(res.paymentData)
                                }
                            } else if (res.toPayMethod == 3) {
                                window.location.href = res.paymentUrl
                            }
                        }
                    } catch (e) {
                        //TODO handle the exception
                        console.error(e);
                    }
                }).catch(() => {
                    uni.hideLoading()
                })
            },
            // 微信支付
            wxPay(res) {
                /*setTimeout(() => {
                    wx.chooseWXPay({
                        timestamp: res.timeStamp, // 支付签名时间戳
                        nonceStr: res.nonceStr, // 支付签名随机串,不长于 32 位
                        package: res.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
                        signType: res.signType, // 微信支付V3的传入 RSA ,微信支付V2的传入格式与V2统一下单的签名格式保持一致
                        paySign: res.paySign, // 支付签名
                        success: function(res) {
                            // 支付成功后的回调函数
                            uni.navigateTo({
                                url: `/pages/pay/paySuccess?orderId=${this.orderId}&youHuiInfo=${JSON
                                    .stringify(this.youHuiInfo)}`
                            })
                        }
                    });
                }, 200)*/
                setTimeout(() => {
                    WeixinJSBridge.invoke(
                        'getBrandWCPayRequest', {
                            "appId": res.appId, //公众号ID,由商户传入
                            "timeStamp": res.timeStamp, //时间戳,自1970年以来的秒数
                            "nonceStr": res.nonceStr, //随机串
                            "package": res.package,
                            "signType": res.signType, //微信签名方式:
                            "paySign": res.paySign //微信签名
                        },
                        (res) => {
                            if (res.err_msg == "get_brand_wcpay_request:ok") {
                                // 使用以上方式判断前端返回,微信团队郑重提示:
                                //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                                /*uni.navigateTo({
                                    url: `/pages/pay/paySuccess?orderId=${this.orderId}&youHuiInfo=${JSON
                        .stringify(this.youHuiInfo)}`
                                })*/
                            }
                        });
                }, 200)
            },
            //支付宝支付
            aliPay(res) {
                ap.tradePay({
                    tradeNO: res.tradeNO
                }, (res) => {
                    if (res.resultCode == 9000) {
                        /*uni.navigateTo({
                            url: `/pages/pay/paySuccess?orderId=${this.orderId}&youHuiInfo=${JSON
                                .stringify(this.youHuiInfo)}`
                        })*/
                        // 支付成功
                    } else if (res.resultCode == 8000 || res.resultCode == 6001) {
                        // 正在处理中 || 取消
                    } else {
                        // 支付失败
                    }
                });
            },
            //银行卡支付
            bankPay(e) {
                uni.showLoading()
                tlPay({
                    orderId: this.orderId,
                    payWay: 3,
                    bankCardId: this.bankCardId,
                    smscode: e
                }).then(res => {
                    uni.hideLoading()
                    uni.hideKeyboard()
                    this.codeShow = false
                    uni.navigateTo({
                        url: `/pages/pay/paySuccess?orderId=${this.orderId}&youHuiInfo=${JSON
                            .stringify(this.youHuiInfo)}`
                    })
                }).catch(() => {
                    uni.hideLoading()
                })
            },
            //显示优惠券
            showCoupon() {
                uni.showLoading()
                queryUseSweepPayCoupon({
                    params: {
                        cusid: this.shopInfo.cusid,
                        c: this.shopInfo.c,
                        money: parseFloat((this.money * 100).toPrecision(12)),
                        score: this.canUseInt
                    }
                }).then(res => {
                    uni.hideLoading()
                    if (res.length > 0) {
                        this.couponList = res
                        this.checkCoupon = this.couponInfo
                        this.couponShow = true;
                    } else {
                        uni.showToast({
                            icon: 'none',
                            title: '暂无可用优惠券'
                        })
                    }
                }).catch(() => {
                    uni.hideLoading()
                })
            },
            clickCoupon(item) {
                if (this.checkCoupon.id == item.id) {
                    this.checkCoupon = {
                        id: '',
                        discount: 0,
                        thresholdValue: 0
                    }
                } else {
                    this.checkCoupon = item
                }
            },
            getCoupon() {
                // item 为优惠券信息
                this.couponInfo = this.checkCoupon;
                this.couponShow = false;
            }
        }
    };
</script>
<style scoped lang="scss">
    .page {
        height: calc(100vh - 0px);
        display: flex;
        flex-direction: column;
        line-height: 1;
    }
    .avg-img {
        width: 80rpx;
        height: 80rpx;
    }
    .pay-box {
        text-align: center;
        padding: 65rpx 0 42rpx;
    }
    .money {
        font-size: 64rpx;
    }
    .tag-pain {
        border: 1px solid #D31F28;
        font-size: 22rpx;
        color: #D31F28;
        border-radius: 4rpx;
        line-height: 1;
        padding: 8rpx 4rpx;
    }
    .item-icon {
        width: 38rpx;
        height: 38rpx;
    }
    .pay-it {
        position: absolute;
        width: 686rpx;
        height: 98rpx;
        bottom: 0;
        border-radius: 10rpx;
        font-size: 34rpx;
        color: #ffffff;
        background-color: #de2d35;
        margin: 32rpx;
    }
    .choose-coupon {
        margin: 32rpx 32rpx 0;
        border-radius: 10rpx;
        background: #fff1f1;
        padding: 26rpx 16rpx;
        color: #D31F28;
        font-size: 28rpx;
    }
    .coupon-list {
        box-sizing: border-box;
        height: calc(50vh - 44px);
    }
    .coupon {
        background-color: rgba(255, 241, 241, 0.47);
        height: 171rpx;
        border: solid 1rpx #f85d64;
        border-radius: 10rpx;
        position: relative;
        overflow: hidden;
    }
    .butt {
        width: 1rpx;
        height: 100%;
        position: relative;
        z-index: 9;
        border-left: 1rpx dashed #f85d64;
    }
    .butt:before {
        z-index: 10;
        box-sizing: border-box;
        position: absolute;
        content: "";
        width: 24rpx;
        height: 12rpx;
        border-bottom: 1rpx solid #f85d64;
        border-right: 1rpx solid #f85d64;
        border-left: 1rpx solid #f85d64;
        border-radius: 0 0 24rpx 24rpx;
        left: -12rpx;
        background-color: #ffffff;
    }
    .butt:after {
        box-sizing: border-box;
        position: absolute;
        content: "";
        width: 24rpx;
        height: 12rpx;
        bottom: 0;
        border-bottom: 1rpx solid #ffff;
        border-right: 1rpx solid #f85d64;
        border-left: 1rpx solid #f85d64;
        border-top: 1rpx solid #f85d64;
        border-radius: 24rpx 24rpx 0 0;
        left: -12rpx;
        background-color: #ffffff;
    }
    .coupon-btn {
        margin: 0 32rpx;
        height: 98rpx;
        border-radius: 10rpx;
        background-color: #D31F28;
        font-size: 34rpx;
        color: #fff;
        line-height: 98rpx;
        text-align: center;
    }
    .u-font-money {
        font-size: 60rpx;
    }
</style>
pages/pay/login.vue
New file
@@ -0,0 +1,42 @@
<template>
    <view>
    </view>
</template>
<script>
    import {
        config,
        ACCESSTOKEN
    } from '@/common/config.js';
    export default {
        data() {
            return {
                platform: this.$utils.getPlat()
            };
        },
        onLoad(opt) {
            uni.clearStorage()
            const redirect_uri = encodeURIComponent(`${config.webURL}/pages/pay/scanpay?cid=${opt.cid}`)
            if (this.platform == 2) {
                window.location.href =
                    `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${config.wx_appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
            } else if (this.platform == 5) {
                window.location.href =
                    `https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=${config.ali_appid}&scope=auth_base&redirect_uri=${redirect_uri}&state=STATE`
            } else if (this.platform == 15) {
                window.location.href =
                    `https://qr.95516.com/qrcGtwWeb-web/api/userAuth?version=1.0.0&redirectUrl=${redirect_uri}`
            } else {
                uni.reLaunch({
                    url: `/pages/pay/scanpay?cid=${opt.cid}`
                })
            }
        }
    }
</script>
<style lang="scss">
</style>
pages/pay/paySuccess.vue
File was renamed from pay/paySuccess.vue
@@ -7,10 +7,10 @@
                    <view class="u-font-32 font-bold u-m-t-10" style="color: #14AF0D;">支付成功</view>
                </view>
                <view class="shop-info">
                    <view class="u-text-center u-font-32 color-666">{{youHuiInfo.shopName}}</view>
                    <view class="u-text-center u-m-t-20">
                        <text class="u-font-30 lh-1">¥</text>
                        <text class="u-font-money lh-1">{{$u.priceFormat(youHuiInfo.payMoney/100, 2)}}</text>
                    <view class="u-text-center u-font-32 color-666">{{youHuiInfo.shopName}}测试门店</view>
                    <view class="u-flex u-col-top u-row-center">
                        <view class="u-font-24 lh-1">¥</view>
                        <view class="u-font-money lh-1">{{$u.priceFormat(youHuiInfo.payMoney/100, 2)}}</view>
                    </view>
                </view>
                <view class="u-flex u-m-t-30 u-font-30">
@@ -19,15 +19,15 @@
                    </view>
                    <view class="u-flex-1 u-text-right">¥{{$u.priceFormat(youHuiInfo.money/100, 2)}}</view>
                </view>
<!--                <view class="u-flex u-m-t-16 u-font-30">
                <view class="u-flex u-m-t-16 u-font-30">
                    <view class="color-999 u-flex">
                        <view class="label" style="color: #F69249;">使用积分</view>
                    </view>
                    <view class="u-flex-1 u-text-right" style="color: #F69249;">{{youHuiInfo.score}}积分<text
                            v-if="youHuiInfo.score>0">抵扣{{$u.priceFormat(youHuiInfo.scoreDkPrice/100, 2)}}元</text>
                    </view>
                </view>-->
                <view v-if="youHuiInfo.couponDkPrice!=0" class="u-flex u-m-t-16 u-font-30">
                </view>
                <view class="u-flex u-m-t-16 u-font-30">
                    <view class="color-999 u-flex">
                        <view class="label">优惠券</view>
                    </view>
@@ -62,6 +62,20 @@
                </view>
            </view>
            <view v-else-if="!join" class="box bg-fff u-m-t-20">
                <navigator class="u-flex" url="/pages/pay/shuaKa/shuaKa">
                    <image class="card-logo" :src="bankCardStyle.logo"></image>
                    <view class="u-flex-1">
                        <view class="u-font-30">领刷{{info.bankCardName}}{{info.totalDiscount/100}}元立减金</view>
                        <view class="u-font-24 color-999">参与刷卡有礼,领更多优惠</view>
                    </view>
                    <view>
                        <u-button type="success" size="mini" text="领取"></u-button>
                    </view>
                </navigator>
            </view>
            <view :url="jumpUrl" class="btn-box">
                <u-button @click="clickDone" text="完成" type="success" plain shape="circle"></u-button>
            </view>
@@ -80,14 +94,14 @@
                    </view>
                    <view class="u-flex-1">¥{{$u.priceFormat(orderInfo.orderPrice/100, 2)}}</view>
                </view>
<!--                <view class="u-flex u-m-t-30 u-font-30">
                <view class="u-flex u-m-t-30 u-font-30">
                    <view class="color-999 u-flex">
                        <view class="label">使用积分</view>:
                    </view>
                    <view class="u-flex-1">{{orderInfo.payIntegral}}积分<text
                            v-if="orderInfo.payIntegral>0">抵扣{{$u.priceFormat(orderInfo.integralMoney/100, 2)}}元</text>
                    </view>
                </view>-->
                </view>
                <view  class="u-flex u-m-t-30 u-font-30">
                    <view class="color-999 u-flex">
                        <view class="label">优惠券</view>:
@@ -102,7 +116,7 @@
                </view>
            </view>
            <view class="btn-box">
                <u-button @click="clickDone" text="完成" type="success" plain shape="circle"></u-button>
                <u-button @click="doJump" text="完成" type="success" plain shape="circle"></u-button>
            </view>
        </block>
@@ -111,12 +125,17 @@
<script>
    import {
        getPayCompleteUrl,
        getWxOrderInfo,
    } from 'common/api/index'
    } from '@/common/api/index'
    import {
        activityInfo,
        myBrushDetail,
        orderRefBrushNode
    } from '@/common/api/shuaka'
    export default {
        data() {
            return {
        plat: this.$utils.getPlat(),
                info: {
                    bankCardName: '',
                    totalDiscount: 0,
@@ -147,20 +166,33 @@
            };
        },
        onLoad(opt) {
            activityInfo().then(res => {
                this.info = res
            })
            myBrushDetail().then(res => {
                if (res) {
                    this.join = true
                } else {
                    this.join = false
                }
            })
            if (uni.getStorageSync("bankCardStyle")) {
                this.bankCardStyle = uni.getStorageSync("bankCardStyle")
            }
            getPayCompleteUrl().then(res => {
                this.jumpUrl = res
            })
            if (opt.youHuiInfo) {
                this.youHuiInfo = JSON.parse(opt.youHuiInfo)
            }
            if (opt.orderId) {
                this.orderId = opt.orderId
                /*orderRefBrushNode({
                orderRefBrushNode({
                    orderId: this.orderId
                }).then(res => {
                    this.couponList = res.coupIdsMap || []
                })*/
                })
            }
        },
        onReady() {
@@ -212,32 +244,9 @@
                return null;
            },
            clickDone() {
        let browser = navigator.userAgent.toLowerCase();
        if (browser.match(/Alipay/i) == "alipay") {
          console.log("支付宝app的浏览器");
          //这个可以关闭安卓系统的手机
          document.addEventListener("AlipayJSBridgeReady", function () {
                AlipayJSBridge.call("closeWindow");
              },
              false
          );
          //这个可以关闭ios系统的手机
          AlipayJSBridge.call('closeWebview'); //支付宝
        } else if (browser.match(/MicroMessenger/i) == "micromessenger") {
          //这个可以关闭安卓系统的手机
          document.addEventListener("WeixinJSBridgeReady", function () {
                WeixinJSBridge.call("closeWindow");
              },
              false
          );
          //这个可以关闭ios系统的手机
          WeixinJSBridge.call("closeWindow");
        } else {
          console.log("其它浏览器");
          window.opener = null;             //如果没有这行和下面的一行则会出现上面的第二个询问框。
          window.open(' ', '_self', ' ');
          window.close()
        }
                // window.close()
                WeixinJSBridge.call('closeWindow');
            },
            doJump() {
                var mchData = {
@@ -295,7 +304,7 @@
    .coupon {
        width: 638rpx;
        height: 172rpx;
        background-image: url('~@/static/pay-by-card-coupon.png');
        background-image: url('~@/static/shuaka/pay-by-card-coupon.png');
        background-size: cover;
        margin: 10rpx auto 20rpx;
        display: flex;
pages/pay/register.vue
New file
@@ -0,0 +1,218 @@
<template>
    <view class="u-p-h-50">
        <view class="title">您好,欢迎注册!</view>
        <u-form labelPosition="top" :model="form" :rules="rules" labelWidth="200"
            :labelStyle="{fontSize:'34rpx',fontWeight:'bold'}" ref="uForm">
            <u-form-item label="姓名" prop="memberName" borderBottom>
                <u-input v-model="form.memberName" border="none" placeholder="请输入姓名"></u-input>
            </u-form-item>
            <u-form-item label="身份证号" prop="idcard" borderBottom>
                <u-input v-model="form.idcard" border="none" placeholder="请输入身份证号"></u-input>
            </u-form-item>
            <u-form-item label="手机号" prop="mobile" borderBottom>
                <u-input v-model="form.mobile" border="none" placeholder="请输入手机号"></u-input>
            </u-form-item>
            <u-form-item label="图形验证码" prop="captchaCode" borderBottom>
                <u-input v-model="form.captchaCode" border="none" placeholder="请输入图形验证码"></u-input>
                <image @click="getImgCode" class="img-code" slot="right" :src="imgCode.bg" mode=""></image>
            </u-form-item>
            <u-form-item label="短信验证码" prop="verificationCode" borderBottom>
                <u-input v-model="form.verificationCode" maxlength="6" border="none" placeholder="请输入短信验证码"></u-input>
                <u-button slot="right" @tap="getCode" color="#de2d35" plain>{{tips}}</u-button>
            </u-form-item>
        </u-form>
        <view class="u-text-center u-m-t-40 color-999 u-font-24">
            <label @click="checked = !checked" class="radio">
                <radio style="transform: scale(0.7);" color="#de2d35" :checked="checked" /><text>我已阅读并同意</text>
                <text style="color: #de2d35;" @click.stop="show = true">《金融生态圈平台会员注册协议》</text>
            </label>
        </view>
        <u-modal confirmText="阅读并同意" confirmColor="#de2d35" @confirm="show = false;checked = true" :show="show" title="金融生态圈平台会员注册协议">
            <scroll-view scroll-y style="height: 60vh;">
                <user-agreement></user-agreement>
            </scroll-view>
        </u-modal>
        <u-code :seconds="seconds" ref="uCode" @change="codeChange"></u-code>
        <view class="btn-box">
            <u-button @click="submit" text="注册" type="error" color="#de2d35" shape="circle"></u-button>
        </view>
    </view>
</template>
<script>
    import {
        getVerify,
        getH5PayCheckVerifyCode,
        h5PayLogin
    } from '@/common/api/index'
    export default {
        data() {
            return {
                show: false,
                checked: true,
                cid: '',
                imgCode: {},
                tips: '',
                // refCode: null,
                seconds: 60,
                form: {
                    memberName: '',
                    idcard: '',
                    mobile: '',
                    captchaCode: '',
                    verificationCode: '',
                },
                rules: {
                    memberName: [{
                        type: 'string',
                        required: true,
                        message: '姓名不能为空',
                        trigger: ['blur']
                    }],
                    idcard: [{
                        type: 'string',
                        required: true,
                        message: '身份证号不能为空',
                        trigger: ['blur']
                    }, {
                        validator: (rule, value, callback) => {
                            return uni.$u.test.idCard(value);
                        },
                        message: '身份证号不正确',
                        // 触发器可以同时用blur和change
                        trigger: ['blur'],
                    }],
                    mobile: [{
                            type: 'string',
                            required: true,
                            message: '手机号不能为空',
                            trigger: ['blur']
                        },
                        {
                            validator: (rule, value, callback) => {
                                return uni.$u.test.mobile(value);
                            },
                            message: '手机号码不正确',
                            // 触发器可以同时用blur和change
                            trigger: ['change'],
                        }
                    ],
                    captchaCode: [{
                        type: 'string',
                        required: true,
                        message: '图形验证码不能为空',
                        trigger: ['blur', 'change']
                    }],
                    verificationCode: [{
                        type: 'string',
                        required: true,
                        message: '短信验证码不能为空',
                        trigger: ['blur', 'change']
                    }],
                },
            };
        },
        onLoad(opt) {
            this.cid = opt.cid
            this.getImgCode()
        },
        methods: {
            codeChange(text) {
                this.tips = text;
            },
            getCode() {
                if (!this.form.captchaCode) {
                    uni.showToast({
                        icon: 'none',
                        title: '请输入图形验证码'
                    })
                    return
                }
                if (!this.form.mobile) {
                    uni.showToast({
                        icon: 'none',
                        title: '请输入手机号'
                    })
                    return
                }
                if (this.$refs.uCode.canGetCode) {
                    // 模拟向后端请求验证码
                    uni.showLoading({
                        title: '正在获取验证码'
                    })
                    getH5PayCheckVerifyCode({
                        mobile: this.form.mobile,
                        captchaCode: this.form.captchaCode,
                        verifyToken: this.imgCode.token
                    }).then(res => {
                        uni.hideLoading();
                        // 这里此提示会被this.start()方法中的提示覆盖
                        uni.$u.toast('验证码已发送');
                        // 通知验证码组件内部开始倒计时
                        this.$refs.uCode.start();
                    }).catch(() => {
                        // uni.hideLoading();
                        this.getImgCode()
                    })
                } else {
                    uni.$u.toast('倒计时结束后再发送');
                }
            },
            getImgCode() {
                uni.showLoading()
                getVerify().then(res => {
                    uni.hideLoading();
                    res.bg = 'data:image/jpeg;base64,' + res.bg
                    this.imgCode = res
                }).catch(() => {
                    uni.hideLoading();
                })
            },
            submit() {
                if(!this.checked){
                    uni.showToast({
                        icon: 'none',
                        title: '请先阅读并同意用户协议'
                    })
                    return
                }
                this.$refs.uForm.validate().then(res => {
                    uni.showLoading()
                    h5PayLogin(this.form).then(res => {
                        uni.hideLoading();
                        uni.setStorageSync('IS_NEW', false)
                        uni.redirectTo({
                            url: '/pages/pay/scanpay?cid=' + this.cid
                        })
                    }).catch(() => {
                        uni.hideLoading();
                    })
                }).catch(errors => {
                    // uni.$u.toast('校验失败')
                })
            }
        },
    }
</script>
<style>
    page {
        background-color: #fff;
    }
</style>
<style lang="scss">
    .title {
        font-size: 44rpx;
        font-weight: bold;
        padding: 50rpx 0;
    }
    .btn-box {
        margin-top: 40rpx;
    }
    .img-code {
        width: 140rpx;
        height: 70rpx;
    }
</style>
pages/pay/scanRes.vue
New file
@@ -0,0 +1,116 @@
<template>
    <view>
        <movable-area :style="'width: ' + windowWidth + 'px;height:' + windowHeight + 'px'">
            <web-view :src="url">
            </web-view>
            <movable-view direction="all" x="553rpx" :y="windowHeight/2-hf" v-if="cid" @click="openPay" class="pay-btn">
                <image class="pay-img" src="/static/pay-btn.jpeg" mode=""></image>
            </movable-view>
        </movable-area>
    </view>
</template>
<script>
    import {
        ACCESSTOKEN,
        config
    } from '@/common/config.js';
    import {
        getWechatInfo,
        getOpenId,
        getOpenIdBase
    } from '@/common/api/index'
    export default {
        data() {
            return {
                hf: uni.upx2px(81),
                cid: '',
                windowHeight: 724,
                windowWidth: 0,
                url: ''
            };
        },
        onLoad(opt) {
            let sysInfo = uni.getSystemInfoSync();
            this.windowHeight = sysInfo.windowHeight;
            this.windowWidth = sysInfo.windowWidth;
            if (opt.cid) {
                uni.setStorageSync('CID', opt.cid)
                if (opt.cid == '1285474127884455937') {
                    this.url =
                        "https://fxm.xintoucloud.com/scene-user-fillin?sceneCode=DE88783ECF1D4DC2BCBF25A1A683651AFA4A9523573FF4080F2086B00E00E78A1235219708A15E8B223AAC2D243884DE"
                } else if (opt.cid == '1586530233928945664') {
                    this.url =
                        "https://fxm.xintoucloud.com/scene-user-fillin?sceneCode=622C5D9E30E54D07BCB3BF280DBEE266F4C88598A368881C81D0D8CECA02C3DB1235219708A15E8B223AAC2D243884DE"
                }
                this.cid = opt.cid
            }
            if (opt.code) {
                uni.showLoading()
                getOpenId({
                    params: {
                        code: opt.code
                    }
                }).then(res => {
                    uni.setStorageSync(ACCESSTOKEN, res.token.accessToken)
                    uni.setStorageSync('IS_NEW', res.isNew)
                    let url = '/pages/pay/scanpay?cid=' + this.cid
                    if (res.isNew) {
                        url = '/pages/pay/wxpay?cid=' + this.cid
                    }
                    uni.hideLoading()
                    uni.redirectTo({
                        url: url
                    })
                }).catch(() => {
                    uni.hideLoading()
                })
            }
        },
        methods: {
            openPay() {
                const TOKEN = uni.getStorageSync(ACCESSTOKEN) || null;
                if (TOKEN) {
                    const IS_NEW = uni.getStorageSync('IS_NEW') || null;
                    let url = '/pages/pay/scanpay?cid=' + this.cid
                    if (IS_NEW) {
                        url = '/pages/pay/wxpay?cid=' + this.cid
                    }
                    uni.redirectTo({
                        url: url
                    })
                } else {
                    uni.showLoading()
                    getWechatInfo().then(res => {
                        const redirect_uri = encodeURIComponent(
                            `${config.webURL}/pages/pay/scanRes?cid=${this.cid}`)
                        window.location.href =
                            `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${res}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
                    })
                }
            }
        }
    }
</script>
<style lang="scss">
    .pay-btn {
        position: fixed;
        z-index: 99999;
        width: 162rpx;
        height: 162rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #fff;
        border-radius: 15rpx;
        overflow: hidden;
    }
    .pay-img {
        width: 162rpx;
        height: 162rpx;
    }
</style>
pages/pay/scanpay.vue
New file
@@ -0,0 +1,876 @@
<!-- 扫码支付 -->
<template>
    <view class="page">
        <u-alert type="warning" closable description="安全提醒:请谨慎核对商家、订单信息,保护自己资金安全!"></u-alert>
        <view class="shop u-flex u-row-between">
            <view class="u-m-r-30">
                <view class="u-font-28 color-666 u-m-b-10">付款给</view>
                <view class="u-font-44 font-bold color-333">{{ shopInfo.shop_name }}</view>
            </view>
            <image :src="shopInfo.logo_image||'/static/imgs/store-logo.png'" class="avg-img"></image>
        </view>
        <view class="u-p-48 bg-fff u-flex-1 content">
            <view class="u-font-28 color-666">金额</view>
            <view class="u-p-v-20 u-flex u-border-bottom u-relative">
                <view class="money-icon color-333">¥</view>
                <view class="u-flex-1 u-flex u-m-l-10" style="height: 80rpx;">
                    <view v-if="money" class="money-num">{{ money }}</view>
                    <view :class="['cursor',{'cursor-act':!money&&bordShow}]"></view>
                    <view v-if="!money" class="u-font-50 color-999">请输入金额</view>
                    <view :class="['cursor',{'cursor-act':money&&bordShow}]"></view>
                </view>
                <view class="mask" @click="showBord"></view>
            </view>
            <view class="u-font-28 color-666 u-m-t-60">选择支付方式</view>
            <u-radio-group v-model="payWay" placement="column">
                <view v-if="platform == 15" class="u-border-bottom u-p-v-20 u-flex u-row-between">
                    <image src="@/static/imgs/pay-union.png" class="pay-icon"></image>
                    <view class="flex-1">
                        <view class="u-font-30 color-333">云闪付</view>
                        <text v-if="isNew" class="tag u-m-t-10">会员享优惠</text>
                        <text v-if="!isNew&&token&&shopInfo.use_score_flag&&shopInfo.app_pay_use_score_flag" class="u-font-24 color-999 u-m-t-10">
                            可用
                            <text class="color-red">{{ integral }}</text>
                            积分
                        </text>
                    </view>
                    <view v-if="token&&couponInfo&&shopInfo.user_coupon_flag&&shopInfo.app_pay_use_coupon_flag" class="tag-pain">
                        满{{
              parseFloat((couponInfo.thresholdValue / 100).toFixed(2))
            }}元减{{ parseFloat((couponInfo.discount / 100).toFixed(2)) }}元
                    </view>
                    <u-radio @change="radioChange($event,15)" :name="15" activeColor="#D41F28" :customStyle="{ marginLeft: '10rpx' }"></u-radio>
                </view>
                <view v-if="platform == 5" class="u-border-bottom u-p-v-20 u-flex u-row-between">
                    <image src="@/static/imgs/pay-zfb.png" class="pay-icon"></image>
                    <view class="flex-1">
                        <view class="u-font-30 color-333">支付宝</view>
                        <text v-if="isNew" class="tag u-m-t-10">会员享优惠</text>
                        <text v-if="!isNew&&token&&shopInfo.use_score_flag&&shopInfo.app_pay_use_score_flag" class="u-font-24 color-999 u-m-t-10">
                            可用
                            <text class="color-red">{{ integral }}</text>
                            积分
                        </text>
                    </view>
                    <view v-if="token&&couponInfo&&shopInfo.user_coupon_flag&&shopInfo.app_pay_use_coupon_flag" class="tag-pain">
                        满{{
              parseFloat((couponInfo.thresholdValue / 100).toFixed(2))
            }}元减{{ parseFloat((couponInfo.discount / 100).toFixed(2)) }}元
                    </view>
                    <u-radio @change="radioChange($event,5)" :name="5" activeColor="#D41F28" :customStyle="{ marginLeft: '10rpx' }"></u-radio>
                </view>
                <view v-if="platform == 2" class="u-border-bottom u-p-v-20 u-flex u-row-between">
                    <image src="@/static/imgs/pay-wx.png" class="pay-icon"></image>
                    <view class="flex-1">
                        <view class="u-font-30 color-333">微信</view>
                        <text v-if="isNew" class="tag u-m-t-10">会员享优惠</text>
                        <text v-if="!isNew&&token&&shopInfo.use_score_flag&&shopInfo.app_pay_use_score_flag" class="u-font-24 color-999 u-m-t-10">
                            可用
                            <text class="color-red">{{ integral }}</text>
                            积分
                        </text>
                    </view>
                    <view v-if="token&&couponInfo&&shopInfo.user_coupon_flag&&shopInfo.app_pay_use_coupon_flag" class="tag-pain">
                        满{{
              parseFloat((couponInfo.thresholdValue / 100).toFixed(2))
            }}元减{{ parseFloat((couponInfo.discount / 100).toFixed(2)) }}元
                    </view>
                    <u-radio @change="radioChange($event,2)" :name="2" activeColor="#D41F28" :customStyle="{ marginLeft: '10rpx' }">
                    </u-radio>
                </view>
                <navigator v-if="shuaka&&token&&bankCard!=-1" class="shuka" url="/pages/pay/shuaKa/shuaKa">
                    <image src="/static/shuaka/shuaka.png" mode=""></image>
                </navigator>
                <view v-if="bankCard.id" class="u-border-bottom u-p-v-20 u-flex">
                    <view @click="bordShow=false;bankCardOpen=true" class="flex-1 u-flex">
                        <image :src="bankCardStyle.logo" class="pay-icon"></image>
                        <view>
                            <view class="u-font-30 color-333 u-flex">
                                {{ bankCard.bankName }}({{ cardType[bankCard.cardType] }})({{ bankCard.cardNo }})
                                <u-icon name="arrow-right" color="#000">
                                </u-icon>
                            </view>
                            <!-- <text v-if="isNew" class="tag u-m-t-10">会员享优惠</text> -->
                            <text v-if="!isNew&&shopInfo.use_score_flag&&shopInfo.bank_pay_use_score_flag" class="u-font-24 color-999 u-m-t-10">
                                可用
                                <text class="color-red">{{ integral }}</text>
                                积分
                            </text>
                        </view>
                    </view>
                    <view v-if="!isNew&&shopInfo.user_coupon_flag&&shopInfo.bank_pay_use_coupon_flag&&couponInfo" class="tag-pain">
                        满{{
              parseFloat((couponInfo.thresholdValue / 100).toFixed(2))
            }}元减{{ parseFloat((couponInfo.discount / 100).toFixed(2)) }}元
                    </view>
                    <u-radio @change="radioChange($event,3)" :name="bankCard.id" activeColor="#D41F28" :customStyle="{ marginLeft: '10rpx' }">
                    </u-radio>
                </view>
            </u-radio-group>
            <navigator v-if="bankCard==-1&&bindCard&&token&&!isNew" class="shuka" url="/pages/pay/bindCard/bindCard">
                <image src="/static/bangka.png" mode=""></image>
            </navigator>
            <navigator v-if="bankCard==-1&&!isNew" url="/pages/pay/bindCard/bindCard" class="u-border-bottom u-p-v-20 u-flex u-row-between">
                <view class="u-flex-1 u-flex ">
                    <image class="pay-icon" :src="bankCardStyle.logo" mode=""></image>
                    <view class="flex-1 u-m-l-20">
                        <view class="u-font-30 color-333">银行卡</view>
                        <view class="u-font-24 color-red">绑卡可享更多优惠</view>
                    </view>
                </view>
                <u-radio disabled activeColor="#D41F28" :customStyle="{ marginLeft: '30rpx' }">
                </u-radio>
            </navigator>
            <navigator v-if="isNew" class="reg-btn" :url="'/pages/pay/register?cid='+cid">
                <image src="/static/register-btn.png" mode=""></image>
            </navigator>
        </view>
        <button class="pay-it" @click="pay">付款</button>
        <!-- 选择银行卡 -->
        <u-popup mode="bottom" :closeable="true" :show="bankCardOpen" :round="10" @close="bankCardOpen = false">
            <view class="u-font-32 color-333 u-text-center u-p-30 u-border-bottom">选择银行支付</view>
            <scroll-view scroll-y class="u-p-h-30 bankCard-list">
                <block v-for="(item,i) in bankCardList" :key="i">
                    <view @click="chooseBankCard(item)" class="u-border-bottom u-p-v-30 u-flex">
                        <view class="flex-1 u-flex">
                            <image :src="bankCardStyle.logo" class="pay-icon"></image>
                            <view>
                                <view class="u-font-26 color-333">{{ item.bankName }}</view>
                                <view class="u-m-t-10 u-font-28 color-333">{{ cardType[item.cardType] }}({{ item.cardNo }})
                                </view>
                            </view>
                        </view>
                        <u-icon name="checkbox-mark" :color="bankCardId==item.id?'#D31F28':'#fff'" size="22"></u-icon>
                    </view>
                </block>
                <navigator url="/pages/pay/bindCard/bindCard" class="u-border-bottom u-p-v-30 u-flex">
                    <view class="add-icon">
                        <u-icon name="plus" bold color="#D31F28"></u-icon>
                    </view>
                    <view class="u-font-28 color-333 u-m-l-20">使用新卡支付</view>
                </navigator>
            </scroll-view>
        </u-popup>
        <!-- 数字键盘 -->
        <u-popup :show="bordShow" :overlay="false" @close="bordShow = false">
            <key-bord @changeMoney="changeMoney" :num.sync="money" @close="bordShow = false" @pay="pay"></key-bord>
        </u-popup>
        <!-- 支付验证码 -->
        <u-popup :show="codeShow" closeable mode="center" @close="codeShow = false">
            <view class="u-p-h-40 u-p-b-40">
                <view class="u-text-center u-p-t-20 u-m-b-30 u-font-34">请输入手机验证码</view>
                <view class="u-text-center u-m-b-20 color-666">{{ shopInfo.shop_name }}</view>
                <view class="u-flex u-row-center font-bold u-m-b-40">
                    <text class="u-font-42">¥</text>
                    <text class="u-font-money">{{ money }}
                    </text>
                </view>
                <u-code-input @finish="bankPay" v-model="smscode" mode="box" :focus="true"></u-code-input>
            </view>
        </u-popup>
    </view>
</template>
<script>
    import {
        config,
        cardType,
        ACCESSTOKEN
    } from '@/common/config.js';
    import {
        headBand,
        bankCardStyle,
        myBankCard,
        queryShop,
        queryMyDiscount,
        getScoreWorth,
        userLogin,
        queryScore,
        queryMyUseSweepPayMaxCoupon,
        getWechatConfigInfo,
        saveWxOrder,
        tlPay
    } from '@/common/api/index'
    import wx from 'weixin-js-sdk'; // 使用js-sdk
    import {
        activityInfo
    } from '@/common/api/shuaka'
    export default {
        data() {
            return {
                platform: this.$utils.getPlat(),
                cardType: cardType,
                cid: '',
                bordShow: false, // 显示键盘
                scoreWorth: 0,
                shopInfo: {
                    shop_name: '',
                    scan_flag: '',
                    use_score_flag: 0, //商铺是否可用积分 0否 1是
                    user_coupon_flag: 0, //商铺是否可用优惠券 0否 1是
                    app_pay_use_score_flag: 0, //微信/支付宝是否可用积分 0否 1是
                    app_pay_use_coupon_flag: 0, //微信/支付宝是否可用优惠券 0否 1是
                    bank_pay_use_score_flag: 0, //银行卡支付是否可用积分 0否 1是
                    bank_pay_use_coupon_flag: 0, //银行卡支付是否可用优惠券 0否 1是
                },
                money: '', // 金额
                integral: 0, // 使用积分
                couponInfo: null, // 优惠券内容
                payWay: 3, //支付方式 5 支付宝 2 微信 3银行卡 15云闪付
                token: null,
                isNew: false, // 是否新用户,新用户查询不到积分和银行卡
                codeShow: false, // 银行卡支付验证码输入弹窗
                smscode: '', // 银行卡支付验证码
                thpinfo: null,
                bankCardStyle: {
                    color: '',
                    logo: ''
                },
                bankCardList: [], //银行卡列表
                bankCard: -1, // 选中银行卡
                bankCardId: null, // 选中银行卡
                bankCardOpen: false,
                canReset: false,
                end: 0,
                count: 0,
                shuaka: null, //刷卡活动
                bindCard: false, // 绑卡有礼
                discount: {
                    memberGradeName: '',
                    shopDiscount: 10
                },
                aLiUserId: ''
            };
        },
        onLoad(opt) {
            this.isNew = uni.getStorageSync('IS_NEW')
            uni.showLoading()
            this.payWay = this.platform
            if (opt.cid) {
                this.cid = opt.cid
                uni.setStorageSync('CID', opt.cid)
                this.init()
            }
            if (opt.code || opt.auth_code || opt.userAuthCode) {
                let code = opt.code
                if (this.platform == 5) {
                    code = opt.auth_code
                }
                if (this.platform == 15) {
                    code = opt.userAuthCode
                }
                this.end++
                userLogin({
                    platform: this.platform,
                    params: {
                        code
                    }
                }).then(res => {
                    this.getToken(res)
                }).catch(() => {
                    uni.hideLoading()
                })
            } else {
                if (process.env.NODE_ENV === 'development') {
                    console.log('开发环境');
                } else {
                    console.log('生产环境');
                    const redirect_uri = encodeURIComponent(window.location.href.split('?')[0] + '?cid=' + this.cid)
                    if (this.platform == 2) {
                        window.location.href =
                            `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${config.wx_appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
                    } else if (this.platform == 5) {
                        window.location.href =
                            `https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=${config.ali_appid}&scope=auth_base&redirect_uri=${redirect_uri}&state=STATE`
                    }
                }
            }
        },
        onShow() {
            this.token = uni.getStorageSync(ACCESSTOKEN) || null
            this.bordShow = false
            this.bankCardOpen = false
            this.codeShow = false
            this.smscode = ''
            if (this.canReset && this.token && !this.isNew) {
                this.end = 0
                this.count = 0
                uni.showLoading()
                this.getUserInfo()
            }
            this.canReset = true
        },
        methods: {
            getToken(res) {
                this.count++
                if (this.count >= this.end) {
                    uni.hideLoading()
                }
                this.token = res.token.accessToken
                uni.setStorageSync(ACCESSTOKEN, res.token.accessToken)
                uni.setStorageSync('IS_NEW', res.isNew)
                this.isNew = res.isNew
                if (!res.isNew) {
                    this.getUserInfo()
                }
            },
            radioChange(e, item) {
                this.bordShow = false
                this.payWay = item
            },
            // 更新金额
            changeMoney(str) {
                this.money = str;
            },
            // 展示键盘
            showBord() {
                this.bordShow = true;
            },
            init() {
                this.end += 5
                //获取商铺信息
                queryShop({
                    params: {
                        cid: this.cid
                    }
                }).then(res => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                    if (res.logo_image) {
                        try {
                            let arr = JSON.parse(res.logo_image)
                            res.logo_image = config.sftpURL + arr[0].path
                        } catch (e) {
                            //TODO handle the exception
                            res.logo_image = ''
                        }
                    }
                    uni.setStorageSync('SHOP_INFO', res)
                    this.shopInfo = res
                }).catch(() => {
                    uni.hideLoading()
                })
                // 刷卡有礼
                activityInfo().then(res => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                    this.shuaka = res
                }).catch(() => {
                    uni.hideLoading()
                })
                // 首绑有礼
                headBand().then(res => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                    this.bindCard = res
                }).catch(() => {
                    uni.hideLoading()
                })
                // 积分价值
                getScoreWorth().then(res => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                    this.scoreWorth = res.settingVal
                }).catch(() => {
                    uni.hideLoading()
                })
                //获取银行卡风格配置
                bankCardStyle().then(res => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                    try {
                        let arr = JSON.parse(res.logo)
                        res.logo = config.sftpURL + arr[0].path
                    } catch (e) {
                        //TODO handle the exception
                        res.logo = ''
                    }
                    this.bankCardStyle = res
                    uni.setStorageSync('bankCardStyle', res)
                }).catch(() => {
                    uni.hideLoading()
                })
                if (this.platform == 2) {
                    this.end += 1
                    //获取微信jsSdk配置
                    const uri = encodeURIComponent(window.location)
                    getWechatConfigInfo({
                        url: uri
                    }).then(res => {
                        this.count++
                        if (this.count >= this.end) {
                            uni.hideLoading()
                        }
                        wx.config({
                            debug: false, // 开启调试模式
                            appId: res.appId, // 必填,公众号的唯一标识
                            timestamp: res.timestamp, // 必填,生成签名的时间戳
                            nonceStr: res.noncestr, // 必填,生成签名的随机串
                            signature: res.signature, // 必填,签名
                            jsApiList: ['chooseWXPay'], // 必填,需要使用的 JS 接口列表
                            openTagList: [
                                'wx-open-launch-weapp'
                            ] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
                        });
                    }).catch(() => {
                        uni.hideLoading()
                    })
                }
            },
            // 获取会员相关信息
            getUserInfo() {
                this.end += 4
                queryMyDiscount({
                    shopId: this.shopInfo.id
                }).then(res => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                    res.shopDiscount = parseFloat(res.shopDiscount / 10)
                    this.discount = res
                    uni.setStorageSync('DISCOUNT_INFO', res)
                }).catch(() => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                })
                //获取用户银行卡
                myBankCard().then(res => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                    this.bankCardList = res.rows
                    if (res.rows[0]) {
                        this.bankCard = res.rows[0]
                        if (this.platform == 3) {
                            this.bankCardId = res.rows[0].id
                        }
                    } else {
                        this.bankCard = -1
                    }
                }).catch(() => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                })
                //获取用户积分
                queryScore().then(res => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                    this.integral = res.totalScore
                }).catch(() => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                })
                //获取用户优惠券
                queryMyUseSweepPayMaxCoupon({
                    params: {
                        shopId: this.shopInfo.id
                    }
                }).then(res => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                    this.couponInfo = res
                }).catch(() => {
                    this.count++
                    if (this.count >= this.end) {
                        uni.hideLoading()
                    }
                })
            },
            // 选择银行卡
            chooseBankCard(item) {
                this.payWay = 3
                this.bankCard = item;
                this.$nextTick(() => {
                    this.bankCardId = item.id
                    this.bankCardOpen = false
                })
            },
            //跳转营销页面
            toDiscount() {
                if (!this.isNew) { //是会员
                    if (this.integral > 0 || this.couponInfo) { //有优惠券或积分
                        if (this.payWay == 3 && (this.shopInfo.bank_pay_use_score_flag || this.shopInfo
                                .bank_pay_use_coupon_flag)) { //银行卡支付
                            uni.navigateTo({
                                url: `/pages/pay/discountpay?integral=${this.integral}&scoreWorth=${this.scoreWorth}&money=${this.money}&payWay=${this.payWay}&bankCardId=${this.bankCardId}`
                            })
                            return false
                        } else if ((this.shopInfo.use_score_flag && this.shopInfo.app_pay_use_score_flag) || (this
                                .shopInfo
                                .user_coupon_flag && this.shopInfo.app_pay_use_coupon_flag)) {
                            uni.navigateTo({
                                url: `/pages/pay/discountpay?integral=${this.integral}&scoreWorth=${this.scoreWorth}&money=${this.money}&payWay=${this.payWay}&bankCardId=${this.bankCardId}`
                            })
                            return false
                        } else if (this.discount.shopDiscount != 1) {
                            uni.navigateTo({
                                url: `/pages/pay/discountpay?integral=${this.integral}&scoreWorth=${this.scoreWorth}&money=${this.money}&payWay=${this.payWay}&bankCardId=${this.bankCardId}`
                            })
                            return false
                        } else {
                            return true
                        }
                    } else if (this.discount.shopDiscount != 1) {
                        uni.navigateTo({
                            url: `/pages/pay/discountpay?integral=${this.integral}&scoreWorth=${this.scoreWorth}&money=${this.money}&payWay=${this.payWay}&bankCardId=${this.bankCardId}`
                        })
                        return false
                    } else {
                        return true
                    }
                } else {
                    return true
                }
            },
            //确认支付
            pay() {
                if (uni.$u.test.isEmpty(this.money)) {
                    uni.$u.toast('请输入金额!')
                    return
                }
                this.bordShow = false
                //判断是否需要跳转营销页面
                if (this.toDiscount()) {
                    // 金额 this.money
                    uni.showLoading()
                    const params = {
                        money: parseFloat((this.money * 100).toPrecision(12)),
                        shopId: this.shopInfo.id,
                        cid: this.cid,
                        payWay: this.payWay,
                        score: 0,
                        couponDetailId: ''
                    }
                    if (this.payWay == 3) {
                        params.bankCardId = this.bankCardId
                    }
                    //生成订单
                    saveWxOrder(params).then(res => {
                        uni.hideLoading()
                        try {
                            this.orderId = res.orderId
                            res.youHuiInfo.shopName = this.shopInfo.shop_name
                            this.youHuiInfo = res.youHuiInfo
                            if (res.toPayMethod == 1) {
                                if (this.payWay == 3) {
                                    this.smscode = ''
                                    this.codeShow = true
                                }
                            } else if (res.toPayMethod == 2) {
                                if (this.payWay == 2) {
                                    this.wxPay(res.paymentData)
                                }
                                if (this.payWay == 5) {
                                    this.aliPay(res.paymentData)
                                }
                            } else if (res.toPayMethod == 3) {
                                window.location.href = res.paymentUrl
                            }
                        } catch (e) {
                            //TODO handle the exception
                            console.error(e);
                        }
                    }).catch(() => {
                        uni.hideLoading()
                    })
                }
            },
            // 微信支付
            wxPay(res) {
                /*setTimeout(() => {
                  wx.chooseWXPay({
                    timestamp: res.timeStamp, // 支付签名时间戳
                    nonceStr: res.nonceStr, // 支付签名随机串,不长于 32 位
                    package: res.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
                    signType: res.signType, // 微信支付V3的传入 RSA ,微信支付V2的传入格式与V2统一下单的签名格式保持一致
                    paySign: res.paySign, // 支付签名
                    success: function (res) {
                      // 支付成功后的回调函数
                      uni.navigateTo({
                        url: `/pages/pay/paySuccess?orderId=${this.orderId}&youHuiInfo=${JSON
                            .stringify(this.youHuiInfo)}`
                      })
                    }
                  });
                }, 200)*/
                setTimeout(() => {
                    WeixinJSBridge.invoke(
                        'getBrandWCPayRequest', {
                            "appId": res.appId, //公众号ID,由商户传入
                            "timeStamp": res.timeStamp, //时间戳,自1970年以来的秒数
                            "nonceStr": res.nonceStr, //随机串
                            "package": res.package,
                            "signType": res.signType, //微信签名方式:
                            "paySign": res.paySign //微信签名
                        },
                        (res) => {
                            if (res.err_msg == "get_brand_wcpay_request:ok") {
                                // 使用以上方式判断前端返回,微信团队郑重提示:
                                //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                                /*uni.navigateTo({
                                    url: `/pages/pay/paySuccess?orderId=${this.orderId}&youHuiInfo=${JSON
                      .stringify(this.youHuiInfo)}`
                                })*/
                            }
                        });
                }, 200)
            },
            //支付宝支付
            aliPay(res) {
                ap.tradePay({
                    tradeNO: res.tradeNO
                }, (res) => {
                    if (res.resultCode == 9000) {
                        /*uni.navigateTo({
                            url: `/pages/pay/paySuccess?orderId=${this.orderId}&youHuiInfo=${JSON
                .stringify(this.youHuiInfo)}`
                        })*/
                        // 支付成功
                    } else if (res.resultCode == 8000 || res.resultCode == 6001) {
                        // 正在处理中 || 取消
                    } else {
                        // 支付失败
                    }
                });
            },
            //银行卡支付
            bankPay(e) {
                uni.showLoading()
                tlPay({
                    orderId: this.orderId,
                    payWay: 3,
                    bankCardId: this.bankCardId,
                    smscode: e,
                }).then(res => {
                    uni.hideLoading()
                    uni.hideKeyboard()
                    this.codeShow = false
                    uni.navigateTo({
                        url: `/pages/pay/paySuccess?orderId=${this.orderId}&youHuiInfo=${JSON
              .stringify(this.youHuiInfo)}`
                    })
                }).catch(() => {
                    uni.hideLoading()
                })
            }
        }
    };
</script>
<style scoped lang="scss">
    .page {
        height: calc(100vh - 0px);
        display: flex;
        flex-direction: column;
    }
    .shop {
        padding: 50rpx 64rpx;
    }
    .avg-img {
        width: 94rpx;
        height: 94rpx;
        border-radius: 10rpx;
        background-color: #ffffff;
    }
    .content {
        border-radius: 40rpx 40rpx 0 0;
    }
    .money {
        font-size: 40rpx;
        color: #333;
    }
    .money-icon {
        font-size: 70rpx;
        // font-weight: bold;
        margin-right: 20rpx;
    }
    .money-num {
        font-size: 96rpx;
        // font-weight: bold;
    }
    .pay-it {
        position: absolute;
        width: 686rpx;
        height: 98rpx;
        bottom: 0;
        border-radius: 10rpx;
        font-size: 34rpx;
        color: #ffffff;
        background-color: #de2d35;
        margin: 32rpx;
    }
    .bank-card-ad {
        padding-top: 50rpx;
        background-image: url(~@/static/bank-card-ad1.png);
        background-size: 100% auto;
        background-position: top center;
        background-repeat: no-repeat;
    }
    .pay-icon {
        align-self: flex-start;
        width: 48rpx;
        height: 48rpx;
        margin-right: 20rpx;
    }
    .tag {
        background-color: #F35656;
        font-size: 20rpx;
        color: #fff;
        border-radius: 4rpx;
        line-height: 1;
        padding: 4rpx;
    }
    .tag-pain {
        border: 1px solid #D31F28;
        font-size: 22rpx;
        color: #D31F28;
        border-radius: 4rpx;
        line-height: 1;
        padding: 8rpx 4rpx;
    }
    .mask {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        bottom: 0;
        z-index: 101;
        background-color: rgba(0, 0, 0, 0);
    }
    @keyframes cursor-blinks {
        0% {
            opacity: 1;
            display: block;
        }
        50% {
            opacity: 0;
            display: none;
        }
        100% {
            opacity: 1;
            display: block;
        }
    }
    .cursor {
        border-left: 1px solid transparent;
        height: 80rpx;
    }
    .cursor-act {
        border-left: 1px solid #333;
        animation: cursor-blinks 1s infinite steps(1, start);
    }
    .reg-btn {
        display: block;
        margin-top: 30rpx;
        width: 654rpx;
        height: 198rpx;
        image {
            width: 100%;
            height: 100%;
        }
    }
    .u-font-money {
        font-size: 60rpx;
    }
    .bankCard-list {
        height: 50vh;
        width: 750rpx;
        box-sizing: border-box;
        .pay-icon {
            align-self: center;
        }
    }
    .add-icon {
        width: 50rpx;
        height: 50rpx;
        border-radius: 25rpx;
        background: #ffc0c38f;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .shuka {
        width: 678rpx;
        height: 45rpx;
        position: relative;
        left: -10rpx;
        image {
            width: 100%;
            height: 100%;
        }
    }
    .btn {
        /* position: fixed;
  bottom: 100rpx; */
        margin: 0 auto;
        margin-top: 120rpx;
        position: relative;
        width: 680rpx;
        height: 100rpx;
    }
    .wx-app {
        position: absolute;
        width: 680rpx;
        height: 100rpx;
    }
</style>
pages/pay/shuaKa/introduce.vue
New file
@@ -0,0 +1,92 @@
<template>
    <view>
        <view class="title">
            <image class="title-icon" src="/static/shuaka/title-icon1.png"></image>
            <view class="title-text">活动累积规则</view>
        </view>
        <view class="content">
            <view class="u-m-t-20">
                1、参与时间:{{$u.timeFormat(info.actStartTime, 'yyyy年mm月dd日')}}到{{$u.timeFormat(info.actEndTime, 'yyyy年mm月dd日')}},名额{{info.numOfUser}}人。
            </view>
            <view>2、累积刷卡笔数有效时间:用户成功参与活动后{{info.dayMax}}天内。</view>
            <view class="u-m-t-20">3、累积规则:用户使用活动指定银行卡进行支付,单笔支付实际支付金额大于等于{{info.numOfMin/100}}元的交易,方可累积活动刷卡笔数。</view>
            <view class="u-m-t-20">
                4、累积上限:用户参与活动后,每个自然日最多累积{{info.numOfDay}}笔活动刷卡笔数,超过{{info.numOfDay}}笔后,当天继续交易将不会计入活动刷卡笔数。</view>
        </view>
        <view class="title">
            <image class="title-icon" src="/static/shuaka/title-icon2.png"></image>
            <view class="title-text">活动规则</view>
        </view>
        <view class="content">{{info.actRules}}</view>
    </view>
</template>
<script>
    import {
        activityInfo
    } from '@/common/api/shuaka'
    export default {
        data() {
            return {
                info: {
                    bankCardName: '',
                    totalDiscount: 0,
                    dayMax: 0,
                    numOfMin: 0,
                    numOfDay: 0,
                    numOfUser: 0,
                    actRules: ''
                },
            };
        },
        onLoad() {
            activityInfo().then(res => {
                if (res) {
                    res.actRules = decodeURIComponent(res.actRules || '')
                    this.info = res
                }
            })
        }
    }
</script>
<style lang="scss" scoped>
    page {
        box-sizing: border-box;
        background-color: #ffffff;
        padding: 0 32rpx 32rpx;
    }
    .title {
        display: flex;
        justify-content: center;
        margin: 60rpx 0;
    }
    .title-icon {
        width: 42rpx;
        height: 42rpx;
        margin-top: 10rpx;
        margin-right: 10rpx;
    }
    .title-text {
        font-size: 36rpx;
        font-weight: 500;
        padding-bottom: 20rpx;
        color: #333333;
        background-image: url('~@/static/shuaka/title-bg.png');
        background-position: left bottom;
        background-size: 170rpx 14rpx;
        background-repeat: no-repeat;
    }
    .content {
        line-height: 1.5;
        font-size: 30rpx;
        font-weight: 400;
        counter-reset: #333333;
        white-space: pre-wrap;
    }
</style>
pages/pay/shuaKa/shuaKa.vue
New file
@@ -0,0 +1,673 @@
<template>
    <view>
        <view :class="join?'page1':'page'">
            <image class="logo1" :src="bankCardStyle.logo"></image>
            <view class="douyu-txt page-title">刷<text>{{info.bankCardName}}</text></view>
            <view class="douyu-txt page-title">最高可得{{info.totalDiscount/100}}元礼包</view>
            <view class="detils-title">刷{{info.bankCardName}},累积笔数获礼包 <navigator class="detail"
                    url="/pages/pay/shuaKa/introduce">详情
                </navigator>
            </view>
            <view v-if="join" class="step-box">
                <view class="step">
                    <view class="step-title">本活动剩余<text>{{diffDay}}</text>天</view>
                    <scroll-view :scroll-into-view="`step-item-${current-1}`" class="step-item-box"
                        scroll-with-animation scroll-x>
                        <view :id="`step-item-${i}`" class="jmy-flex step-item" v-for="(item,i) in milepost" :key="i">
                            <view @click="stepClick(i)" class="jmy-text-center">
                                <image class="step-icon"
                                    :src="item.lackBrushCount>0?'/static/shuaka/pay-by-card-step.png':'/static/shuaka/pay-by-card-step-act.png'">
                                </image>
                                <view :class="['step-item-title',{'step-item-title-act':current==i}]">
                                    {{item.nodeName}}
                                </view>
                            </view>
                            <view v-if="item.lackBrushCount==0&&item.curt&&i<milepost.length-1"
                                class="step-line step-line-cur"></view>
                            <view v-else-if="item.lackBrushCount>0&&i<milepost.length-1"
                                class="step-line step-line-next">
                            </view>
                            <view v-else-if="item.lackBrushCount==0&&i<milepost.length-1" class="step-line"></view>
                        </view>
                    </scroll-view>
                </view>
                <swiper @change="bindchange" next-margin="62rpx" style="height: calc(100vh - 600rpx);" :current="current">
                    <swiper-item v-for="(post,i) in milepost" :key="i">
                        <scroll-view scroll-y="true" style="height: calc(100% - 40rpx);">
                            <view class="coupon-box">
                                <view class="jmy-flex coupon-box-title">
                                    <image src="/static/shuaka/coupon-title-left.png"></image>
                                    <view v-if="post.lackBrushCount==0">你已获得以下优惠券</view>
                                    <view v-else>
                                        <view v-if="post.nodeNumOfMin-post.lackBrushCount">
                                            已刷{{post.nodeNumOfMin-post.lackBrushCount}}笔</view>
                                        <view>再刷<text style="color: #D31F28;">{{post.lackBrushCount}}</text>笔可解锁以下优惠券
                                        </view>
                                    </view>
                                    <image src="/static/shuaka/coupon-title-right.png"></image>
                                </view>
                                <view v-for="(item,i) in post.lackBrushCount==0?post.coupIdsMap:post.coupIds" :key="i"
                                    :class="['coupon',post.lackBrushCount==0?'coupon-get':'coupon-lock' ]">
                                    <view class="num">
                                        <view>
                                            <text class="unit">¥</text>
                                            <text class="money">{{parseFloat(item.discount/100)}}</text>
                                        </view>
                                        <view class="condition">
                                            满{{parseFloat((item.threshold_value||item.thresholdValue)/100)}}元使用
                                        </view>
                                    </view>
                                    <view class="info">
                                        <view class="title">{{item.name}}</view>
                                        <view v-if="item.validityDay" class="validity">
                                            有效期:领取后{{item.validityDay}}天</view>
                                        <view v-else class="validity">
                                            有效期至:{{$u.timeFormat(item.out_time||item.validityEndTime, 'yyyy-mm-dd hh:MM')}}
                                        </view>
                                    </view>
                                    <image v-if="post.lackBrushCount!=0" class="lock-icon"
                                        src="/static/shuaka/pay-by-card-lock.png" mode=""></image>
                                </view>
                            </view>
                        </scroll-view>
                    </swiper-item>
                </swiper>
                <!-- <view @click="checkNotice" :class="['notice',{'check':notice}]">通知我参与活动进展</view> -->
            </view>
            <image v-else @click="joinActivity" class="btn" src="/static/shuaka/pay-by-card-btn.png"></image>
        </view>
        <u-popup :show="popup" @close="popup=false;getDto()" mode="center" bgColor="transparent">
            <view class="popup">
                <view class="popup-title">恭喜获得</view>
                <view class="jmy-flex popup-sub-title">
                    <image src="/static/shuaka/coupon-title-left.png"></image>
                    <view>已获<text>{{couponIds.length}}</text>张优惠券</view>
                    <image src="/static/shuaka/coupon-title-right.png"></image>
                </view>
                <scroll-view class="scroll-view" scroll-y>
                    <view v-for="(item,i) in couponIds" :key="i" class="coupon1">
                        <view class="num">
                            <view>
                                <text class="unit">¥</text>
                                <text class="money">{{parseFloat(item.discount/100)}}</text>
                            </view>
                            <view class="condition">满{{parseFloat(item.threshold_value/100)}}元使用</view>
                        </view>
                        <view class="info">
                            <view class="title">{{item.name}}</view>
                            <view v-if="item.validityDay" class="validity">
                                有效期:领取后{{item.validityDay}}天</view>
                            <view v-else class="validity">
                                有效期至:{{$u.timeFormat(item.out_time||item.validityEndTime, 'yyyy-mm-dd hh:MM')}}</view>
                        </view>
                    </view>
                </scroll-view>
                <navigator class="popup-btn jmy-flex" url="/pages/myCard/myCard">查看卡包</navigator>
            </view>
            <image @click="popup=false;getDto()" class="popup-close" src="/static/shuaka/popup-close.png"></image>
        </u-popup>
    </view>
</template>
<script>
    import {
        bankCardStyle,
    } from '@/common/api/index'
    import {
        activityInfo,
        signActivity,
        myBrushDetail
    } from '@/common/api/shuaka'
    export default {
        data() {
            return {
                brushCount: 0,
                bankCardStyle: {
                    color: '',
                    logo: ''
                }, //银行卡风格
                current: 0,
                join: false,
                notice: true,
                popup: false,
                couponList: [],
                couponIds: [],
                info: {
                    bankCardName: '',
                    totalDiscount: 0,
                    milepost: []
                },
                milepost: [],
                diffDay: 0,
            };
        },
        onLoad() {
            //获取银行卡风格配置
            bankCardStyle().then(res => {
                try {
                    res.logo = this.$utils.getGoodsImg(res.logo, '2')
                } catch (e) {
                    //TODO handle the exception
                    res.logo = ''
                }
                this.bankCardStyle = res
                // console.log(this.bankCardStyle);
            }).catch(() => {
                uni.hideLoading()
            })
            /* 活动详情 */
            activityInfo().then(res => {
                this.info = res
            })
            this.getDto()
        },
        methods: {
            getDto() {
                uni.showLoading()
                /* 参与信息 */
                myBrushDetail().then(res => {
                    uni.hideLoading()
                    if (res) {
                        this.diffDay = this.$utils.getDiffDay(res.taskStartTime, res.taskEndTime)
                        this.join = true
                        this.brushCount = Number(res.brushCount)
                        res.milePost.map((item, i) => {
                            if (item.lackBrushCount == 0) {
                                this.current = i
                            }
                        })
                        res.milePost[this.current].curt = true
                        if (res.milePost[this.current].lackBrushCount == 0) {
                            this.couponList = res.milePost[this.current].coupIdsMap
                        } else {
                            this.couponList = res.milePost[this.current].coupIds
                        }
                        this.milepost = res.milePost
                    }
                }).catch(() => {
                    uni.hideLoading()
                })
            },
            stepClick(i) {
                const cur = this.milepost[i]
                if (cur.lackBrushCount == 0) {
                    this.couponList = cur.coupIdsMap
                } else {
                    this.couponList = cur.coupIds
                }
                this.current = i
            },
            bindchange({
                detail: {
                    current
                }
            }) {
                this.current = current
            },
            joinActivity() {
                signActivity().then(res => {
                    if (res.isOk) {
                        if (this.couponIds) {
                            this.couponIds = res.couponIds
                            this.popup = true
                        } else {
                            this.join = true
                            uni.showToast({
                                icon: 'success',
                                title: '参与成功'
                            })
                        }
                    } else {
                        uni.showToast({
                            icon: 'none',
                            title: res.reason
                        })
                    }
                })
            },
            checkNotice() {
                this.notice = !this.notice
            },
            closePopup() {
                this.popup = !this.popup
            },
        }
    }
</script>
<style lang="scss" scoped>
    @font-face {
        font-family: "DOUYU";
        src: url("https://zhkj.jinmingyuan.com:8443/sftpxcx/jrstq/font/DOUYU.ttf");
    }
    .jmy-flex {
        display: flex;
        align-items: center;
    }
    .jmy-flex-nowrap {
        flex-wrap: nowrap;
    }
    .jmy-text-center {
        text-align: center;
    }
    .douyu-txt {
        font-family: "DOUYU";
    }
    .page {
        min-height: 100vh;
        background-image: url('~@/static/shuaka/pay-by-card-bg.png');
        background-position: center top;
        background-color: #FDEDDE;
        background-size: 100% auto;
        background-repeat: no-repeat;
    }
    .page1 {
        min-height: 100vh;
        background-image: url('~@/static/shuaka/pay-by-card-bg-top.png');
        background-position: center top;
        background-color: #F8F9F9;
        background-size: 100% auto;
        background-repeat: no-repeat;
    }
    .logo1 {
        box-sizing: border-box;
        padding: 10rpx;
        width: 90rpx;
        height: 90rpx;
        background-color: #ffffff;
        border-radius: 45rpx;
        margin: 30rpx 30rpx 0;
    }
    .page-title {
        font-size: 60rpx;
        font-weight: 400;
        color: #6670E7;
        text-align: center;
        line-height: 1.3;
    }
    .page-title text {
        color: #FB5B4A;
    }
    .detils-title {
        width: 590rpx;
        height: 65rpx;
        line-height: 65rpx;
        margin: 20rpx auto;
        background-image: url('~@/static/shuaka/pay-by-card-dto-ttitle-bg.png');
        background-size: cover;
        color: #6670E7;
        font-size: 25rpx;
        font-weight: 400;
        text-align: center;
    }
    .detail {
        display: inline-block;
        font-size: 28rpx;
        color: #FB5B4A;
        margin-left: 30rpx;
    }
    .detail::after {
        content: '';
        display: inline-block;
        width: 10rpx;
        height: 10rpx;
        border-top: 1rpx solid #FB5B4A;
        border-right: 1rpx solid #FB5B4A;
        transform: rotate(45deg);
        position: relative;
        bottom: 4rpx;
    }
    .demo {
        display: block;
        width: 683rpx;
        height: 708rpx;
        margin: auto;
    }
    .btn {
        position: fixed;
        bottom: 30rpx;
        bottom: calc(24rpx + constant(safe-area-inset-bottom));
        /* 兼容 iOS < 11.2 */
        bottom: calc(24rpx + env(safe-area-inset-bottom));
        /* 兼容 iOS >= 11.2 */
        left: 0;
        width: 703rpx;
        height: 137rpx;
    }
    .step-box {
        flex: 1;
        background-color: #F8F9F9;
        display: flex;
        flex-direction: column;
    }
    .step {
        background-color: #ffffff;
    }
    .step-title {
        font-size: 28rpx;
        color: #7B4324;
        font-weight: 500;
        text-align: center;
        padding: 20rpx;
    }
    .step-title text {
        color: #D31F28;
        font-weight: 700;
    }
    .step-icon {
        width: 70rpx;
        height: 70rpx;
    }
    .step-item-title {
        font-size: 22rpx;
        font-weight: 400;
        color: #7B4324;
    }
    .step-item-title-act {
        color: #FB5B4A;
    }
    .step-line {
        background-image: linear-gradient(to right, #FFA91E 0, #FFA91E 100%);
        width: 117rpx;
        height: 4rpx;
        border-radius: 2rpx;
        position: relative;
        top: -20rpx;
    }
    .step-line-cur {
        background-image: linear-gradient(to right, #FFA91E 0, #FFA91E 50%, #EFEFEF 51%, #EFEFEF 100%);
    }
    .step-line-next {
        background-image: linear-gradient(to right, #EFEFEF 0, #EFEFEF 100%);
    }
    .step-item-box {
        background-color: #ffffff;
        white-space: nowrap;
    }
    .step-item {
        display: inline-flex;
        padding-bottom: 20rpx;
    }
    .step-item-box .step-item:first-child {
        padding-left: 40rpx;
    }
    .step-item-box .step-item:last-child {
        padding-right: 40rpx;
    }
    .coupon-box {
        width: 652rpx;
        margin: 32rpx;
        border-radius: 10rpx;
        border: 1rpx solid rgba(255, 177, 166, 1);
        background: linear-gradient(180.4deg, rgba(255, 255, 255, 1) 0%, rgba(255, 253, 249, 1) 100%);
    }
    .coupon-box-title {
        justify-content: center;
        text-align: center;
        margin: 20rpx;
        font-size: 28rpx;
        font-weight: 400;
        color: #333;
    }
    .coupon-box-title image {
        width: 132rpx;
        height: 21rpx;
    }
    .coupon-box-title text {
        font-size: 28rpx;
        font-weight: 400;
        color: #333;
        margin: 0 10rpx;
    }
    .coupon {
        width: 598rpx;
        height: 180rpx;
        background-size: cover;
        margin: 20rpx auto;
        display: flex;
        align-items: center;
    }
    .lock-icon {
        width: 58rpx;
        height: 58rpx;
        margin-left: 15rpx;
    }
    .coupon-get {
        background-image: url('~@/static/shuaka/pay-by-card-coupon-get.png');
    }
    .coupon-lock {
        background-image: url('~@/static/shuaka/pay-by-card-coupon-lock.png');
    }
    .num {
        color: #D31F28;
        width: 150rpx;
        text-align: center;
        display: flex;
        flex-direction: column;
        justify-content: center;
    }
    .coupon-lock .num {
        color: #CBCBCB;
    }
    .unit {
        font-size: 36rpx;
        font-weight: 900;
    }
    .money {
        line-height: 1;
        font-size: 64rpx;
        font-weight: 900;
    }
    .condition {
        font-size: 20rpx;
        font-weight: 400;
    }
    .info {
        width: 360rpx;
        display: flex;
        flex-direction: column;
        justify-content: center;
        padding: 0 10rpx;
    }
    .title {
        font-size: 26rpx;
        font-weight: 400;
        color: #333;
        overflow: hidden;
        text-overflow: ellipsis;
        /* white-space:nowrap; */
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }
    .coupon-lock .title {
        opacity: 0.33;
    }
    .validity {
        margin-top: 15rpx;
        font-size: 20rpx;
        font-weight: 400;
        color: #999;
    }
    .coupon-lock .validity {
        opacity: 0.33;
    }
    .notice {
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 24rpx;
        line-height: 1;
        font-weight: 400;
        color: #333;
        margin-bottom: 40rpx;
    }
    .notice::before {
        box-sizing: border-box;
        display: inline-block;
        content: '';
        margin-right: 10rpx;
        width: 28rpx;
        height: 28rpx;
        border: 1px solid #999;
        border-radius: 4rpx;
        transition: all 0.3s;
    }
    .notice.check::before {
        border: none;
        background-image: url('~@/static/shuaka/notice-check.png');
        background-size: cover;
        transition: all 0.3s;
    }
    .popup {
        box-sizing: border-box;
        width: 632rpx;
        height: 935rpx;
        background-image: url('~@/static/shuaka/pay-by-card-modal-bg.png');
        background-size: cover;
        padding: 210rpx 40rpx 20rpx;
    }
    .popup-close {
        display: block;
        margin: 40rpx auto 0;
        width: 64rpx;
        height: 64rpx;
    }
    .popup-title {
        font-size: 42rpx;
        font-weight: 700;
        color: #F2281F;
        text-align: center;
        line-height: 1;
        margin-top: 20rpx;
    }
    .popup-sub-title {
        justify-content: center;
        margin: 20rpx 0 10rpx;
        color: #B36C44;
        font-size: 28rpx;
    }
    .popup-sub-title view {
        margin: 0 10rpx;
    }
    .popup-sub-title text {
        color: #D31F28;
    }
    .popup-sub-title image {
        width: 132rpx;
        height: 21rpx;
    }
    .popup-btn {
        margin: 20rpx auto 0;
        width: 478rpx;
        height: 88rpx;
        border-radius: 44rpx;
        background-color: rgba(238, 68, 82, 1);
        font-size: 36rpx;
        font-weight: 500;
        color: #fff;
        justify-content: center;
    }
    .scroll-view {
        height: 435rpx;
    }
    .coupon1 {
        width: 508rpx;
        height: 145rpx;
        background-image: url('~@/static/shuaka/pay-by-card-coupon.png');
        background-size: cover;
        margin: 20rpx auto;
        display: flex;
        align-items: center;
    }
    .coupon1 .num {
        height: 110rpx;
        border-right: 1rpx dashed #FA969A;
    }
    .coupon1 .unit {
        font-size: 24rpx;
    }
    .coupon1 .money {
        font-size: 50rpx;
    }
    .coupon1 .condition {
        font-size: 20rpx;
    }
    .coupon1 .title {
        text-align: left;
        font-size: 24rpx;
    }
    .coupon1 .validity {
        font-size: 20rpx;
    }
</style>
pages/pay/wxpay.vue
New file
@@ -0,0 +1,292 @@
<template>
    <view>
        <view class="u-relative">
            <view class="u-p-30 u-flex">
                <image :src="info.logo_image||'/static/imgs/store-logo.png'" class="avg-img"></image>
                <view class="u-font-32 font-bold color-333 u-m-l-20">{{ info.shop_name }}</view>
            </view>
            <view class="pay-box bg-fff">
                <view class="u-font-24 color-666">金额</view>
                <view class="u-p-v-20 u-flex u-border-bottom-f5 u-relative">
                    <view class="money-icon color-333">¥</view>
                    <view class="u-flex-1 u-flex u-m-l-10" style="height: 80rpx;">
                        <view v-if="money" class="u-font-40">{{money}}</view>
                        <view v-if="!money&&bordShow" class="cursor"></view>
                        <view v-if="!money" class="u-font-32 color-999">请输入金额</view>
                        <view v-if="money&&bordShow" class="cursor"></view>
                    </view>
                    <!-- <u-input placeholder="请输入金额" v-model="money" border="none" disabled disabledColor="#FFFFFF"
                        placeholderStyle="color: #c0c4cc" fontSize="40rpx" color="#333"></u-input> -->
                    <view class="mask" @click="showBord"></view>
                </view>
                <view class="u-font-24 color-666 u-p-v-20">选择支付方式</view>
                <view>
                    <u-radio-group v-model="payType" placement="column">
                        <view v-if="platform == 0 || platform == 2"
                            class="u-border-bottom-f5 u-p-v-20 u-flex u-row-between">
                            <view class="flex-1 u-flex">
                                <image src="@/static/imgs/pay-wx.png" class="pay-icon"></image>
                                <view class="u-font-30 color-333 u-m-l-10">微信</view>
                            </view>
                            <u-radio :name="0" activeColor="#D41F28" :customStyle="{ marginLeft: '30rpx' }"></u-radio>
                        </view>
                        <view v-if="platform == 1 || platform == 2"
                            class="u-border-bottom-f5 u-p-v-20 u-flex u-row-between">
                            <view class="flex-1 u-flex">
                                <image src="@/static/imgs/pay-zfb.png" class="pay-icon"></image>
                                <view class="u-font-30 color-333 u-m-l-10">支付宝</view>
                            </view>
                            <u-radio :name="1" activeColor="#D41F28" :customStyle="{ marginLeft: '30rpx' }"></u-radio>
                        </view>
                        <view class="u-border-bottom-f5 u-p-v-20 u-flex u-row-between">
                            <view class="flex-1 u-flex">
                                <image src="@/static/imgs/pay-jyk.png" class="pay-icon"></image>
                                <view class="u-m-l-10 flex-1 u-flex u-row-between">
                                    <view>
                                        <view class="u-font-30 color-333">金燕卡(8646)</view>
                                        <view class="u-font-24 color-999">
                                            可用
                                            <text class="color-red">15</text>
                                            积分
                                            <text class="color-red">满40-20</text>
                                            优惠券
                                        </view>
                                    </view>
                                    <u-tag text="享8折优惠" type="error" plain size="mini"></u-tag>
                                </view>
                            </view>
                            <u-radio :name="2" activeColor="#D41F28" :customStyle="{ marginLeft: '30rpx' }"></u-radio>
                        </view>
                    </u-radio-group>
                </view>
                <button class="pay-it" @click="pay">确定支付</button>
            </view>
        </view>
        <navigator class="reg-btn" :url="'/pages/pay/register?cid='+cid">
            <image src="/static/register-btn.png" mode=""></image>
        </navigator>
        <u-popup :show="bordShow" :overlay="false" @close="close" @open="open">
            <key-bord @changeMoney="changeMoney" :num.sync="money" @close="close" @pay="pay"></key-bord>
        </u-popup>
    </view>
</template>
<script>
    import {
        config
    } from '@/common/config.js';
    import {
        queryShop,
        getWechatInfo,
        getWechatConfigInfo,
        saveWxOrder
    } from '@/common/api/index'
    import wx from 'weixin-js-sdk'; // 使用js-sdk
    export default {
        data() {
            return {
        platform: this.$utils.getPlat(),
                cid: '',
                info: {
                    shop_name: '',
                    scan_flag: '',
                    use_score_flag: '',
                    user_coupon_flag: ''
                },
                hasNum: false, // 是否输入金额
                money: '', // 金额
                transStyles: {
                    position: 'fixed',
                    bottom: 0,
                    left: 0,
                    width: '100%',
                    backgroundColor: '#FFFFFF',
                    zIndex: 1001
                },
                payType: this.$utils.getPlat(), // 支付方式
                bordShow: false // 显示键盘
            };
        },
        onLoad(opt) {
            this.cid = opt.cid
            uni.showLoading()
            queryShop({
                params: opt
            }).then(res => {
                if (res.logo_image) {
                    try {
                        let arr = JSON.parse(res.logo_image)
                        res.logo_image = config.sftpURL + arr[0].path
                    } catch (e) {
                        //TODO handle the exception
                        res.logo_image = ''
                    }
                }
                this.info = res
                this.registerSDK()
            }).catch(() => {
                uni.hideLoading()
            })
        },
        methods: {
            registerSDK() {
                const uri = encodeURIComponent(window.location)
                getWechatConfigInfo({
                    url: uri
                }).then(res => {
                    uni.hideLoading()
                    wx.config({
                        debug: false, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印。
                        appId: res.appId, // 必填,公众号的唯一标识
                        timestamp: res.timestamp, // 必填,生成签名的时间戳
                        nonceStr: res.nonceStr, // 必填,生成签名的随机串
                        signature: res.signature, // 必填,签名
                        jsApiList: ['chooseWXPay'] // 必填,需要使用的 JS 接口列表
                    });
                }).catch(() => {
                    uni.hideLoading()
                })
            },
            // 更新金额
            changeMoney(str) {
                this.money = str;
            },
            // 展示键盘
            showBord() {
                this.bordShow = true;
            },
            // 关闭键盘
            close() {
                this.bordShow = false;
            },
            pay() {
                if (!this.money) {
                    uni.showToast({
                        icon: 'none',
                        title: '请输入金额'
                    });
                    return;
                }
                uni.showLoading()
                saveWxOrder({
                    cusid: this.info.cusid,
                    c: this.info.c,
                    money: parseInt(this.money * 100)
                }).then(res => {
                    uni.hideLoading()
                    setTimeout(() => {
                        wx.chooseWXPay({
                            timestamp: res.timeStamp, // 支付签名时间戳
                            nonceStr: res.nonceStr, // 支付签名随机串,不长于 32 位
                            package: res.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
                            signType: res.signType, // 微信支付V3的传入 RSA ,微信支付V2的传入格式与V2统一下单的签名格式保持一致
                            paySign: res.paySign, // 支付签名
                            success: function(ret) {
                                // 支付成功后的回调函数
                                uni.navigateTo({
                                    url: '/pages/pay/paySuccess?youHuiInfo=' + JSON
                                        .stringify(res.youHuiInfo)
                                })
                            }
                        });
                    }, 200)
                }).catch(() => {
                    uni.hideLoading()
                })
            }
        }
    };
</script>
<style scoped lang="scss">
    .avg-img {
        width: 80rpx;
        height: 80rpx;
    }
    .reg-btn {
        display: block;
        margin: 80rpx auto 0;
        width: 686rpx;
        height: 198rpx;
        image {
            width: 100%;
            height: 100%;
        }
    }
    .pay-box {
        padding: 40rpx 20rpx;
        border-radius: 10rpx;
        margin: 0 30rpx;
    }
    .money-icon {
        font-size: 50rpx;
        font-weight: bold;
        margin-right: 20rpx;
    }
    .money-num {
        font-size: 50rpx;
        font-weight: bold;
    }
    .pay-icon {
        width: 48rpx;
        height: 48rpx;
    }
    .mask {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        bottom: 0;
        z-index: 101;
        background-color: rgba(0, 0, 0, 0);
    }
    .pay-it {
        border-radius: 50rpx;
        font-size: 34rpx;
        color: #ffffff;
        background-color: #de2d35;
        width: 90%;
        margin-top: 20rpx;
    }
    @keyframes cursor-blinks {
        0% {
            opacity: 1;
            display: block;
        }
        50% {
            opacity: 0;
            display: none;
        }
        100% {
            opacity: 1;
            display: block;
        }
    }
    .cursor {
        border-left: 1px solid #333;
        margin-left: 2px;
        height: 40rpx;
        animation: cursor-blinks 1s infinite steps(1, start)
    }
    .cursor-act {
        border-left-color: transparent;
        animation: cursor-blinks 1s infinite steps(1, start);
    }
</style>
pay/index.vue
File was deleted
pay/scanpay.vue
File was deleted
static/act-bg.png
static/bangka.png
static/bank-card-ad1.png
static/bank-card-ad2.png
static/bind-card-modal.png
static/bind-card-title.png
static/cart/icon_add.png
static/cart/icon_addLight.png
static/cart/icon_less.png
static/cart/icon_lessLight.png
static/check-type.png
static/close-icon.png
static/coupon-bg2.png
static/coupon-icon.png
static/del-icon.png
Binary files differ
static/empty.png
Binary files differ
static/imgs/del-icon.png
static/imgs/pay-jyk.png
static/imgs/pay-union.png
static/imgs/pay-wx.png
static/imgs/pay-zfb.png
static/imgs/store-logo.png
static/integral.png
static/no_coupon.png
Binary files differ
static/pay-btn.jpeg
static/pay-btn.png
static/pay-by-card-coupon.png
Binary files differ
static/paySuccess.png

static/register-btn.png
static/shuaka/coupon-title-left.png
static/shuaka/coupon-title-right.png
static/shuaka/notice-check.png
static/shuaka/pay-by-card-bg-top.png
static/shuaka/pay-by-card-bg.png
static/shuaka/pay-by-card-btn.png
static/shuaka/pay-by-card-coupon-get.png
static/shuaka/pay-by-card-coupon-lock.png
static/shuaka/pay-by-card-coupon.png
static/shuaka/pay-by-card-dto-ttitle-bg.png
static/shuaka/pay-by-card-lock.png
static/shuaka/pay-by-card-modal-bg.png
static/shuaka/pay-by-card-step-act.png
static/shuaka/pay-by-card-step.png
static/shuaka/popup-close.png
static/shuaka/shuaka.png
static/shuaka/title-bg.png
static/shuaka/title-icon1.png
static/shuaka/title-icon2.png
static/store-logo.png
Binary files differ
static/title-left.png
static/title-right.png
uni_modules/uview-ui/components/u-input/u-input.vue
@@ -88,7 +88,7 @@
 * @property {Boolean}            password                是否密码类型 ( 默认 false )
 * @property {String | Number}    maxlength                最大输入长度,设置为 -1 的时候不限制最大长度 ( 默认 -1 )
 * @property {String}            placeholder                输入框为空时的占位符
 * @property {String}            placeholderClass        指定placeholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/ ( 默认 'input-placeholder' )
 * @property {String}            placeholderClass        指定placeholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写::v-deep ( 默认 'input-placeholder' )
 * @property {String | Object}    placeholderStyle        指定placeholder的样式,字符串/对象形式,如"color: red;"
 * @property {Boolean}            showWordLimit            是否显示输入字数统计,只在 type ="text"或type ="textarea"时有效 ( 默认 false )
 * @property {String}            confirmType                设置右下角按钮的文字,兼容性详见uni-app文档 ( 默认 'done' )
uni_modules/uview-ui/components/u-parse/u-parse.vue
@@ -127,7 +127,7 @@
        // #ifndef APP-PLUS-NVUE
        let deep = ' '
        // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
        deep = '>>>'
        deep = '::v-deep'
        // #endif
        const selector = uni.createSelectorQuery()
          // #ifndef MP-ALIPAY
uni_modules/uview-ui/components/u-textarea/u-textarea.vue
@@ -48,7 +48,7 @@
 *
 * @property {String | Number}         value                    输入框的内容
 * @property {String | Number}        placeholder                输入框为空时占位符
 * @property {String}                placeholderClass        指定placeholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/ ( 默认 'input-placeholder' )
 * @property {String}                placeholderClass        指定placeholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写::v-deep ( 默认 'input-placeholder' )
 * @property {String | Object}        placeholderStyle        指定placeholder的样式,字符串/对象形式,如"color: red;"
 * @property {String | Number}        height                    输入框高度(默认 70 )
 * @property {String}                confirmType                设置键盘右下角按钮的文字,仅微信小程序,App-vue和H5有效(默认 'done' )